Merge remote-tracking branch 'origin/master' into pr/gloss-water/58324

This commit is contained in:
Alex Dima 2018-10-23 10:23:32 +02:00
commit 8f2469fa9d
2307 changed files with 65330 additions and 60876 deletions

View file

@ -1,4 +1,5 @@
{
"root": true,
"env": {
"node": true,
"es6": true
@ -16,4 +17,4 @@
"experimentalObjectRestSpread": true
}
}
}
}

View file

@ -27,5 +27,7 @@
'2018-07-30 18:00, US/Pacific': 'endgame',
'2018-08-13 12:00, US/Pacific': 'development', # 1.26.0 released
'2018-08-27 18:00, US/Pacific': 'endgame',
# '2018-09-05 12:00, US/Pacific': 'development', # 1.27.0 released
'2018-09-05 12:00, US/Pacific': 'development', # 1.27.0 released
'2018-09-24 18:00, US/Pacific': 'endgame',
# '2018-10-03 12:00, US/Pacific': 'development', # 1.28.0 released
}

View file

@ -15,12 +15,15 @@
css-less-scss: [ aeschli ],
debug-console: [],
debug: {
assignees: [ weinand ],
assignees: [ isidorn ],
assignLabel: false
},
diff-editor: [],
dropdown: [],
editor: [],
editor: {
assignees: [],
assignLabel: false
},
editor-1000-limit: [],
editor-autoclosing: [],
editor-autoindent: [],
@ -60,7 +63,7 @@
assignLabel: false
},
file-explorer: {
assignees: [ bpasero ],
assignees: [ isidorn ],
assignLabel: false
},
file-glob: [],

15
.github/commands.yml vendored
View file

@ -29,7 +29,7 @@
type: 'label',
name: '*out-of-scope',
action: 'close',
comment: "This issue is being closed to keep the number of issues in our inbox on a manageable level, we are closing issues that are not going to be addressed in the foreseeable future: We look at the number of votes the issue has received and the number of duplicate issues filed. If you disagree and feel that this issue is crucial: We are happy to listen and to reconsider.\n\nIf you wonder what we are up to, please see our [roadmap](https://aka.ms/vscoderoadmap) and [issue reporting](https://aka.ms/vscodeissuereporting) guidelines.\n\nThanks for your understanding and happy coding!"
comment: "This issue is being closed to keep the number of issues in our inbox on a manageable level, we are closing issues that are not going to be addressed in the foreseeable future: We look at the number of votes the issue has received and the number of duplicate issues filed. More details [here](https://aka.ms/vscode-out-of-scope). If you disagree and feel that this issue is crucial: We are happy to listen and to reconsider.\n\nIf you wonder what we are up to, please see our [roadmap](https://aka.ms/vscoderoadmap) and [issue reporting](https://aka.ms/vscodeissuereporting) guidelines.\n\nThanks for your understanding and happy coding!"
},
{
type: 'label',
@ -37,6 +37,12 @@
action: 'close',
comment: "This issue is caused by an extension, please file it with the repository (or contact) the extension has linked in its overview in VS Code or the [marketplace](https://aka.ms/vscodemarketplace) for VS Code. See also our [issue reporting](https://aka.ms/vscodeissuereporting) guidelines.\n\nHappy Coding!"
},
{
type: 'label',
name: '*as-designed',
action: 'close',
comment: "The described behavior is how it is expected to work. If you disagree, please explain what is expected and what is not in more detail. See also our [issue reporting](https://aka.ms/vscodeissuereporting) guidelines.\n\nHappy Coding!"
},
{
type: 'comment',
name: 'duplicate',
@ -69,5 +75,12 @@
addLabel: 'needs more info',
comment: "Thanks for creating this issue! We figured it's missing some basic information or in some other way doesn't follow our [issue reporting](https://aka.ms/vscodeissuereporting) guidelines. Please take the time to review these and update the issue.\n\nHappy Coding!"
},
{
type: 'comment',
name: 'a11ymas',
allowUsers: ['AccessibilityTestingTeam-TCS'],
action: 'updateLabels',
addLabel: 'a11ymas'
},
]
}

1
.github/locker.yml vendored
View file

@ -1,5 +1,6 @@
{
daysAfterClose: 45,
daysSinceLastUpdate: 3,
ignoredLabels: ['*out-of-scope'],
perform: true
}

17
.vscode/launch.json vendored
View file

@ -145,9 +145,9 @@
"linux": {
"runtimeExecutable": "${workspaceFolder}/scripts/code.sh"
},
"urlFilter": "*index.html*",
"urlFilter": "*workbench.html*",
"runtimeArgs": [
"--inspect=5875"
"--inspect=5875", "--no-cached-data"
],
"smartStep": true,
"skipFiles": [
@ -155,6 +155,19 @@
],
"webRoot": "${workspaceFolder}"
},
{
"type": "node",
"request": "launch",
"name": "Launch VS Code (Main Process)",
"runtimeExecutable": "${workspaceFolder}/scripts/code.sh",
"runtimeArgs": [
"--no-cached-data"
],
"smartStep": true,
"outFiles": [
"${workspaceFolder}/out/**/*.js"
]
},
{
"type": "node",
"request": "launch",

View file

@ -21,7 +21,8 @@
"out-vscode/**": true,
"i18n/**": true,
"extensions/**/out/**": true,
"test/smoke/out/**": true
"test/smoke/out/**": true,
"src/vs/base/test/node/uri.test.data.txt": true
},
"tslint.enable": true,
"lcov.path": [
@ -42,5 +43,4 @@
"emmet.excludeLanguages": [],
"typescript.preferences.importModuleSpecifier": "non-relative",
"typescript.preferences.quoteStyle": "single"
}

57
.vscode/shared.code-snippets vendored Normal file
View file

@ -0,0 +1,57 @@
{
// Each snippet is defined under a snippet name and has a scope, prefix, body and
// description. The scope defines in watch languages the snippet is applicable. The prefix is what is
// used to trigger the snippet and the body will be expanded and inserted.Possible variables are:
// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.
// Placeholders with the same ids are connected.
// Example:
"JavaScript, TypeScript Copyright Header": {
"scope": "javascript,typescript",
"prefix": [
"header",
"stub",
"copyright"
],
"body": [
"/*---------------------------------------------------------------------------------------------",
" * Copyright (c) Microsoft Corporation. All rights reserved.",
" * Licensed under the MIT License. See License.txt in the project root for license information.",
" *--------------------------------------------------------------------------------------------*/",
"",
"'use strict';",
"",
"$0"
],
"description": "Insert Copyright Statement"
},
"TS -> Inject Service": {
"description": "Constructor Injection Pattern",
"prefix": "@inject",
"body": "@$1 private readonly _$2: ${1},$0"
},
"TS -> Event & Emitter": {
"prefix": "emitter",
"description": "Add emitter and event properties",
"body": [
"private _onDid$1 = new Emitter<$2>();",
"readonly onDid$1: Event<$2> = this._onDid$1.event;"
],
},
"CSS Copyright Header": {
"scope": "css",
"prefix": [
"header",
"stub",
"copyright"
],
"body": [
"/*---------------------------------------------------------------------------------------------",
" * Copyright (c) Microsoft Corporation. All rights reserved.",
" * Licensed under the MIT License. See License.txt in the project root for license information.",
" *--------------------------------------------------------------------------------------------*/",
"",
"$0"
],
"description": "Insert Copyright Statement"
}
}

14
.vscode/tasks.json vendored
View file

@ -28,6 +28,20 @@
}
}
},
{
"type": "npm",
"script": "strict-null-check-watch",
"label": "TS - Strict Null Checks",
"isBackground": true,
"presentation": {
"reveal": "never"
},
"problemMatcher": {
"base": "$tsc-watch",
"owner": "typescript-strict-null",
"applyTo": "allDocuments"
}
},
{
"type": "gulp",
"task": "tslint",

View file

@ -1,3 +1,3 @@
disturl "https://atom.io/download/electron"
target "2.0.7"
target "2.0.11"
runtime "electron"

View file

@ -2,7 +2,7 @@
Welcome, and thank you for your interest in contributing to VS Code!
There are many ways that you can contribute, beyond writing code. The goal of this document is to provide a high-level overview of how you can get involved.
There are many ways in which you can contribute, beyond writing code. The goal of this document is to provide a high-level overview of how you can get involved.
## Asking Questions
@ -12,9 +12,9 @@ The active community will be eager to assist you. Your well-worded question will
## Providing Feedback
Your comments and feedback are welcome, and the development team is available via handful of different channels.
Your comments and feedback are welcome, and the development team is available via a handful of different channels.
See the [Feedback Channels](https://github.com/Microsoft/vscode/wiki/Feedback-Channels) wiki page for details about how to share your thoughts.
See the [Feedback Channels](https://github.com/Microsoft/vscode/wiki/Feedback-Channels) wiki page for details on how to share your thoughts.
## Reporting Issues
@ -46,14 +46,15 @@ File a single issue per problem and feature request. Do not enumerate multiple b
Do not add your issue as a comment to an existing issue unless it's for the identical input. Many issues look similar, but have different causes.
The more information you can provide, the more likely someone will be successful reproducing the issue and finding a fix.
The more information you can provide, the more likely someone will be successful at reproducing the issue and finding a fix.
The built-in tool for reporting an issue, which you can access by using `Report Issue` in VS Code's Help menu, can help streamline this process by automatically providing the version of VS Code, all your installed extensions, and your system info. Additionally, the tool will search among existing issues to see if a similar issue already exists.
Please include the following with each issue:
* Version of VS Code
* List of extensions that you have installed.
* **Tip:** You can easily add the list of extensions by creating the issue using `Report Issues` from VS Code's Help menu
* List of extensions that you have installed
* Reproducible steps (1... 2... 3...) that cause the issue
@ -87,8 +88,8 @@ Once submitted, your report will go into the [issue tracking](https://github.com
We use a bot to help us manage issues. This bot currently:
* Automatically closes any issue marked `needs-more-info` if there has been no response in past 7 days.
* Automatically locks 45 days after they are closed.
* Automatically closes any issue marked `needs-more-info` if there has been no response in the past 7 days.
* Automatically locks issues 45 days after they are closed.
If you believe the bot got something wrong, please open a new issue and let us know.

View file

@ -51,7 +51,7 @@
},
{
"name": "electron",
"version": "2.0.7",
"version": "2.0.11",
"license": "MIT",
"repositoryURL": "https://github.com/electron/electron",
"isProd": true

View file

@ -1,7 +1,9 @@
# Visual Studio Code - Open Source
[![Build Status](https://vscode.visualstudio.com/_apis/public/build/definitions/a4cdce18-a05c-4bb8-9476-5d07e63bfd76/1/badge?branch=master)](https://aka.ms/vscode-builds)
[![Gitter](https://img.shields.io/badge/chat-on%20gitter-blue.svg)](https://gitter.im/Microsoft/vscode)
[![Build Status](https://vscode.visualstudio.com/_apis/public/build/definitions/a4cdce18-a05c-4bb8-9476-5d07e63bfd76/1/badge?branchName=master)](https://aka.ms/vscode-builds)
[![Feature Requests](https://img.shields.io/github/issues/Microsoft/vscode/feature-request.svg)](https://github.com/Microsoft/vscode/issues?q=is%3Aopen+is%3Aissue+label%3Afeature-request+sort%3Areactions-%2B1-desc)
[![Bugs](https://img.shields.io/github/issues/Microsoft/vscode/bug.svg)](https://github.com/Microsoft/vscode/issues?utf8=✓&q=is%3Aissue+is%3Aopen+label%3Abug)
[![Gitter](https://img.shields.io/badge/chat-on%20gitter-yellow.svg)](https://gitter.im/Microsoft/vscode)
[VS Code](https://code.visualstudio.com) is a new type of tool that combines the simplicity of
a code editor with what developers need for their core edit-build-debug cycle. Code
@ -24,19 +26,19 @@ The [`vscode`](https://github.com/microsoft/vscode) repository is where we do de
If you are interested in fixing issues and contributing directly to the code base,
please see the document [How to Contribute](https://github.com/Microsoft/vscode/wiki/How-to-Contribute), which covers the following:
* [How to build and run from source](https://github.com/Microsoft/vscode/wiki/How-to-Contribute#build-and-run-from-source)
* [The development workflow, including debugging and running tests](https://github.com/Microsoft/vscode/wiki/How-to-Contribute#development-workflow)
* [How to build and run from source](https://github.com/Microsoft/vscode/wiki/How-to-Contribute#build-and-run)
* [The development workflow, including debugging and running tests](https://github.com/Microsoft/vscode/wiki/How-to-Contribute#debugging)
* [Coding Guidelines](https://github.com/Microsoft/vscode/wiki/Coding-Guidelines)
* [Submitting pull requests](https://github.com/Microsoft/vscode/wiki/How-to-Contribute#pull-requests)
* [Contributing to translations](https://aka.ms/vscodeloc)
Please see also our [Code of Conduct](CODE_OF_CONDUCT.md).
Please also see our [Code of Conduct](CODE_OF_CONDUCT.md).
## Feedback
* Ask a question on [Stack Overflow](https://stackoverflow.com/questions/tagged/vscode).
* Request a new feature on [GitHub](CONTRIBUTING.md).
* Vote for [popular feature requests](https://github.com/Microsoft/vscode/issues?q=is%3Aopen+is%3Aissue+label%3Afeature-request+sort%3Areactions-%2B1-desc).
* Vote for [Popular Feature Requests](https://github.com/Microsoft/vscode/issues?q=is%3Aopen+is%3Aissue+label%3Afeature-request+sort%3Areactions-%2B1-desc).
* File a bug in [GitHub Issues](https://github.com/Microsoft/vscode/issues).
* [Tweet](https://twitter.com/code) us with other feedback.
@ -44,7 +46,7 @@ Please see also our [Code of Conduct](CODE_OF_CONDUCT.md).
Many of the core components and extensions to Code live in their own repositories on GitHub. For example, the [node debug adapter](https://github.com/microsoft/vscode-node-debug) and the [mono debug adapter](https://github.com/microsoft/vscode-mono-debug).
For a complete list, please see the [Related Projects](https://github.com/Microsoft/vscode/wiki/Related-Projects) page on our wiki.
For a complete list, please visit the [Related Projects](https://github.com/Microsoft/vscode/wiki/Related-Projects) page on our [wiki](https://github.com/Microsoft/vscode/wiki).
## License

View file

@ -14,30 +14,30 @@ This project incorporates components from the projects listed below. The origina
7. atom/language-sass version 0.52.0 (https://github.com/atom/language-sass)
8. atom/language-shellscript (https://github.com/atom/language-shellscript)
9. atom/language-xml (https://github.com/atom/language-xml)
10. chjj-marked version 0.3.18 (https://github.com/npmcomponent/chjj-marked)
11. chriskempson/tomorrow-theme (https://github.com/chriskempson/tomorrow-theme)
12. Colorsublime-Themes version 0.1.0 (https://github.com/Colorsublime/Colorsublime-Themes)
13. daaain/Handlebars (https://github.com/daaain/Handlebars)
14. davidrios/pug-tmbundle (https://github.com/davidrios/pug-tmbundle)
15. definitelytyped (https://github.com/DefinitelyTyped/DefinitelyTyped)
16. demyte/language-cshtml (https://github.com/demyte/language-cshtml)
17. Document Object Model ()
18. dotnet/csharp-tmLanguage version 0.1.0 (https://github.com/dotnet/csharp-tmLanguage)
19. expand-abbreviation version 0.5.8 (https://github.com/emmetio/expand-abbreviation)
20. fadeevab/make.tmbundle (https://github.com/fadeevab/make.tmbundle)
21. freebroccolo/atom-language-swift (https://github.com/freebroccolo/atom-language-swift)
22. HTML 5.1 W3C Working Draft version 08 October 2015 (http://www.w3.org/TR/2015/WD-html51-20151008/)
23. Ikuyadeu/vscode-R (https://github.com/Ikuyadeu/vscode-R)
24. Ionic documentation version 1.2.4 (https://github.com/ionic-team/ionic-site)
25. ionide/ionide-fsgrammar (https://github.com/ionide/ionide-fsgrammar)
26. js-beautify version 1.6.8 (https://github.com/beautify-web/js-beautify)
27. Jxck/assert version 1.0.0 (https://github.com/Jxck/assert)
28. language-docker (https://github.com/moby/moby)
29. language-go version 0.39.0 (https://github.com/atom/language-go)
30. language-less (https://github.com/atom/language-less)
31. language-php (https://github.com/atom/language-php)
32. language-rust version 0.4.9 (https://github.com/zargony/atom-language-rust)
33. MagicStack/MagicPython (https://github.com/MagicStack/MagicPython)
10. chriskempson/tomorrow-theme (https://github.com/chriskempson/tomorrow-theme)
11. Colorsublime-Themes version 0.1.0 (https://github.com/Colorsublime/Colorsublime-Themes)
12. daaain/Handlebars (https://github.com/daaain/Handlebars)
13. davidrios/pug-tmbundle (https://github.com/davidrios/pug-tmbundle)
14. definitelytyped (https://github.com/DefinitelyTyped/DefinitelyTyped)
15. demyte/language-cshtml (https://github.com/demyte/language-cshtml)
16. Document Object Model ()
17. dotnet/csharp-tmLanguage version 0.1.0 (https://github.com/dotnet/csharp-tmLanguage)
18. expand-abbreviation version 0.5.8 (https://github.com/emmetio/expand-abbreviation)
19. fadeevab/make.tmbundle (https://github.com/fadeevab/make.tmbundle)
20. freebroccolo/atom-language-swift (https://github.com/freebroccolo/atom-language-swift)
21. HTML 5.1 W3C Working Draft version 08 October 2015 (http://www.w3.org/TR/2015/WD-html51-20151008/)
22. Ikuyadeu/vscode-R (https://github.com/Ikuyadeu/vscode-R)
23. Ionic documentation version 1.2.4 (https://github.com/ionic-team/ionic-site)
24. ionide/ionide-fsgrammar (https://github.com/ionide/ionide-fsgrammar)
25. js-beautify version 1.6.8 (https://github.com/beautify-web/js-beautify)
26. Jxck/assert version 1.0.0 (https://github.com/Jxck/assert)
27. language-docker (https://github.com/moby/moby)
28. language-go version 0.39.0 (https://github.com/atom/language-go)
29. language-less (https://github.com/atom/language-less)
30. language-php (https://github.com/atom/language-php)
31. language-rust version 0.4.9 (https://github.com/zargony/atom-language-rust)
32. MagicStack/MagicPython (https://github.com/MagicStack/MagicPython)
33. marked version 0.5.0 (https://github.com/markedjs/marked)
34. mdn-data version 1.1.12 (https://github.com/mdn/data)
35. Microsoft/TypeScript-TmLanguage version 0.0.1 (https://github.com/Microsoft/TypeScript-TmLanguage)
36. Microsoft/vscode-JSON.tmLanguage (https://github.com/Microsoft/vscode-JSON.tmLanguage)
@ -60,12 +60,13 @@ This project incorporates components from the projects listed below. The origina
53. textmate/markdown.tmbundle (https://github.com/textmate/markdown.tmbundle)
54. textmate/perl.tmbundle (https://github.com/textmate/perl.tmbundle)
55. textmate/ruby.tmbundle (https://github.com/textmate/ruby.tmbundle)
56. textmate/yaml.tmbundle (https://github.com/textmate/yaml.tmbundle)
57. TypeScript-TmLanguage version 0.1.8 (https://github.com/Microsoft/TypeScript-TmLanguage)
58. Unicode ()
59. vscode-logfile-highlighter version 1.2.0 (https://github.com/emilast/vscode-logfile-highlighter)
60. vscode-swift version 0.0.1 (https://github.com/owensd/vscode-swift)
61. Web Background Synchronization (https://github.com/WICG/BackgroundSync)
56. textmate/toml.tmbundle (https://github.com/textmate/toml.tmbundle)
57. textmate/yaml.tmbundle (https://github.com/textmate/yaml.tmbundle)
58. TypeScript-TmLanguage version 0.1.8 (https://github.com/Microsoft/TypeScript-TmLanguage)
59. Unicode ()
60. vscode-logfile-highlighter version 1.2.0 (https://github.com/emilast/vscode-logfile-highlighter)
61. vscode-swift version 0.0.1 (https://github.com/owensd/vscode-swift)
62. Web Background Synchronization (https://github.com/WICG/BackgroundSync)
%% atom/language-c NOTICES AND INFORMATION BEGIN HERE
@ -450,32 +451,6 @@ suitability for any purpose.
=========================================
END OF atom/language-xml NOTICES AND INFORMATION
%% chjj-marked NOTICES AND INFORMATION BEGIN HERE
=========================================
The MIT License (MIT)
Copyright (c) 2011-2014, Christopher Jeffrey (https://github.com/chjj/)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
=========================================
END OF chjj-marked NOTICES AND INFORMATION
%% chriskempson/tomorrow-theme NOTICES AND INFORMATION BEGIN HERE
=========================================
The MIT License (MIT)
@ -1072,7 +1047,7 @@ Apache License
END OF TERMS AND CONDITIONS
Copyright 2013-2017 Docker, Inc.
Copyright 2013-2018 Docker, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -1305,6 +1280,12 @@ THE SOFTWARE.
=========================================
END OF MagicStack/MagicPython NOTICES AND INFORMATION
%% marked NOTICES AND INFORMATION BEGIN HERE
=========================================
Copyright (c) 2011-2018, Christopher Jeffrey. (MIT License)
=========================================
END OF marked NOTICES AND INFORMATION
%% mdn-data NOTICES AND INFORMATION BEGIN HERE
=========================================
Mozilla Public License Version 2.0
@ -2199,6 +2180,20 @@ to the base-name name of the original file, and an extension of txt, html, or si
=========================================
END OF textmate/ruby.tmbundle NOTICES AND INFORMATION
%% textmate/toml.tmbundle NOTICES AND INFORMATION BEGIN HERE
=========================================
Copyright (c) https://github.com/infininight and https://github.com/mojombo
Permission to copy, use, modify, sell and distribute this
software is granted. This software is provided "as is" without
express or implied warranty, and with no claim as to its
suitability for any purpose
An exception is made for files in readable text which contain their own license information, or files where an accompanying
file exists (in the same directory) with a "-license" suffix added to the base-name name of the original file, and an extension .
of txt, html, or similar. For example "tidy" is accompanied by "tidy-license.txt".
=========================================
END OF textmate/toml.tmbundle NOTICES AND INFORMATION
%% textmate/yaml.tmbundle NOTICES AND INFORMATION BEGIN HERE
=========================================
Copyright (c) 2015 FichteFoll <fichtefoll2@googlemail.com>

View file

@ -1,12 +1,32 @@
[
{
"name": "ms-vscode.node-debug",
"version": "1.28.1",
"repo": "https://github.com/Microsoft/vscode-node-debug"
"version": "1.29.0",
"repo": "https://github.com/Microsoft/vscode-node-debug",
"metadata": {
"id": "b6ded8fb-a0a0-4c1c-acbd-ab2a3bc995a6",
"publisherId": {
"publisherId": "5f5636e7-69ed-4afe-b5d6-8d231fb3d3ee",
"publisherName": "ms-vscode",
"displayName": "Microsoft",
"flags": "verified"
},
"publisherDisplayName": "Microsoft"
}
},
{
"name": "ms-vscode.node-debug2",
"version": "1.28.0",
"repo": "https://github.com/Microsoft/vscode-node-debug2"
"version": "1.29.1",
"repo": "https://github.com/Microsoft/vscode-node-debug2",
"metadata": {
"id": "36d19e17-7569-4841-a001-947eb18602b2",
"publisherId": {
"publisherId": "5f5636e7-69ed-4afe-b5d6-8d231fb3d3ee",
"publisherName": "ms-vscode",
"displayName": "Microsoft",
"flags": "verified"
},
"publisherDisplayName": "Microsoft"
}
}
]
]

View file

@ -28,7 +28,7 @@ var editorEntryPoints = [
name: 'vs/editor/editor.main',
include: [],
exclude: ['vs/css', 'vs/nls'],
prepend: ['out-build/vs/css.js', 'out-build/vs/nls.js'],
prepend: ['out-editor-build/vs/css.js', 'out-editor-build/vs/nls.js'],
},
{
name: 'vs/base/common/worker/simpleWorker',
@ -79,16 +79,21 @@ gulp.task('extract-editor-src', ['clean-editor-src'], function () {
apiusages,
extrausages
],
typings: [
'typings/lib.ie11_safe_es6.d.ts',
'typings/thenable.d.ts',
'typings/es6-promise.d.ts',
'typings/require-monaco.d.ts',
'vs/monaco.d.ts'
],
libs: [
`lib.d.ts`,
`lib.es2015.collection.d.ts`
`lib.es5.d.ts`,
`lib.dom.d.ts`,
`lib.webworker.importscripts.d.ts`
],
redirects: {
'vs/base/browser/ui/octiconLabel/octiconLabel': 'vs/base/browser/ui/octiconLabel/octiconLabel.mock',
},
compilerOptions: {
module: 2, // ModuleKind.AMD
},
shakeLevel: 2, // 0-Files, 1-InnerFile, 2-ClassMembers
importIgnorePattern: /^vs\/css!/,
destRoot: path.join(root, 'out-editor-src')
@ -108,6 +113,8 @@ gulp.task('optimize-editor', ['clean-optimized-editor', 'compile-editor-build'],
loaderConfig: {
paths: {
'vs': 'out-editor-build/vs',
'vs/css': 'out-editor-build/vs/css.build',
'vs/nls': 'out-editor-build/vs/nls.build',
'vscode': 'empty:'
}
},
@ -125,7 +132,7 @@ gulp.task('clean-editor-esm', util.rimraf('out-editor-esm'));
gulp.task('extract-editor-esm', ['clean-editor-esm', 'clean-editor-distro', 'extract-editor-src'], function () {
standalone.createESMSourcesAndResources2({
srcFolder: './out-editor-src',
outFolder: './out-editor-esm/src',
outFolder: './out-editor-esm',
outResourcesFolder: './out-monaco-editor-core/esm',
ignores: [
'inlineEntryPoint:0.ts',

View file

@ -21,6 +21,7 @@ const nlsDev = require('vscode-nls-dev');
const root = path.dirname(__dirname);
const commit = util.getVersion(root);
const plumber = require('gulp-plumber');
const _ = require('underscore');
const extensionsPath = path.join(path.dirname(__dirname), 'extensions');
@ -35,7 +36,8 @@ const tasks = compilations.map(function (tsconfigFile) {
const absolutePath = path.join(extensionsPath, tsconfigFile);
const relativeDirname = path.dirname(tsconfigFile);
const tsOptions = require(absolutePath).compilerOptions;
const tsconfig = require(absolutePath);
const tsOptions = _.assign({}, tsconfig.extends ? require(path.join(extensionsPath, relativeDirname, tsconfig.extends)).compilerOptions : {}, tsconfig.compilerOptions);
tsOptions.verbose = false;
tsOptions.sourceMap = true;

View file

@ -80,7 +80,7 @@ const indentationFilter = [
'!src/vs/*/**/*.d.ts',
'!src/typings/**/*.d.ts',
'!extensions/**/*.d.ts',
'!**/*.{svg,exe,png,bmp,scpt,bat,cmd,cur,ttf,woff,eot,md,ps1,template,yaml,yml,d.ts.recipe}',
'!**/*.{svg,exe,png,bmp,scpt,bat,cmd,cur,ttf,woff,eot,md,ps1,template,yaml,yml,d.ts.recipe,ico,icns}',
'!build/{lib,tslintRules}/**/*.js',
'!build/**/*.sh',
'!build/tfs/**/*.js',
@ -98,6 +98,8 @@ const copyrightFilter = [
'!**/*.md',
'!**/*.bat',
'!**/*.cmd',
'!**/*.ico',
'!**/*.icns',
'!**/*.xml',
'!**/*.sh',
'!**/*.txt',

View file

@ -13,7 +13,6 @@ const es = require('event-stream');
const util = require('./lib/util');
const remote = require('gulp-remote-src');
const zip = require('gulp-vinyl-zip');
const assign = require('object-assign');
const pkg = require('../package.json');
@ -55,7 +54,7 @@ gulp.task('mixin', function () {
.pipe(util.rebase(2))
.pipe(productJsonFilter)
.pipe(buffer())
.pipe(json(o => assign({}, require('../product.json'), o)))
.pipe(json(o => Object.assign({}, require('../product.json'), o)))
.pipe(productJsonFilter.restore);
all = es.merge(mixin);

View file

@ -64,7 +64,6 @@ const vscodeResources = [
'out-build/vs/base/node/{stdForkStart.js,terminateProcess.sh,cpuUsage.sh}',
'out-build/vs/base/browser/ui/octiconLabel/octicons/**',
'out-build/vs/workbench/browser/media/*-theme.css',
'out-build/vs/workbench/electron-browser/bootstrap/**',
'out-build/vs/workbench/parts/debug/**/*.json',
'out-build/vs/workbench/parts/execution/**/*.scpt',
'out-build/vs/workbench/parts/webview/electron-browser/webview-pre.js',
@ -73,6 +72,7 @@ const vscodeResources = [
'out-build/vs/workbench/parts/welcome/walkThrough/**/*.md',
'out-build/vs/workbench/services/files/**/*.exe',
'out-build/vs/workbench/services/files/**/*.md',
'out-build/vs/code/electron-browser/workbench/**',
'out-build/vs/code/electron-browser/sharedProcess/sharedProcess.js',
'out-build/vs/code/electron-browser/issue/issueReporter.js',
'out-build/vs/code/electron-browser/processExplorer/processExplorer.js',
@ -99,7 +99,7 @@ gulp.task('optimize-vscode', ['clean-optimized-vscode', 'compile-build', 'compil
gulp.task('optimize-index-js', ['optimize-vscode'], () => {
const fullpath = path.join(process.cwd(), 'out-vscode/vs/workbench/electron-browser/bootstrap/index.js');
const fullpath = path.join(process.cwd(), 'out-vscode/vs/code/electron-browser/workbench/workbench.js');
const contents = fs.readFileSync(fullpath).toString();
const newContents = contents.replace('[/*BUILD->INSERT_NODE_MODULES*/]', JSON.stringify(nodeModules));
fs.writeFileSync(fullpath, newContents);
@ -114,6 +114,16 @@ gulp.task('minify-vscode', ['clean-minified-vscode', 'optimize-index-js'], commo
// @ts-ignore JSON checking: darwinCredits is optional
const darwinCreditsTemplate = product.darwinCredits && _.template(fs.readFileSync(path.join(root, product.darwinCredits), 'utf8'));
function darwinBundleDocumentType(extensions, icon) {
return {
name: product.nameLong + ' document',
role: 'Editor',
ostypes: ["TEXT", "utxt", "TUTX", "****"],
extensions: extensions,
iconFile: icon
};
}
const config = {
version: getElectronVersion(),
productAppName: product.nameLong,
@ -124,18 +134,42 @@ const config = {
darwinApplicationCategoryType: 'public.app-category.developer-tools',
darwinHelpBookFolder: 'VS Code HelpBook',
darwinHelpBookName: 'VS Code HelpBook',
darwinBundleDocumentTypes: [{
name: product.nameLong + ' document',
role: 'Editor',
ostypes: ["TEXT", "utxt", "TUTX", "****"],
extensions: ["ascx", "asp", "aspx", "bash", "bash_login", "bash_logout", "bash_profile", "bashrc", "bat", "bowerrc", "c", "cc", "clj", "cljs", "cljx", "clojure", "cmd", "code-workspace", "coffee", "config", "cpp", "cs", "cshtml", "csproj", "css", "csx", "ctp", "cxx", "dockerfile", "dot", "dtd", "editorconfig", "edn", "eyaml", "eyml", "fs", "fsi", "fsscript", "fsx", "gemspec", "gitattributes", "gitconfig", "gitignore", "go", "h", "handlebars", "hbs", "hh", "hpp", "htm", "html", "hxx", "ini", "jade", "jav", "java", "js", "jscsrc", "jshintrc", "jshtm", "json", "jsp", "less", "lua", "m", "makefile", "markdown", "md", "mdoc", "mdown", "mdtext", "mdtxt", "mdwn", "mkd", "mkdn", "ml", "mli", "php", "phtml", "pl", "pl6", "pm", "pm6", "pod", "pp", "profile", "properties", "ps1", "psd1", "psgi", "psm1", "pug", "py", "r", "rb", "rhistory", "rprofile", "rs", "rt", "scss", "sh", "shtml", "sql", "svg", "svgz", "t", "ts", "txt", "vb", "wxi", "wxl", "wxs", "xaml", "xcodeproj", "xcworkspace", "xml", "yaml", "yml", "zlogin", "zlogout", "zprofile", "zsh", "zshenv", "zshrc"],
iconFile: 'resources/darwin/code_file.icns'
}],
darwinBundleDocumentTypes: [
darwinBundleDocumentType(["bat", "cmd"], 'resources/darwin/bat.icns'),
darwinBundleDocumentType(["bowerrc"], 'resources/darwin/bower.icns'),
darwinBundleDocumentType(["c", "h"], 'resources/darwin/c.icns'),
darwinBundleDocumentType(["config", "editorconfig", "gitattributes", "gitconfig", "gitignore", "ini"], 'resources/darwin/config.icns'),
darwinBundleDocumentType(["cc", "cpp", "cxx", "hh", "hpp", "hxx"], 'resources/darwin/cpp.icns'),
darwinBundleDocumentType(["cs", "csx"], 'resources/darwin/csharp.icns'),
darwinBundleDocumentType(["css"], 'resources/darwin/css.icns'),
darwinBundleDocumentType(["go"], 'resources/darwin/go.icns'),
darwinBundleDocumentType(["asp", "aspx", "cshtml", "htm", "html", "jshtm", "jsp", "phtml", "shtml"], 'resources/darwin/html.icns'),
darwinBundleDocumentType(["jade"], 'resources/darwin/jade.icns'),
darwinBundleDocumentType(["jav", "java"], 'resources/darwin/java.icns'),
darwinBundleDocumentType(["js", "jscsrc", "jshintrc", "mjs"], 'resources/darwin/javascript.icns'),
darwinBundleDocumentType(["json"], 'resources/darwin/json.icns'),
darwinBundleDocumentType(["less"], 'resources/darwin/less.icns'),
darwinBundleDocumentType(["markdown", "md", "mdoc", "mdown", "mdtext", "mdtxt", "mdwn", "mkd", "mkdn"], 'resources/darwin/markdown.icns'),
darwinBundleDocumentType(["php"], 'resources/darwin/php.icns'),
darwinBundleDocumentType(["ps1", "psd1", "psm1"], 'resources/darwin/powershell.icns'),
darwinBundleDocumentType(["py"], 'resources/darwin/python.icns'),
darwinBundleDocumentType(["gemspec", "rb"], 'resources/darwin/ruby.icns'),
darwinBundleDocumentType(["scss"], 'resources/darwin/sass.icns'),
darwinBundleDocumentType(["bash", "bash_login", "bash_logout", "bash_profile", "bashrc", "profile", "rhistory", "rprofile", "sh", "zlogin", "zlogout", "zprofile", "zsh", "zshenv", "zshrc"], 'resources/darwin/shell.icns'),
darwinBundleDocumentType(["sql"], 'resources/darwin/sql.icns'),
darwinBundleDocumentType(["ts"], 'resources/darwin/typescript.icns'),
darwinBundleDocumentType(["tsx", "jsx"], 'resources/darwin/react.icns'),
darwinBundleDocumentType(["vue"], 'resources/darwin/vue.icns'),
darwinBundleDocumentType(["ascx", "csproj", "dtd", "wxi", "wxl", "wxs", "xml", "xaml"], 'resources/darwin/xml.icns'),
darwinBundleDocumentType(["eyaml", "eyml", "yaml", "yml"], 'resources/darwin/yaml.icns'),
darwinBundleDocumentType(["clj", "cljs", "cljx", "clojure", "code-workspace", "coffee", "ctp", "dockerfile", "dot", "edn", "fs", "fsi", "fsscript", "fsx", "handlebars", "hbs", "lua", "m", "makefile", "ml", "mli", "pl", "pl6", "pm", "pm6", "pod", "pp", "properties", "psgi", "pug", "r", "rs", "rt", "svg", "svgz", "t", "txt", "vb", "xcodeproj", "xcworkspace"], 'resources/darwin/default.icns')
],
darwinBundleURLTypes: [{
role: 'Viewer',
name: product.nameLong,
urlSchemes: [product.urlProtocol]
}],
darwinForceDarkModeSupport: true,
darwinCredits: darwinCreditsTemplate ? Buffer.from(darwinCreditsTemplate({ commit: commit, date: new Date().toISOString() })) : void 0,
linuxExecutableName: product.applicationName,
winIcon: 'resources/win32/code.ico',
@ -166,6 +200,8 @@ gulp.task('clean-electron', util.rimraf('.build/electron'));
gulp.task('electron', ['clean-electron'], getElectron(process.arch));
gulp.task('electron-ia32', ['clean-electron'], getElectron('ia32'));
gulp.task('electron-x64', ['clean-electron'], getElectron('x64'));
gulp.task('electron-arm', ['clean-electron'], getElectron('arm'));
gulp.task('electron-arm64', ['clean-electron'], getElectron('arm64'));
/**
@ -214,8 +250,8 @@ function packageTask(platform, arch, opts) {
const checksums = computeChecksums(out, [
'vs/workbench/workbench.main.js',
'vs/workbench/workbench.main.css',
'vs/workbench/electron-browser/bootstrap/index.html',
'vs/workbench/electron-browser/bootstrap/index.js'
'vs/code/electron-browser/workbench/workbench.html',
'vs/code/electron-browser/workbench/workbench.js'
]);
const src = gulp.src(out + '/**', { base: '.' })
@ -238,8 +274,15 @@ function packageTask(platform, arch, opts) {
}
const name = product.nameShort;
const packageJsonUpdates = { name, version };
// for linux url handling
if (platform === 'linux') {
packageJsonUpdates.desktopName = `${product.applicationName}-url-handler.desktop`;
}
const packageJsonStream = gulp.src(['package.json'], { base: '.' })
.pipe(json({ name, version }));
.pipe(json(packageJsonUpdates));
const date = new Date().toISOString();
const productJsonUpdate = { commit, date, checksums };
@ -267,19 +310,20 @@ function packageTask(platform, arch, opts) {
const deps = gulp.src(depsSrc, { base: '.', dot: true })
.pipe(filter(['**', '!**/package-lock.json']))
.pipe(util.cleanNodeModule('fsevents', ['binding.gyp', 'fsevents.cc', 'build/**', 'src/**', 'test/**'], ['**/*.node']))
.pipe(util.cleanNodeModule('oniguruma', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node', 'src/*.js']))
.pipe(util.cleanNodeModule('vscode-sqlite3', ['binding.gyp', 'benchmark/**', 'cloudformation/**', 'deps/**', 'test/**', 'build/**', 'src/**'], ['build/Release/*.node']))
.pipe(util.cleanNodeModule('oniguruma', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['build/Release/*.node', 'src/*.js']))
.pipe(util.cleanNodeModule('windows-mutex', ['binding.gyp', 'build/**', 'src/**'], ['**/*.node']))
.pipe(util.cleanNodeModule('native-keymap', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node']))
.pipe(util.cleanNodeModule('native-is-elevated', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node']))
.pipe(util.cleanNodeModule('native-watchdog', ['binding.gyp', 'build/**', 'src/**'], ['**/*.node']))
.pipe(util.cleanNodeModule('spdlog', ['binding.gyp', 'build/**', 'deps/**', 'src/**', 'test/**'], ['**/*.node']))
.pipe(util.cleanNodeModule('native-keymap', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['build/Release/*.node']))
.pipe(util.cleanNodeModule('native-is-elevated', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['build/Release/*.node']))
.pipe(util.cleanNodeModule('native-watchdog', ['binding.gyp', 'build/**', 'src/**'], ['build/Release/*.node']))
.pipe(util.cleanNodeModule('spdlog', ['binding.gyp', 'build/**', 'deps/**', 'src/**', 'test/**'], ['build/Release/*.node']))
.pipe(util.cleanNodeModule('jschardet', ['dist/**']))
.pipe(util.cleanNodeModule('windows-foreground-love', ['binding.gyp', 'build/**', 'src/**'], ['**/*.node']))
.pipe(util.cleanNodeModule('windows-process-tree', ['binding.gyp', 'build/**', 'src/**'], ['**/*.node']))
.pipe(util.cleanNodeModule('gc-signals', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node', 'src/index.js']))
.pipe(util.cleanNodeModule('gc-signals', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['build/Release/*.node', 'src/index.js']))
.pipe(util.cleanNodeModule('keytar', ['binding.gyp', 'build/**', 'src/**', 'script/**', 'node_modules/**'], ['**/*.node']))
.pipe(util.cleanNodeModule('node-pty', ['binding.gyp', 'build/**', 'src/**', 'tools/**'], ['build/Release/*.exe', 'build/Release/*.dll', 'build/Release/*.node']))
.pipe(util.cleanNodeModule('vscode-nsfw', ['binding.gyp', 'build/**', 'src/**', 'openpa/**', 'includes/**'], ['**/*.node', '**/*.a']))
.pipe(util.cleanNodeModule('vscode-nsfw', ['binding.gyp', 'build/**', 'src/**', 'openpa/**', 'includes/**'], ['build/Release/*.node', '**/*.a']))
.pipe(util.cleanNodeModule('vsda', ['binding.gyp', 'README.md', 'build/**', '*.bat', '*.sh', '*.cpp', '*.h'], ['build/Release/vsda.node']))
.pipe(createAsar(path.join(process.cwd(), 'node_modules'), ['**/*.node', '**/vscode-ripgrep/bin/*', '**/node-pty/build/Release/*'], 'app/node_modules.asar'));
@ -294,7 +338,37 @@ function packageTask(platform, arch, opts) {
);
if (platform === 'win32') {
all = es.merge(all, gulp.src(['resources/win32/code_file.ico', 'resources/win32/code_70x70.png', 'resources/win32/code_150x150.png'], { base: '.' }));
all = es.merge(all, gulp.src([
'resources/win32/bower.ico',
'resources/win32/c.ico',
'resources/win32/config.ico',
'resources/win32/cpp.ico',
'resources/win32/csharp.ico',
'resources/win32/css.ico',
'resources/win32/default.ico',
'resources/win32/go.ico',
'resources/win32/html.ico',
'resources/win32/jade.ico',
'resources/win32/java.ico',
'resources/win32/javascript.ico',
'resources/win32/json.ico',
'resources/win32/less.ico',
'resources/win32/markdown.ico',
'resources/win32/php.ico',
'resources/win32/powershell.ico',
'resources/win32/python.ico',
'resources/win32/react.ico',
'resources/win32/ruby.ico',
'resources/win32/sass.ico',
'resources/win32/shell.ico',
'resources/win32/sql.ico',
'resources/win32/typescript.ico',
'resources/win32/vue.ico',
'resources/win32/xml.ico',
'resources/win32/yaml.ico',
'resources/win32/code_70x70.png',
'resources/win32/code_150x150.png'
], { base: '.' }));
} else if (platform === 'linux') {
all = es.merge(all, gulp.src('resources/linux/code.png', { base: '.' }));
} else if (platform === 'darwin') {
@ -350,6 +424,7 @@ gulp.task('clean-vscode-darwin', util.rimraf(path.join(buildRoot, 'VSCode-darwin
gulp.task('clean-vscode-linux-ia32', util.rimraf(path.join(buildRoot, 'VSCode-linux-ia32')));
gulp.task('clean-vscode-linux-x64', util.rimraf(path.join(buildRoot, 'VSCode-linux-x64')));
gulp.task('clean-vscode-linux-arm', util.rimraf(path.join(buildRoot, 'VSCode-linux-arm')));
gulp.task('clean-vscode-linux-arm64', util.rimraf(path.join(buildRoot, 'VSCode-linux-arm64')));
gulp.task('vscode-win32-ia32', ['optimize-vscode', 'clean-vscode-win32-ia32'], packageTask('win32', 'ia32'));
gulp.task('vscode-win32-x64', ['optimize-vscode', 'clean-vscode-win32-x64'], packageTask('win32', 'x64'));
@ -357,6 +432,7 @@ gulp.task('vscode-darwin', ['optimize-vscode', 'clean-vscode-darwin'], packageTa
gulp.task('vscode-linux-ia32', ['optimize-vscode', 'clean-vscode-linux-ia32'], packageTask('linux', 'ia32'));
gulp.task('vscode-linux-x64', ['optimize-vscode', 'clean-vscode-linux-x64'], packageTask('linux', 'x64'));
gulp.task('vscode-linux-arm', ['optimize-vscode', 'clean-vscode-linux-arm'], packageTask('linux', 'arm'));
gulp.task('vscode-linux-arm64', ['optimize-vscode', 'clean-vscode-linux-arm64'], packageTask('linux', 'arm64'));
gulp.task('vscode-win32-ia32-min', ['minify-vscode', 'clean-vscode-win32-ia32'], packageTask('win32', 'ia32', { minified: true }));
gulp.task('vscode-win32-x64-min', ['minify-vscode', 'clean-vscode-win32-x64'], packageTask('win32', 'x64', { minified: true }));
@ -364,6 +440,7 @@ gulp.task('vscode-darwin-min', ['minify-vscode', 'clean-vscode-darwin'], package
gulp.task('vscode-linux-ia32-min', ['minify-vscode', 'clean-vscode-linux-ia32'], packageTask('linux', 'ia32', { minified: true }));
gulp.task('vscode-linux-x64-min', ['minify-vscode', 'clean-vscode-linux-x64'], packageTask('linux', 'x64', { minified: true }));
gulp.task('vscode-linux-arm-min', ['minify-vscode', 'clean-vscode-linux-arm'], packageTask('linux', 'arm', { minified: true }));
gulp.task('vscode-linux-arm64-min', ['minify-vscode', 'clean-vscode-linux-arm64'], packageTask('linux', 'arm64', { minified: true }));
// Transifex Localizations

View file

@ -19,7 +19,7 @@ const rpmDependencies = require('../resources/linux/rpm/dependencies.json');
const linuxPackageRevision = Math.floor(new Date().getTime() / 1000);
function getDebPackageArch(arch) {
return { x64: 'amd64', ia32: 'i386', arm: 'armhf' }[arch];
return { x64: 'amd64', ia32: 'i386', arm: 'armhf', arm64: "arm64" }[arch];
}
function prepareDebPackage(arch) {
@ -29,11 +29,17 @@ function prepareDebPackage(arch) {
return function () {
const desktop = gulp.src('resources/linux/code.desktop', { base: '.' })
.pipe(rename('usr/share/applications/' + product.applicationName + '.desktop'));
const desktopUrlHandler = gulp.src('resources/linux/code-url-handler.desktop', { base: '.' })
.pipe(rename('usr/share/applications/' + product.applicationName + '-url-handler.desktop'));
const desktops = es.merge(desktop, desktopUrlHandler)
.pipe(replace('@@NAME_LONG@@', product.nameLong))
.pipe(replace('@@NAME_SHORT@@', product.nameShort))
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@ICON@@', product.applicationName))
.pipe(rename('usr/share/applications/' + product.applicationName + '.desktop'));
.pipe(replace('@@URLPROTOCOL@@', product.urlProtocol));
const appdata = gulp.src('resources/linux/code.appdata.xml', { base: '.' })
.pipe(replace('@@NAME_LONG@@', product.nameLong))
@ -78,7 +84,7 @@ function prepareDebPackage(arch) {
.pipe(replace('@@UPDATEURL@@', product.updateUrl || '@@UPDATEURL@@'))
.pipe(rename('DEBIAN/postinst'));
const all = es.merge(control, postinst, postrm, prerm, desktop, appdata, icon, code);
const all = es.merge(control, postinst, postrm, prerm, desktops, appdata, icon, code);
return all.pipe(vfs.dest(destination));
};
@ -98,7 +104,7 @@ function getRpmBuildPath(rpmArch) {
}
function getRpmPackageArch(arch) {
return { x64: 'x86_64', ia32: 'i386', arm: 'armhf' }[arch];
return { x64: 'x86_64', ia32: 'i386', arm: 'armhf', arm64: "arm64" }[arch];
}
function prepareRpmPackage(arch) {
@ -107,12 +113,18 @@ function prepareRpmPackage(arch) {
return function () {
const desktop = gulp.src('resources/linux/code.desktop', { base: '.' })
.pipe(replace('@@NAME_LONG@@', product.nameLong))
.pipe(replace('@@NAME_SHORT@@', product.nameShort))
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@ICON@@', product.applicationName))
.pipe(rename('BUILD/usr/share/applications/' + product.applicationName + '.desktop'));
const desktopUrlHandler = gulp.src('resources/linux/code-url-handler.desktop', { base: '.' })
.pipe(rename('BUILD/usr/share/applications/' + product.applicationName + '-url-handler.desktop'));
const desktops = es.merge(desktop, desktopUrlHandler)
.pipe(replace('@@NAME_LONG@@', product.nameLong))
.pipe(replace('@@NAME_SHORT@@', product.nameShort))
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@ICON@@', product.applicationName))
.pipe(replace('@@URLPROTOCOL@@', product.urlProtocol));
const appdata = gulp.src('resources/linux/code.appdata.xml', { base: '.' })
.pipe(replace('@@NAME_LONG@@', product.nameLong))
.pipe(replace('@@NAME@@', product.applicationName))
@ -142,7 +154,7 @@ function prepareRpmPackage(arch) {
const specIcon = gulp.src('resources/linux/rpm/code.xpm', { base: '.' })
.pipe(rename('SOURCES/' + product.applicationName + '.xpm'));
const all = es.merge(code, desktop, appdata, icon, spec, specIcon);
const all = es.merge(code, desktops, appdata, icon, spec, specIcon);
return all.pipe(vfs.dest(getRpmBuildPath(rpmArch)));
};
@ -208,30 +220,39 @@ function buildSnapPackage(arch) {
gulp.task('clean-vscode-linux-ia32-deb', util.rimraf('.build/linux/deb/i386'));
gulp.task('clean-vscode-linux-x64-deb', util.rimraf('.build/linux/deb/amd64'));
gulp.task('clean-vscode-linux-arm-deb', util.rimraf('.build/linux/deb/armhf'));
gulp.task('clean-vscode-linux-arm64-deb', util.rimraf('.build/linux/deb/arm64'));
gulp.task('clean-vscode-linux-ia32-rpm', util.rimraf('.build/linux/rpm/i386'));
gulp.task('clean-vscode-linux-x64-rpm', util.rimraf('.build/linux/rpm/x86_64'));
gulp.task('clean-vscode-linux-arm-rpm', util.rimraf('.build/linux/rpm/armhf'));
gulp.task('clean-vscode-linux-arm64-rpm', util.rimraf('.build/linux/rpm/arm64'));
gulp.task('clean-vscode-linux-ia32-snap', util.rimraf('.build/linux/snap/x64'));
gulp.task('clean-vscode-linux-x64-snap', util.rimraf('.build/linux/snap/x64'));
gulp.task('clean-vscode-linux-arm-snap', util.rimraf('.build/linux/snap/x64'));
gulp.task('clean-vscode-linux-arm64-snap', util.rimraf('.build/linux/snap/x64'));
gulp.task('vscode-linux-ia32-prepare-deb', ['clean-vscode-linux-ia32-deb'], prepareDebPackage('ia32'));
gulp.task('vscode-linux-x64-prepare-deb', ['clean-vscode-linux-x64-deb'], prepareDebPackage('x64'));
gulp.task('vscode-linux-arm-prepare-deb', ['clean-vscode-linux-arm-deb'], prepareDebPackage('arm'));
gulp.task('vscode-linux-arm64-prepare-deb', ['clean-vscode-linux-arm64-deb'], prepareDebPackage('arm64'));
gulp.task('vscode-linux-ia32-build-deb', ['vscode-linux-ia32-prepare-deb'], buildDebPackage('ia32'));
gulp.task('vscode-linux-x64-build-deb', ['vscode-linux-x64-prepare-deb'], buildDebPackage('x64'));
gulp.task('vscode-linux-arm-build-deb', ['vscode-linux-arm-prepare-deb'], buildDebPackage('arm'));
gulp.task('vscode-linux-arm64-build-deb', ['vscode-linux-arm64-prepare-deb'], buildDebPackage('arm64'));
gulp.task('vscode-linux-ia32-prepare-rpm', ['clean-vscode-linux-ia32-rpm'], prepareRpmPackage('ia32'));
gulp.task('vscode-linux-x64-prepare-rpm', ['clean-vscode-linux-x64-rpm'], prepareRpmPackage('x64'));
gulp.task('vscode-linux-arm-prepare-rpm', ['clean-vscode-linux-arm-rpm'], prepareRpmPackage('arm'));
gulp.task('vscode-linux-arm64-prepare-rpm', ['clean-vscode-linux-arm64-rpm'], prepareRpmPackage('arm64'));
gulp.task('vscode-linux-ia32-build-rpm', ['vscode-linux-ia32-prepare-rpm'], buildRpmPackage('ia32'));
gulp.task('vscode-linux-x64-build-rpm', ['vscode-linux-x64-prepare-rpm'], buildRpmPackage('x64'));
gulp.task('vscode-linux-arm-build-rpm', ['vscode-linux-arm-prepare-rpm'], buildRpmPackage('arm'));
gulp.task('vscode-linux-arm64-build-rpm', ['vscode-linux-arm64-prepare-rpm'], buildRpmPackage('arm64'));
gulp.task('vscode-linux-ia32-prepare-snap', ['clean-vscode-linux-ia32-snap'], prepareSnapPackage('ia32'));
gulp.task('vscode-linux-x64-prepare-snap', ['clean-vscode-linux-x64-snap'], prepareSnapPackage('x64'));
gulp.task('vscode-linux-arm-prepare-snap', ['clean-vscode-linux-arm-snap'], prepareSnapPackage('arm'));
gulp.task('vscode-linux-arm64-prepare-snap', ['clean-vscode-linux-arm64-snap'], prepareSnapPackage('arm64'));
gulp.task('vscode-linux-ia32-build-snap', ['vscode-linux-ia32-prepare-snap'], buildSnapPackage('ia32'));
gulp.task('vscode-linux-x64-build-snap', ['vscode-linux-x64-prepare-snap'], buildSnapPackage('x64'));
gulp.task('vscode-linux-arm-build-snap', ['vscode-linux-arm-prepare-snap'], buildSnapPackage('arm'));
gulp.task('vscode-linux-arm64-build-snap', ['vscode-linux-arm64-prepare-snap'], buildSnapPackage('arm64'));

View file

@ -15,6 +15,7 @@ const util = require('./lib/util');
const pkg = require('../package.json');
const product = require('../product.json');
const vfs = require('vinyl-fs');
const rcedit = require('rcedit');
const mkdirp = require('mkdirp');
const repoPath = path.dirname(__dirname);
@ -30,12 +31,15 @@ function packageInnoSetup(iss, options, cb) {
options = options || {};
const definitions = options.definitions || {};
const debug = process.argv.some(arg => arg === '--debug-inno');
if (debug) {
if (process.argv.some(arg => arg === '--debug-inno')) {
definitions['Debug'] = 'true';
}
if (process.argv.some(arg => arg === '--sign')) {
definitions['Sign'] = 'true';
}
const keys = Object.keys(definitions);
keys.forEach(key => assert(typeof definitions[key] === 'string', `Missing value for '${key}' in Inno Setup package step`));
@ -134,4 +138,14 @@ function copyInnoUpdater(arch) {
}
gulp.task('vscode-win32-ia32-copy-inno-updater', copyInnoUpdater('ia32'));
gulp.task('vscode-win32-x64-copy-inno-updater', copyInnoUpdater('x64'));
gulp.task('vscode-win32-x64-copy-inno-updater', copyInnoUpdater('x64'));
function patchInnoUpdater(arch) {
return cb => {
const icon = path.join(repoPath, 'resources', 'win32', 'code.ico');
rcedit(path.join(buildPath(arch), 'tools', 'inno_updater.exe'), { icon }, cb);
};
}
gulp.task('vscode-win32-ia32-inno-updater', ['vscode-win32-ia32-copy-inno-updater'], patchInnoUpdater('ia32'));
gulp.task('vscode-win32-x64-inno-updater', ['vscode-win32-x64-copy-inno-updater'], patchInnoUpdater('x64'));

15
build/jsconfig.json Normal file
View file

@ -0,0 +1,15 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2017",
"jsx": "preserve",
"checkJs": true
},
"include": [
"**/*.js"
],
"exclude": [
"node_modules",
"**/node_modules/*"
]
}

View file

@ -4,33 +4,33 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var path = require("path");
var es = require("event-stream");
var pickle = require("chromium-pickle-js");
var Filesystem = require("asar/lib/filesystem");
var VinylFile = require("vinyl");
var minimatch = require("minimatch");
const path = require("path");
const es = require("event-stream");
const pickle = require('chromium-pickle-js');
const Filesystem = require('asar/lib/filesystem');
const VinylFile = require("vinyl");
const minimatch = require("minimatch");
function createAsar(folderPath, unpackGlobs, destFilename) {
var shouldUnpackFile = function (file) {
for (var i = 0; i < unpackGlobs.length; i++) {
const shouldUnpackFile = (file) => {
for (let i = 0; i < unpackGlobs.length; i++) {
if (minimatch(file.relative, unpackGlobs[i])) {
return true;
}
}
return false;
};
var filesystem = new Filesystem(folderPath);
var out = [];
const filesystem = new Filesystem(folderPath);
const out = [];
// Keep track of pending inserts
var pendingInserts = 0;
var onFileInserted = function () { pendingInserts--; };
let pendingInserts = 0;
let onFileInserted = () => { pendingInserts--; };
// Do not insert twice the same directory
var seenDir = {};
var insertDirectoryRecursive = function (dir) {
const seenDir = {};
const insertDirectoryRecursive = (dir) => {
if (seenDir[dir]) {
return;
}
var lastSlash = dir.lastIndexOf('/');
let lastSlash = dir.lastIndexOf('/');
if (lastSlash === -1) {
lastSlash = dir.lastIndexOf('\\');
}
@ -40,8 +40,8 @@ function createAsar(folderPath, unpackGlobs, destFilename) {
seenDir[dir] = true;
filesystem.insertDirectory(dir);
};
var insertDirectoryForFile = function (file) {
var lastSlash = file.lastIndexOf('/');
const insertDirectoryForFile = (file) => {
let lastSlash = file.lastIndexOf('/');
if (lastSlash === -1) {
lastSlash = file.lastIndexOf('\\');
}
@ -49,7 +49,7 @@ function createAsar(folderPath, unpackGlobs, destFilename) {
insertDirectoryRecursive(file.substring(0, lastSlash));
}
};
var insertFile = function (relativePath, stat, shouldUnpack) {
const insertFile = (relativePath, stat, shouldUnpack) => {
insertDirectoryForFile(relativePath);
pendingInserts++;
filesystem.insertFile(relativePath, shouldUnpack, { stat: stat }, {}, onFileInserted);
@ -59,13 +59,13 @@ function createAsar(folderPath, unpackGlobs, destFilename) {
return;
}
if (!file.stat.isFile()) {
throw new Error("unknown item in stream!");
throw new Error(`unknown item in stream!`);
}
var shouldUnpack = shouldUnpackFile(file);
const shouldUnpack = shouldUnpackFile(file);
insertFile(file.relative, { size: file.contents.length, mode: file.stat.mode }, shouldUnpack);
if (shouldUnpack) {
// The file goes outside of xx.asar, in a folder xx.asar.unpacked
var relative = path.relative(folderPath, file.path);
const relative = path.relative(folderPath, file.path);
this.queue(new VinylFile({
cwd: folderPath,
base: folderPath,
@ -79,34 +79,33 @@ function createAsar(folderPath, unpackGlobs, destFilename) {
out.push(file.contents);
}
}, function () {
var _this = this;
var finish = function () {
let finish = () => {
{
var headerPickle = pickle.createEmpty();
const headerPickle = pickle.createEmpty();
headerPickle.writeString(JSON.stringify(filesystem.header));
var headerBuf = headerPickle.toBuffer();
var sizePickle = pickle.createEmpty();
const headerBuf = headerPickle.toBuffer();
const sizePickle = pickle.createEmpty();
sizePickle.writeUInt32(headerBuf.length);
var sizeBuf = sizePickle.toBuffer();
const sizeBuf = sizePickle.toBuffer();
out.unshift(headerBuf);
out.unshift(sizeBuf);
}
var contents = Buffer.concat(out);
const contents = Buffer.concat(out);
out.length = 0;
_this.queue(new VinylFile({
this.queue(new VinylFile({
cwd: folderPath,
base: folderPath,
path: destFilename,
contents: contents
}));
_this.queue(null);
this.queue(null);
};
// Call finish() only when all file inserts have finished...
if (pendingInserts === 0) {
finish();
}
else {
onFileInserted = function () {
onFileInserted = () => {
pendingInserts--;
if (pendingInserts === 0) {
finish();

View file

@ -7,8 +7,8 @@
import * as path from 'path';
import * as es from 'event-stream';
import * as pickle from 'chromium-pickle-js';
import * as Filesystem from 'asar/lib/filesystem';
const pickle = require('chromium-pickle-js');
const Filesystem = require('asar/lib/filesystem');
import * as VinylFile from 'vinyl';
import * as minimatch from 'minimatch';

View file

@ -49,7 +49,7 @@ function syncMarketplaceExtension(extension) {
rimraf.sync(getExtensionPath(extension));
return ext.fromMarketplace(extension.name, extension.version)
return ext.fromMarketplace(extension.name, extension.version, extension.metadata)
.pipe(rename(p => p.dirname = `${extension.name}/${p.dirname}`))
.pipe(vfs.dest('.build/builtInExtensions'))
.on('end', () => util.log(util.colors.blue('[marketplace]'), extension.name, util.colors.green('✔︎')));

View file

@ -4,19 +4,19 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
var fs = require("fs");
var path = require("path");
var vm = require("vm");
const fs = require("fs");
const path = require("path");
const vm = require("vm");
/**
* Bundle `entryPoints` given config `config`.
*/
function bundle(entryPoints, config, callback) {
var entryPointsMap = {};
entryPoints.forEach(function (module) {
const entryPointsMap = {};
entryPoints.forEach((module) => {
entryPointsMap[module.name] = module;
});
var allMentionedModulesMap = {};
entryPoints.forEach(function (module) {
const allMentionedModulesMap = {};
entryPoints.forEach((module) => {
allMentionedModulesMap[module.name] = true;
(module.include || []).forEach(function (includedModule) {
allMentionedModulesMap[includedModule] = true;
@ -25,26 +25,30 @@ function bundle(entryPoints, config, callback) {
allMentionedModulesMap[excludedModule] = true;
});
});
var code = require('fs').readFileSync(path.join(__dirname, '../../src/vs/loader.js'));
var r = vm.runInThisContext('(function(require, module, exports) { ' + code + '\n});');
var loaderModule = { exports: {} };
const code = require('fs').readFileSync(path.join(__dirname, '../../src/vs/loader.js'));
const r = vm.runInThisContext('(function(require, module, exports) { ' + code + '\n});');
const loaderModule = { exports: {} };
r.call({}, require, loaderModule, loaderModule.exports);
var loader = loaderModule.exports;
const loader = loaderModule.exports;
config.isBuild = true;
config.paths = config.paths || {};
config.paths['vs/nls'] = 'out-build/vs/nls.build';
config.paths['vs/css'] = 'out-build/vs/css.build';
if (!config.paths['vs/nls']) {
config.paths['vs/nls'] = 'out-build/vs/nls.build';
}
if (!config.paths['vs/css']) {
config.paths['vs/css'] = 'out-build/vs/css.build';
}
loader.config(config);
loader(['require'], function (localRequire) {
var resolvePath = function (path) {
var r = localRequire.toUrl(path);
loader(['require'], (localRequire) => {
const resolvePath = (path) => {
const r = localRequire.toUrl(path);
if (!/\.js/.test(r)) {
return r + '.js';
}
return r;
};
for (var moduleId in entryPointsMap) {
var entryPoint = entryPointsMap[moduleId];
for (const moduleId in entryPointsMap) {
const entryPoint = entryPointsMap[moduleId];
if (entryPoint.append) {
entryPoint.append = entryPoint.append.map(resolvePath);
}
@ -53,59 +57,59 @@ function bundle(entryPoints, config, callback) {
}
}
});
loader(Object.keys(allMentionedModulesMap), function () {
var modules = loader.getBuildInfo();
var partialResult = emitEntryPoints(modules, entryPointsMap);
var cssInlinedResources = loader('vs/css').getInlinedResources();
loader(Object.keys(allMentionedModulesMap), () => {
const modules = loader.getBuildInfo();
const partialResult = emitEntryPoints(modules, entryPointsMap);
const cssInlinedResources = loader('vs/css').getInlinedResources();
callback(null, {
files: partialResult.files,
cssInlinedResources: cssInlinedResources,
bundleData: partialResult.bundleData
});
}, function (err) { return callback(err, null); });
}, (err) => callback(err, null));
}
exports.bundle = bundle;
function emitEntryPoints(modules, entryPoints) {
var modulesMap = {};
modules.forEach(function (m) {
const modulesMap = {};
modules.forEach((m) => {
modulesMap[m.id] = m;
});
var modulesGraph = {};
modules.forEach(function (m) {
const modulesGraph = {};
modules.forEach((m) => {
modulesGraph[m.id] = m.dependencies;
});
var sortedModules = topologicalSort(modulesGraph);
var result = [];
var usedPlugins = {};
var bundleData = {
const sortedModules = topologicalSort(modulesGraph);
let result = [];
const usedPlugins = {};
const bundleData = {
graph: modulesGraph,
bundles: {}
};
Object.keys(entryPoints).forEach(function (moduleToBundle) {
var info = entryPoints[moduleToBundle];
var rootNodes = [moduleToBundle].concat(info.include || []);
var allDependencies = visit(rootNodes, modulesGraph);
var excludes = ['require', 'exports', 'module'].concat(info.exclude || []);
excludes.forEach(function (excludeRoot) {
var allExcludes = visit([excludeRoot], modulesGraph);
Object.keys(allExcludes).forEach(function (exclude) {
Object.keys(entryPoints).forEach((moduleToBundle) => {
const info = entryPoints[moduleToBundle];
const rootNodes = [moduleToBundle].concat(info.include || []);
const allDependencies = visit(rootNodes, modulesGraph);
const excludes = ['require', 'exports', 'module'].concat(info.exclude || []);
excludes.forEach((excludeRoot) => {
const allExcludes = visit([excludeRoot], modulesGraph);
Object.keys(allExcludes).forEach((exclude) => {
delete allDependencies[exclude];
});
});
var includedModules = sortedModules.filter(function (module) {
const includedModules = sortedModules.filter((module) => {
return allDependencies[module];
});
bundleData.bundles[moduleToBundle] = includedModules;
var res = emitEntryPoint(modulesMap, modulesGraph, moduleToBundle, includedModules, info.prepend, info.append, info.dest);
const res = emitEntryPoint(modulesMap, modulesGraph, moduleToBundle, includedModules, info.prepend || [], info.append || [], info.dest);
result = result.concat(res.files);
for (var pluginName in res.usedPlugins) {
for (const pluginName in res.usedPlugins) {
usedPlugins[pluginName] = usedPlugins[pluginName] || res.usedPlugins[pluginName];
}
});
Object.keys(usedPlugins).forEach(function (pluginName) {
var plugin = usedPlugins[pluginName];
Object.keys(usedPlugins).forEach((pluginName) => {
const plugin = usedPlugins[pluginName];
if (typeof plugin.finishBuild === 'function') {
var write = function (filename, contents) {
const write = (filename, contents) => {
result.push({
dest: filename,
sources: [{
@ -124,16 +128,16 @@ function emitEntryPoints(modules, entryPoints) {
};
}
function extractStrings(destFiles) {
var parseDefineCall = function (moduleMatch, depsMatch) {
var module = moduleMatch.replace(/^"|"$/g, '');
var deps = depsMatch.split(',');
deps = deps.map(function (dep) {
const parseDefineCall = (moduleMatch, depsMatch) => {
const module = moduleMatch.replace(/^"|"$/g, '');
let deps = depsMatch.split(',');
deps = deps.map((dep) => {
dep = dep.trim();
dep = dep.replace(/^"|"$/g, '');
dep = dep.replace(/^'|'$/g, '');
var prefix = null;
var _path = null;
var pieces = dep.split('!');
let prefix = null;
let _path = null;
const pieces = dep.split('!');
if (pieces.length > 1) {
prefix = pieces[0] + '!';
_path = pieces[1];
@ -143,7 +147,7 @@ function extractStrings(destFiles) {
_path = pieces[0];
}
if (/^\.\//.test(_path) || /^\.\.\//.test(_path)) {
var res = path.join(path.dirname(module), _path).replace(/\\/g, '/');
const res = path.join(path.dirname(module), _path).replace(/\\/g, '/');
return prefix + res;
}
return prefix + _path;
@ -153,7 +157,7 @@ function extractStrings(destFiles) {
deps: deps
};
};
destFiles.forEach(function (destFile, index) {
destFiles.forEach((destFile) => {
if (!/\.js$/.test(destFile.dest)) {
return;
}
@ -161,44 +165,44 @@ function extractStrings(destFiles) {
return;
}
// Do one pass to record the usage counts for each module id
var useCounts = {};
destFile.sources.forEach(function (source) {
var matches = source.contents.match(/define\(("[^"]+"),\s*\[(((, )?("|')[^"']+("|'))+)\]/);
const useCounts = {};
destFile.sources.forEach((source) => {
const matches = source.contents.match(/define\(("[^"]+"),\s*\[(((, )?("|')[^"']+("|'))+)\]/);
if (!matches) {
return;
}
var defineCall = parseDefineCall(matches[1], matches[2]);
const defineCall = parseDefineCall(matches[1], matches[2]);
useCounts[defineCall.module] = (useCounts[defineCall.module] || 0) + 1;
defineCall.deps.forEach(function (dep) {
defineCall.deps.forEach((dep) => {
useCounts[dep] = (useCounts[dep] || 0) + 1;
});
});
var sortedByUseModules = Object.keys(useCounts);
sortedByUseModules.sort(function (a, b) {
const sortedByUseModules = Object.keys(useCounts);
sortedByUseModules.sort((a, b) => {
return useCounts[b] - useCounts[a];
});
var replacementMap = {};
sortedByUseModules.forEach(function (module, index) {
const replacementMap = {};
sortedByUseModules.forEach((module, index) => {
replacementMap[module] = index;
});
destFile.sources.forEach(function (source) {
source.contents = source.contents.replace(/define\(("[^"]+"),\s*\[(((, )?("|')[^"']+("|'))+)\]/, function (_, moduleMatch, depsMatch) {
var defineCall = parseDefineCall(moduleMatch, depsMatch);
return "define(__m[" + replacementMap[defineCall.module] + "/*" + defineCall.module + "*/], __M([" + defineCall.deps.map(function (dep) { return replacementMap[dep] + '/*' + dep + '*/'; }).join(',') + "])";
destFile.sources.forEach((source) => {
source.contents = source.contents.replace(/define\(("[^"]+"),\s*\[(((, )?("|')[^"']+("|'))+)\]/, (_, moduleMatch, depsMatch) => {
const defineCall = parseDefineCall(moduleMatch, depsMatch);
return `define(__m[${replacementMap[defineCall.module]}/*${defineCall.module}*/], __M([${defineCall.deps.map(dep => replacementMap[dep] + '/*' + dep + '*/').join(',')}])`;
});
});
destFile.sources.unshift({
path: null,
contents: [
'(function() {',
"var __m = " + JSON.stringify(sortedByUseModules) + ";",
"var __M = function(deps) {",
" var result = [];",
" for (var i = 0, len = deps.length; i < len; i++) {",
" result[i] = __m[deps[i]];",
" }",
" return result;",
"};"
`var __m = ${JSON.stringify(sortedByUseModules)};`,
`var __M = function(deps) {`,
` var result = [];`,
` for (var i = 0, len = deps.length; i < len; i++) {`,
` result[i] = __m[deps[i]];`,
` }`,
` return result;`,
`};`
].join('\n')
});
destFile.sources.push({
@ -210,7 +214,7 @@ function extractStrings(destFiles) {
}
function removeDuplicateTSBoilerplate(destFiles) {
// Taken from typescript compiler => emitFiles
var BOILERPLATE = [
const BOILERPLATE = [
{ start: /^var __extends/, end: /^}\)\(\);$/ },
{ start: /^var __assign/, end: /^};$/ },
{ start: /^var __decorate/, end: /^};$/ },
@ -219,14 +223,14 @@ function removeDuplicateTSBoilerplate(destFiles) {
{ start: /^var __awaiter/, end: /^};$/ },
{ start: /^var __generator/, end: /^};$/ },
];
destFiles.forEach(function (destFile) {
var SEEN_BOILERPLATE = [];
destFile.sources.forEach(function (source) {
var lines = source.contents.split(/\r\n|\n|\r/);
var newLines = [];
var IS_REMOVING_BOILERPLATE = false, END_BOILERPLATE;
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
destFiles.forEach((destFile) => {
const SEEN_BOILERPLATE = [];
destFile.sources.forEach((source) => {
const lines = source.contents.split(/\r\n|\n|\r/);
const newLines = [];
let IS_REMOVING_BOILERPLATE = false, END_BOILERPLATE;
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
if (IS_REMOVING_BOILERPLATE) {
newLines.push('');
if (END_BOILERPLATE.test(line)) {
@ -234,8 +238,8 @@ function removeDuplicateTSBoilerplate(destFiles) {
}
}
else {
for (var j = 0; j < BOILERPLATE.length; j++) {
var boilerplate = BOILERPLATE[j];
for (let j = 0; j < BOILERPLATE.length; j++) {
const boilerplate = BOILERPLATE[j];
if (boilerplate.start.test(line)) {
if (SEEN_BOILERPLATE[j]) {
IS_REMOVING_BOILERPLATE = true;
@ -263,45 +267,45 @@ function emitEntryPoint(modulesMap, deps, entryPoint, includedModules, prepend,
if (!dest) {
dest = entryPoint + '.js';
}
var mainResult = {
const mainResult = {
sources: [],
dest: dest
}, results = [mainResult];
var usedPlugins = {};
var getLoaderPlugin = function (pluginName) {
const usedPlugins = {};
const getLoaderPlugin = (pluginName) => {
if (!usedPlugins[pluginName]) {
usedPlugins[pluginName] = modulesMap[pluginName].exports;
}
return usedPlugins[pluginName];
};
includedModules.forEach(function (c) {
var bangIndex = c.indexOf('!');
includedModules.forEach((c) => {
const bangIndex = c.indexOf('!');
if (bangIndex >= 0) {
var pluginName = c.substr(0, bangIndex);
var plugin = getLoaderPlugin(pluginName);
const pluginName = c.substr(0, bangIndex);
const plugin = getLoaderPlugin(pluginName);
mainResult.sources.push(emitPlugin(entryPoint, plugin, pluginName, c.substr(bangIndex + 1)));
return;
}
var module = modulesMap[c];
const module = modulesMap[c];
if (module.path === 'empty:') {
return;
}
var contents = readFileAndRemoveBOM(module.path);
const contents = readFileAndRemoveBOM(module.path);
if (module.shim) {
mainResult.sources.push(emitShimmedModule(c, deps[c], module.shim, module.path, contents));
}
else {
mainResult.sources.push(emitNamedModule(c, deps[c], module.defineLocation, module.path, contents));
mainResult.sources.push(emitNamedModule(c, module.defineLocation, module.path, contents));
}
});
Object.keys(usedPlugins).forEach(function (pluginName) {
var plugin = usedPlugins[pluginName];
Object.keys(usedPlugins).forEach((pluginName) => {
const plugin = usedPlugins[pluginName];
if (typeof plugin.writeFile === 'function') {
var req = (function () {
const req = (() => {
throw new Error('no-no!');
});
req.toUrl = function (something) { return something; };
var write = function (filename, contents) {
req.toUrl = something => something;
const write = (filename, contents) => {
results.push({
dest: filename,
sources: [{
@ -313,15 +317,15 @@ function emitEntryPoint(modulesMap, deps, entryPoint, includedModules, prepend,
plugin.writeFile(pluginName, entryPoint, req, write, {});
}
});
var toIFile = function (path) {
var contents = readFileAndRemoveBOM(path);
const toIFile = (path) => {
const contents = readFileAndRemoveBOM(path);
return {
path: path,
contents: contents
};
};
var toPrepend = (prepend || []).map(toIFile);
var toAppend = (append || []).map(toIFile);
const toPrepend = (prepend || []).map(toIFile);
const toAppend = (append || []).map(toIFile);
mainResult.sources = toPrepend.concat(mainResult.sources).concat(toAppend);
return {
files: results,
@ -329,8 +333,8 @@ function emitEntryPoint(modulesMap, deps, entryPoint, includedModules, prepend,
};
}
function readFileAndRemoveBOM(path) {
var BOM_CHAR_CODE = 65279;
var contents = fs.readFileSync(path, 'utf8');
const BOM_CHAR_CODE = 65279;
let contents = fs.readFileSync(path, 'utf8');
// Remove BOM
if (contents.charCodeAt(0) === BOM_CHAR_CODE) {
contents = contents.substring(1);
@ -338,15 +342,15 @@ function readFileAndRemoveBOM(path) {
return contents;
}
function emitPlugin(entryPoint, plugin, pluginName, moduleName) {
var result = '';
let result = '';
if (typeof plugin.write === 'function') {
var write = (function (what) {
const write = ((what) => {
result += what;
});
write.getEntryPoint = function () {
write.getEntryPoint = () => {
return entryPoint;
};
write.asModule = function (moduleId, code) {
write.asModule = (moduleId, code) => {
code = code.replace(/^define\(/, 'define("' + moduleId + '",');
result += code;
};
@ -357,20 +361,20 @@ function emitPlugin(entryPoint, plugin, pluginName, moduleName) {
contents: result
};
}
function emitNamedModule(moduleId, myDeps, defineCallPosition, path, contents) {
function emitNamedModule(moduleId, defineCallPosition, path, contents) {
// `defineCallPosition` is the position in code: |define()
var defineCallOffset = positionToOffset(contents, defineCallPosition.line, defineCallPosition.col);
const defineCallOffset = positionToOffset(contents, defineCallPosition.line, defineCallPosition.col);
// `parensOffset` is the position in code: define|()
var parensOffset = contents.indexOf('(', defineCallOffset);
var insertStr = '"' + moduleId + '", ';
const parensOffset = contents.indexOf('(', defineCallOffset);
const insertStr = '"' + moduleId + '", ';
return {
path: path,
contents: contents.substr(0, parensOffset + 1) + insertStr + contents.substr(parensOffset + 1)
};
}
function emitShimmedModule(moduleId, myDeps, factory, path, contents) {
var strDeps = (myDeps.length > 0 ? '"' + myDeps.join('", "') + '"' : '');
var strDefine = 'define("' + moduleId + '", [' + strDeps + '], ' + factory + ');';
const strDeps = (myDeps.length > 0 ? '"' + myDeps.join('", "') + '"' : '');
const strDefine = 'define("' + moduleId + '", [' + strDeps + '], ' + factory + ');';
return {
path: path,
contents: contents + '\n;\n' + strDefine
@ -383,7 +387,8 @@ function positionToOffset(str, desiredLine, desiredCol) {
if (desiredLine === 1) {
return desiredCol - 1;
}
var line = 1, lastNewLineOffset = -1;
let line = 1;
let lastNewLineOffset = -1;
do {
if (desiredLine === line) {
return lastNewLineOffset + 1 + desiredCol - 1;
@ -397,14 +402,15 @@ function positionToOffset(str, desiredLine, desiredCol) {
* Return a set of reachable nodes in `graph` starting from `rootNodes`
*/
function visit(rootNodes, graph) {
var result = {}, queue = rootNodes;
rootNodes.forEach(function (node) {
const result = {};
const queue = rootNodes;
rootNodes.forEach((node) => {
result[node] = true;
});
while (queue.length > 0) {
var el = queue.shift();
var myEdges = graph[el] || [];
myEdges.forEach(function (toNode) {
const el = queue.shift();
const myEdges = graph[el] || [];
myEdges.forEach((toNode) => {
if (!result[toNode]) {
result[toNode] = true;
queue.push(toNode);
@ -417,11 +423,11 @@ function visit(rootNodes, graph) {
* Perform a topological sort on `graph`
*/
function topologicalSort(graph) {
var allNodes = {}, outgoingEdgeCount = {}, inverseEdges = {};
Object.keys(graph).forEach(function (fromNode) {
const allNodes = {}, outgoingEdgeCount = {}, inverseEdges = {};
Object.keys(graph).forEach((fromNode) => {
allNodes[fromNode] = true;
outgoingEdgeCount[fromNode] = graph[fromNode].length;
graph[fromNode].forEach(function (toNode) {
graph[fromNode].forEach((toNode) => {
allNodes[toNode] = true;
outgoingEdgeCount[toNode] = outgoingEdgeCount[toNode] || 0;
inverseEdges[toNode] = inverseEdges[toNode] || [];
@ -429,8 +435,8 @@ function topologicalSort(graph) {
});
});
// https://en.wikipedia.org/wiki/Topological_sorting
var S = [], L = [];
Object.keys(allNodes).forEach(function (node) {
const S = [], L = [];
Object.keys(allNodes).forEach((node) => {
if (outgoingEdgeCount[node] === 0) {
delete outgoingEdgeCount[node];
S.push(node);
@ -439,10 +445,10 @@ function topologicalSort(graph) {
while (S.length > 0) {
// Ensure the exact same order all the time with the same inputs
S.sort();
var n = S.shift();
const n = S.shift();
L.push(n);
var myInverseEdges = inverseEdges[n] || [];
myInverseEdges.forEach(function (m) {
const myInverseEdges = inverseEdges[n] || [];
myInverseEdges.forEach((m) => {
outgoingEdgeCount[m]--;
if (outgoingEdgeCount[m] === 0) {
delete outgoingEdgeCount[m];

View file

@ -3,9 +3,9 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import fs = require('fs');
import path = require('path');
import vm = require('vm');
import * as fs from 'fs';
import * as path from 'path';
import * as vm from 'vm';
interface IPosition {
line: number;
@ -64,7 +64,7 @@ interface INodeSet {
}
export interface IFile {
path: string;
path: string | null;
contents: string;
}
@ -97,13 +97,13 @@ export interface ILoaderConfig {
/**
* Bundle `entryPoints` given config `config`.
*/
export function bundle(entryPoints: IEntryPoint[], config: ILoaderConfig, callback: (err: any, result: IBundleResult) => void): void {
let entryPointsMap: IEntryPointMap = {};
export function bundle(entryPoints: IEntryPoint[], config: ILoaderConfig, callback: (err: any, result: IBundleResult | null) => void): void {
const entryPointsMap: IEntryPointMap = {};
entryPoints.forEach((module: IEntryPoint) => {
entryPointsMap[module.name] = module;
});
let allMentionedModulesMap: { [modules: string]: boolean; } = {};
const allMentionedModulesMap: { [modules: string]: boolean; } = {};
entryPoints.forEach((module: IEntryPoint) => {
allMentionedModulesMap[module.name] = true;
(module.include || []).forEach(function (includedModule) {
@ -115,28 +115,32 @@ export function bundle(entryPoints: IEntryPoint[], config: ILoaderConfig, callba
});
var code = require('fs').readFileSync(path.join(__dirname, '../../src/vs/loader.js'));
var r: Function = <any>vm.runInThisContext('(function(require, module, exports) { ' + code + '\n});');
var loaderModule = { exports: {} };
const code = require('fs').readFileSync(path.join(__dirname, '../../src/vs/loader.js'));
const r: Function = <any>vm.runInThisContext('(function(require, module, exports) { ' + code + '\n});');
const loaderModule = { exports: {} };
r.call({}, require, loaderModule, loaderModule.exports);
var loader: any = loaderModule.exports;
const loader: any = loaderModule.exports;
config.isBuild = true;
config.paths = config.paths || {};
config.paths['vs/nls'] = 'out-build/vs/nls.build';
config.paths['vs/css'] = 'out-build/vs/css.build';
if (!config.paths['vs/nls']) {
config.paths['vs/nls'] = 'out-build/vs/nls.build';
}
if (!config.paths['vs/css']) {
config.paths['vs/css'] = 'out-build/vs/css.build';
}
loader.config(config);
loader(['require'], (localRequire) => {
let resolvePath = (path: string) => {
let r = localRequire.toUrl(path);
loader(['require'], (localRequire: any) => {
const resolvePath = (path: string) => {
const r = localRequire.toUrl(path);
if (!/\.js/.test(r)) {
return r + '.js';
}
return r;
};
for (let moduleId in entryPointsMap) {
let entryPoint = entryPointsMap[moduleId];
for (const moduleId in entryPointsMap) {
const entryPoint = entryPointsMap[moduleId];
if (entryPoint.append) {
entryPoint.append = entryPoint.append.map(resolvePath);
}
@ -147,76 +151,76 @@ export function bundle(entryPoints: IEntryPoint[], config: ILoaderConfig, callba
});
loader(Object.keys(allMentionedModulesMap), () => {
let modules = <IBuildModuleInfo[]>loader.getBuildInfo();
let partialResult = emitEntryPoints(modules, entryPointsMap);
let cssInlinedResources = loader('vs/css').getInlinedResources();
const modules = <IBuildModuleInfo[]>loader.getBuildInfo();
const partialResult = emitEntryPoints(modules, entryPointsMap);
const cssInlinedResources = loader('vs/css').getInlinedResources();
callback(null, {
files: partialResult.files,
cssInlinedResources: cssInlinedResources,
bundleData: partialResult.bundleData
});
}, (err) => callback(err, null));
}, (err: any) => callback(err, null));
}
function emitEntryPoints(modules: IBuildModuleInfo[], entryPoints: IEntryPointMap): IPartialBundleResult {
let modulesMap: IBuildModuleInfoMap = {};
const modulesMap: IBuildModuleInfoMap = {};
modules.forEach((m: IBuildModuleInfo) => {
modulesMap[m.id] = m;
});
let modulesGraph: IGraph = {};
const modulesGraph: IGraph = {};
modules.forEach((m: IBuildModuleInfo) => {
modulesGraph[m.id] = m.dependencies;
});
let sortedModules = topologicalSort(modulesGraph);
const sortedModules = topologicalSort(modulesGraph);
let result: IConcatFile[] = [];
let usedPlugins: IPluginMap = {};
let bundleData: IBundleData = {
const usedPlugins: IPluginMap = {};
const bundleData: IBundleData = {
graph: modulesGraph,
bundles: {}
};
Object.keys(entryPoints).forEach((moduleToBundle: string) => {
let info = entryPoints[moduleToBundle];
let rootNodes = [moduleToBundle].concat(info.include || []);
let allDependencies = visit(rootNodes, modulesGraph);
let excludes: string[] = ['require', 'exports', 'module'].concat(info.exclude || []);
const info = entryPoints[moduleToBundle];
const rootNodes = [moduleToBundle].concat(info.include || []);
const allDependencies = visit(rootNodes, modulesGraph);
const excludes: string[] = ['require', 'exports', 'module'].concat(info.exclude || []);
excludes.forEach((excludeRoot: string) => {
let allExcludes = visit([excludeRoot], modulesGraph);
const allExcludes = visit([excludeRoot], modulesGraph);
Object.keys(allExcludes).forEach((exclude: string) => {
delete allDependencies[exclude];
});
});
let includedModules = sortedModules.filter((module: string) => {
const includedModules = sortedModules.filter((module: string) => {
return allDependencies[module];
});
bundleData.bundles[moduleToBundle] = includedModules;
let res = emitEntryPoint(
const res = emitEntryPoint(
modulesMap,
modulesGraph,
moduleToBundle,
includedModules,
info.prepend,
info.append,
info.prepend || [],
info.append || [],
info.dest
);
result = result.concat(res.files);
for (let pluginName in res.usedPlugins) {
for (const pluginName in res.usedPlugins) {
usedPlugins[pluginName] = usedPlugins[pluginName] || res.usedPlugins[pluginName];
}
});
Object.keys(usedPlugins).forEach((pluginName: string) => {
let plugin = usedPlugins[pluginName];
const plugin = usedPlugins[pluginName];
if (typeof plugin.finishBuild === 'function') {
let write = (filename: string, contents: string) => {
const write = (filename: string, contents: string) => {
result.push({
dest: filename,
sources: [{
@ -237,16 +241,16 @@ function emitEntryPoints(modules: IBuildModuleInfo[], entryPoints: IEntryPointMa
}
function extractStrings(destFiles: IConcatFile[]): IConcatFile[] {
let parseDefineCall = (moduleMatch: string, depsMatch: string) => {
let module = moduleMatch.replace(/^"|"$/g, '');
const parseDefineCall = (moduleMatch: string, depsMatch: string) => {
const module = moduleMatch.replace(/^"|"$/g, '');
let deps = depsMatch.split(',');
deps = deps.map((dep) => {
dep = dep.trim();
dep = dep.replace(/^"|"$/g, '');
dep = dep.replace(/^'|'$/g, '');
let prefix: string = null;
let _path: string = null;
let pieces = dep.split('!');
let prefix: string | null = null;
let _path: string | null = null;
const pieces = dep.split('!');
if (pieces.length > 1) {
prefix = pieces[0] + '!';
_path = pieces[1];
@ -256,7 +260,7 @@ function extractStrings(destFiles: IConcatFile[]): IConcatFile[] {
}
if (/^\.\//.test(_path) || /^\.\.\//.test(_path)) {
let res = path.join(path.dirname(module), _path).replace(/\\/g, '/');
const res = path.join(path.dirname(module), _path).replace(/\\/g, '/');
return prefix + res;
}
return prefix + _path;
@ -267,7 +271,7 @@ function extractStrings(destFiles: IConcatFile[]): IConcatFile[] {
};
};
destFiles.forEach((destFile, index) => {
destFiles.forEach((destFile) => {
if (!/\.js$/.test(destFile.dest)) {
return;
}
@ -276,33 +280,33 @@ function extractStrings(destFiles: IConcatFile[]): IConcatFile[] {
}
// Do one pass to record the usage counts for each module id
let useCounts: { [moduleId: string]: number; } = {};
const useCounts: { [moduleId: string]: number; } = {};
destFile.sources.forEach((source) => {
let matches = source.contents.match(/define\(("[^"]+"),\s*\[(((, )?("|')[^"']+("|'))+)\]/);
const matches = source.contents.match(/define\(("[^"]+"),\s*\[(((, )?("|')[^"']+("|'))+)\]/);
if (!matches) {
return;
}
let defineCall = parseDefineCall(matches[1], matches[2]);
const defineCall = parseDefineCall(matches[1], matches[2]);
useCounts[defineCall.module] = (useCounts[defineCall.module] || 0) + 1;
defineCall.deps.forEach((dep) => {
useCounts[dep] = (useCounts[dep] || 0) + 1;
});
});
let sortedByUseModules = Object.keys(useCounts);
const sortedByUseModules = Object.keys(useCounts);
sortedByUseModules.sort((a, b) => {
return useCounts[b] - useCounts[a];
});
let replacementMap: { [moduleId: string]: number; } = {};
const replacementMap: { [moduleId: string]: number; } = {};
sortedByUseModules.forEach((module, index) => {
replacementMap[module] = index;
});
destFile.sources.forEach((source) => {
source.contents = source.contents.replace(/define\(("[^"]+"),\s*\[(((, )?("|')[^"']+("|'))+)\]/, (_, moduleMatch, depsMatch) => {
let defineCall = parseDefineCall(moduleMatch, depsMatch);
const defineCall = parseDefineCall(moduleMatch, depsMatch);
return `define(__m[${replacementMap[defineCall.module]}/*${defineCall.module}*/], __M([${defineCall.deps.map(dep => replacementMap[dep] + '/*' + dep + '*/').join(',')}])`;
});
});
@ -332,7 +336,7 @@ function extractStrings(destFiles: IConcatFile[]): IConcatFile[] {
function removeDuplicateTSBoilerplate(destFiles: IConcatFile[]): IConcatFile[] {
// Taken from typescript compiler => emitFiles
let BOILERPLATE = [
const BOILERPLATE = [
{ start: /^var __extends/, end: /^}\)\(\);$/ },
{ start: /^var __assign/, end: /^};$/ },
{ start: /^var __decorate/, end: /^};$/ },
@ -343,22 +347,22 @@ function removeDuplicateTSBoilerplate(destFiles: IConcatFile[]): IConcatFile[] {
];
destFiles.forEach((destFile) => {
let SEEN_BOILERPLATE = [];
const SEEN_BOILERPLATE: boolean[] = [];
destFile.sources.forEach((source) => {
let lines = source.contents.split(/\r\n|\n|\r/);
let newLines: string[] = [];
const lines = source.contents.split(/\r\n|\n|\r/);
const newLines: string[] = [];
let IS_REMOVING_BOILERPLATE = false, END_BOILERPLATE: RegExp;
for (let i = 0; i < lines.length; i++) {
let line = lines[i];
const line = lines[i];
if (IS_REMOVING_BOILERPLATE) {
newLines.push('');
if (END_BOILERPLATE.test(line)) {
if (END_BOILERPLATE!.test(line)) {
IS_REMOVING_BOILERPLATE = false;
}
} else {
for (let j = 0; j < BOILERPLATE.length; j++) {
let boilerplate = BOILERPLATE[j];
const boilerplate = BOILERPLATE[j];
if (boilerplate.start.test(line)) {
if (SEEN_BOILERPLATE[j]) {
IS_REMOVING_BOILERPLATE = true;
@ -398,19 +402,19 @@ function emitEntryPoint(
includedModules: string[],
prepend: string[],
append: string[],
dest: string
dest: string | undefined
): IEmitEntryPointResult {
if (!dest) {
dest = entryPoint + '.js';
}
let mainResult: IConcatFile = {
const mainResult: IConcatFile = {
sources: [],
dest: dest
},
results: IConcatFile[] = [mainResult];
let usedPlugins: IPluginMap = {};
let getLoaderPlugin = (pluginName: string): ILoaderPlugin => {
const usedPlugins: IPluginMap = {};
const getLoaderPlugin = (pluginName: string): ILoaderPlugin => {
if (!usedPlugins[pluginName]) {
usedPlugins[pluginName] = modulesMap[pluginName].exports;
}
@ -418,39 +422,39 @@ function emitEntryPoint(
};
includedModules.forEach((c: string) => {
let bangIndex = c.indexOf('!');
const bangIndex = c.indexOf('!');
if (bangIndex >= 0) {
let pluginName = c.substr(0, bangIndex);
let plugin = getLoaderPlugin(pluginName);
const pluginName = c.substr(0, bangIndex);
const plugin = getLoaderPlugin(pluginName);
mainResult.sources.push(emitPlugin(entryPoint, plugin, pluginName, c.substr(bangIndex + 1)));
return;
}
let module = modulesMap[c];
const module = modulesMap[c];
if (module.path === 'empty:') {
return;
}
let contents = readFileAndRemoveBOM(module.path);
const contents = readFileAndRemoveBOM(module.path);
if (module.shim) {
mainResult.sources.push(emitShimmedModule(c, deps[c], module.shim, module.path, contents));
} else {
mainResult.sources.push(emitNamedModule(c, deps[c], module.defineLocation, module.path, contents));
mainResult.sources.push(emitNamedModule(c, module.defineLocation, module.path, contents));
}
});
Object.keys(usedPlugins).forEach((pluginName: string) => {
let plugin = usedPlugins[pluginName];
const plugin = usedPlugins[pluginName];
if (typeof plugin.writeFile === 'function') {
let req: ILoaderPluginReqFunc = <any>(() => {
const req: ILoaderPluginReqFunc = <any>(() => {
throw new Error('no-no!');
});
req.toUrl = something => something;
let write = (filename: string, contents: string) => {
const write = (filename: string, contents: string) => {
results.push({
dest: filename,
sources: [{
@ -463,16 +467,16 @@ function emitEntryPoint(
}
});
let toIFile = (path): IFile => {
let contents = readFileAndRemoveBOM(path);
const toIFile = (path: string): IFile => {
const contents = readFileAndRemoveBOM(path);
return {
path: path,
contents: contents
};
};
let toPrepend = (prepend || []).map(toIFile);
let toAppend = (append || []).map(toIFile);
const toPrepend = (prepend || []).map(toIFile);
const toAppend = (append || []).map(toIFile);
mainResult.sources = toPrepend.concat(mainResult.sources).concat(toAppend);
@ -483,8 +487,8 @@ function emitEntryPoint(
}
function readFileAndRemoveBOM(path: string): string {
var BOM_CHAR_CODE = 65279;
var contents = fs.readFileSync(path, 'utf8');
const BOM_CHAR_CODE = 65279;
let contents = fs.readFileSync(path, 'utf8');
// Remove BOM
if (contents.charCodeAt(0) === BOM_CHAR_CODE) {
contents = contents.substring(1);
@ -495,7 +499,7 @@ function readFileAndRemoveBOM(path: string): string {
function emitPlugin(entryPoint: string, plugin: ILoaderPlugin, pluginName: string, moduleName: string): IFile {
let result = '';
if (typeof plugin.write === 'function') {
let write: ILoaderPluginWriteFunc = <any>((what) => {
const write: ILoaderPluginWriteFunc = <any>((what: string) => {
result += what;
});
write.getEntryPoint = () => {
@ -513,15 +517,15 @@ function emitPlugin(entryPoint: string, plugin: ILoaderPlugin, pluginName: strin
};
}
function emitNamedModule(moduleId: string, myDeps: string[], defineCallPosition: IPosition, path: string, contents: string): IFile {
function emitNamedModule(moduleId: string, defineCallPosition: IPosition, path: string, contents: string): IFile {
// `defineCallPosition` is the position in code: |define()
let defineCallOffset = positionToOffset(contents, defineCallPosition.line, defineCallPosition.col);
const defineCallOffset = positionToOffset(contents, defineCallPosition.line, defineCallPosition.col);
// `parensOffset` is the position in code: define|()
let parensOffset = contents.indexOf('(', defineCallOffset);
const parensOffset = contents.indexOf('(', defineCallOffset);
let insertStr = '"' + moduleId + '", ';
const insertStr = '"' + moduleId + '", ';
return {
path: path,
@ -530,8 +534,8 @@ function emitNamedModule(moduleId: string, myDeps: string[], defineCallPosition:
}
function emitShimmedModule(moduleId: string, myDeps: string[], factory: string, path: string, contents: string): IFile {
let strDeps = (myDeps.length > 0 ? '"' + myDeps.join('", "') + '"' : '');
let strDefine = 'define("' + moduleId + '", [' + strDeps + '], ' + factory + ');';
const strDeps = (myDeps.length > 0 ? '"' + myDeps.join('", "') + '"' : '');
const strDefine = 'define("' + moduleId + '", [' + strDeps + '], ' + factory + ');';
return {
path: path,
contents: contents + '\n;\n' + strDefine
@ -546,8 +550,8 @@ function positionToOffset(str: string, desiredLine: number, desiredCol: number):
return desiredCol - 1;
}
let line = 1,
lastNewLineOffset = -1;
let line = 1;
let lastNewLineOffset = -1;
do {
if (desiredLine === line) {
@ -565,16 +569,16 @@ function positionToOffset(str: string, desiredLine: number, desiredCol: number):
* Return a set of reachable nodes in `graph` starting from `rootNodes`
*/
function visit(rootNodes: string[], graph: IGraph): INodeSet {
let result: INodeSet = {},
queue = rootNodes;
const result: INodeSet = {};
const queue = rootNodes;
rootNodes.forEach((node) => {
result[node] = true;
});
while (queue.length > 0) {
let el = queue.shift();
let myEdges = graph[el] || [];
const el = queue.shift();
const myEdges = graph[el!] || [];
myEdges.forEach((toNode) => {
if (!result[toNode]) {
result[toNode] = true;
@ -591,7 +595,7 @@ function visit(rootNodes: string[], graph: IGraph): INodeSet {
*/
function topologicalSort(graph: IGraph): string[] {
let allNodes: INodeSet = {},
const allNodes: INodeSet = {},
outgoingEdgeCount: { [node: string]: number; } = {},
inverseEdges: IGraph = {};
@ -609,7 +613,7 @@ function topologicalSort(graph: IGraph): string[] {
});
// https://en.wikipedia.org/wiki/Topological_sorting
let S: string[] = [],
const S: string[] = [],
L: string[] = [];
Object.keys(allNodes).forEach((node: string) => {
@ -623,10 +627,10 @@ function topologicalSort(graph: IGraph): string[] {
// Ensure the exact same order all the time with the same inputs
S.sort();
let n: string = S.shift();
const n: string = S.shift()!;
L.push(n);
let myInverseEdges = inverseEdges[n] || [];
const myInverseEdges = inverseEdges[n] || [];
myInverseEdges.forEach((m: string) => {
outgoingEdgeCount[m]--;
if (outgoingEdgeCount[m] === 0) {

View file

@ -4,44 +4,54 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var gulp = require("gulp");
var tsb = require("gulp-tsb");
var es = require("event-stream");
var watch = require('./watch');
var nls = require("./nls");
var util = require("./util");
var reporter_1 = require("./reporter");
var path = require("path");
var bom = require("gulp-bom");
var sourcemaps = require("gulp-sourcemaps");
var _ = require("underscore");
var monacodts = require("../monaco/api");
var fs = require("fs");
var reporter = reporter_1.createReporter();
const es = require("event-stream");
const fs = require("fs");
const gulp = require("gulp");
const bom = require("gulp-bom");
const sourcemaps = require("gulp-sourcemaps");
const tsb = require("gulp-tsb");
const path = require("path");
const ts = require("typescript");
const _ = require("underscore");
const monacodts = require("../monaco/api");
const nls = require("./nls");
const reporter_1 = require("./reporter");
const util = require("./util");
const util2 = require("gulp-util");
const watch = require('./watch');
const reporter = reporter_1.createReporter();
function getTypeScriptCompilerOptions(src) {
var rootDir = path.join(__dirname, "../../" + src);
var options = require("../../" + src + "/tsconfig.json").compilerOptions;
const rootDir = path.join(__dirname, `../../${src}`);
const tsconfig = require(`../../${src}/tsconfig.json`);
let options;
if (tsconfig.extends) {
options = Object.assign({}, require(path.join(rootDir, tsconfig.extends)).compilerOptions, tsconfig.compilerOptions);
}
else {
options = tsconfig.compilerOptions;
}
options.verbose = false;
options.sourceMap = true;
if (process.env['VSCODE_NO_SOURCEMAP']) { // To be used by developers in a hurry
options.sourceMap = false;
}
options.rootDir = rootDir;
options.baseUrl = rootDir;
options.sourceRoot = util.toFileUri(rootDir);
options.newLine = /\r\n/.test(fs.readFileSync(__filename, 'utf8')) ? 'CRLF' : 'LF';
return options;
}
function createCompile(src, build, emitError) {
var opts = _.clone(getTypeScriptCompilerOptions(src));
const opts = _.clone(getTypeScriptCompilerOptions(src));
opts.inlineSources = !!build;
opts.noFilesystemLookup = true;
var ts = tsb.create(opts, true, null, function (err) { return reporter(err.toString()); });
const ts = tsb.create(opts, true, undefined, err => reporter(err.toString()));
return function (token) {
var utf8Filter = util.filter(function (data) { return /(\/|\\)test(\/|\\).*utf8/.test(data.path); });
var tsFilter = util.filter(function (data) { return /\.ts$/.test(data.path); });
var noDeclarationsFilter = util.filter(function (data) { return !(/\.d\.ts$/.test(data.path)); });
var input = es.through();
var output = input
const utf8Filter = util.filter(data => /(\/|\\)test(\/|\\).*utf8/.test(data.path));
const tsFilter = util.filter(data => /\.ts$/.test(data.path));
const noDeclarationsFilter = util.filter(data => !(/\.d\.ts$/.test(data.path)));
const input = es.through();
const output = input
.pipe(utf8Filter)
.pipe(bom())
.pipe(utf8Filter.restore)
@ -57,92 +67,150 @@ function createCompile(src, build, emitError) {
sourceRoot: opts.sourceRoot
}))
.pipe(tsFilter.restore)
.pipe(reporter.end(emitError));
.pipe(reporter.end(!!emitError));
return es.duplex(input, output);
};
}
var libDtsGlob = 'node_modules/typescript/lib/*.d.ts';
const typesDts = [
'node_modules/typescript/lib/*.d.ts',
'node_modules/@types/**/*.d.ts',
'!node_modules/@types/webpack/**/*',
'!node_modules/@types/uglify-js/**/*',
];
function compileTask(src, out, build) {
return function () {
var compile = createCompile(src, build, true);
var srcPipe = es.merge(gulp.src(src + "/**", { base: "" + src }), gulp.src(libDtsGlob));
// Do not write .d.ts files to disk, as they are not needed there.
var dtsFilter = util.filter(function (data) { return !/\.d\.ts$/.test(data.path); });
const compile = createCompile(src, build, true);
const srcPipe = es.merge(gulp.src(`${src}/**`, { base: `${src}` }), gulp.src(typesDts));
let generator = new MonacoGenerator(false);
if (src === 'src') {
generator.execute();
}
return srcPipe
.pipe(generator.stream)
.pipe(compile())
.pipe(dtsFilter)
.pipe(gulp.dest(out))
.pipe(dtsFilter.restore)
.pipe(src !== 'src' ? es.through() : monacodtsTask(out, false));
.pipe(gulp.dest(out));
};
}
exports.compileTask = compileTask;
function watchTask(out, build) {
return function () {
var compile = createCompile('src', build);
var src = es.merge(gulp.src('src/**', { base: 'src' }), gulp.src(libDtsGlob));
var watchSrc = watch('src/**', { base: 'src' });
// Do not write .d.ts files to disk, as they are not needed there.
var dtsFilter = util.filter(function (data) { return !/\.d\.ts$/.test(data.path); });
const compile = createCompile('src', build);
const src = es.merge(gulp.src('src/**', { base: 'src' }), gulp.src(typesDts));
const watchSrc = watch('src/**', { base: 'src' });
let generator = new MonacoGenerator(true);
generator.execute();
return watchSrc
.pipe(generator.stream)
.pipe(util.incremental(compile, src, true))
.pipe(dtsFilter)
.pipe(gulp.dest(out))
.pipe(dtsFilter.restore)
.pipe(monacodtsTask(out, true));
.pipe(gulp.dest(out));
};
}
exports.watchTask = watchTask;
function monacodtsTask(out, isWatch) {
var basePath = path.resolve(process.cwd(), out);
var neededFiles = {};
monacodts.getFilesToWatch(out).forEach(function (filePath) {
filePath = path.normalize(filePath);
neededFiles[filePath] = true;
});
var inputFiles = {};
for (var filePath in neededFiles) {
if (/\bsrc(\/|\\)vs\b/.test(filePath)) {
// This file is needed from source => simply read it now
inputFiles[filePath] = fs.readFileSync(filePath).toString();
}
}
var setInputFile = function (filePath, contents) {
if (inputFiles[filePath] === contents) {
// no change
return;
}
inputFiles[filePath] = contents;
var neededInputFilesCount = Object.keys(neededFiles).length;
var availableInputFilesCount = Object.keys(inputFiles).length;
if (neededInputFilesCount === availableInputFilesCount) {
run();
}
};
var run = function () {
var result = monacodts.run(out, inputFiles);
if (!result.isTheSame) {
if (isWatch) {
fs.writeFileSync(result.filePath, result.content);
const REPO_SRC_FOLDER = path.join(__dirname, '../../src');
class MonacoGenerator {
constructor(isWatch) {
this._isWatch = isWatch;
this.stream = es.through();
this._inputFiles = monacodts.getIncludesInRecipe().map((moduleId) => {
if (/\.d\.ts$/.test(moduleId)) {
// This source file is already in .d.ts form
return path.join(REPO_SRC_FOLDER, moduleId);
}
else {
fs.writeFileSync(result.filePath, result.content);
resultStream.emit('error', 'monaco.d.ts is no longer up to date. Please run gulp watch and commit the new file.');
return path.join(REPO_SRC_FOLDER, `${moduleId}.ts`);
}
});
// Install watchers
this._watchers = [];
if (this._isWatch) {
this._inputFiles.forEach((filePath) => {
const watcher = fs.watch(filePath);
watcher.addListener('change', () => {
this._inputFileChanged[filePath] = true;
// Avoid hitting empty files... :/
setTimeout(() => this.execute(), 10);
});
this._watchers.push(watcher);
});
const recipeWatcher = fs.watch(monacodts.RECIPE_PATH);
recipeWatcher.addListener('change', () => {
this._recipeFileChanged = true;
// Avoid hitting empty files... :/
setTimeout(() => this.execute(), 10);
});
this._watchers.push(recipeWatcher);
}
};
var resultStream;
if (isWatch) {
watch('build/monaco/*').pipe(es.through(function () {
run();
}));
this._inputFileChanged = {};
this._inputFiles.forEach(file => this._inputFileChanged[file] = true);
this._recipeFileChanged = true;
this._dtsFilesContents = {};
this._dtsFilesContents2 = {};
}
resultStream = es.through(function (data) {
var filePath = path.normalize(path.resolve(basePath, data.relative));
if (neededFiles[filePath]) {
setInputFile(filePath, data.contents.toString());
dispose() {
this._watchers.forEach(watcher => watcher.close());
}
_run() {
let somethingChanged = false;
const setDTSFileContent = (file, contents) => {
if (this._dtsFilesContents[file] === contents) {
return;
}
this._dtsFilesContents[file] = contents;
this._dtsFilesContents2[file] = ts.createSourceFile(file, contents, ts.ScriptTarget.ES5);
somethingChanged = true;
};
const fileMap = {};
this._inputFiles.forEach((inputFile) => {
if (!this._inputFileChanged[inputFile]) {
return;
}
this._inputFileChanged[inputFile] = false;
const inputFileContents = fs.readFileSync(inputFile).toString();
if (/\.d\.ts$/.test(inputFile)) {
// This is a .d.ts file
setDTSFileContent(inputFile, inputFileContents);
return;
}
fileMap[inputFile] = inputFileContents;
});
if (Object.keys(fileMap).length > 0) {
const service = ts.createLanguageService(new monacodts.TypeScriptLanguageServiceHost({}, fileMap, {}));
Object.keys(fileMap).forEach((fileName) => {
const output = service.getEmitOutput(fileName, true).outputFiles[0].text;
const destFileName = fileName.replace(/\.ts$/, '.d.ts');
setDTSFileContent(destFileName, output);
});
}
this.emit('data', data);
});
return resultStream;
if (this._recipeFileChanged) {
this._recipeFileChanged = false;
somethingChanged = true;
}
if (!somethingChanged) {
// Nothing changed
return null;
}
return monacodts.run2('src', this._dtsFilesContents2);
}
_log(message, ...rest) {
util2.log(util2.colors.cyan('[monaco.d.ts]'), message, ...rest);
}
execute() {
const startTime = Date.now();
const result = this._run();
if (!result) {
// nothing really changed
this._log(`monaco.d.ts is unchanged - total time took ${Date.now() - startTime} ms`);
return;
}
if (result.isTheSame) {
this._log(`monaco.d.ts is unchanged - total time took ${Date.now() - startTime} ms`);
return;
}
fs.writeFileSync(result.filePath, result.content);
fs.writeFileSync(path.join(REPO_SRC_FOLDER, 'vs/editor/common/standalone/standaloneEnums.ts'), result.enums);
this._log(`monaco.d.ts is changed - total time took ${Date.now() - startTime} ms`);
if (!this._isWatch) {
this.stream.emit('error', 'monaco.d.ts is no longer up to date. Please run gulp watch and commit the new file.');
}
}
}

View file

@ -5,31 +5,40 @@
'use strict';
import * as gulp from 'gulp';
import * as tsb from 'gulp-tsb';
import * as es from 'event-stream';
const watch = require('./watch');
import * as nls from './nls';
import * as util from './util';
import { createReporter } from './reporter';
import * as path from 'path';
import * as fs from 'fs';
import * as gulp from 'gulp';
import * as bom from 'gulp-bom';
import * as sourcemaps from 'gulp-sourcemaps';
import * as tsb from 'gulp-tsb';
import * as path from 'path';
import * as ts from 'typescript';
import * as _ from 'underscore';
import * as monacodts from '../monaco/api';
import * as fs from 'fs';
import * as nls from './nls';
import { createReporter } from './reporter';
import * as util from './util';
import * as util2 from 'gulp-util';
const watch = require('./watch');
const reporter = createReporter();
function getTypeScriptCompilerOptions(src: string) {
const rootDir = path.join(__dirname, `../../${src}`);
const options = require(`../../${src}/tsconfig.json`).compilerOptions;
const tsconfig = require(`../../${src}/tsconfig.json`);
let options: { [key: string]: any };
if (tsconfig.extends) {
options = Object.assign({}, require(path.join(rootDir, tsconfig.extends)).compilerOptions, tsconfig.compilerOptions);
} else {
options = tsconfig.compilerOptions;
}
options.verbose = false;
options.sourceMap = true;
if (process.env['VSCODE_NO_SOURCEMAP']) { // To be used by developers in a hurry
options.sourceMap = false;
}
options.rootDir = rootDir;
options.baseUrl = rootDir;
options.sourceRoot = util.toFileUri(rootDir);
options.newLine = /\r\n/.test(fs.readFileSync(__filename, 'utf8')) ? 'CRLF' : 'LF';
return options;
@ -40,7 +49,7 @@ function createCompile(src: string, build: boolean, emitError?: boolean): (token
opts.inlineSources = !!build;
opts.noFilesystemLookup = true;
const ts = tsb.create(opts, true, null, err => reporter(err.toString()));
const ts = tsb.create(opts, true, undefined, err => reporter(err.toString()));
return function (token?: util.ICancellationToken) {
@ -65,13 +74,18 @@ function createCompile(src: string, build: boolean, emitError?: boolean): (token
sourceRoot: opts.sourceRoot
}))
.pipe(tsFilter.restore)
.pipe(reporter.end(emitError));
.pipe(reporter.end(!!emitError));
return es.duplex(input, output);
};
}
const libDtsGlob = 'node_modules/typescript/lib/*.d.ts';
const typesDts = [
'node_modules/typescript/lib/*.d.ts',
'node_modules/@types/**/*.d.ts',
'!node_modules/@types/webpack/**/*',
'!node_modules/@types/uglify-js/**/*',
];
export function compileTask(src: string, out: string, build: boolean): () => NodeJS.ReadWriteStream {
@ -80,18 +94,18 @@ export function compileTask(src: string, out: string, build: boolean): () => Nod
const srcPipe = es.merge(
gulp.src(`${src}/**`, { base: `${src}` }),
gulp.src(libDtsGlob),
gulp.src(typesDts),
);
// Do not write .d.ts files to disk, as they are not needed there.
const dtsFilter = util.filter(data => !/\.d\.ts$/.test(data.path));
let generator = new MonacoGenerator(false);
if (src === 'src') {
generator.execute();
}
return srcPipe
.pipe(generator.stream)
.pipe(compile())
.pipe(dtsFilter)
.pipe(gulp.dest(out))
.pipe(dtsFilter.restore)
.pipe(src !== 'src' ? es.through() : monacodtsTask(out, false));
.pipe(gulp.dest(out));
};
}
@ -102,80 +116,157 @@ export function watchTask(out: string, build: boolean): () => NodeJS.ReadWriteSt
const src = es.merge(
gulp.src('src/**', { base: 'src' }),
gulp.src(libDtsGlob),
gulp.src(typesDts),
);
const watchSrc = watch('src/**', { base: 'src' });
// Do not write .d.ts files to disk, as they are not needed there.
const dtsFilter = util.filter(data => !/\.d\.ts$/.test(data.path));
let generator = new MonacoGenerator(true);
generator.execute();
return watchSrc
.pipe(generator.stream)
.pipe(util.incremental(compile, src, true))
.pipe(dtsFilter)
.pipe(gulp.dest(out))
.pipe(dtsFilter.restore)
.pipe(monacodtsTask(out, true));
.pipe(gulp.dest(out));
};
}
function monacodtsTask(out: string, isWatch: boolean): NodeJS.ReadWriteStream {
const REPO_SRC_FOLDER = path.join(__dirname, '../../src');
const basePath = path.resolve(process.cwd(), out);
class MonacoGenerator {
private readonly _isWatch: boolean;
public readonly stream: NodeJS.ReadWriteStream;
/**
* This list is never changed for the lifetime of this object.
*/
private readonly _inputFiles: string[];
private readonly _watchers: fs.FSWatcher[];
const neededFiles: { [file: string]: boolean; } = {};
monacodts.getFilesToWatch(out).forEach(function (filePath) {
filePath = path.normalize(filePath);
neededFiles[filePath] = true;
});
private _inputFileChanged: { [filePath: string]: boolean; };
private _recipeFileChanged: boolean;
const inputFiles: { [file: string]: string; } = {};
for (let filePath in neededFiles) {
if (/\bsrc(\/|\\)vs\b/.test(filePath)) {
// This file is needed from source => simply read it now
inputFiles[filePath] = fs.readFileSync(filePath).toString();
private _dtsFilesContents: { [filePath: string]: string; };
private _dtsFilesContents2: { [filePath: string]: ts.SourceFile; };
constructor(isWatch: boolean) {
this._isWatch = isWatch;
this.stream = es.through();
this._inputFiles = monacodts.getIncludesInRecipe().map((moduleId) => {
if (/\.d\.ts$/.test(moduleId)) {
// This source file is already in .d.ts form
return path.join(REPO_SRC_FOLDER, moduleId);
} else {
return path.join(REPO_SRC_FOLDER, `${moduleId}.ts`);
}
});
// Install watchers
this._watchers = [];
if (this._isWatch) {
this._inputFiles.forEach((filePath) => {
const watcher = fs.watch(filePath);
watcher.addListener('change', () => {
this._inputFileChanged[filePath] = true;
// Avoid hitting empty files... :/
setTimeout(() => this.execute(), 10);
});
this._watchers.push(watcher);
});
const recipeWatcher = fs.watch(monacodts.RECIPE_PATH);
recipeWatcher.addListener('change', () => {
this._recipeFileChanged = true;
// Avoid hitting empty files... :/
setTimeout(() => this.execute(), 10);
});
this._watchers.push(recipeWatcher);
}
this._inputFileChanged = {};
this._inputFiles.forEach(file => this._inputFileChanged[file] = true);
this._recipeFileChanged = true;
this._dtsFilesContents = {};
this._dtsFilesContents2 = {};
}
const setInputFile = (filePath: string, contents: string) => {
if (inputFiles[filePath] === contents) {
// no change
public dispose(): void {
this._watchers.forEach(watcher => watcher.close());
}
private _run(): monacodts.IMonacoDeclarationResult | null {
let somethingChanged = false;
const setDTSFileContent = (file: string, contents: string): void => {
if (this._dtsFilesContents[file] === contents) {
return;
}
this._dtsFilesContents[file] = contents;
this._dtsFilesContents2[file] = ts.createSourceFile(file, contents, ts.ScriptTarget.ES5);
somethingChanged = true;
};
const fileMap: { [fileName: string]: string; } = {};
this._inputFiles.forEach((inputFile) => {
if (!this._inputFileChanged[inputFile]) {
return;
}
this._inputFileChanged[inputFile] = false;
const inputFileContents = fs.readFileSync(inputFile).toString();
if (/\.d\.ts$/.test(inputFile)) {
// This is a .d.ts file
setDTSFileContent(inputFile, inputFileContents);
return;
}
fileMap[inputFile] = inputFileContents;
});
if (Object.keys(fileMap).length > 0) {
const service = ts.createLanguageService(new monacodts.TypeScriptLanguageServiceHost({}, fileMap, {}));
Object.keys(fileMap).forEach((fileName) => {
const output = service.getEmitOutput(fileName, true).outputFiles[0].text;
const destFileName = fileName.replace(/\.ts$/, '.d.ts');
setDTSFileContent(destFileName, output);
});
}
if (this._recipeFileChanged) {
this._recipeFileChanged = false;
somethingChanged = true;
}
if (!somethingChanged) {
// Nothing changed
return null;
}
return monacodts.run2('src', this._dtsFilesContents2);
}
private _log(message: any, ...rest: any[]): void {
util2.log(util2.colors.cyan('[monaco.d.ts]'), message, ...rest);
}
public execute(): void {
const startTime = Date.now();
const result = this._run();
if (!result) {
// nothing really changed
this._log(`monaco.d.ts is unchanged - total time took ${Date.now() - startTime} ms`);
return;
}
inputFiles[filePath] = contents;
const neededInputFilesCount = Object.keys(neededFiles).length;
const availableInputFilesCount = Object.keys(inputFiles).length;
if (neededInputFilesCount === availableInputFilesCount) {
run();
if (result.isTheSame) {
this._log(`monaco.d.ts is unchanged - total time took ${Date.now() - startTime} ms`);
return;
}
};
const run = () => {
const result = monacodts.run(out, inputFiles);
if (!result.isTheSame) {
if (isWatch) {
fs.writeFileSync(result.filePath, result.content);
} else {
fs.writeFileSync(result.filePath, result.content);
resultStream.emit('error', 'monaco.d.ts is no longer up to date. Please run gulp watch and commit the new file.');
}
fs.writeFileSync(result.filePath, result.content);
fs.writeFileSync(path.join(REPO_SRC_FOLDER, 'vs/editor/common/standalone/standaloneEnums.ts'), result.enums);
this._log(`monaco.d.ts is changed - total time took ${Date.now() - startTime} ms`);
if (!this._isWatch) {
this.stream.emit('error', 'monaco.d.ts is no longer up to date. Please run gulp watch and commit the new file.');
}
};
let resultStream: NodeJS.ReadWriteStream;
if (isWatch) {
watch('build/monaco/*').pipe(es.through(function () {
run();
}));
}
resultStream = es.through(function (data) {
const filePath = path.normalize(path.resolve(basePath, data.relative));
if (neededFiles[filePath]) {
setInputFile(filePath, data.contents.toString());
}
this.emit('data', data);
});
return resultStream;
}

View file

@ -11,6 +11,7 @@ const root = path.dirname(path.dirname(__dirname));
function getElectronVersion() {
const yarnrc = fs.readFileSync(path.join(root, '.yarnrc'), 'utf8');
// @ts-ignore
const target = /^target "(.*)"$/m.exec(yarnrc)[1];
return target;
@ -19,6 +20,7 @@ function getElectronVersion() {
module.exports.getElectronVersion = getElectronVersion;
// returns 0 if the right version of electron is in .build/electron
// @ts-ignore
if (require.main === module) {
const version = getElectronVersion();
const versionFile = path.join(root, '.build', 'electron', 'version');

View file

@ -3,41 +3,28 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
var es = require("event-stream");
var fs = require("fs");
var glob = require("glob");
var gulp = require("gulp");
var path = require("path");
var File = require("vinyl");
var vsce = require("vsce");
var stats_1 = require("./stats");
var util2 = require("./util");
var assign = require("object-assign");
var remote = require("gulp-remote-src");
var flatmap = require('gulp-flatmap');
var vzip = require('gulp-vinyl-zip');
var filter = require('gulp-filter');
var rename = require('gulp-rename');
var util = require('gulp-util');
var buffer = require('gulp-buffer');
var json = require('gulp-json-editor');
var webpack = require('webpack');
var webpackGulp = require('webpack-stream');
var root = path.resolve(path.join(__dirname, '..', '..'));
const es = require("event-stream");
const fs = require("fs");
const glob = require("glob");
const gulp = require("gulp");
const path = require("path");
const File = require("vinyl");
const vsce = require("vsce");
const stats_1 = require("./stats");
const util2 = require("./util");
const remote = require("gulp-remote-src");
const vzip = require('gulp-vinyl-zip');
const filter = require("gulp-filter");
const rename = require("gulp-rename");
const util = require('gulp-util');
const buffer = require('gulp-buffer');
const json = require("gulp-json-editor");
const webpack = require('webpack');
const webpackGulp = require('webpack-stream');
const root = path.resolve(path.join(__dirname, '..', '..'));
function fromLocal(extensionPath, sourceMappingURLBase) {
var webpackFilename = path.join(extensionPath, 'extension.webpack.config.js');
const webpackFilename = path.join(extensionPath, 'extension.webpack.config.js');
if (fs.existsSync(webpackFilename)) {
return fromLocalWebpack(extensionPath, sourceMappingURLBase);
}
@ -45,32 +32,31 @@ function fromLocal(extensionPath, sourceMappingURLBase) {
return fromLocalNormal(extensionPath);
}
}
exports.fromLocal = fromLocal;
function fromLocalWebpack(extensionPath, sourceMappingURLBase) {
var result = es.through();
var packagedDependencies = [];
var packageJsonConfig = require(path.join(extensionPath, 'package.json'));
var webpackRootConfig = require(path.join(extensionPath, 'extension.webpack.config.js'));
for (var key in webpackRootConfig.externals) {
const result = es.through();
const packagedDependencies = [];
const packageJsonConfig = require(path.join(extensionPath, 'package.json'));
const webpackRootConfig = require(path.join(extensionPath, 'extension.webpack.config.js'));
for (const key in webpackRootConfig.externals) {
if (key in packageJsonConfig.dependencies) {
packagedDependencies.push(key);
}
}
vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn, packagedDependencies: packagedDependencies }).then(function (fileNames) {
var files = fileNames
.map(function (fileName) { return path.join(extensionPath, fileName); })
.map(function (filePath) { return new File({
vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn, packagedDependencies }).then(fileNames => {
const files = fileNames
.map(fileName => path.join(extensionPath, fileName))
.map(filePath => new File({
path: filePath,
stat: fs.statSync(filePath),
base: extensionPath,
contents: fs.createReadStream(filePath)
}); });
var filesStream = es.readArray(files);
}));
const filesStream = es.readArray(files);
// check for a webpack configuration files, then invoke webpack
// and merge its output with the files stream. also rewrite the package.json
// file to a new entry point
var webpackConfigLocations = glob.sync(path.join(extensionPath, '/**/extension.webpack.config.js'), { ignore: ['**/node_modules'] });
var packageJsonFilter = filter(function (f) {
const webpackConfigLocations = glob.sync(path.join(extensionPath, '/**/extension.webpack.config.js'), { ignore: ['**/node_modules'] });
const packageJsonFilter = filter(f => {
if (path.basename(f.path) === 'package.json') {
// only modify package.json's next to the webpack file.
// to be safe, use existsSync instead of path comparison.
@ -78,22 +64,22 @@ function fromLocalWebpack(extensionPath, sourceMappingURLBase) {
}
return false;
}, { restore: true });
var patchFilesStream = filesStream
const patchFilesStream = filesStream
.pipe(packageJsonFilter)
.pipe(buffer())
.pipe(json(function (data) {
.pipe(json((data) => {
// hardcoded entry point directory!
data.main = data.main.replace('/out/', /dist/);
return data;
}))
.pipe(packageJsonFilter.restore);
var webpackStreams = webpackConfigLocations.map(function (webpackConfigPath) {
var webpackDone = function (err, stats) {
util.log("Bundled extension: " + util.colors.yellow(path.join(path.basename(extensionPath), path.relative(extensionPath, webpackConfigPath))) + "...");
const webpackStreams = webpackConfigLocations.map(webpackConfigPath => {
const webpackDone = (err, stats) => {
util.log(`Bundled extension: ${util.colors.yellow(path.join(path.basename(extensionPath), path.relative(extensionPath, webpackConfigPath)))}...`);
if (err) {
result.emit('error', err);
}
var compilation = stats.compilation;
const { compilation } = stats;
if (compilation.errors.length > 0) {
result.emit('error', compilation.errors.join('\n'));
}
@ -101,8 +87,8 @@ function fromLocalWebpack(extensionPath, sourceMappingURLBase) {
result.emit('error', compilation.warnings.join('\n'));
}
};
var webpackConfig = __assign({}, require(webpackConfigPath), { mode: 'production' });
var relativeOutputPath = path.relative(extensionPath, webpackConfig.output.path);
const webpackConfig = Object.assign({}, require(webpackConfigPath), { mode: 'production' });
const relativeOutputPath = path.relative(extensionPath, webpackConfig.output.path);
return webpackGulp(webpackConfig, webpack, webpackDone)
.pipe(es.through(function (data) {
data.stat = data.stat || {};
@ -114,9 +100,9 @@ function fromLocalWebpack(extensionPath, sourceMappingURLBase) {
// * rewrite sourceMappingURL
// * save to disk so that upload-task picks this up
if (sourceMappingURLBase) {
var contents = data.contents.toString('utf8');
const contents = data.contents.toString('utf8');
data.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, function (_m, g1) {
return "\n//# sourceMappingURL=" + sourceMappingURLBase + "/extensions/" + path.basename(extensionPath) + "/" + relativeOutputPath + "/" + g1;
return `\n//# sourceMappingURL=${sourceMappingURLBase}/extensions/${path.basename(extensionPath)}/${relativeOutputPath}/${g1}`;
}), 'utf8');
if (/\.js\.map$/.test(data.path)) {
if (!fs.existsSync(path.dirname(data.path))) {
@ -128,150 +114,116 @@ function fromLocalWebpack(extensionPath, sourceMappingURLBase) {
this.emit('data', data);
}));
});
es.merge.apply(es, webpackStreams.concat([patchFilesStream])).pipe(result);
}).catch(function (err) { return result.emit('error', err); });
es.merge(...webpackStreams, patchFilesStream)
// .pipe(es.through(function (data) {
// // debug
// console.log('out', data.path, data.contents.length);
// this.emit('data', data);
// }))
.pipe(result);
}).catch(err => {
console.error(extensionPath);
console.error(packagedDependencies);
result.emit('error', err);
});
return result.pipe(stats_1.createStatsStream(path.basename(extensionPath)));
}
function fromLocalNormal(extensionPath) {
var result = es.through();
const result = es.through();
vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn })
.then(function (fileNames) {
var files = fileNames
.map(function (fileName) { return path.join(extensionPath, fileName); })
.map(function (filePath) { return new File({
.then(fileNames => {
const files = fileNames
.map(fileName => path.join(extensionPath, fileName))
.map(filePath => new File({
path: filePath,
stat: fs.statSync(filePath),
base: extensionPath,
contents: fs.createReadStream(filePath)
}); });
}));
es.readArray(files).pipe(result);
})
.catch(function (err) { return result.emit('error', err); });
.catch(err => result.emit('error', err));
return result.pipe(stats_1.createStatsStream(path.basename(extensionPath)));
}
function error(err) {
var result = es.through();
setTimeout(function () { return result.emit('error', err); });
return result;
}
var baseHeaders = {
const baseHeaders = {
'X-Market-Client-Id': 'VSCode Build',
'User-Agent': 'VSCode Build',
'X-Market-User-Id': '291C1CD0-051A-4123-9B4B-30D60EF52EE2',
};
function fromMarketplace(extensionName, version) {
var filterType = 7;
var value = extensionName;
var criterium = { filterType: filterType, value: value };
var criteria = [criterium];
var pageNumber = 1;
var pageSize = 1;
var sortBy = 0;
var sortOrder = 0;
var flags = 0x1 | 0x2 | 0x80;
var assetTypes = ['Microsoft.VisualStudio.Services.VSIXPackage'];
var filters = [{ criteria: criteria, pageNumber: pageNumber, pageSize: pageSize, sortBy: sortBy, sortOrder: sortOrder }];
var body = JSON.stringify({ filters: filters, assetTypes: assetTypes, flags: flags });
var headers = assign({}, baseHeaders, {
'Content-Type': 'application/json',
'Accept': 'application/json;api-version=3.0-preview.1',
'Content-Length': body.length
});
var options = {
base: 'https://marketplace.visualstudio.com/_apis/public/gallery',
function fromMarketplace(extensionName, version, metadata) {
const [publisher, name] = extensionName.split('.');
const url = `https://marketplace.visualstudio.com/_apis/public/gallery/publishers/${publisher}/vsextensions/${name}/${version}/vspackage`;
util.log('Downloading extension:', util.colors.yellow(`${extensionName}@${version}`), '...');
const options = {
base: url,
requestOptions: {
method: 'POST',
gzip: true,
headers: headers,
body: body
headers: baseHeaders
}
};
return remote('/extensionquery', options)
.pipe(flatmap(function (stream, f) {
var rawResult = f.contents.toString('utf8');
var result = JSON.parse(rawResult);
var extension = result.results[0].extensions[0];
if (!extension) {
return error("No such extension: " + extension);
}
var metadata = {
id: extension.extensionId,
publisherId: extension.publisher,
publisherDisplayName: extension.publisher.displayName
};
var extensionVersion = extension.versions.filter(function (v) { return v.version === version; })[0];
if (!extensionVersion) {
return error("No such extension version: " + extensionName + " @ " + version);
}
var asset = extensionVersion.files.filter(function (f) { return f.assetType === 'Microsoft.VisualStudio.Services.VSIXPackage'; })[0];
if (!asset) {
return error("No VSIX found for extension version: " + extensionName + " @ " + version);
}
util.log('Downloading extension:', util.colors.yellow(extensionName + "@" + version), '...');
var options = {
base: asset.source,
requestOptions: {
gzip: true,
headers: baseHeaders
}
};
return remote('', options)
.pipe(flatmap(function (stream) {
var packageJsonFilter = filter('package.json', { restore: true });
return stream
.pipe(vzip.src())
.pipe(filter('extension/**'))
.pipe(rename(function (p) { return p.dirname = p.dirname.replace(/^extension\/?/, ''); }))
.pipe(packageJsonFilter)
.pipe(buffer())
.pipe(json({ __metadata: metadata }))
.pipe(packageJsonFilter.restore);
}));
}));
const packageJsonFilter = filter('package.json', { restore: true });
return remote('', options)
.pipe(vzip.src())
.pipe(filter('extension/**'))
.pipe(rename(p => p.dirname = p.dirname.replace(/^extension\/?/, '')))
.pipe(packageJsonFilter)
.pipe(buffer())
.pipe(json({ __metadata: metadata }))
.pipe(packageJsonFilter.restore);
}
exports.fromMarketplace = fromMarketplace;
var excludedExtensions = [
const excludedExtensions = [
'vscode-api-tests',
'vscode-colorize-tests',
'ms-vscode.node-debug',
'ms-vscode.node-debug2',
];
var builtInExtensions = require('../builtInExtensions.json');
function packageExtensionsStream(opts) {
opts = opts || {};
var localExtensionDescriptions = glob.sync('extensions/*/package.json')
.map(function (manifestPath) {
var extensionPath = path.dirname(path.join(root, manifestPath));
var extensionName = path.basename(extensionPath);
const builtInExtensions = require('../builtInExtensions.json');
/**
* We're doing way too much stuff at once, with webpack et al. So much stuff
* that while downloading extensions from the marketplace, node js doesn't get enough
* stack frames to complete the download in under 2 minutes, at which point the
* marketplace server cuts off the http request. So, we sequentialize the extensino tasks.
*/
function sequence(streamProviders) {
const result = es.through();
function pop() {
if (streamProviders.length === 0) {
result.emit('end');
}
else {
const fn = streamProviders.shift();
fn()
.on('end', function () { setTimeout(pop, 0); })
.pipe(result, { end: false });
}
}
pop();
return result;
}
function packageExtensionsStream(optsIn) {
const opts = optsIn || {};
const localExtensionDescriptions = glob.sync('extensions/*/package.json')
.map(manifestPath => {
const extensionPath = path.dirname(path.join(root, manifestPath));
const extensionName = path.basename(extensionPath);
return { name: extensionName, path: extensionPath };
})
.filter(function (_a) {
var name = _a.name;
return excludedExtensions.indexOf(name) === -1;
})
.filter(function (_a) {
var name = _a.name;
return opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true;
})
.filter(function (_a) {
var name = _a.name;
return builtInExtensions.every(function (b) { return b.name !== name; });
});
var localExtensions = es.merge.apply(es, localExtensionDescriptions.map(function (extension) {
.filter(({ name }) => excludedExtensions.indexOf(name) === -1)
.filter(({ name }) => opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true)
.filter(({ name }) => builtInExtensions.every(b => b.name !== name));
const localExtensions = () => es.merge(...localExtensionDescriptions.map(extension => {
return fromLocal(extension.path, opts.sourceMappingURLBase)
.pipe(rename(function (p) { return p.dirname = "extensions/" + extension.name + "/" + p.dirname; }));
.pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`));
}));
var localExtensionDependencies = gulp.src('extensions/node_modules/**', { base: '.' });
var marketplaceExtensions = es.merge.apply(es, builtInExtensions
.filter(function (_a) {
var name = _a.name;
return opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true;
})
.map(function (extension) {
return fromMarketplace(extension.name, extension.version)
.pipe(rename(function (p) { return p.dirname = "extensions/" + extension.name + "/" + p.dirname; }));
const localExtensionDependencies = () => gulp.src('extensions/node_modules/**', { base: '.' });
const marketplaceExtensions = () => es.merge(...builtInExtensions
.filter(({ name }) => opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true)
.map(extension => {
return fromMarketplace(extension.name, extension.version, extension.metadata)
.pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`));
}));
return es.merge(localExtensions, localExtensionDependencies, marketplaceExtensions)
return sequence([localExtensions, localExtensionDependencies, marketplaceExtensions])
.pipe(util2.setExecutableBit(['**/*.sh']))
.pipe(filter(['**', '!**/*.js.map']));
}

View file

@ -13,21 +13,19 @@ import * as File from 'vinyl';
import * as vsce from 'vsce';
import { createStatsStream } from './stats';
import * as util2 from './util';
import assign = require('object-assign');
import remote = require('gulp-remote-src');
const flatmap = require('gulp-flatmap');
const vzip = require('gulp-vinyl-zip');
const filter = require('gulp-filter');
const rename = require('gulp-rename');
import filter = require('gulp-filter');
import rename = require('gulp-rename');
const util = require('gulp-util');
const buffer = require('gulp-buffer');
const json = require('gulp-json-editor');
import json = require('gulp-json-editor');
const webpack = require('webpack');
const webpackGulp = require('webpack-stream');
const root = path.resolve(path.join(__dirname, '..', '..'));
export function fromLocal(extensionPath: string, sourceMappingURLBase?: string): Stream {
function fromLocal(extensionPath: string, sourceMappingURLBase?: string): Stream {
const webpackFilename = path.join(extensionPath, 'extension.webpack.config.js');
if (fs.existsSync(webpackFilename)) {
return fromLocalWebpack(extensionPath, sourceMappingURLBase);
@ -36,18 +34,19 @@ export function fromLocal(extensionPath: string, sourceMappingURLBase?: string):
}
}
function fromLocalWebpack(extensionPath: string, sourceMappingURLBase: string): Stream {
let result = es.through();
function fromLocalWebpack(extensionPath: string, sourceMappingURLBase: string | undefined): Stream {
const result = es.through();
let packagedDependencies: string[] = [];
let packageJsonConfig = require(path.join(extensionPath, 'package.json'));
let webpackRootConfig = require(path.join(extensionPath, 'extension.webpack.config.js'));
const packagedDependencies: string[] = [];
const packageJsonConfig = require(path.join(extensionPath, 'package.json'));
const webpackRootConfig = require(path.join(extensionPath, 'extension.webpack.config.js'));
for (const key in webpackRootConfig.externals) {
if (key in packageJsonConfig.dependencies) {
packagedDependencies.push(key);
}
}
vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn, packagedDependencies }).then(fileNames => {
const files = fileNames
.map(fileName => path.join(extensionPath, fileName))
@ -80,7 +79,7 @@ function fromLocalWebpack(extensionPath: string, sourceMappingURLBase: string):
const patchFilesStream = filesStream
.pipe(packageJsonFilter)
.pipe(buffer())
.pipe(json(data => {
.pipe(json((data: any) => {
// hardcoded entry point directory!
data.main = data.main.replace('/out/', /dist/);
return data;
@ -90,7 +89,7 @@ function fromLocalWebpack(extensionPath: string, sourceMappingURLBase: string):
const webpackStreams = webpackConfigLocations.map(webpackConfigPath => {
const webpackDone = (err, stats) => {
const webpackDone = (err: any, stats: any) => {
util.log(`Bundled extension: ${util.colors.yellow(path.join(path.basename(extensionPath), path.relative(extensionPath, webpackConfigPath)))}...`);
if (err) {
result.emit('error', err);
@ -108,7 +107,7 @@ function fromLocalWebpack(extensionPath: string, sourceMappingURLBase: string):
...require(webpackConfigPath),
...{ mode: 'production' }
};
let relativeOutputPath = path.relative(extensionPath, webpackConfig.output.path);
const relativeOutputPath = path.relative(extensionPath, webpackConfig.output.path);
return webpackGulp(webpackConfig, webpack, webpackDone)
.pipe(es.through(function (data) {
@ -145,7 +144,11 @@ function fromLocalWebpack(extensionPath: string, sourceMappingURLBase: string):
// }))
.pipe(result);
}).catch(err => result.emit('error', err));
}).catch(err => {
console.error(extensionPath);
console.error(packagedDependencies);
result.emit('error', err);
});
return result.pipe(createStatsStream(path.basename(extensionPath)));
}
@ -171,96 +174,36 @@ function fromLocalNormal(extensionPath: string): Stream {
return result.pipe(createStatsStream(path.basename(extensionPath)));
}
function error(err: any): Stream {
const result = es.through();
setTimeout(() => result.emit('error', err));
return result;
}
const baseHeaders = {
'X-Market-Client-Id': 'VSCode Build',
'User-Agent': 'VSCode Build',
'X-Market-User-Id': '291C1CD0-051A-4123-9B4B-30D60EF52EE2',
};
export function fromMarketplace(extensionName: string, version: string): Stream {
const filterType = 7;
const value = extensionName;
const criterium = { filterType, value };
const criteria = [criterium];
const pageNumber = 1;
const pageSize = 1;
const sortBy = 0;
const sortOrder = 0;
const flags = 0x1 | 0x2 | 0x80;
const assetTypes = ['Microsoft.VisualStudio.Services.VSIXPackage'];
const filters = [{ criteria, pageNumber, pageSize, sortBy, sortOrder }];
const body = JSON.stringify({ filters, assetTypes, flags });
const headers: any = assign({}, baseHeaders, {
'Content-Type': 'application/json',
'Accept': 'application/json;api-version=3.0-preview.1',
'Content-Length': body.length
});
export function fromMarketplace(extensionName: string, version: string, metadata: any): Stream {
const [publisher, name] = extensionName.split('.');
const url = `https://marketplace.visualstudio.com/_apis/public/gallery/publishers/${publisher}/vsextensions/${name}/${version}/vspackage`;
util.log('Downloading extension:', util.colors.yellow(`${extensionName}@${version}`), '...');
const options = {
base: 'https://marketplace.visualstudio.com/_apis/public/gallery',
base: url,
requestOptions: {
method: 'POST',
gzip: true,
headers,
body: body
headers: baseHeaders
}
};
return remote('/extensionquery', options)
.pipe(flatmap((stream, f) => {
const rawResult = f.contents.toString('utf8');
const result = JSON.parse(rawResult);
const extension = result.results[0].extensions[0];
if (!extension) {
return error(`No such extension: ${extension}`);
}
const packageJsonFilter = filter('package.json', { restore: true });
const metadata = {
id: extension.extensionId,
publisherId: extension.publisher,
publisherDisplayName: extension.publisher.displayName
};
const extensionVersion = extension.versions.filter(v => v.version === version)[0];
if (!extensionVersion) {
return error(`No such extension version: ${extensionName} @ ${version}`);
}
const asset = extensionVersion.files.filter(f => f.assetType === 'Microsoft.VisualStudio.Services.VSIXPackage')[0];
if (!asset) {
return error(`No VSIX found for extension version: ${extensionName} @ ${version}`);
}
util.log('Downloading extension:', util.colors.yellow(`${extensionName}@${version}`), '...');
const options = {
base: asset.source,
requestOptions: {
gzip: true,
headers: baseHeaders
}
};
return remote('', options)
.pipe(flatmap(stream => {
const packageJsonFilter = filter('package.json', { restore: true });
return stream
.pipe(vzip.src())
.pipe(filter('extension/**'))
.pipe(rename(p => p.dirname = p.dirname.replace(/^extension\/?/, '')))
.pipe(packageJsonFilter)
.pipe(buffer())
.pipe(json({ __metadata: metadata }))
.pipe(packageJsonFilter.restore);
}));
}));
return remote('', options)
.pipe(vzip.src())
.pipe(filter('extension/**'))
.pipe(rename(p => p.dirname = p.dirname!.replace(/^extension\/?/, '')))
.pipe(packageJsonFilter)
.pipe(buffer())
.pipe(json({ __metadata: metadata }))
.pipe(packageJsonFilter.restore);
}
interface IPackageExtensionsOptions {
@ -278,10 +221,41 @@ const excludedExtensions = [
'ms-vscode.node-debug2',
];
const builtInExtensions: { name: string, version: string, repo: string; }[] = require('../builtInExtensions.json');
interface IBuiltInExtension {
name: string;
version: string;
repo: string;
metadata: any;
}
export function packageExtensionsStream(opts?: IPackageExtensionsOptions): NodeJS.ReadWriteStream {
opts = opts || {};
const builtInExtensions: IBuiltInExtension[] = require('../builtInExtensions.json');
/**
* We're doing way too much stuff at once, with webpack et al. So much stuff
* that while downloading extensions from the marketplace, node js doesn't get enough
* stack frames to complete the download in under 2 minutes, at which point the
* marketplace server cuts off the http request. So, we sequentialize the extensino tasks.
*/
function sequence(streamProviders: { (): Stream }[]): Stream {
const result = es.through();
function pop() {
if (streamProviders.length === 0) {
result.emit('end');
} else {
const fn = streamProviders.shift()!;
fn()
.on('end', function () { setTimeout(pop, 0); })
.pipe(result, { end: false });
}
}
pop();
return result;
}
export function packageExtensionsStream(optsIn?: IPackageExtensionsOptions): NodeJS.ReadWriteStream {
const opts = optsIn || {};
const localExtensionDescriptions = (<string[]>glob.sync('extensions/*/package.json'))
.map(manifestPath => {
@ -293,23 +267,23 @@ export function packageExtensionsStream(opts?: IPackageExtensionsOptions): NodeJ
.filter(({ name }) => opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true)
.filter(({ name }) => builtInExtensions.every(b => b.name !== name));
const localExtensions = es.merge(...localExtensionDescriptions.map(extension => {
const localExtensions = () => es.merge(...localExtensionDescriptions.map(extension => {
return fromLocal(extension.path, opts.sourceMappingURLBase)
.pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`));
}));
const localExtensionDependencies = gulp.src('extensions/node_modules/**', { base: '.' });
const localExtensionDependencies = () => gulp.src('extensions/node_modules/**', { base: '.' });
const marketplaceExtensions = es.merge(
const marketplaceExtensions = () => es.merge(
...builtInExtensions
.filter(({ name }) => opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true)
.map(extension => {
return fromMarketplace(extension.name, extension.version)
return fromMarketplace(extension.name, extension.version, extension.metadata)
.pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`));
})
);
return es.merge(localExtensions, localExtensionDependencies, marketplaceExtensions)
return sequence([localExtensions, localExtensionDependencies, marketplaceExtensions])
.pipe(util2.setExecutableBit(['**/*.sh']))
.pipe(filter(['**', '!**/*.js.map']));
}

View file

@ -4,15 +4,15 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var path = require("path");
var fs = require("fs");
const path = require("path");
const fs = require("fs");
/**
* Returns the sha1 commit version of a repository or undefined in case of failure.
*/
function getVersion(repo) {
var git = path.join(repo, '.git');
var headPath = path.join(git, 'HEAD');
var head;
const git = path.join(repo, '.git');
const headPath = path.join(git, 'HEAD');
let head;
try {
head = fs.readFileSync(headPath, 'utf8').trim();
}
@ -22,29 +22,29 @@ function getVersion(repo) {
if (/^[0-9a-f]{40}$/i.test(head)) {
return head;
}
var refMatch = /^ref: (.*)$/.exec(head);
const refMatch = /^ref: (.*)$/.exec(head);
if (!refMatch) {
return void 0;
}
var ref = refMatch[1];
var refPath = path.join(git, ref);
const ref = refMatch[1];
const refPath = path.join(git, ref);
try {
return fs.readFileSync(refPath, 'utf8').trim();
}
catch (e) {
// noop
}
var packedRefsPath = path.join(git, 'packed-refs');
var refsRaw;
const packedRefsPath = path.join(git, 'packed-refs');
let refsRaw;
try {
refsRaw = fs.readFileSync(packedRefsPath, 'utf8').trim();
}
catch (e) {
return void 0;
}
var refsRegex = /^([0-9a-f]{40})\s+(.+)$/gm;
var refsMatch;
var refs = {};
const refsRegex = /^([0-9a-f]{40})\s+(.+)$/gm;
let refsMatch;
let refs = {};
while (refsMatch = refsRegex.exec(refsRaw)) {
refs[refsMatch[2]] = refsMatch[1];
}

View file

@ -10,7 +10,7 @@ import * as fs from 'fs';
/**
* Returns the sha1 commit version of a repository or undefined in case of failure.
*/
export function getVersion(repo: string): string {
export function getVersion(repo: string): string | undefined {
const git = path.join(repo, '.git');
const headPath = path.join(git, 'HEAD');
let head: string;
@ -50,7 +50,7 @@ export function getVersion(repo: string): string {
}
const refsRegex = /^([0-9a-f]{40})\s+(.+)$/gm;
let refsMatch: RegExpExecArray;
let refsMatch: RegExpExecArray | null;
let refs: { [ref: string]: string } = {};
while (refsMatch = refsRegex.exec(refsRaw)) {

File diff suppressed because it is too large Load diff

View file

@ -78,10 +78,6 @@
"name": "vs/workbench/parts/logs",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/navigation",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/output",
"project": "vscode-workbench"
@ -114,6 +110,10 @@
"name": "vs/workbench/parts/snippets",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/stats",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/surveys",
"project": "vscode-workbench"

View file

@ -7,15 +7,15 @@ import * as path from 'path';
import * as fs from 'fs';
import { through, readable, ThroughStream } from 'event-stream';
import File = require('vinyl');
import * as File from 'vinyl';
import * as Is from 'is';
import * as xml2js from 'xml2js';
import * as glob from 'glob';
import * as https from 'https';
import * as gulp from 'gulp';
var util = require('gulp-util');
var iconv = require('iconv-lite');
import * as util from 'gulp-util';
import * as iconv from 'iconv-lite';
const NUMBER_OF_CONCURRENT_DOWNLOADS = 4;
@ -71,7 +71,7 @@ interface Map<V> {
interface Item {
id: string;
message: string;
comment: string;
comment?: string;
}
export interface Resource {
@ -137,27 +137,6 @@ module PackageJsonFormat {
}
}
interface ModuleJsonFormat {
messages: string[];
keys: (string | LocalizeInfo)[];
}
module ModuleJsonFormat {
export function is(value: any): value is ModuleJsonFormat {
let candidate = value as ModuleJsonFormat;
return Is.defined(candidate)
&& Is.array(candidate.messages) && candidate.messages.every(message => Is.string(message))
&& Is.array(candidate.keys) && candidate.keys.every(key => Is.string(key) || LocalizeInfo.is(key));
}
}
interface BundledExtensionHeaderFormat {
id: string;
type: string;
hash: string;
outDir: string;
}
interface BundledExtensionFormat {
[key: string]: {
messages: string[];
@ -168,7 +147,7 @@ interface BundledExtensionFormat {
export class Line {
private buffer: string[] = [];
constructor(private indent: number = 0) {
constructor(indent: number = 0) {
if (indent > 0) {
this.buffer.push(new Array(indent + 1).join(' '));
}
@ -235,8 +214,8 @@ export class XLF {
let existingKeys = new Set<string>();
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
let realKey: string;
let comment: string;
let realKey: string | undefined;
let comment: string | undefined;
if (Is.string(key)) {
realKey = key;
comment = undefined;
@ -286,17 +265,17 @@ export class XLF {
}
static parsePseudo = function (xlfString: string): Promise<ParsedXLF[]> {
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
let parser = new xml2js.Parser();
let files: { messages: Map<string>, originalFilePath: string, language: string }[] = [];
parser.parseString(xlfString, function (err, result) {
parser.parseString(xlfString, function (_err: any, result: any) {
const fileNodes: any[] = result['xliff']['file'];
fileNodes.forEach(file => {
const originalFilePath = file.$.original;
const messages: Map<string> = {};
const transUnits = file.body[0]['trans-unit'];
if (transUnits) {
transUnits.forEach(unit => {
transUnits.forEach((unit: any) => {
const key = unit.$.id;
const val = pseudify(unit.source[0]['_'].toString());
if (key && val) {
@ -317,7 +296,7 @@ export class XLF {
let files: { messages: Map<string>, originalFilePath: string, language: string }[] = [];
parser.parseString(xlfString, function (err, result) {
parser.parseString(xlfString, function (err: any, result: any) {
if (err) {
reject(new Error(`XLF parsing error: Failed to parse XLIFF string. ${err}`));
}
@ -340,7 +319,7 @@ export class XLF {
const transUnits = file.body[0]['trans-unit'];
if (transUnits) {
transUnits.forEach(unit => {
transUnits.forEach((unit: any) => {
const key = unit.$.id;
if (!unit.target) {
return; // No translation available
@ -369,7 +348,7 @@ export interface ITask<T> {
interface ILimitedTaskFactory<T> {
factory: ITask<Promise<T>>;
c: (value?: T | Thenable<T>) => void;
c: (value?: T | Promise<T>) => void;
e: (error?: any) => void;
}
@ -391,7 +370,7 @@ export class Limiter<T> {
private consume(): void {
while (this.outstandingPromises.length && this.runningPromises < this.maxDegreeOfParalellism) {
const iLimitedTask = this.outstandingPromises.shift();
const iLimitedTask = this.outstandingPromises.shift()!;
this.runningPromises++;
const promise = iLimitedTask.factory();
@ -419,8 +398,8 @@ function stripComments(content: string): string {
* Third matches block comments
* Fourth matches line comments
*/
var regexp: RegExp = /("(?:[^\\\"]*(?:\\.)?)*")|('(?:[^\\\']*(?:\\.)?)*')|(\/\*(?:\r?\n|.)*?\*\/)|(\/{2,}.*?(?:(?:\r?\n)|$))/g;
let result = content.replace(regexp, (match, m1, m2, m3, m4) => {
const regexp = /("(?:[^\\\"]*(?:\\.)?)*")|('(?:[^\\\']*(?:\\.)?)*')|(\/\*(?:\r?\n|.)*?\*\/)|(\/{2,}.*?(?:(?:\r?\n)|$))/g;
let result = content.replace(regexp, (match, _m1, _m2, m3, m4) => {
// Only one of m1, m2, m3, m4 matches
if (m3) {
// A block comment. Replace with nothing
@ -442,9 +421,9 @@ function stripComments(content: string): string {
}
function escapeCharacters(value: string): string {
var result: string[] = [];
for (var i = 0; i < value.length; i++) {
var ch = value.charAt(i);
const result: string[] = [];
for (let i = 0; i < value.length; i++) {
const ch = value.charAt(i);
switch (ch) {
case '\'':
result.push('\\\'');
@ -484,7 +463,6 @@ function processCoreBundleFormat(fileHeader: string, languages: Language[], json
let statistics: Map<number> = Object.create(null);
let total: number = 0;
let defaultMessages: Map<Map<string>> = Object.create(null);
let modules = Object.keys(keysSection);
modules.forEach((module) => {
@ -497,7 +475,6 @@ function processCoreBundleFormat(fileHeader: string, languages: Language[], json
let messageMap: Map<string> = Object.create(null);
defaultMessages[module] = messageMap;
keys.map((key, i) => {
total++;
if (typeof key === 'string') {
messageMap[key] = messages[i];
} else {
@ -520,7 +497,7 @@ function processCoreBundleFormat(fileHeader: string, languages: Language[], json
modules.forEach((module) => {
let order = keysSection[module];
let i18nFile = path.join(cwd, module) + '.i18n.json';
let messages: Map<string> = null;
let messages: Map<string> | null = null;
if (fs.existsSync(i18nFile)) {
let content = stripComments(fs.readFileSync(i18nFile, 'utf8'));
messages = JSON.parse(content);
@ -533,13 +510,13 @@ function processCoreBundleFormat(fileHeader: string, languages: Language[], json
}
let localizedMessages: string[] = [];
order.forEach((keyInfo) => {
let key: string = null;
let key: string | null = null;
if (typeof keyInfo === 'string') {
key = keyInfo;
} else {
key = keyInfo.key;
}
let message: string = messages[key];
let message: string = messages![key];
if (!message) {
if (process.env['VSCODE_BUILD_VERBOSE']) {
log(`No localized message found for key ${key} in module ${module}. Using default message.`);
@ -816,8 +793,8 @@ export function createXlfFilesForIsl(): ThroughStream {
}
export function pushXlfFiles(apiHostname: string, username: string, password: string): ThroughStream {
let tryGetPromises = [];
let updateCreatePromises = [];
let tryGetPromises: Array<Promise<boolean>> = [];
let updateCreatePromises: Array<Promise<boolean>> = [];
return through(function (this: ThroughStream, file: File) {
const project = path.dirname(file.relative);
@ -882,7 +859,7 @@ function getAllResources(project: string, apiHostname: string, username: string,
export function findObsoleteResources(apiHostname: string, username: string, password: string): ThroughStream {
let resourcesByProject: Map<string[]> = Object.create(null);
resourcesByProject[extensionsProject] = [].concat(externalExtensionsWithTranslations); // clone
resourcesByProject[extensionsProject] = ([] as any[]).concat(externalExtensionsWithTranslations); // clone
return through(function (this: ThroughStream, file: File) {
const project = path.dirname(file.relative);
@ -899,7 +876,7 @@ export function findObsoleteResources(apiHostname: string, username: string, pas
const json = JSON.parse(fs.readFileSync('./build/lib/i18n.resources.json', 'utf8'));
let i18Resources = [...json.editor, ...json.workbench].map((r: Resource) => r.project + '/' + r.name.replace(/\//g, '_'));
let extractedResources = [];
let extractedResources: string[] = [];
for (let project of [workbenchProject, editorProject]) {
for (let resource of resourcesByProject[project]) {
if (resource !== 'setup_messages') {
@ -912,7 +889,7 @@ export function findObsoleteResources(apiHostname: string, username: string, pas
console.log(`[i18n] Missing resources in file 'build/lib/i18n.resources.json': JSON.stringify(${extractedResources.filter(p => i18Resources.indexOf(p) === -1)})`);
}
let promises = [];
let promises: Array<Promise<void>> = [];
for (let project in resourcesByProject) {
promises.push(
getAllResources(project, apiHostname, username, password).then(resources => {
@ -957,7 +934,7 @@ function tryGetResource(project: string, slug: string, apiHostname: string, cred
}
function createResource(project: string, slug: string, xlfFile: File, apiHostname: string, credentials: any): Promise<any> {
return new Promise((resolve, reject) => {
return new Promise((_resolve, reject) => {
const data = JSON.stringify({
'content': xlfFile.contents.toString(),
'name': slug,
@ -1048,8 +1025,8 @@ export function pullCoreAndExtensionsXlfFiles(apiHostname: string, username: str
// extensions
let extensionsToLocalize = Object.create(null);
glob.sync('./extensions/**/*.nls.json', ).forEach(extension => extensionsToLocalize[extension.split('/')[2]] = true);
glob.sync('./extensions/*/node_modules/vscode-nls', ).forEach(extension => extensionsToLocalize[extension.split('/')[2]] = true);
glob.sync('./extensions/**/*.nls.json').forEach(extension => extensionsToLocalize[extension.split('/')[2]] = true);
glob.sync('./extensions/*/node_modules/vscode-nls').forEach(extension => extensionsToLocalize[extension.split('/')[2]] = true);
Object.keys(extensionsToLocalize).forEach(extension => {
_coreAndExtensionResources.push({ name: extension, project: extensionsProject });
@ -1077,7 +1054,7 @@ function pullXlfFiles(apiHostname: string, username: string, password: string, l
let expectedTranslationsCount = resources.length;
let translationsRetrieved = 0, called = false;
return readable(function (count, callback) {
return readable(function (_count: any, callback: any) {
// Mark end of stream when all resources were retrieved
if (translationsRetrieved === expectedTranslationsCount) {
return this.emit('end');
@ -1087,7 +1064,7 @@ function pullXlfFiles(apiHostname: string, username: string, password: string, l
called = true;
const stream = this;
resources.map(function (resource) {
retrieveResource(language, resource, apiHostname, credentials).then((file: File) => {
retrieveResource(language, resource, apiHostname, credentials).then((file: File | null) => {
if (file) {
stream.emit('data', file);
}
@ -1099,10 +1076,10 @@ function pullXlfFiles(apiHostname: string, username: string, password: string, l
callback();
});
}
const limiter = new Limiter<File>(NUMBER_OF_CONCURRENT_DOWNLOADS);
const limiter = new Limiter<File | null>(NUMBER_OF_CONCURRENT_DOWNLOADS);
function retrieveResource(language: Language, resource: Resource, apiHostname, credentials): Promise<File> {
return limiter.queue(() => new Promise<File>((resolve, reject) => {
function retrieveResource(language: Language, resource: Resource, apiHostname: string, credentials: string): Promise<File | null> {
return limiter.queue(() => new Promise<File | null>((resolve, reject) => {
const slug = resource.name.replace(/\//g, '_');
const project = resource.project;
let transifexLanguageId = language.id === 'ps' ? 'en' : language.transifexId || language.id;
@ -1205,7 +1182,6 @@ export function prepareI18nPackFiles(externalExtensions: Map<string>, resultingT
let mainPack: I18nPack = { version: i18nPackVersion, contents: {} };
let extensionsPacks: Map<I18nPack> = {};
return through(function (this: ThroughStream, xlf: File) {
let stream = this;
let project = path.dirname(xlf.path);
let resource = path.basename(xlf.path, '.xlf');
let contents = xlf.contents.toString();
@ -1298,7 +1274,7 @@ function createIslFile(originalFilePath: string, messages: Map<string>, language
let firstChar = line.charAt(0);
if (firstChar === '[' || firstChar === ';') {
if (line === '; *** Inno Setup version 5.5.3+ English messages ***') {
content.push(`; *** Inno Setup version 5.5.3+ ${innoSetup.defaultInfo.name} messages ***`);
content.push(`; *** Inno Setup version 5.5.3+ ${innoSetup.defaultInfo!.name} messages ***`);
} else {
content.push(line);
}
@ -1308,9 +1284,9 @@ function createIslFile(originalFilePath: string, messages: Map<string>, language
let translated = line;
if (key) {
if (key === 'LanguageName') {
translated = `${key}=${innoSetup.defaultInfo.name}`;
translated = `${key}=${innoSetup.defaultInfo!.name}`;
} else if (key === 'LanguageID') {
translated = `${key}=${innoSetup.defaultInfo.id}`;
translated = `${key}=${innoSetup.defaultInfo!.id}`;
} else if (key === 'LanguageCodePage') {
translated = `${key}=${innoSetup.codePage.substr(2)}`;
} else {
@ -1331,14 +1307,14 @@ function createIslFile(originalFilePath: string, messages: Map<string>, language
return new File({
path: filePath,
contents: iconv.encode(Buffer.from(content.join('\r\n'), 'utf8'), innoSetup.codePage)
contents: iconv.encode(Buffer.from(content.join('\r\n'), 'utf8').toString(), innoSetup.codePage)
});
}
function encodeEntities(value: string): string {
var result: string[] = [];
for (var i = 0; i < value.length; i++) {
var ch = value[i];
let result: string[] = [];
for (let i = 0; i < value.length; i++) {
let ch = value[i];
switch (ch) {
case '<':
result.push('&lt;');

View file

@ -3,13 +3,12 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var ts = require("typescript");
var lazy = require("lazy.js");
var event_stream_1 = require("event-stream");
var File = require("vinyl");
var sm = require("source-map");
var assign = require("object-assign");
var path = require("path");
const ts = require("typescript");
const lazy = require("lazy.js");
const event_stream_1 = require("event-stream");
const File = require("vinyl");
const sm = require("source-map");
const path = require("path");
var CollectStepResult;
(function (CollectStepResult) {
CollectStepResult[CollectStepResult["Yes"] = 0] = "Yes";
@ -18,9 +17,9 @@ var CollectStepResult;
CollectStepResult[CollectStepResult["NoAndRecurse"] = 3] = "NoAndRecurse";
})(CollectStepResult || (CollectStepResult = {}));
function collect(node, fn) {
var result = [];
const result = [];
function loop(node) {
var stepResult = fn(node);
const stepResult = fn(node);
if (stepResult === CollectStepResult.Yes || stepResult === CollectStepResult.YesAndRecurse) {
result.push(node);
}
@ -32,43 +31,45 @@ function collect(node, fn) {
return result;
}
function clone(object) {
var result = {};
for (var id in object) {
const result = {};
for (const id in object) {
result[id] = object[id];
}
return result;
}
function template(lines) {
var indent = '', wrap = '';
let indent = '', wrap = '';
if (lines.length > 1) {
indent = '\t';
wrap = '\n';
}
return "/*---------------------------------------------------------\n * Copyright (C) Microsoft Corporation. All rights reserved.\n *--------------------------------------------------------*/\ndefine([], [" + (wrap + lines.map(function (l) { return indent + l; }).join(',\n') + wrap) + "]);";
return `/*---------------------------------------------------------
* Copyright (C) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------*/
define([], [${wrap + lines.map(l => indent + l).join(',\n') + wrap}]);`;
}
/**
* Returns a stream containing the patched JavaScript and source maps.
*/
function nls() {
var input = event_stream_1.through();
var output = input.pipe(event_stream_1.through(function (f) {
var _this = this;
const input = event_stream_1.through();
const output = input.pipe(event_stream_1.through(function (f) {
if (!f.sourceMap) {
return this.emit('error', new Error("File " + f.relative + " does not have sourcemaps."));
return this.emit('error', new Error(`File ${f.relative} does not have sourcemaps.`));
}
var source = f.sourceMap.sources[0];
let source = f.sourceMap.sources[0];
if (!source) {
return this.emit('error', new Error("File " + f.relative + " does not have a source in the source map."));
return this.emit('error', new Error(`File ${f.relative} does not have a source in the source map.`));
}
var root = f.sourceMap.sourceRoot;
const root = f.sourceMap.sourceRoot;
if (root) {
source = path.join(root, source);
}
var typescript = f.sourceMap.sourcesContent[0];
const typescript = f.sourceMap.sourcesContent[0];
if (!typescript) {
return this.emit('error', new Error("File " + f.relative + " does not have the original content in the source map."));
return this.emit('error', new Error(`File ${f.relative} does not have the original content in the source map.`));
}
nls.patchFiles(f, typescript).forEach(function (f) { return _this.emit('data', f); });
nls.patchFiles(f, typescript).forEach(f => this.emit('data', f));
}));
return event_stream_1.duplex(input, output);
}
@ -76,8 +77,7 @@ function isImportNode(node) {
return node.kind === ts.SyntaxKind.ImportDeclaration || node.kind === ts.SyntaxKind.ImportEqualsDeclaration;
}
(function (nls_1) {
function fileFrom(file, contents, path) {
if (path === void 0) { path = file.path; }
function fileFrom(file, contents, path = file.path) {
return new File({
contents: Buffer.from(contents),
base: file.base,
@ -87,29 +87,27 @@ function isImportNode(node) {
}
nls_1.fileFrom = fileFrom;
function mappedPositionFrom(source, lc) {
return { source: source, line: lc.line + 1, column: lc.character };
return { source, line: lc.line + 1, column: lc.character };
}
nls_1.mappedPositionFrom = mappedPositionFrom;
function lcFrom(position) {
return { line: position.line - 1, character: position.column };
}
nls_1.lcFrom = lcFrom;
var SingleFileServiceHost = /** @class */ (function () {
function SingleFileServiceHost(options, filename, contents) {
var _this = this;
class SingleFileServiceHost {
constructor(options, filename, contents) {
this.options = options;
this.filename = filename;
this.getCompilationSettings = function () { return _this.options; };
this.getScriptFileNames = function () { return [_this.filename]; };
this.getScriptVersion = function () { return '1'; };
this.getScriptSnapshot = function (name) { return name === _this.filename ? _this.file : _this.lib; };
this.getCurrentDirectory = function () { return ''; };
this.getDefaultLibFileName = function () { return 'lib.d.ts'; };
this.getCompilationSettings = () => this.options;
this.getScriptFileNames = () => [this.filename];
this.getScriptVersion = () => '1';
this.getScriptSnapshot = (name) => name === this.filename ? this.file : this.lib;
this.getCurrentDirectory = () => '';
this.getDefaultLibFileName = () => 'lib.d.ts';
this.file = ts.ScriptSnapshot.fromString(contents);
this.lib = ts.ScriptSnapshot.fromString('');
}
return SingleFileServiceHost;
}());
}
nls_1.SingleFileServiceHost = SingleFileServiceHost;
function isCallExpressionWithinTextSpanCollectStep(textSpan, node) {
if (!ts.textSpanContainsTextSpan({ start: node.pos, length: node.end - node.pos }, textSpan)) {
@ -117,97 +115,96 @@ function isImportNode(node) {
}
return node.kind === ts.SyntaxKind.CallExpression ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse;
}
function analyze(contents, options) {
if (options === void 0) { options = {}; }
var filename = 'file.ts';
var serviceHost = new SingleFileServiceHost(assign(clone(options), { noResolve: true }), filename, contents);
var service = ts.createLanguageService(serviceHost);
var sourceFile = ts.createSourceFile(filename, contents, ts.ScriptTarget.ES5, true);
function analyze(contents, options = {}) {
const filename = 'file.ts';
const serviceHost = new SingleFileServiceHost(Object.assign(clone(options), { noResolve: true }), filename, contents);
const service = ts.createLanguageService(serviceHost);
const sourceFile = ts.createSourceFile(filename, contents, ts.ScriptTarget.ES5, true);
// all imports
var imports = lazy(collect(sourceFile, function (n) { return isImportNode(n) ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse; }));
const imports = lazy(collect(sourceFile, n => isImportNode(n) ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse));
// import nls = require('vs/nls');
var importEqualsDeclarations = imports
.filter(function (n) { return n.kind === ts.SyntaxKind.ImportEqualsDeclaration; })
.map(function (n) { return n; })
.filter(function (d) { return d.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference; })
.filter(function (d) { return d.moduleReference.expression.getText() === '\'vs/nls\''; });
const importEqualsDeclarations = imports
.filter(n => n.kind === ts.SyntaxKind.ImportEqualsDeclaration)
.map(n => n)
.filter(d => d.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference)
.filter(d => d.moduleReference.expression.getText() === '\'vs/nls\'');
// import ... from 'vs/nls';
var importDeclarations = imports
.filter(function (n) { return n.kind === ts.SyntaxKind.ImportDeclaration; })
.map(function (n) { return n; })
.filter(function (d) { return d.moduleSpecifier.kind === ts.SyntaxKind.StringLiteral; })
.filter(function (d) { return d.moduleSpecifier.getText() === '\'vs/nls\''; })
.filter(function (d) { return !!d.importClause && !!d.importClause.namedBindings; });
var nlsExpressions = importEqualsDeclarations
.map(function (d) { return d.moduleReference.expression; })
.concat(importDeclarations.map(function (d) { return d.moduleSpecifier; }))
.map(function (d) { return ({
const importDeclarations = imports
.filter(n => n.kind === ts.SyntaxKind.ImportDeclaration)
.map(n => n)
.filter(d => d.moduleSpecifier.kind === ts.SyntaxKind.StringLiteral)
.filter(d => d.moduleSpecifier.getText() === '\'vs/nls\'')
.filter(d => !!d.importClause && !!d.importClause.namedBindings);
const nlsExpressions = importEqualsDeclarations
.map(d => d.moduleReference.expression)
.concat(importDeclarations.map(d => d.moduleSpecifier))
.map(d => ({
start: ts.getLineAndCharacterOfPosition(sourceFile, d.getStart()),
end: ts.getLineAndCharacterOfPosition(sourceFile, d.getEnd())
}); });
}));
// `nls.localize(...)` calls
var nlsLocalizeCallExpressions = importDeclarations
.filter(function (d) { return d.importClause.namedBindings.kind === ts.SyntaxKind.NamespaceImport; })
.map(function (d) { return d.importClause.namedBindings.name; })
.concat(importEqualsDeclarations.map(function (d) { return d.name; }))
const nlsLocalizeCallExpressions = importDeclarations
.filter(d => !!(d.importClause && d.importClause.namedBindings && d.importClause.namedBindings.kind === ts.SyntaxKind.NamespaceImport))
.map(d => d.importClause.namedBindings.name)
.concat(importEqualsDeclarations.map(d => d.name))
// find read-only references to `nls`
.map(function (n) { return service.getReferencesAtPosition(filename, n.pos + 1); })
.map(n => service.getReferencesAtPosition(filename, n.pos + 1))
.flatten()
.filter(function (r) { return !r.isWriteAccess; })
.filter(r => !r.isWriteAccess)
// find the deepest call expressions AST nodes that contain those references
.map(function (r) { return collect(sourceFile, function (n) { return isCallExpressionWithinTextSpanCollectStep(r.textSpan, n); }); })
.map(function (a) { return lazy(a).last(); })
.filter(function (n) { return !!n; })
.map(function (n) { return n; })
.map(r => collect(sourceFile, n => isCallExpressionWithinTextSpanCollectStep(r.textSpan, n)))
.map(a => lazy(a).last())
.filter(n => !!n)
.map(n => n)
// only `localize` calls
.filter(function (n) { return n.expression.kind === ts.SyntaxKind.PropertyAccessExpression && n.expression.name.getText() === 'localize'; });
.filter(n => n.expression.kind === ts.SyntaxKind.PropertyAccessExpression && n.expression.name.getText() === 'localize');
// `localize` named imports
var allLocalizeImportDeclarations = importDeclarations
.filter(function (d) { return d.importClause.namedBindings.kind === ts.SyntaxKind.NamedImports; })
.map(function (d) { return [].concat(d.importClause.namedBindings.elements); })
const allLocalizeImportDeclarations = importDeclarations
.filter(d => !!(d.importClause && d.importClause.namedBindings && d.importClause.namedBindings.kind === ts.SyntaxKind.NamedImports))
.map(d => [].concat(d.importClause.namedBindings.elements))
.flatten();
// `localize` read-only references
var localizeReferences = allLocalizeImportDeclarations
.filter(function (d) { return d.name.getText() === 'localize'; })
.map(function (n) { return service.getReferencesAtPosition(filename, n.pos + 1); })
const localizeReferences = allLocalizeImportDeclarations
.filter(d => d.name.getText() === 'localize')
.map(n => service.getReferencesAtPosition(filename, n.pos + 1))
.flatten()
.filter(function (r) { return !r.isWriteAccess; });
.filter(r => !r.isWriteAccess);
// custom named `localize` read-only references
var namedLocalizeReferences = allLocalizeImportDeclarations
.filter(function (d) { return d.propertyName && d.propertyName.getText() === 'localize'; })
.map(function (n) { return service.getReferencesAtPosition(filename, n.name.pos + 1); })
const namedLocalizeReferences = allLocalizeImportDeclarations
.filter(d => d.propertyName && d.propertyName.getText() === 'localize')
.map(n => service.getReferencesAtPosition(filename, n.name.pos + 1))
.flatten()
.filter(function (r) { return !r.isWriteAccess; });
.filter(r => !r.isWriteAccess);
// find the deepest call expressions AST nodes that contain those references
var localizeCallExpressions = localizeReferences
const localizeCallExpressions = localizeReferences
.concat(namedLocalizeReferences)
.map(function (r) { return collect(sourceFile, function (n) { return isCallExpressionWithinTextSpanCollectStep(r.textSpan, n); }); })
.map(function (a) { return lazy(a).last(); })
.filter(function (n) { return !!n; })
.map(function (n) { return n; });
.map(r => collect(sourceFile, n => isCallExpressionWithinTextSpanCollectStep(r.textSpan, n)))
.map(a => lazy(a).last())
.filter(n => !!n)
.map(n => n);
// collect everything
var localizeCalls = nlsLocalizeCallExpressions
const localizeCalls = nlsLocalizeCallExpressions
.concat(localizeCallExpressions)
.map(function (e) { return e.arguments; })
.filter(function (a) { return a.length > 1; })
.sort(function (a, b) { return a[0].getStart() - b[0].getStart(); })
.map(function (a) { return ({
.map(e => e.arguments)
.filter(a => a.length > 1)
.sort((a, b) => a[0].getStart() - b[0].getStart())
.map(a => ({
keySpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getStart()), end: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getEnd()) },
key: a[0].getText(),
valueSpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getStart()), end: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getEnd()) },
value: a[1].getText()
}); });
}));
return {
localizeCalls: localizeCalls.toArray(),
nlsExpressions: nlsExpressions.toArray()
};
}
nls_1.analyze = analyze;
var TextModel = /** @class */ (function () {
function TextModel(contents) {
var regex = /\r\n|\r|\n/g;
var index = 0;
var match;
class TextModel {
constructor(contents) {
const regex = /\r\n|\r|\n/g;
let index = 0;
let match;
this.lines = [];
this.lineEndings = [];
while (match = regex.exec(contents)) {
@ -220,85 +217,80 @@ function isImportNode(node) {
this.lineEndings.push('');
}
}
TextModel.prototype.get = function (index) {
get(index) {
return this.lines[index];
};
TextModel.prototype.set = function (index, line) {
}
set(index, line) {
this.lines[index] = line;
};
Object.defineProperty(TextModel.prototype, "lineCount", {
get: function () {
return this.lines.length;
},
enumerable: true,
configurable: true
});
}
get lineCount() {
return this.lines.length;
}
/**
* Applies patch(es) to the model.
* Multiple patches must be ordered.
* Does not support patches spanning multiple lines.
*/
TextModel.prototype.apply = function (patch) {
var startLineNumber = patch.span.start.line;
var endLineNumber = patch.span.end.line;
var startLine = this.lines[startLineNumber] || '';
var endLine = this.lines[endLineNumber] || '';
apply(patch) {
const startLineNumber = patch.span.start.line;
const endLineNumber = patch.span.end.line;
const startLine = this.lines[startLineNumber] || '';
const endLine = this.lines[endLineNumber] || '';
this.lines[startLineNumber] = [
startLine.substring(0, patch.span.start.character),
patch.content,
endLine.substring(patch.span.end.character)
].join('');
for (var i = startLineNumber + 1; i <= endLineNumber; i++) {
for (let i = startLineNumber + 1; i <= endLineNumber; i++) {
this.lines[i] = '';
}
};
TextModel.prototype.toString = function () {
}
toString() {
return lazy(this.lines).zip(this.lineEndings)
.flatten().toArray().join('');
};
return TextModel;
}());
}
}
nls_1.TextModel = TextModel;
function patchJavascript(patches, contents, moduleId) {
var model = new nls.TextModel(contents);
const model = new nls.TextModel(contents);
// patch the localize calls
lazy(patches).reverse().each(function (p) { return model.apply(p); });
lazy(patches).reverse().each(p => model.apply(p));
// patch the 'vs/nls' imports
var firstLine = model.get(0);
var patchedFirstLine = firstLine.replace(/(['"])vs\/nls\1/g, "$1vs/nls!" + moduleId + "$1");
const firstLine = model.get(0);
const patchedFirstLine = firstLine.replace(/(['"])vs\/nls\1/g, `$1vs/nls!${moduleId}$1`);
model.set(0, patchedFirstLine);
return model.toString();
}
nls_1.patchJavascript = patchJavascript;
function patchSourcemap(patches, rsm, smc) {
var smg = new sm.SourceMapGenerator({
const smg = new sm.SourceMapGenerator({
file: rsm.file,
sourceRoot: rsm.sourceRoot
});
patches = patches.reverse();
var currentLine = -1;
var currentLineDiff = 0;
var source = null;
smc.eachMapping(function (m) {
var patch = patches[patches.length - 1];
var original = { line: m.originalLine, column: m.originalColumn };
var generated = { line: m.generatedLine, column: m.generatedColumn };
let currentLine = -1;
let currentLineDiff = 0;
let source = null;
smc.eachMapping(m => {
const patch = patches[patches.length - 1];
const original = { line: m.originalLine, column: m.originalColumn };
const generated = { line: m.generatedLine, column: m.generatedColumn };
if (currentLine !== generated.line) {
currentLineDiff = 0;
}
currentLine = generated.line;
generated.column += currentLineDiff;
if (patch && m.generatedLine - 1 === patch.span.end.line && m.generatedColumn === patch.span.end.character) {
var originalLength = patch.span.end.character - patch.span.start.character;
var modifiedLength = patch.content.length;
var lengthDiff = modifiedLength - originalLength;
const originalLength = patch.span.end.character - patch.span.start.character;
const modifiedLength = patch.content.length;
const lengthDiff = modifiedLength - originalLength;
currentLineDiff += lengthDiff;
generated.column += lengthDiff;
patches.pop();
}
source = rsm.sourceRoot ? path.relative(rsm.sourceRoot, m.source) : m.source;
source = source.replace(/\\/g, '/');
smg.addMapping({ source: source, name: m.name, original: original, generated: generated });
smg.addMapping({ source, name: m.name, original, generated });
}, null, sm.SourceMapConsumer.GENERATED_ORDER);
if (source) {
smg.setSourceContent(source, smc.sourceContentFor(source));
@ -307,47 +299,47 @@ function isImportNode(node) {
}
nls_1.patchSourcemap = patchSourcemap;
function patch(moduleId, typescript, javascript, sourcemap) {
var _a = analyze(typescript), localizeCalls = _a.localizeCalls, nlsExpressions = _a.nlsExpressions;
const { localizeCalls, nlsExpressions } = analyze(typescript);
if (localizeCalls.length === 0) {
return { javascript: javascript, sourcemap: sourcemap };
return { javascript, sourcemap };
}
var nlsKeys = template(localizeCalls.map(function (lc) { return lc.key; }));
var nls = template(localizeCalls.map(function (lc) { return lc.value; }));
var smc = new sm.SourceMapConsumer(sourcemap);
var positionFrom = mappedPositionFrom.bind(null, sourcemap.sources[0]);
var i = 0;
const nlsKeys = template(localizeCalls.map(lc => lc.key));
const nls = template(localizeCalls.map(lc => lc.value));
const smc = new sm.SourceMapConsumer(sourcemap);
const positionFrom = mappedPositionFrom.bind(null, sourcemap.sources[0]);
let i = 0;
// build patches
var patches = lazy(localizeCalls)
.map(function (lc) { return ([
const patches = lazy(localizeCalls)
.map(lc => ([
{ range: lc.keySpan, content: '' + (i++) },
{ range: lc.valueSpan, content: 'null' }
]); })
]))
.flatten()
.map(function (c) {
var start = lcFrom(smc.generatedPositionFor(positionFrom(c.range.start)));
var end = lcFrom(smc.generatedPositionFor(positionFrom(c.range.end)));
return { span: { start: start, end: end }, content: c.content };
.map(c => {
const start = lcFrom(smc.generatedPositionFor(positionFrom(c.range.start)));
const end = lcFrom(smc.generatedPositionFor(positionFrom(c.range.end)));
return { span: { start, end }, content: c.content };
})
.toArray();
javascript = patchJavascript(patches, javascript, moduleId);
// since imports are not within the sourcemap information,
// we must do this MacGyver style
if (nlsExpressions.length) {
javascript = javascript.replace(/^define\(.*$/m, function (line) {
return line.replace(/(['"])vs\/nls\1/g, "$1vs/nls!" + moduleId + "$1");
javascript = javascript.replace(/^define\(.*$/m, line => {
return line.replace(/(['"])vs\/nls\1/g, `$1vs/nls!${moduleId}$1`);
});
}
sourcemap = patchSourcemap(patches, sourcemap, smc);
return { javascript: javascript, sourcemap: sourcemap, nlsKeys: nlsKeys, nls: nls };
return { javascript, sourcemap, nlsKeys, nls };
}
nls_1.patch = patch;
function patchFiles(javascriptFile, typescript) {
// hack?
var moduleId = javascriptFile.relative
const moduleId = javascriptFile.relative
.replace(/\.js$/, '')
.replace(/\\/g, '/');
var _a = patch(moduleId, typescript, javascriptFile.contents.toString(), javascriptFile.sourceMap), javascript = _a.javascript, sourcemap = _a.sourcemap, nlsKeys = _a.nlsKeys, nls = _a.nls;
var result = [fileFrom(javascriptFile, javascript)];
const { javascript, sourcemap, nlsKeys, nls } = patch(moduleId, typescript, javascriptFile.contents.toString(), javascriptFile.sourceMap);
const result = [fileFrom(javascriptFile, javascript)];
result[0].sourceMap = sourcemap;
if (nlsKeys) {
result.push(fileFrom(javascriptFile, nlsKeys, javascriptFile.path.replace(/\.js$/, '.nls.keys.js')));

View file

@ -6,10 +6,9 @@
import * as ts from 'typescript';
import * as lazy from 'lazy.js';
import { duplex, through } from 'event-stream';
import File = require('vinyl');
import * as File from 'vinyl';
import * as sm from 'source-map';
import assign = require('object-assign');
import path = require('path');
import * as path from 'path';
declare class FileSourceMap extends File {
public sourceMap: sm.RawSourceMap;
@ -26,7 +25,7 @@ function collect(node: ts.Node, fn: (node: ts.Node) => CollectStepResult): ts.No
const result: ts.Node[] = [];
function loop(node: ts.Node) {
var stepResult = fn(node);
const stepResult = fn(node);
if (stepResult === CollectStepResult.Yes || stepResult === CollectStepResult.YesAndRecurse) {
result.push(node);
@ -42,8 +41,8 @@ function collect(node: ts.Node, fn: (node: ts.Node) => CollectStepResult): ts.No
}
function clone<T>(object: T): T {
var result = <T>{};
for (var id in object) {
const result = <T>{};
for (const id in object) {
result[id] = object[id];
}
return result;
@ -67,8 +66,8 @@ define([], [${ wrap + lines.map(l => indent + l).join(',\n') + wrap}]);`;
* Returns a stream containing the patched JavaScript and source maps.
*/
function nls(): NodeJS.ReadWriteStream {
var input = through();
var output = input.pipe(through(function (f: FileSourceMap) {
const input = through();
const output = input.pipe(through(function (f: FileSourceMap) {
if (!f.sourceMap) {
return this.emit('error', new Error(`File ${f.relative} does not have sourcemaps.`));
}
@ -83,7 +82,7 @@ function nls(): NodeJS.ReadWriteStream {
source = path.join(root, source);
}
const typescript = f.sourceMap.sourcesContent[0];
const typescript = f.sourceMap.sourcesContent![0];
if (!typescript) {
return this.emit('error', new Error(`File ${f.relative} does not have the original content in the source map.`));
}
@ -174,7 +173,7 @@ module nls {
export function analyze(contents: string, options: ts.CompilerOptions = {}): ILocalizeAnalysisResult {
const filename = 'file.ts';
const serviceHost = new SingleFileServiceHost(assign(clone(options), { noResolve: true }), filename, contents);
const serviceHost = new SingleFileServiceHost(Object.assign(clone(options), { noResolve: true }), filename, contents);
const service = ts.createLanguageService(serviceHost);
const sourceFile = ts.createSourceFile(filename, contents, ts.ScriptTarget.ES5, true);
@ -206,8 +205,8 @@ module nls {
// `nls.localize(...)` calls
const nlsLocalizeCallExpressions = importDeclarations
.filter(d => d.importClause.namedBindings.kind === ts.SyntaxKind.NamespaceImport)
.map(d => (<ts.NamespaceImport>d.importClause.namedBindings).name)
.filter(d => !!(d.importClause && d.importClause.namedBindings && d.importClause.namedBindings.kind === ts.SyntaxKind.NamespaceImport))
.map(d => (<ts.NamespaceImport>d.importClause!.namedBindings).name)
.concat(importEqualsDeclarations.map(d => d.name))
// find read-only references to `nls`
@ -226,8 +225,8 @@ module nls {
// `localize` named imports
const allLocalizeImportDeclarations = importDeclarations
.filter(d => d.importClause.namedBindings.kind === ts.SyntaxKind.NamedImports)
.map(d => [].concat((<ts.NamedImports>d.importClause.namedBindings).elements))
.filter(d => !!(d.importClause && d.importClause.namedBindings && d.importClause.namedBindings.kind === ts.SyntaxKind.NamedImports))
.map(d => ([] as any[]).concat((<ts.NamedImports>d.importClause!.namedBindings!).elements))
.flatten();
// `localize` read-only references
@ -279,7 +278,7 @@ module nls {
constructor(contents: string) {
const regex = /\r\n|\r|\n/g;
let index = 0;
let match: RegExpExecArray;
let match: RegExpExecArray | null;
this.lines = [];
this.lineEndings = [];
@ -360,7 +359,7 @@ module nls {
patches = patches.reverse();
let currentLine = -1;
let currentLineDiff = 0;
let source = null;
let source: string | null = null;
smc.eachMapping(m => {
const patch = patches[patches.length - 1];

View file

@ -4,30 +4,30 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var es = require("event-stream");
var gulp = require("gulp");
var concat = require("gulp-concat");
var minifyCSS = require("gulp-cssnano");
var filter = require("gulp-filter");
var flatmap = require("gulp-flatmap");
var sourcemaps = require("gulp-sourcemaps");
var uglify = require("gulp-uglify");
var composer = require("gulp-uglify/composer");
var gulpUtil = require("gulp-util");
var path = require("path");
var pump = require("pump");
var uglifyes = require("uglify-es");
var VinylFile = require("vinyl");
var bundle = require("./bundle");
var i18n_1 = require("./i18n");
var stats_1 = require("./stats");
var util = require("./util");
var REPO_ROOT_PATH = path.join(__dirname, '../..');
const es = require("event-stream");
const gulp = require("gulp");
const concat = require("gulp-concat");
const minifyCSS = require("gulp-cssnano");
const filter = require("gulp-filter");
const flatmap = require("gulp-flatmap");
const sourcemaps = require("gulp-sourcemaps");
const uglify = require("gulp-uglify");
const composer = require("gulp-uglify/composer");
const gulpUtil = require("gulp-util");
const path = require("path");
const pump = require("pump");
const uglifyes = require("uglify-es");
const VinylFile = require("vinyl");
const bundle = require("./bundle");
const i18n_1 = require("./i18n");
const stats_1 = require("./stats");
const util = require("./util");
const REPO_ROOT_PATH = path.join(__dirname, '../..');
function log(prefix, message) {
gulpUtil.log(gulpUtil.colors.cyan('[' + prefix + ']'), message);
}
function loaderConfig(emptyPaths) {
var result = {
const result = {
paths: {
'vs': 'out-build/vs',
'vscode': 'empty:'
@ -38,20 +38,20 @@ function loaderConfig(emptyPaths) {
return result;
}
exports.loaderConfig = loaderConfig;
var IS_OUR_COPYRIGHT_REGEXP = /Copyright \(C\) Microsoft Corporation/i;
const IS_OUR_COPYRIGHT_REGEXP = /Copyright \(C\) Microsoft Corporation/i;
function loader(src, bundledFileHeader, bundleLoader) {
var sources = [
src + "/vs/loader.js"
let sources = [
`${src}/vs/loader.js`
];
if (bundleLoader) {
sources = sources.concat([
src + "/vs/css.js",
src + "/vs/nls.js"
`${src}/vs/css.js`,
`${src}/vs/nls.js`
]);
}
var isFirst = true;
let isFirst = true;
return (gulp
.src(sources, { base: "" + src })
.src(sources, { base: `${src}` })
.pipe(es.through(function (data) {
if (isFirst) {
isFirst = false;
@ -74,12 +74,12 @@ function loader(src, bundledFileHeader, bundleLoader) {
})));
}
function toConcatStream(src, bundledFileHeader, sources, dest) {
var useSourcemaps = /\.js$/.test(dest) && !/\.nls\.js$/.test(dest);
const useSourcemaps = /\.js$/.test(dest) && !/\.nls\.js$/.test(dest);
// If a bundle ends up including in any of the sources our copyright, then
// insert a fake source at the beginning of each bundle with our copyright
var containsOurCopyright = false;
for (var i = 0, len = sources.length; i < len; i++) {
var fileContents = sources[i].contents;
let containsOurCopyright = false;
for (let i = 0, len = sources.length; i < len; i++) {
const fileContents = sources[i].contents;
if (IS_OUR_COPYRIGHT_REGEXP.test(fileContents)) {
containsOurCopyright = true;
break;
@ -91,9 +91,9 @@ function toConcatStream(src, bundledFileHeader, sources, dest) {
contents: bundledFileHeader
});
}
var treatedSources = sources.map(function (source) {
var root = source.path ? REPO_ROOT_PATH.replace(/\\/g, '/') : '';
var base = source.path ? root + ("/" + src) : '';
const treatedSources = sources.map(function (source) {
const root = source.path ? REPO_ROOT_PATH.replace(/\\/g, '/') : '';
const base = source.path ? root + `/${src}` : '';
return new VinylFile({
path: source.path ? root + '/' + source.path.replace(/\\/g, '/') : 'fake',
base: base,
@ -111,33 +111,33 @@ function toBundleStream(src, bundledFileHeader, bundles) {
}));
}
function optimizeTask(opts) {
var src = opts.src;
var entryPoints = opts.entryPoints;
var otherSources = opts.otherSources;
var resources = opts.resources;
var loaderConfig = opts.loaderConfig;
var bundledFileHeader = opts.header;
var bundleLoader = (typeof opts.bundleLoader === 'undefined' ? true : opts.bundleLoader);
var out = opts.out;
const src = opts.src;
const entryPoints = opts.entryPoints;
const otherSources = opts.otherSources;
const resources = opts.resources;
const loaderConfig = opts.loaderConfig;
const bundledFileHeader = opts.header;
const bundleLoader = (typeof opts.bundleLoader === 'undefined' ? true : opts.bundleLoader);
const out = opts.out;
return function () {
var bundlesStream = es.through(); // this stream will contain the bundled files
var resourcesStream = es.through(); // this stream will contain the resources
var bundleInfoStream = es.through(); // this stream will contain bundleInfo.json
const bundlesStream = es.through(); // this stream will contain the bundled files
const resourcesStream = es.through(); // this stream will contain the resources
const bundleInfoStream = es.through(); // this stream will contain bundleInfo.json
bundle.bundle(entryPoints, loaderConfig, function (err, result) {
if (err) {
if (err || !result) {
return bundlesStream.emit('error', JSON.stringify(err));
}
toBundleStream(src, bundledFileHeader, result.files).pipe(bundlesStream);
// Remove css inlined resources
var filteredResources = resources.slice();
const filteredResources = resources.slice();
result.cssInlinedResources.forEach(function (resource) {
if (process.env['VSCODE_BUILD_VERBOSE']) {
log('optimizer', 'excluding inlined: ' + resource);
}
filteredResources.push('!' + resource);
});
gulp.src(filteredResources, { base: "" + src }).pipe(resourcesStream);
var bundleInfoArray = [];
gulp.src(filteredResources, { base: `${src}` }).pipe(resourcesStream);
const bundleInfoArray = [];
if (opts.bundleInfo) {
bundleInfoArray.push(new VinylFile({
path: 'bundleInfo.json',
@ -147,9 +147,9 @@ function optimizeTask(opts) {
}
es.readArray(bundleInfoArray).pipe(bundleInfoStream);
});
var otherSourcesStream = es.through();
var otherSourcesStreamArr = [];
gulp.src(otherSources, { base: "" + src })
const otherSourcesStream = es.through();
const otherSourcesStreamArr = [];
gulp.src(otherSources, { base: `${src}` })
.pipe(es.through(function (data) {
otherSourcesStreamArr.push(toConcatStream(src, bundledFileHeader, [data], data.relative));
}, function () {
@ -160,10 +160,10 @@ function optimizeTask(opts) {
es.merge(otherSourcesStreamArr).pipe(otherSourcesStream);
}
}));
var result = es.merge(loader(src, bundledFileHeader, bundleLoader), bundlesStream, otherSourcesStream, resourcesStream, bundleInfoStream);
const result = es.merge(loader(src, bundledFileHeader, bundleLoader), bundlesStream, otherSourcesStream, resourcesStream, bundleInfoStream);
return result
.pipe(sourcemaps.write('./', {
sourceRoot: null,
sourceRoot: undefined,
addComment: true,
includeContent: true
}))
@ -180,14 +180,14 @@ exports.optimizeTask = optimizeTask;
* to have a file "context" to include our copyright only once per file.
*/
function uglifyWithCopyrights() {
var preserveComments = function (f) {
return function (node, comment) {
var text = comment.value;
var type = comment.type;
const preserveComments = (f) => {
return (_node, comment) => {
const text = comment.value;
const type = comment.type;
if (/@minifier_do_not_preserve/.test(text)) {
return false;
}
var isOurCopyright = IS_OUR_COPYRIGHT_REGEXP.test(text);
const isOurCopyright = IS_OUR_COPYRIGHT_REGEXP.test(text);
if (isOurCopyright) {
if (f.__hasOurCopyright) {
return false;
@ -205,10 +205,10 @@ function uglifyWithCopyrights() {
return false;
};
};
var minify = composer(uglifyes);
var input = es.through();
var output = input
.pipe(flatmap(function (stream, f) {
const minify = composer(uglifyes);
const input = es.through();
const output = input
.pipe(flatmap((stream, f) => {
return stream.pipe(minify({
output: {
comments: preserveComments(f),
@ -219,18 +219,18 @@ function uglifyWithCopyrights() {
return es.duplex(input, output);
}
function minifyTask(src, sourceMapBaseUrl) {
var sourceMappingURL = sourceMapBaseUrl && (function (f) { return sourceMapBaseUrl + "/" + f.relative + ".map"; });
return function (cb) {
var jsFilter = filter('**/*.js', { restore: true });
var cssFilter = filter('**/*.css', { restore: true });
const sourceMappingURL = sourceMapBaseUrl ? ((f) => `${sourceMapBaseUrl}/${f.relative}.map`) : undefined;
return cb => {
const jsFilter = filter('**/*.js', { restore: true });
const cssFilter = filter('**/*.css', { restore: true });
pump(gulp.src([src + '/**', '!' + src + '/**/*.map']), jsFilter, sourcemaps.init({ loadMaps: true }), uglifyWithCopyrights(), jsFilter.restore, cssFilter, minifyCSS({ reduceIdents: false }), cssFilter.restore, sourcemaps.write('./', {
sourceMappingURL: sourceMappingURL,
sourceRoot: null,
sourceMappingURL,
sourceRoot: undefined,
includeContent: true,
addComment: true
}), gulp.dest(src + '-min'), function (err) {
}), gulp.dest(src + '-min'), (err) => {
if (err instanceof uglify.GulpUglifyError) {
console.error("Uglify error in '" + (err.cause && err.cause.filename) + "'");
console.error(`Uglify error in '${err.cause && err.cause.filename}'`);
}
cb(err);
});

View file

@ -32,7 +32,7 @@ function log(prefix: string, message: string): void {
}
export function loaderConfig(emptyPaths?: string[]) {
const result = {
const result: any = {
paths: {
'vs': 'out-build/vs',
'vscode': 'empty:'
@ -188,7 +188,7 @@ export function optimizeTask(opts: IOptimizeTaskOpts): () => NodeJS.ReadWriteStr
const bundleInfoStream = es.through(); // this stream will contain bundleInfo.json
bundle.bundle(entryPoints, loaderConfig, function (err, result) {
if (err) { return bundlesStream.emit('error', JSON.stringify(err)); }
if (err || !result) { return bundlesStream.emit('error', JSON.stringify(err)); }
toBundleStream(src, bundledFileHeader, result.files).pipe(bundlesStream);
@ -237,7 +237,7 @@ export function optimizeTask(opts: IOptimizeTaskOpts): () => NodeJS.ReadWriteStr
return result
.pipe(sourcemaps.write('./', {
sourceRoot: null,
sourceRoot: undefined,
addComment: true,
includeContent: true
}))
@ -258,7 +258,7 @@ declare class FileWithCopyright extends VinylFile {
*/
function uglifyWithCopyrights(): NodeJS.ReadWriteStream {
const preserveComments = (f: FileWithCopyright) => {
return (node, comment: { value: string; type: string; }) => {
return (_node: any, comment: { value: string; type: string; }) => {
const text = comment.value;
const type = comment.type;
@ -286,7 +286,7 @@ function uglifyWithCopyrights(): NodeJS.ReadWriteStream {
};
};
const minify = composer(uglifyes);
const minify = (composer as any)(uglifyes);
const input = es.through();
const output = input
.pipe(flatmap((stream, f) => {
@ -302,7 +302,7 @@ function uglifyWithCopyrights(): NodeJS.ReadWriteStream {
}
export function minifyTask(src: string, sourceMapBaseUrl?: string): (cb: any) => void {
const sourceMappingURL = sourceMapBaseUrl && (f => `${sourceMapBaseUrl}/${f.relative}.map`);
const sourceMappingURL = sourceMapBaseUrl ? ((f: any) => `${sourceMapBaseUrl}/${f.relative}.map`) : undefined;
return cb => {
const jsFilter = filter('**/*.js', { restore: true });
@ -319,13 +319,13 @@ export function minifyTask(src: string, sourceMapBaseUrl?: string): (cb: any) =>
cssFilter.restore,
sourcemaps.write('./', {
sourceMappingURL,
sourceRoot: null,
sourceRoot: undefined,
includeContent: true,
addComment: true
}),
} as any),
gulp.dest(src + '-min')
, (err: any) => {
if (err instanceof uglify.GulpUglifyError) {
if (err instanceof (uglify as any).GulpUglifyError) {
console.error(`Uglify error in '${err.cause && err.cause.filename}'`);
}

View file

@ -4,20 +4,20 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var es = require("event-stream");
var _ = require("underscore");
var util = require("gulp-util");
var fs = require("fs");
var path = require("path");
var allErrors = [];
var startTime = null;
var count = 0;
const es = require("event-stream");
const _ = require("underscore");
const util = require("gulp-util");
const fs = require("fs");
const path = require("path");
const allErrors = [];
let startTime = null;
let count = 0;
function onStart() {
if (count++ > 0) {
return;
}
startTime = new Date().getTime();
util.log("Starting " + util.colors.green('compilation') + "...");
util.log(`Starting ${util.colors.green('compilation')}...`);
}
function onEnd() {
if (--count > 0) {
@ -25,7 +25,7 @@ function onEnd() {
}
log();
}
var buildLogPath = path.join(path.dirname(path.dirname(__dirname)), '.build', 'log');
const buildLogPath = path.join(path.dirname(path.dirname(__dirname)), '.build', 'log');
try {
fs.mkdirSync(path.dirname(buildLogPath));
}
@ -33,61 +33,52 @@ catch (err) {
// ignore
}
function log() {
var errors = _.flatten(allErrors);
var seen = new Set();
errors.map(function (err) {
const errors = _.flatten(allErrors);
const seen = new Set();
errors.map(err => {
if (!seen.has(err)) {
seen.add(err);
util.log(util.colors.red('Error') + ": " + err);
util.log(`${util.colors.red('Error')}: ${err}`);
}
});
var regex = /^([^(]+)\((\d+),(\d+)\): (.*)$/;
var messages = errors
.map(function (err) { return regex.exec(err); })
.filter(function (match) { return !!match; })
.map(function (_a) {
var path = _a[1], line = _a[2], column = _a[3], message = _a[4];
return ({ path: path, line: parseInt(line), column: parseInt(column), message: message });
});
const regex = /^([^(]+)\((\d+),(\d+)\): (.*)$/;
const messages = errors
.map(err => regex.exec(err))
.filter(match => !!match)
.map(x => x)
.map(([, path, line, column, message]) => ({ path, line: parseInt(line), column: parseInt(column), message }));
try {
fs.writeFileSync(buildLogPath, JSON.stringify(messages));
}
catch (err) {
//noop
}
util.log("Finished " + util.colors.green('compilation') + " with " + errors.length + " errors after " + util.colors.magenta((new Date().getTime() - startTime) + ' ms'));
util.log(`Finished ${util.colors.green('compilation')} with ${errors.length} errors after ${util.colors.magenta((new Date().getTime() - startTime) + ' ms')}`);
}
function createReporter() {
var errors = [];
const errors = [];
allErrors.push(errors);
var ReportFunc = /** @class */ (function () {
function ReportFunc(err) {
errors.push(err);
}
ReportFunc.hasErrors = function () {
return errors.length > 0;
};
ReportFunc.end = function (emitError) {
errors.length = 0;
onStart();
return es.through(null, function () {
onEnd();
if (emitError && errors.length > 0) {
errors.__logged__ = true;
if (!errors.__logged__) {
log();
}
var err = new Error("Found " + errors.length + " errors");
err.__reporter__ = true;
this.emit('error', err);
const result = (err) => errors.push(err);
result.hasErrors = () => errors.length > 0;
result.end = (emitError) => {
errors.length = 0;
onStart();
return es.through(undefined, function () {
onEnd();
if (emitError && errors.length > 0) {
if (!errors.__logged__) {
log();
}
else {
this.emit('end');
}
});
};
return ReportFunc;
}());
return ReportFunc;
errors.__logged__ = true;
const err = new Error(`Found ${errors.length} errors`);
err.__reporter__ = true;
this.emit('error', err);
}
else {
this.emit('end');
}
});
};
return result;
}
exports.createReporter = createReporter;

View file

@ -12,7 +12,7 @@ import * as fs from 'fs';
import * as path from 'path';
const allErrors: string[][] = [];
let startTime: number = null;
let startTime: number | null = null;
let count = 0;
function onStart(): void {
@ -55,6 +55,7 @@ function log(): void {
const messages = errors
.map(err => regex.exec(err))
.filter(match => !!match)
.map(x => x as string[])
.map(([, path, line, column, message]) => ({ path, line: parseInt(line), column: parseInt(column), message }));
try {
@ -64,7 +65,7 @@ function log(): void {
//noop
}
util.log(`Finished ${util.colors.green('compilation')} with ${errors.length} errors after ${util.colors.magenta((new Date().getTime() - startTime) + ' ms')}`);
util.log(`Finished ${util.colors.green('compilation')} with ${errors.length} errors after ${util.colors.magenta((new Date().getTime() - startTime!) + ' ms')}`);
}
export interface IReporter {
@ -77,38 +78,32 @@ export function createReporter(): IReporter {
const errors: string[] = [];
allErrors.push(errors);
class ReportFunc {
constructor(err: string) {
errors.push(err);
}
const result = (err: string) => errors.push(err);
static hasErrors(): boolean {
return errors.length > 0;
}
result.hasErrors = () => errors.length > 0;
static end(emitError: boolean): NodeJS.ReadWriteStream {
errors.length = 0;
onStart();
result.end = (emitError: boolean): NodeJS.ReadWriteStream => {
errors.length = 0;
onStart();
return es.through(null, function () {
onEnd();
return es.through(undefined, function () {
onEnd();
if (emitError && errors.length > 0) {
(errors as any).__logged__ = true;
if (!(errors as any).__logged__) {
log();
}
const err = new Error(`Found ${errors.length} errors`);
(err as any).__reporter__ = true;
this.emit('error', err);
} else {
this.emit('end');
if (emitError && errors.length > 0) {
if (!(errors as any).__logged__) {
log();
}
});
}
}
return <IReporter><any>ReportFunc;
(errors as any).__logged__ = true;
const err = new Error(`Found ${errors.length} errors`);
(err as any).__reporter__ = true;
this.emit('error', err);
} else {
this.emit('end');
}
});
};
return result;
}

View file

@ -5,35 +5,50 @@
'use strict';
var snaps;
(function (snaps) {
var fs = require('fs');
var path = require('path');
var os = require('os');
var cp = require('child_process');
var mksnapshot = path.join(__dirname, "../../node_modules/.bin/" + (process.platform === 'win32' ? 'mksnapshot.cmd' : 'mksnapshot'));
var product = require('../../product.json');
var arch = (process.argv.join('').match(/--arch=(.*)/) || [])[1];
const fs = require('fs');
const path = require('path');
const os = require('os');
const cp = require('child_process');
const mksnapshot = path.join(__dirname, `../../node_modules/.bin/${process.platform === 'win32' ? 'mksnapshot.cmd' : 'mksnapshot'}`);
const product = require('../../product.json');
const arch = (process.argv.join('').match(/--arch=(.*)/) || [])[1];
//
var loaderFilepath;
var startupBlobFilepath;
let loaderFilepath;
let startupBlobFilepath;
switch (process.platform) {
case 'darwin':
loaderFilepath = "VSCode-darwin/" + product.nameLong + ".app/Contents/Resources/app/out/vs/loader.js";
startupBlobFilepath = "VSCode-darwin/" + product.nameLong + ".app/Contents/Frameworks/Electron Framework.framework/Resources/snapshot_blob.bin";
loaderFilepath = `VSCode-darwin/${product.nameLong}.app/Contents/Resources/app/out/vs/loader.js`;
startupBlobFilepath = `VSCode-darwin/${product.nameLong}.app/Contents/Frameworks/Electron Framework.framework/Resources/snapshot_blob.bin`;
break;
case 'win32':
case 'linux':
loaderFilepath = "VSCode-" + process.platform + "-" + arch + "/resources/app/out/vs/loader.js";
startupBlobFilepath = "VSCode-" + process.platform + "-" + arch + "/snapshot_blob.bin";
loaderFilepath = `VSCode-${process.platform}-${arch}/resources/app/out/vs/loader.js`;
startupBlobFilepath = `VSCode-${process.platform}-${arch}/snapshot_blob.bin`;
default:
throw new Error('Unknown platform');
}
loaderFilepath = path.join(__dirname, '../../../', loaderFilepath);
startupBlobFilepath = path.join(__dirname, '../../../', startupBlobFilepath);
snapshotLoader(loaderFilepath, startupBlobFilepath);
function snapshotLoader(loaderFilepath, startupBlobFilepath) {
var inputFile = fs.readFileSync(loaderFilepath);
var wrappedInputFile = "\n\t\tvar Monaco_Loader_Init;\n\t\t(function() {\n\t\t\tvar doNotInitLoader = true;\n\t\t\t" + inputFile.toString() + ";\n\t\t\tMonaco_Loader_Init = function() {\n\t\t\t\tAMDLoader.init();\n\t\t\t\tCSSLoaderPlugin.init();\n\t\t\t\tNLSLoaderPlugin.init();\n\n\t\t\t\treturn { define, require };\n\t\t\t}\n\t\t})();\n\t\t";
var wrappedInputFilepath = path.join(os.tmpdir(), 'wrapped-loader.js');
const inputFile = fs.readFileSync(loaderFilepath);
const wrappedInputFile = `
var Monaco_Loader_Init;
(function() {
var doNotInitLoader = true;
${inputFile.toString()};
Monaco_Loader_Init = function() {
AMDLoader.init();
CSSLoaderPlugin.init();
NLSLoaderPlugin.init();
return { define, require };
}
})();
`;
const wrappedInputFilepath = path.join(os.tmpdir(), 'wrapped-loader.js');
console.log(wrappedInputFilepath);
fs.writeFileSync(wrappedInputFilepath, wrappedInputFile);
cp.execFileSync(mksnapshot, [wrappedInputFilepath, "--startup_blob", startupBlobFilepath]);
cp.execFileSync(mksnapshot, [wrappedInputFilepath, `--startup_blob`, startupBlobFilepath]);
}
})(snaps || (snaps = {}));

View file

@ -30,6 +30,9 @@ namespace snaps {
case 'linux':
loaderFilepath = `VSCode-${process.platform}-${arch}/resources/app/out/vs/loader.js`;
startupBlobFilepath = `VSCode-${process.platform}-${arch}/snapshot_blob.bin`;
default:
throw new Error('Unknown platform');
}
loaderFilepath = path.join(__dirname, '../../../', loaderFilepath);

View file

@ -4,13 +4,13 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var fs = require("fs");
var path = require("path");
var tss = require("./treeshaking");
var REPO_ROOT = path.join(__dirname, '../../');
var SRC_DIR = path.join(REPO_ROOT, 'src');
var dirCache = {};
const ts = require("typescript");
const fs = require("fs");
const path = require("path");
const tss = require("./treeshaking");
const REPO_ROOT = path.join(__dirname, '../../');
const SRC_DIR = path.join(REPO_ROOT, 'src');
let dirCache = {};
function writeFile(filePath, contents) {
function ensureDirs(dirPath) {
if (dirCache[dirPath]) {
@ -27,32 +27,39 @@ function writeFile(filePath, contents) {
fs.writeFileSync(filePath, contents);
}
function extractEditor(options) {
var result = tss.shake(options);
for (var fileName in result) {
const tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.json')).toString());
tsConfig.compilerOptions.noUnusedLocals = false;
tsConfig.compilerOptions.preserveConstEnums = false;
tsConfig.compilerOptions.declaration = false;
delete tsConfig.compilerOptions.types;
tsConfig.exclude = [];
options.compilerOptions = tsConfig.compilerOptions;
let result = tss.shake(options);
for (let fileName in result) {
if (result.hasOwnProperty(fileName)) {
writeFile(path.join(options.destRoot, fileName), result[fileName]);
}
}
var copied = {};
var copyFile = function (fileName) {
let copied = {};
const copyFile = (fileName) => {
if (copied[fileName]) {
return;
}
copied[fileName] = true;
var srcPath = path.join(options.sourcesRoot, fileName);
var dstPath = path.join(options.destRoot, fileName);
const srcPath = path.join(options.sourcesRoot, fileName);
const dstPath = path.join(options.destRoot, fileName);
writeFile(dstPath, fs.readFileSync(srcPath));
};
var writeOutputFile = function (fileName, contents) {
const writeOutputFile = (fileName, contents) => {
writeFile(path.join(options.destRoot, fileName), contents);
};
for (var fileName in result) {
for (let fileName in result) {
if (result.hasOwnProperty(fileName)) {
var fileContents = result[fileName];
var info = ts.preProcessFile(fileContents);
for (var i = info.importedFiles.length - 1; i >= 0; i--) {
var importedFileName = info.importedFiles[i].fileName;
var importedFilePath = void 0;
const fileContents = result[fileName];
const info = ts.preProcessFile(fileContents);
for (let i = info.importedFiles.length - 1; i >= 0; i--) {
const importedFileName = info.importedFiles[i].fileName;
let importedFilePath;
if (/^vs\/css!/.test(importedFileName)) {
importedFilePath = importedFileName.substr('vs/css!'.length) + '.css';
}
@ -73,55 +80,43 @@ function extractEditor(options) {
}
}
}
var tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.json')).toString());
tsConfig.compilerOptions.noUnusedLocals = false;
tsConfig.compilerOptions.preserveConstEnums = false;
tsConfig.compilerOptions.declaration = false;
writeOutputFile('tsconfig.json', JSON.stringify(tsConfig, null, '\t'));
[
'vs/css.build.js',
'vs/css.d.ts',
'vs/css.js',
'vs/loader.js',
'vs/monaco.d.ts',
'vs/nls.build.js',
'vs/nls.d.ts',
'vs/nls.js',
'vs/nls.mock.ts',
'typings/lib.ie11_safe_es6.d.ts',
'typings/thenable.d.ts',
'typings/es6-promise.d.ts',
'typings/require.d.ts',
].forEach(copyFile);
}
exports.extractEditor = extractEditor;
function createESMSourcesAndResources2(options) {
var SRC_FOLDER = path.join(REPO_ROOT, options.srcFolder);
var OUT_FOLDER = path.join(REPO_ROOT, options.outFolder);
var OUT_RESOURCES_FOLDER = path.join(REPO_ROOT, options.outResourcesFolder);
var getDestAbsoluteFilePath = function (file) {
var dest = options.renames[file.replace(/\\/g, '/')] || file;
const SRC_FOLDER = path.join(REPO_ROOT, options.srcFolder);
const OUT_FOLDER = path.join(REPO_ROOT, options.outFolder);
const OUT_RESOURCES_FOLDER = path.join(REPO_ROOT, options.outResourcesFolder);
const getDestAbsoluteFilePath = (file) => {
let dest = options.renames[file.replace(/\\/g, '/')] || file;
if (dest === 'tsconfig.json') {
return path.join(OUT_FOLDER, "../tsconfig.json");
return path.join(OUT_FOLDER, `tsconfig.json`);
}
if (/\.ts$/.test(dest)) {
return path.join(OUT_FOLDER, dest);
}
return path.join(OUT_RESOURCES_FOLDER, dest);
};
var allFiles = walkDirRecursive(SRC_FOLDER);
for (var i = 0; i < allFiles.length; i++) {
var file = allFiles[i];
const allFiles = walkDirRecursive(SRC_FOLDER);
for (let i = 0; i < allFiles.length; i++) {
const file = allFiles[i];
if (options.ignores.indexOf(file.replace(/\\/g, '/')) >= 0) {
continue;
}
if (file === 'tsconfig.json') {
var tsConfig = JSON.parse(fs.readFileSync(path.join(SRC_FOLDER, file)).toString());
tsConfig.compilerOptions.moduleResolution = undefined;
tsConfig.compilerOptions.baseUrl = undefined;
const tsConfig = JSON.parse(fs.readFileSync(path.join(SRC_FOLDER, file)).toString());
tsConfig.compilerOptions.module = 'es6';
tsConfig.compilerOptions.rootDir = 'src';
tsConfig.compilerOptions.outDir = path.relative(path.dirname(OUT_FOLDER), OUT_RESOURCES_FOLDER);
tsConfig.compilerOptions.outDir = path.join(path.relative(OUT_FOLDER, OUT_RESOURCES_FOLDER), 'vs');
write(getDestAbsoluteFilePath(file), JSON.stringify(tsConfig, null, '\t'));
continue;
}
@ -132,13 +127,13 @@ function createESMSourcesAndResources2(options) {
}
if (/\.ts$/.test(file)) {
// Transform the .ts file
var fileContents = fs.readFileSync(path.join(SRC_FOLDER, file)).toString();
var info = ts.preProcessFile(fileContents);
for (var i_1 = info.importedFiles.length - 1; i_1 >= 0; i_1--) {
var importedFilename = info.importedFiles[i_1].fileName;
var pos = info.importedFiles[i_1].pos;
var end = info.importedFiles[i_1].end;
var importedFilepath = void 0;
let fileContents = fs.readFileSync(path.join(SRC_FOLDER, file)).toString();
const info = ts.preProcessFile(fileContents);
for (let i = info.importedFiles.length - 1; i >= 0; i--) {
const importedFilename = info.importedFiles[i].fileName;
const pos = info.importedFiles[i].pos;
const end = info.importedFiles[i].end;
let importedFilepath;
if (/^vs\/css!/.test(importedFilename)) {
importedFilepath = importedFilename.substr('vs/css!'.length) + '.css';
}
@ -148,7 +143,7 @@ function createESMSourcesAndResources2(options) {
if (/(^\.\/)|(^\.\.\/)/.test(importedFilepath)) {
importedFilepath = path.join(path.dirname(file), importedFilepath);
}
var relativePath = void 0;
let relativePath;
if (importedFilepath === path.dirname(file)) {
relativePath = '../' + path.basename(path.dirname(file));
}
@ -166,25 +161,25 @@ function createESMSourcesAndResources2(options) {
+ fileContents.substring(end + 1));
}
fileContents = fileContents.replace(/import ([a-zA-z0-9]+) = require\(('[^']+')\);/g, function (_, m1, m2) {
return "import * as " + m1 + " from " + m2 + ";";
return `import * as ${m1} from ${m2};`;
});
write(getDestAbsoluteFilePath(file), fileContents);
continue;
}
console.log("UNKNOWN FILE: " + file);
console.log(`UNKNOWN FILE: ${file}`);
}
function walkDirRecursive(dir) {
if (dir.charAt(dir.length - 1) !== '/' || dir.charAt(dir.length - 1) !== '\\') {
dir += '/';
}
var result = [];
let result = [];
_walkDirRecursive(dir, result, dir.length);
return result;
}
function _walkDirRecursive(dir, result, trimPos) {
var files = fs.readdirSync(dir);
for (var i = 0; i < files.length; i++) {
var file = path.join(dir, files[i]);
const files = fs.readdirSync(dir);
for (let i = 0; i < files.length; i++) {
const file = path.join(dir, files[i]);
if (fs.statSync(file).isDirectory()) {
_walkDirRecursive(file, result, trimPos);
}
@ -199,10 +194,10 @@ function createESMSourcesAndResources2(options) {
}
writeFile(absoluteFilePath, contents);
function toggleComments(fileContents) {
var lines = fileContents.split(/\r\n|\r|\n/);
var mode = 0;
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
let lines = fileContents.split(/\r\n|\r|\n/);
let mode = 0;
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
if (mode === 0) {
if (/\/\/ ESM-comment-begin/.test(line)) {
mode = 1;
@ -241,30 +236,30 @@ function transportCSS(module, enqueue, write) {
if (!/\.css/.test(module)) {
return false;
}
var filename = path.join(SRC_DIR, module);
var fileContents = fs.readFileSync(filename).toString();
var inlineResources = 'base64'; // see https://github.com/Microsoft/monaco-editor/issues/148
var inlineResourcesLimit = 300000; //3000; // see https://github.com/Microsoft/monaco-editor/issues/336
var newContents = _rewriteOrInlineUrls(fileContents, inlineResources === 'base64', inlineResourcesLimit);
const filename = path.join(SRC_DIR, module);
const fileContents = fs.readFileSync(filename).toString();
const inlineResources = 'base64'; // see https://github.com/Microsoft/monaco-editor/issues/148
const inlineResourcesLimit = 300000; //3000; // see https://github.com/Microsoft/monaco-editor/issues/336
const newContents = _rewriteOrInlineUrls(fileContents, inlineResources === 'base64', inlineResourcesLimit);
write(module, newContents);
return true;
function _rewriteOrInlineUrls(contents, forceBase64, inlineByteLimit) {
return _replaceURL(contents, function (url) {
var imagePath = path.join(path.dirname(module), url);
var fileContents = fs.readFileSync(path.join(SRC_DIR, imagePath));
return _replaceURL(contents, (url) => {
let imagePath = path.join(path.dirname(module), url);
let fileContents = fs.readFileSync(path.join(SRC_DIR, imagePath));
if (fileContents.length < inlineByteLimit) {
var MIME = /\.svg$/.test(url) ? 'image/svg+xml' : 'image/png';
var DATA = ';base64,' + fileContents.toString('base64');
const MIME = /\.svg$/.test(url) ? 'image/svg+xml' : 'image/png';
let DATA = ';base64,' + fileContents.toString('base64');
if (!forceBase64 && /\.svg$/.test(url)) {
// .svg => url encode as explained at https://codepen.io/tigt/post/optimizing-svgs-in-data-uris
var newText = fileContents.toString()
let newText = fileContents.toString()
.replace(/"/g, '\'')
.replace(/</g, '%3C')
.replace(/>/g, '%3E')
.replace(/&/g, '%26')
.replace(/#/g, '%23')
.replace(/\s+/g, ' ');
var encodedData = ',' + newText;
let encodedData = ',' + newText;
if (encodedData.length < DATA.length) {
DATA = encodedData;
}
@ -277,12 +272,8 @@ function transportCSS(module, enqueue, write) {
}
function _replaceURL(contents, replacer) {
// Use ")" as the terminator as quotes are oftentimes not used at all
return contents.replace(/url\(\s*([^\)]+)\s*\)?/g, function (_) {
var matches = [];
for (var _i = 1; _i < arguments.length; _i++) {
matches[_i - 1] = arguments[_i];
}
var url = matches[0];
return contents.replace(/url\(\s*([^\)]+)\s*\)?/g, (_, ...matches) => {
let url = matches[0];
// Eliminate starting quotes (the initial whitespace is not captured)
if (url.charAt(0) === '"' || url.charAt(0) === '\'') {
url = url.substring(1);

View file

@ -31,6 +31,15 @@ function writeFile(filePath: string, contents: Buffer | string): void {
}
export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: string }): void {
const tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.json')).toString());
tsConfig.compilerOptions.noUnusedLocals = false;
tsConfig.compilerOptions.preserveConstEnums = false;
tsConfig.compilerOptions.declaration = false;
delete tsConfig.compilerOptions.types;
tsConfig.exclude = [];
options.compilerOptions = tsConfig.compilerOptions;
let result = tss.shake(options);
for (let fileName in result) {
if (result.hasOwnProperty(fileName)) {
@ -47,7 +56,7 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str
const dstPath = path.join(options.destRoot, fileName);
writeFile(dstPath, fs.readFileSync(srcPath));
};
const writeOutputFile = (fileName: string, contents: string) => {
const writeOutputFile = (fileName: string, contents: string | Buffer) => {
writeFile(path.join(options.destRoot, fileName), contents);
};
for (let fileName in result) {
@ -79,10 +88,6 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str
}
}
const tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.json')).toString());
tsConfig.compilerOptions.noUnusedLocals = false;
tsConfig.compilerOptions.preserveConstEnums = false;
tsConfig.compilerOptions.declaration = false;
writeOutputFile('tsconfig.json', JSON.stringify(tsConfig, null, '\t'));
[
@ -90,15 +95,10 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str
'vs/css.d.ts',
'vs/css.js',
'vs/loader.js',
'vs/monaco.d.ts',
'vs/nls.build.js',
'vs/nls.d.ts',
'vs/nls.js',
'vs/nls.mock.ts',
'typings/lib.ie11_safe_es6.d.ts',
'typings/thenable.d.ts',
'typings/es6-promise.d.ts',
'typings/require.d.ts',
].forEach(copyFile);
}
@ -118,7 +118,7 @@ export function createESMSourcesAndResources2(options: IOptions2): void {
const getDestAbsoluteFilePath = (file: string): string => {
let dest = options.renames[file.replace(/\\/g, '/')] || file;
if (dest === 'tsconfig.json') {
return path.join(OUT_FOLDER, `../tsconfig.json`);
return path.join(OUT_FOLDER, `tsconfig.json`);
}
if (/\.ts$/.test(dest)) {
return path.join(OUT_FOLDER, dest);
@ -136,11 +136,8 @@ export function createESMSourcesAndResources2(options: IOptions2): void {
if (file === 'tsconfig.json') {
const tsConfig = JSON.parse(fs.readFileSync(path.join(SRC_FOLDER, file)).toString());
tsConfig.compilerOptions.moduleResolution = undefined;
tsConfig.compilerOptions.baseUrl = undefined;
tsConfig.compilerOptions.module = 'es6';
tsConfig.compilerOptions.rootDir = 'src';
tsConfig.compilerOptions.outDir = path.relative(path.dirname(OUT_FOLDER), OUT_RESOURCES_FOLDER);
tsConfig.compilerOptions.outDir = path.join(path.relative(OUT_FOLDER, OUT_RESOURCES_FOLDER), 'vs');
write(getDestAbsoluteFilePath(file), JSON.stringify(tsConfig, null, '\t'));
continue;
}
@ -321,7 +318,7 @@ function transportCSS(module: string, enqueue: (module: string) => void, write:
function _replaceURL(contents: string, replacer: (url: string) => string): string {
// Use ")" as the terminator as quotes are oftentimes not used at all
return contents.replace(/url\(\s*([^\)]+)\s*\)?/g, (_: string, ...matches: string[]) => {
var url = matches[0];
let url = matches[0];
// Eliminate starting quotes (the initial whitespace is not captured)
if (url.charAt(0) === '"' || url.charAt(0) === '\'') {
url = url.substring(1);

View file

@ -4,44 +4,43 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var es = require("event-stream");
var util = require("gulp-util");
var appInsights = require("applicationinsights");
var Entry = /** @class */ (function () {
function Entry(name, totalCount, totalSize) {
const es = require("event-stream");
const util = require("gulp-util");
const appInsights = require("applicationinsights");
class Entry {
constructor(name, totalCount, totalSize) {
this.name = name;
this.totalCount = totalCount;
this.totalSize = totalSize;
}
Entry.prototype.toString = function (pretty) {
toString(pretty) {
if (!pretty) {
if (this.totalCount === 1) {
return this.name + ": " + this.totalSize + " bytes";
return `${this.name}: ${this.totalSize} bytes`;
}
else {
return this.name + ": " + this.totalCount + " files with " + this.totalSize + " bytes";
return `${this.name}: ${this.totalCount} files with ${this.totalSize} bytes`;
}
}
else {
if (this.totalCount === 1) {
return "Stats for '" + util.colors.grey(this.name) + "': " + Math.round(this.totalSize / 1204) + "KB";
return `Stats for '${util.colors.grey(this.name)}': ${Math.round(this.totalSize / 1204)}KB`;
}
else {
var count = this.totalCount < 100
const count = this.totalCount < 100
? util.colors.green(this.totalCount.toString())
: util.colors.red(this.totalCount.toString());
return "Stats for '" + util.colors.grey(this.name) + "': " + count + " files, " + Math.round(this.totalSize / 1204) + "KB";
return `Stats for '${util.colors.grey(this.name)}': ${count} files, ${Math.round(this.totalSize / 1204)}KB`;
}
}
};
return Entry;
}());
var _entries = new Map();
}
}
const _entries = new Map();
function createStatsStream(group, log) {
var entry = new Entry(group, 0, 0);
const entry = new Entry(group, 0, 0);
_entries.set(entry.name, entry);
return es.through(function (data) {
var file = data;
const file = data;
if (typeof file.path === 'string') {
entry.totalCount += 1;
if (Buffer.isBuffer(file.contents)) {
@ -58,13 +57,13 @@ function createStatsStream(group, log) {
}, function () {
if (log) {
if (entry.totalCount === 1) {
util.log("Stats for '" + util.colors.grey(entry.name) + "': " + Math.round(entry.totalSize / 1204) + "KB");
util.log(`Stats for '${util.colors.grey(entry.name)}': ${Math.round(entry.totalSize / 1204)}KB`);
}
else {
var count = entry.totalCount < 100
const count = entry.totalCount < 100
? util.colors.green(entry.totalCount.toString())
: util.colors.red(entry.totalCount.toString());
util.log("Stats for '" + util.colors.grey(entry.name) + "': " + count + " files, " + Math.round(entry.totalSize / 1204) + "KB");
util.log(`Stats for '${util.colors.grey(entry.name)}': ${count} files, ${Math.round(entry.totalSize / 1204)}KB`);
}
}
this.emit('end');
@ -72,9 +71,9 @@ function createStatsStream(group, log) {
}
exports.createStatsStream = createStatsStream;
function submitAllStats(productJson, commit) {
var sorted = [];
const sorted = [];
// move entries for single files to the front
_entries.forEach(function (value) {
_entries.forEach(value => {
if (value.totalCount === 1) {
sorted.unshift(value);
}
@ -83,40 +82,54 @@ function submitAllStats(productJson, commit) {
}
});
// print to console
for (var _i = 0, sorted_1 = sorted; _i < sorted_1.length; _i++) {
var entry = sorted_1[_i];
for (const entry of sorted) {
console.log(entry.toString(true));
}
// send data as telementry event when the
// product is configured to send telemetry
if (!productJson || !productJson.aiConfig || typeof productJson.aiConfig.asimovKey !== 'string') {
return Promise.resolve();
return Promise.resolve(false);
}
return new Promise(function (resolve) {
var sizes = {};
var counts = {};
for (var _i = 0, sorted_2 = sorted; _i < sorted_2.length; _i++) {
var entry = sorted_2[_i];
sizes[entry.name] = entry.totalSize;
counts[entry.name] = entry.totalCount;
}
appInsights.setup(productJson.aiConfig.asimovKey)
.setAutoCollectConsole(false)
.setAutoCollectExceptions(false)
.setAutoCollectPerformance(false)
.setAutoCollectRequests(false)
.start();
var client = appInsights.getClient(productJson.aiConfig.asimovKey);
client.config.endpointUrl = 'https://vortex.data.microsoft.com/collect/v1';
/* __GDPR__
"monacoworkbench/packagemetrics" : {
"commit" : {"classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }
"size" : {"classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }
"count" : {"classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }
return new Promise(resolve => {
try {
const sizes = {};
const counts = {};
for (const entry of sorted) {
sizes[entry.name] = entry.totalSize;
counts[entry.name] = entry.totalCount;
}
*/
client.trackEvent("monacoworkbench/packagemetrics", { commit: commit, size: JSON.stringify(sizes), count: JSON.stringify(counts) });
client.sendPendingData(function () { return resolve(); });
appInsights.setup(productJson.aiConfig.asimovKey)
.setAutoCollectConsole(false)
.setAutoCollectExceptions(false)
.setAutoCollectPerformance(false)
.setAutoCollectRequests(false)
.setAutoCollectDependencies(false)
.setAutoDependencyCorrelation(false)
.start();
appInsights.defaultClient.config.endpointUrl = 'https://vortex.data.microsoft.com/collect/v1';
/* __GDPR__
"monacoworkbench/packagemetrics" : {
"commit" : {"classification": "SystemMetaData", "purpose": "PerformanceAndHealth" },
"size" : {"classification": "SystemMetaData", "purpose": "PerformanceAndHealth" },
"count" : {"classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }
}
*/
appInsights.defaultClient.trackEvent({
name: 'monacoworkbench/packagemetrics',
properties: { commit, size: JSON.stringify(sizes), count: JSON.stringify(counts) }
});
appInsights.defaultClient.flush({
callback: () => {
appInsights.dispose();
resolve(true);
}
});
}
catch (err) {
console.error('ERROR sending build stats as telemetry event!');
console.error(err);
resolve(false);
}
});
}
exports.submitAllStats = submitAllStats;

View file

@ -25,7 +25,7 @@ class Entry {
return `Stats for '${util.colors.grey(this.name)}': ${Math.round(this.totalSize / 1204)}KB`;
} else {
let count = this.totalCount < 100
const count = this.totalCount < 100
? util.colors.green(this.totalCount.toString())
: util.colors.red(this.totalCount.toString());
@ -43,7 +43,7 @@ export function createStatsStream(group: string, log?: boolean): es.ThroughStrea
_entries.set(entry.name, entry);
return es.through(function (data) {
let file = data as File;
const file = data as File;
if (typeof file.path === 'string') {
entry.totalCount += 1;
if (Buffer.isBuffer(file.contents)) {
@ -61,7 +61,7 @@ export function createStatsStream(group: string, log?: boolean): es.ThroughStrea
util.log(`Stats for '${util.colors.grey(entry.name)}': ${Math.round(entry.totalSize / 1204)}KB`);
} else {
let count = entry.totalCount < 100
const count = entry.totalCount < 100
? util.colors.green(entry.totalCount.toString())
: util.colors.red(entry.totalCount.toString());
@ -73,9 +73,9 @@ export function createStatsStream(group: string, log?: boolean): es.ThroughStrea
});
}
export function submitAllStats(productJson: any, commit: string): Promise<void> {
export function submitAllStats(productJson: any, commit: string): Promise<boolean> {
let sorted: Entry[] = [];
const sorted: Entry[] = [];
// move entries for single files to the front
_entries.forEach(value => {
if (value.totalCount === 1) {
@ -93,37 +93,55 @@ export function submitAllStats(productJson: any, commit: string): Promise<void>
// send data as telementry event when the
// product is configured to send telemetry
if (!productJson || !productJson.aiConfig || typeof productJson.aiConfig.asimovKey !== 'string') {
return Promise.resolve();
return Promise.resolve(false);
}
return new Promise(resolve => {
try {
const sizes = {};
const counts = {};
for (const entry of sorted) {
sizes[entry.name] = entry.totalSize;
counts[entry.name] = entry.totalCount;
}
appInsights.setup(productJson.aiConfig.asimovKey)
.setAutoCollectConsole(false)
.setAutoCollectExceptions(false)
.setAutoCollectPerformance(false)
.setAutoCollectRequests(false)
.start();
const client = appInsights.getClient(productJson.aiConfig.asimovKey);
client.config.endpointUrl = 'https://vortex.data.microsoft.com/collect/v1';
/* __GDPR__
"monacoworkbench/packagemetrics" : {
"commit" : {"classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }
"size" : {"classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }
"count" : {"classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }
const sizes: any = {};
const counts: any = {};
for (const entry of sorted) {
sizes[entry.name] = entry.totalSize;
counts[entry.name] = entry.totalCount;
}
*/
client.trackEvent(`monacoworkbench/packagemetrics`, { commit, size: JSON.stringify(sizes), count: JSON.stringify(counts) });
client.sendPendingData(() => resolve());
appInsights.setup(productJson.aiConfig.asimovKey)
.setAutoCollectConsole(false)
.setAutoCollectExceptions(false)
.setAutoCollectPerformance(false)
.setAutoCollectRequests(false)
.setAutoCollectDependencies(false)
.setAutoDependencyCorrelation(false)
.start();
appInsights.defaultClient.config.endpointUrl = 'https://vortex.data.microsoft.com/collect/v1';
/* __GDPR__
"monacoworkbench/packagemetrics" : {
"commit" : {"classification": "SystemMetaData", "purpose": "PerformanceAndHealth" },
"size" : {"classification": "SystemMetaData", "purpose": "PerformanceAndHealth" },
"count" : {"classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }
}
*/
appInsights.defaultClient.trackEvent({
name: 'monacoworkbench/packagemetrics',
properties: { commit, size: JSON.stringify(sizes), count: JSON.stringify(counts) }
});
appInsights.defaultClient.flush({
callback: () => {
appInsights.dispose();
resolve(true);
}
});
} catch (err) {
console.error('ERROR sending build stats as telemetry event!');
console.error(err);
resolve(false);
}
});
}

View file

@ -4,30 +4,30 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
var assert = require("assert");
var i18n = require("../i18n");
suite('XLF Parser Tests', function () {
var sampleXlf = '<?xml version="1.0" encoding="utf-8"?><xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"><file original="vs/base/common/keybinding" source-language="en" datatype="plaintext"><body><trans-unit id="key1"><source xml:lang="en">Key #1</source></trans-unit><trans-unit id="key2"><source xml:lang="en">Key #2 &amp;</source></trans-unit></body></file></xliff>';
var sampleTranslatedXlf = '<?xml version="1.0" encoding="utf-8"?><xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"><file original="vs/base/common/keybinding" source-language="en" target-language="ru" datatype="plaintext"><body><trans-unit id="key1"><source xml:lang="en">Key #1</source><target>Кнопка #1</target></trans-unit><trans-unit id="key2"><source xml:lang="en">Key #2 &amp;</source><target>Кнопка #2 &amp;</target></trans-unit></body></file></xliff>';
var originalFilePath = 'vs/base/common/keybinding';
var keys = ['key1', 'key2'];
var messages = ['Key #1', 'Key #2 &'];
var translatedMessages = { key1: 'Кнопка #1', key2: 'Кнопка #2 &' };
test('Keys & messages to XLF conversion', function () {
var xlf = new i18n.XLF('vscode-workbench');
const assert = require("assert");
const i18n = require("../i18n");
suite('XLF Parser Tests', () => {
const sampleXlf = '<?xml version="1.0" encoding="utf-8"?><xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"><file original="vs/base/common/keybinding" source-language="en" datatype="plaintext"><body><trans-unit id="key1"><source xml:lang="en">Key #1</source></trans-unit><trans-unit id="key2"><source xml:lang="en">Key #2 &amp;</source></trans-unit></body></file></xliff>';
const sampleTranslatedXlf = '<?xml version="1.0" encoding="utf-8"?><xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"><file original="vs/base/common/keybinding" source-language="en" target-language="ru" datatype="plaintext"><body><trans-unit id="key1"><source xml:lang="en">Key #1</source><target>Кнопка #1</target></trans-unit><trans-unit id="key2"><source xml:lang="en">Key #2 &amp;</source><target>Кнопка #2 &amp;</target></trans-unit></body></file></xliff>';
const originalFilePath = 'vs/base/common/keybinding';
const keys = ['key1', 'key2'];
const messages = ['Key #1', 'Key #2 &'];
const translatedMessages = { key1: 'Кнопка #1', key2: 'Кнопка #2 &' };
test('Keys & messages to XLF conversion', () => {
const xlf = new i18n.XLF('vscode-workbench');
xlf.addFile(originalFilePath, keys, messages);
var xlfString = xlf.toString();
const xlfString = xlf.toString();
assert.strictEqual(xlfString.replace(/\s{2,}/g, ''), sampleXlf);
});
test('XLF to keys & messages conversion', function () {
test('XLF to keys & messages conversion', () => {
i18n.XLF.parse(sampleTranslatedXlf).then(function (resolvedFiles) {
assert.deepEqual(resolvedFiles[0].messages, translatedMessages);
assert.strictEqual(resolvedFiles[0].originalFilePath, originalFilePath);
});
});
test('JSON file source path to Transifex resource match', function () {
var editorProject = 'vscode-editor', workbenchProject = 'vscode-workbench';
var platform = { name: 'vs/platform', project: editorProject }, editorContrib = { name: 'vs/editor/contrib', project: editorProject }, editor = { name: 'vs/editor', project: editorProject }, base = { name: 'vs/base', project: editorProject }, code = { name: 'vs/code', project: workbenchProject }, workbenchParts = { name: 'vs/workbench/parts/html', project: workbenchProject }, workbenchServices = { name: 'vs/workbench/services/files', project: workbenchProject }, workbench = { name: 'vs/workbench', project: workbenchProject };
test('JSON file source path to Transifex resource match', () => {
const editorProject = 'vscode-editor', workbenchProject = 'vscode-workbench';
const platform = { name: 'vs/platform', project: editorProject }, editorContrib = { name: 'vs/editor/contrib', project: editorProject }, editor = { name: 'vs/editor', project: editorProject }, base = { name: 'vs/base', project: editorProject }, code = { name: 'vs/code', project: workbenchProject }, workbenchParts = { name: 'vs/workbench/parts/html', project: workbenchProject }, workbenchServices = { name: 'vs/workbench/services/files', project: workbenchProject }, workbench = { name: 'vs/workbench', project: workbenchProject };
assert.deepEqual(i18n.getResource('vs/platform/actions/browser/menusExtensionPoint'), platform);
assert.deepEqual(i18n.getResource('vs/editor/contrib/clipboard/browser/clipboard'), editorContrib);
assert.deepEqual(i18n.getResource('vs/editor/common/modes/modesRegistry'), editor);

View file

@ -15,7 +15,7 @@ suite('XLF Parser Tests', () => {
const translatedMessages = { key1: 'Кнопка #1', key2: 'Кнопка #2 &' };
test('Keys & messages to XLF conversion', () => {
let xlf = new i18n.XLF('vscode-workbench');
const xlf = new i18n.XLF('vscode-workbench');
xlf.addFile(originalFilePath, keys, messages);
const xlfString = xlf.toString();

View file

@ -4,18 +4,49 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var fs = require("fs");
var path = require("path");
var ts = require("typescript");
var TYPESCRIPT_LIB_FOLDER = path.dirname(require.resolve('typescript/lib/lib.d.ts'));
const fs = require("fs");
const path = require("path");
const ts = require("typescript");
const TYPESCRIPT_LIB_FOLDER = path.dirname(require.resolve('typescript/lib/lib.d.ts'));
var ShakeLevel;
(function (ShakeLevel) {
ShakeLevel[ShakeLevel["Files"] = 0] = "Files";
ShakeLevel[ShakeLevel["InnerFile"] = 1] = "InnerFile";
ShakeLevel[ShakeLevel["ClassMembers"] = 2] = "ClassMembers";
})(ShakeLevel = exports.ShakeLevel || (exports.ShakeLevel = {}));
function printDiagnostics(diagnostics) {
for (let i = 0; i < diagnostics.length; i++) {
const diag = diagnostics[i];
let result = '';
if (diag.file) {
result += `${diag.file.fileName}: `;
}
if (diag.file && diag.start) {
let location = diag.file.getLineAndCharacterOfPosition(diag.start);
result += `- ${location.line + 1},${location.character} - `;
}
result += JSON.stringify(diag.messageText);
console.log(result);
}
}
function shake(options) {
var languageService = createTypeScriptLanguageService(options);
const languageService = createTypeScriptLanguageService(options);
const program = languageService.getProgram();
const globalDiagnostics = program.getGlobalDiagnostics();
if (globalDiagnostics.length > 0) {
printDiagnostics(globalDiagnostics);
throw new Error(`Compilation Errors encountered.`);
}
const syntacticDiagnostics = program.getSyntacticDiagnostics();
if (syntacticDiagnostics.length > 0) {
printDiagnostics(syntacticDiagnostics);
throw new Error(`Compilation Errors encountered.`);
}
const semanticDiagnostics = program.getSemanticDiagnostics();
if (semanticDiagnostics.length > 0) {
printDiagnostics(semanticDiagnostics);
throw new Error(`Compilation Errors encountered.`);
}
markNodes(languageService, options);
return generateResult(languageService, options.shakeLevel);
}
@ -23,93 +54,98 @@ exports.shake = shake;
//#region Discovery, LanguageService & Setup
function createTypeScriptLanguageService(options) {
// Discover referenced files
var FILES = discoverAndReadFiles(options);
const FILES = discoverAndReadFiles(options);
// Add fake usage files
options.inlineEntryPoints.forEach(function (inlineEntryPoint, index) {
FILES["inlineEntryPoint:" + index + ".ts"] = inlineEntryPoint;
options.inlineEntryPoints.forEach((inlineEntryPoint, index) => {
FILES[`inlineEntryPoint:${index}.ts`] = inlineEntryPoint;
});
// Add additional typings
options.typings.forEach((typing) => {
const filePath = path.join(options.sourcesRoot, typing);
FILES[typing] = fs.readFileSync(filePath).toString();
});
// Resolve libs
var RESOLVED_LIBS = {};
options.libs.forEach(function (filename) {
var filepath = path.join(TYPESCRIPT_LIB_FOLDER, filename);
RESOLVED_LIBS["defaultLib:" + filename] = fs.readFileSync(filepath).toString();
const RESOLVED_LIBS = {};
options.libs.forEach((filename) => {
const filepath = path.join(TYPESCRIPT_LIB_FOLDER, filename);
RESOLVED_LIBS[`defaultLib:${filename}`] = fs.readFileSync(filepath).toString();
});
var host = new TypeScriptLanguageServiceHost(RESOLVED_LIBS, FILES, options.compilerOptions);
const host = new TypeScriptLanguageServiceHost(RESOLVED_LIBS, FILES, ts.convertCompilerOptionsFromJson(options.compilerOptions, ``).options);
return ts.createLanguageService(host);
}
/**
* Read imports and follow them until all files have been handled
*/
function discoverAndReadFiles(options) {
var FILES = {};
var in_queue = Object.create(null);
var queue = [];
var enqueue = function (moduleId) {
const FILES = {};
const in_queue = Object.create(null);
const queue = [];
const enqueue = (moduleId) => {
if (in_queue[moduleId]) {
return;
}
in_queue[moduleId] = true;
queue.push(moduleId);
};
options.entryPoints.forEach(function (entryPoint) { return enqueue(entryPoint); });
options.entryPoints.forEach((entryPoint) => enqueue(entryPoint));
while (queue.length > 0) {
var moduleId = queue.shift();
var dts_filename = path.join(options.sourcesRoot, moduleId + '.d.ts');
const moduleId = queue.shift();
const dts_filename = path.join(options.sourcesRoot, moduleId + '.d.ts');
if (fs.existsSync(dts_filename)) {
var dts_filecontents = fs.readFileSync(dts_filename).toString();
FILES[moduleId + '.d.ts'] = dts_filecontents;
const dts_filecontents = fs.readFileSync(dts_filename).toString();
FILES[`${moduleId}.d.ts`] = dts_filecontents;
continue;
}
var ts_filename = void 0;
let ts_filename;
if (options.redirects[moduleId]) {
ts_filename = path.join(options.sourcesRoot, options.redirects[moduleId] + '.ts');
}
else {
ts_filename = path.join(options.sourcesRoot, moduleId + '.ts');
}
var ts_filecontents = fs.readFileSync(ts_filename).toString();
var info = ts.preProcessFile(ts_filecontents);
for (var i = info.importedFiles.length - 1; i >= 0; i--) {
var importedFileName = info.importedFiles[i].fileName;
const ts_filecontents = fs.readFileSync(ts_filename).toString();
const info = ts.preProcessFile(ts_filecontents);
for (let i = info.importedFiles.length - 1; i >= 0; i--) {
const importedFileName = info.importedFiles[i].fileName;
if (options.importIgnorePattern.test(importedFileName)) {
// Ignore vs/css! imports
continue;
}
var importedModuleId = importedFileName;
let importedModuleId = importedFileName;
if (/(^\.\/)|(^\.\.\/)/.test(importedModuleId)) {
importedModuleId = path.join(path.dirname(moduleId), importedModuleId);
}
enqueue(importedModuleId);
}
FILES[moduleId + '.ts'] = ts_filecontents;
FILES[`${moduleId}.ts`] = ts_filecontents;
}
return FILES;
}
/**
* A TypeScript language service host
*/
var TypeScriptLanguageServiceHost = /** @class */ (function () {
function TypeScriptLanguageServiceHost(libs, files, compilerOptions) {
class TypeScriptLanguageServiceHost {
constructor(libs, files, compilerOptions) {
this._libs = libs;
this._files = files;
this._compilerOptions = compilerOptions;
}
// --- language service host ---------------
TypeScriptLanguageServiceHost.prototype.getCompilationSettings = function () {
getCompilationSettings() {
return this._compilerOptions;
};
TypeScriptLanguageServiceHost.prototype.getScriptFileNames = function () {
}
getScriptFileNames() {
return ([]
.concat(Object.keys(this._libs))
.concat(Object.keys(this._files)));
};
TypeScriptLanguageServiceHost.prototype.getScriptVersion = function (fileName) {
}
getScriptVersion(_fileName) {
return '1';
};
TypeScriptLanguageServiceHost.prototype.getProjectVersion = function () {
}
getProjectVersion() {
return '1';
};
TypeScriptLanguageServiceHost.prototype.getScriptSnapshot = function (fileName) {
}
getScriptSnapshot(fileName) {
if (this._files.hasOwnProperty(fileName)) {
return ts.ScriptSnapshot.fromString(this._files[fileName]);
}
@ -119,21 +155,20 @@ var TypeScriptLanguageServiceHost = /** @class */ (function () {
else {
return ts.ScriptSnapshot.fromString('');
}
};
TypeScriptLanguageServiceHost.prototype.getScriptKind = function (fileName) {
}
getScriptKind(_fileName) {
return ts.ScriptKind.TS;
};
TypeScriptLanguageServiceHost.prototype.getCurrentDirectory = function () {
}
getCurrentDirectory() {
return '';
};
TypeScriptLanguageServiceHost.prototype.getDefaultLibFileName = function (options) {
}
getDefaultLibFileName(_options) {
return 'defaultLib:lib.d.ts';
};
TypeScriptLanguageServiceHost.prototype.isDefaultLibFileName = function (fileName) {
}
isDefaultLibFileName(fileName) {
return fileName === this.getDefaultLibFileName(this._compilerOptions);
};
return TypeScriptLanguageServiceHost;
}());
}
}
//#endregion
//#region Tree Shaking
var NodeColor;
@ -150,7 +185,7 @@ function setColor(node, color) {
}
function nodeOrParentIsBlack(node) {
while (node) {
var color = getColor(node);
const color = getColor(node);
if (color === 2 /* Black */) {
return true;
}
@ -162,8 +197,7 @@ function nodeOrChildIsBlack(node) {
if (getColor(node) === 2 /* Black */) {
return true;
}
for (var _i = 0, _a = node.getChildren(); _i < _a.length; _i++) {
var child = _a[_i];
for (const child of node.getChildren()) {
if (nodeOrChildIsBlack(child)) {
return true;
}
@ -171,19 +205,22 @@ function nodeOrChildIsBlack(node) {
return false;
}
function markNodes(languageService, options) {
var program = languageService.getProgram();
const program = languageService.getProgram();
if (!program) {
throw new Error('Could not get program from language service');
}
if (options.shakeLevel === 0 /* Files */) {
// Mark all source files Black
program.getSourceFiles().forEach(function (sourceFile) {
program.getSourceFiles().forEach((sourceFile) => {
setColor(sourceFile, 2 /* Black */);
});
return;
}
var black_queue = [];
var gray_queue = [];
var sourceFilesLoaded = {};
const black_queue = [];
const gray_queue = [];
const sourceFilesLoaded = {};
function enqueueTopLevelModuleStatements(sourceFile) {
sourceFile.forEachChild(function (node) {
sourceFile.forEachChild((node) => {
if (ts.isImportDeclaration(node)) {
if (!node.importClause && ts.isStringLiteral(node.moduleSpecifier)) {
setColor(node, 2 /* Black */);
@ -192,7 +229,7 @@ function markNodes(languageService, options) {
return;
}
if (ts.isExportDeclaration(node)) {
if (ts.isStringLiteral(node.moduleSpecifier)) {
if (node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) {
setColor(node, 2 /* Black */);
enqueueImport(node, node.moduleSpecifier.text);
}
@ -220,7 +257,7 @@ function markNodes(languageService, options) {
gray_queue.push(node);
}
function enqueue_black(node) {
var previousColor = getColor(node);
const previousColor = getColor(node);
if (previousColor === 2 /* Black */) {
return;
}
@ -238,12 +275,12 @@ function markNodes(languageService, options) {
if (nodeOrParentIsBlack(node)) {
return;
}
var fileName = node.getSourceFile().fileName;
const fileName = node.getSourceFile().fileName;
if (/^defaultLib:/.test(fileName) || /\.d\.ts$/.test(fileName)) {
setColor(node, 2 /* Black */);
return;
}
var sourceFile = node.getSourceFile();
const sourceFile = node.getSourceFile();
if (!sourceFilesLoaded[sourceFile.fileName]) {
sourceFilesLoaded[sourceFile.fileName] = true;
enqueueTopLevelModuleStatements(sourceFile);
@ -254,12 +291,15 @@ function markNodes(languageService, options) {
setColor(node, 2 /* Black */);
black_queue.push(node);
if (options.shakeLevel === 2 /* ClassMembers */ && (ts.isMethodDeclaration(node) || ts.isMethodSignature(node) || ts.isPropertySignature(node) || ts.isGetAccessor(node) || ts.isSetAccessor(node))) {
var references = languageService.getReferencesAtPosition(node.getSourceFile().fileName, node.name.pos + node.name.getLeadingTriviaWidth());
const references = languageService.getReferencesAtPosition(node.getSourceFile().fileName, node.name.pos + node.name.getLeadingTriviaWidth());
if (references) {
for (var i = 0, len = references.length; i < len; i++) {
var reference = references[i];
var referenceSourceFile = program.getSourceFile(reference.fileName);
var referenceNode = getTokenAtPosition(referenceSourceFile, reference.textSpan.start, false, false);
for (let i = 0, len = references.length; i < len; i++) {
const reference = references[i];
const referenceSourceFile = program.getSourceFile(reference.fileName);
if (!referenceSourceFile) {
continue;
}
const referenceNode = getTokenAtPosition(referenceSourceFile, reference.textSpan.start, false, false);
if (ts.isMethodDeclaration(referenceNode.parent)
|| ts.isPropertyDeclaration(referenceNode.parent)
|| ts.isGetAccessor(referenceNode.parent)
@ -271,9 +311,9 @@ function markNodes(languageService, options) {
}
}
function enqueueFile(filename) {
var sourceFile = program.getSourceFile(filename);
const sourceFile = program.getSourceFile(filename);
if (!sourceFile) {
console.warn("Cannot find source file " + filename);
console.warn(`Cannot find source file ${filename}`);
return;
}
enqueue_black(sourceFile);
@ -283,8 +323,8 @@ function markNodes(languageService, options) {
// this import should be ignored
return;
}
var nodeSourceFile = node.getSourceFile();
var fullPath;
const nodeSourceFile = node.getSourceFile();
let fullPath;
if (/(^\.\/)|(^\.\.\/)/.test(importText)) {
fullPath = path.join(path.dirname(nodeSourceFile.fileName), importText) + '.ts';
}
@ -293,25 +333,25 @@ function markNodes(languageService, options) {
}
enqueueFile(fullPath);
}
options.entryPoints.forEach(function (moduleId) { return enqueueFile(moduleId + '.ts'); });
options.entryPoints.forEach(moduleId => enqueueFile(moduleId + '.ts'));
// Add fake usage files
options.inlineEntryPoints.forEach(function (_, index) { return enqueueFile("inlineEntryPoint:" + index + ".ts"); });
var step = 0;
var checker = program.getTypeChecker();
var _loop_1 = function () {
options.inlineEntryPoints.forEach((_, index) => enqueueFile(`inlineEntryPoint:${index}.ts`));
let step = 0;
const checker = program.getTypeChecker();
while (black_queue.length > 0 || gray_queue.length > 0) {
++step;
var node = void 0;
let node;
if (step % 100 === 0) {
console.log(step + "/" + (step + black_queue.length + gray_queue.length) + " (" + black_queue.length + ", " + gray_queue.length + ")");
console.log(`${step}/${step + black_queue.length + gray_queue.length} (${black_queue.length}, ${gray_queue.length})`);
}
if (black_queue.length === 0) {
for (var i = 0; i < gray_queue.length; i++) {
var node_1 = gray_queue[i];
var nodeParent = node_1.parent;
for (let i = 0; i < gray_queue.length; i++) {
const node = gray_queue[i];
const nodeParent = node.parent;
if ((ts.isClassDeclaration(nodeParent) || ts.isInterfaceDeclaration(nodeParent)) && nodeOrChildIsBlack(nodeParent)) {
gray_queue.splice(i, 1);
black_queue.push(node_1);
setColor(node_1, 2 /* Black */);
black_queue.push(node);
setColor(node, 2 /* Black */);
i--;
}
}
@ -320,17 +360,18 @@ function markNodes(languageService, options) {
node = black_queue.shift();
}
else {
return "break";
// only gray nodes remaining...
break;
}
var nodeSourceFile = node.getSourceFile();
var loop = function (node) {
var _a = getRealNodeSymbol(checker, node), symbol = _a[0], symbolImportNode = _a[1];
const nodeSourceFile = node.getSourceFile();
const loop = (node) => {
const [symbol, symbolImportNode] = getRealNodeSymbol(checker, node);
if (symbolImportNode) {
setColor(symbolImportNode, 2 /* Black */);
}
if (symbol && !nodeIsInItsOwnDeclaration(nodeSourceFile, node, symbol)) {
for (var i = 0, len = symbol.declarations.length; i < len; i++) {
var declaration = symbol.declarations[i];
for (let i = 0, len = symbol.declarations.length; i < len; i++) {
const declaration = symbol.declarations[i];
if (ts.isSourceFile(declaration)) {
// Do not enqueue full source files
// (they can be the declaration of a module import)
@ -338,9 +379,9 @@ function markNodes(languageService, options) {
}
if (options.shakeLevel === 2 /* ClassMembers */ && (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration))) {
enqueue_black(declaration.name);
for (var j = 0; j < declaration.members.length; j++) {
var member = declaration.members[j];
var memberName = member.name ? member.name.getText() : null;
for (let j = 0; j < declaration.members.length; j++) {
const member = declaration.members[j];
const memberName = member.name ? member.name.getText() : null;
if (ts.isConstructorDeclaration(member)
|| ts.isConstructSignatureDeclaration(member)
|| ts.isIndexSignatureDeclaration(member)
@ -354,8 +395,7 @@ function markNodes(languageService, options) {
}
// queue the heritage clauses
if (declaration.heritageClauses) {
for (var _i = 0, _b = declaration.heritageClauses; _i < _b.length; _i++) {
var heritageClause = _b[_i];
for (let heritageClause of declaration.heritageClauses) {
enqueue_black(heritageClause);
}
}
@ -368,17 +408,12 @@ function markNodes(languageService, options) {
node.forEachChild(loop);
};
node.forEachChild(loop);
};
while (black_queue.length > 0 || gray_queue.length > 0) {
var state_1 = _loop_1();
if (state_1 === "break")
break;
}
}
function nodeIsInItsOwnDeclaration(nodeSourceFile, node, symbol) {
for (var i = 0, len = symbol.declarations.length; i < len; i++) {
var declaration = symbol.declarations[i];
var declarationSourceFile = declaration.getSourceFile();
for (let i = 0, len = symbol.declarations.length; i < len; i++) {
const declaration = symbol.declarations[i];
const declarationSourceFile = declaration.getSourceFile();
if (nodeSourceFile === declarationSourceFile) {
if (declaration.pos <= node.pos && node.end <= declaration.end) {
return true;
@ -388,25 +423,28 @@ function nodeIsInItsOwnDeclaration(nodeSourceFile, node, symbol) {
return false;
}
function generateResult(languageService, shakeLevel) {
var program = languageService.getProgram();
var result = {};
var writeFile = function (filePath, contents) {
const program = languageService.getProgram();
if (!program) {
throw new Error('Could not get program from language service');
}
let result = {};
const writeFile = (filePath, contents) => {
result[filePath] = contents;
};
program.getSourceFiles().forEach(function (sourceFile) {
var fileName = sourceFile.fileName;
program.getSourceFiles().forEach((sourceFile) => {
const fileName = sourceFile.fileName;
if (/^defaultLib:/.test(fileName)) {
return;
}
var destination = fileName;
const destination = fileName;
if (/\.d\.ts$/.test(fileName)) {
if (nodeOrChildIsBlack(sourceFile)) {
writeFile(destination, sourceFile.text);
}
return;
}
var text = sourceFile.text;
var result = '';
let text = sourceFile.text;
let result = '';
function keep(node) {
result += text.substring(node.pos, node.end);
}
@ -435,24 +473,24 @@ function generateResult(languageService, shakeLevel) {
}
}
else {
var survivingImports = [];
for (var i = 0; i < node.importClause.namedBindings.elements.length; i++) {
var importNode = node.importClause.namedBindings.elements[i];
let survivingImports = [];
for (let i = 0; i < node.importClause.namedBindings.elements.length; i++) {
const importNode = node.importClause.namedBindings.elements[i];
if (getColor(importNode) === 2 /* Black */) {
survivingImports.push(importNode.getFullText(sourceFile));
}
}
var leadingTriviaWidth = node.getLeadingTriviaWidth();
var leadingTrivia = sourceFile.text.substr(node.pos, leadingTriviaWidth);
const leadingTriviaWidth = node.getLeadingTriviaWidth();
const leadingTrivia = sourceFile.text.substr(node.pos, leadingTriviaWidth);
if (survivingImports.length > 0) {
if (node.importClause && getColor(node.importClause) === 2 /* Black */) {
return write(leadingTrivia + "import " + node.importClause.name.text + ", {" + survivingImports.join(',') + " } from" + node.moduleSpecifier.getFullText(sourceFile) + ";");
if (node.importClause && node.importClause.name && getColor(node.importClause) === 2 /* Black */) {
return write(`${leadingTrivia}import ${node.importClause.name.text}, {${survivingImports.join(',')} } from${node.moduleSpecifier.getFullText(sourceFile)};`);
}
return write(leadingTrivia + "import {" + survivingImports.join(',') + " } from" + node.moduleSpecifier.getFullText(sourceFile) + ";");
return write(`${leadingTrivia}import {${survivingImports.join(',')} } from${node.moduleSpecifier.getFullText(sourceFile)};`);
}
else {
if (node.importClause && getColor(node.importClause) === 2 /* Black */) {
return write(leadingTrivia + "import " + node.importClause.name.text + " from" + node.moduleSpecifier.getFullText(sourceFile) + ";");
if (node.importClause && node.importClause.name && getColor(node.importClause) === 2 /* Black */) {
return write(`${leadingTrivia}import ${node.importClause.name.text} from${node.moduleSpecifier.getFullText(sourceFile)};`);
}
}
}
@ -464,10 +502,10 @@ function generateResult(languageService, shakeLevel) {
}
}
if (shakeLevel === 2 /* ClassMembers */ && (ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node)) && nodeOrChildIsBlack(node)) {
var toWrite = node.getFullText();
for (var i = node.members.length - 1; i >= 0; i--) {
var member = node.members[i];
if (getColor(member) === 2 /* Black */) {
let toWrite = node.getFullText();
for (let i = node.members.length - 1; i >= 0; i--) {
const member = node.members[i];
if (getColor(member) === 2 /* Black */ || !member.name) {
// keep method
continue;
}
@ -475,8 +513,8 @@ function generateResult(languageService, shakeLevel) {
// TODO: keep all members ending with `Brand`...
continue;
}
var pos = member.pos - node.pos;
var end = member.end - node.pos;
let pos = member.pos - node.pos;
let end = member.end - node.pos;
toWrite = toWrite.substring(0, pos) + toWrite.substring(end);
}
return write(toWrite);
@ -508,68 +546,9 @@ function generateResult(languageService, shakeLevel) {
* Returns the node's symbol and the `import` node (if the symbol resolved from a different module)
*/
function getRealNodeSymbol(checker, node) {
/**
* Returns the containing object literal property declaration given a possible name node, e.g. "a" in x = { "a": 1 }
*/
/* @internal */
function getContainingObjectLiteralElement(node) {
switch (node.kind) {
case ts.SyntaxKind.StringLiteral:
case ts.SyntaxKind.NumericLiteral:
if (node.parent.kind === ts.SyntaxKind.ComputedPropertyName) {
return ts.isObjectLiteralElement(node.parent.parent) ? node.parent.parent : undefined;
}
// falls through
case ts.SyntaxKind.Identifier:
return ts.isObjectLiteralElement(node.parent) &&
(node.parent.parent.kind === ts.SyntaxKind.ObjectLiteralExpression || node.parent.parent.kind === ts.SyntaxKind.JsxAttributes) &&
node.parent.name === node ? node.parent : undefined;
}
return undefined;
}
function getPropertySymbolsFromType(type, propName) {
function getTextOfPropertyName(name) {
function isStringOrNumericLiteral(node) {
var kind = node.kind;
return kind === ts.SyntaxKind.StringLiteral
|| kind === ts.SyntaxKind.NumericLiteral;
}
switch (name.kind) {
case ts.SyntaxKind.Identifier:
return name.text;
case ts.SyntaxKind.StringLiteral:
case ts.SyntaxKind.NumericLiteral:
return name.text;
case ts.SyntaxKind.ComputedPropertyName:
return isStringOrNumericLiteral(name.expression) ? name.expression.text : undefined;
}
}
var name = getTextOfPropertyName(propName);
if (name && type) {
var result = [];
var symbol_1 = type.getProperty(name);
if (type.flags & ts.TypeFlags.Union) {
for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
var t = _a[_i];
var symbol_2 = t.getProperty(name);
if (symbol_2) {
result.push(symbol_2);
}
}
return result;
}
if (symbol_1) {
result.push(symbol_1);
return result;
}
}
return undefined;
}
function getPropertySymbolsFromContextualType(typeChecker, node) {
var objectLiteral = node.parent;
var contextualType = typeChecker.getContextualType(objectLiteral);
return getPropertySymbolsFromType(contextualType, node.name);
}
const getPropertySymbolsFromContextualType = ts.getPropertySymbolsFromContextualType;
const getContainingObjectLiteralElement = ts.getContainingObjectLiteralElement;
const getNameFromPropertyName = ts.getNameFromPropertyName;
// Go to the original declaration for cases:
//
// (1) when the aliased symbol was declared in the location(parent).
@ -597,10 +576,15 @@ function getRealNodeSymbol(checker, node) {
return [null, null];
}
}
var symbol = checker.getSymbolAtLocation(node);
var importNode = null;
const { parent } = node;
let symbol = checker.getSymbolAtLocation(node);
let importNode = null;
// If this is an alias, and the request came at the declaration location
// get the aliased symbol instead. This allows for goto def on an import e.g.
// import {A, B} from "mod";
// to jump to the implementation directly.
if (symbol && symbol.flags & ts.SymbolFlags.Alias && shouldSkipAlias(node, symbol.declarations[0])) {
var aliased = checker.getAliasedSymbol(symbol);
const aliased = checker.getAliasedSymbol(symbol);
if (aliased.declarations) {
// We should mark the import as visited
importNode = symbol.declarations[0];
@ -627,13 +611,22 @@ function getRealNodeSymbol(checker, node) {
// pr/*destination*/op1: number
// }
// bar<Test>(({pr/*goto*/op1})=>{});
if (ts.isPropertyName(node) && ts.isBindingElement(node.parent) && ts.isObjectBindingPattern(node.parent.parent) &&
(node === (node.parent.propertyName || node.parent.name))) {
var type = checker.getTypeAtLocation(node.parent.parent);
if (type) {
var propSymbols = getPropertySymbolsFromType(type, node);
if (propSymbols) {
symbol = propSymbols[0];
if (ts.isPropertyName(node) && ts.isBindingElement(parent) && ts.isObjectBindingPattern(parent.parent) &&
(node === (parent.propertyName || parent.name))) {
const name = getNameFromPropertyName(node);
const type = checker.getTypeAtLocation(parent.parent);
if (name && type) {
if (type.isUnion()) {
const prop = type.types[0].getProperty(name);
if (prop) {
symbol = prop;
}
}
else {
const prop = type.getProperty(name);
if (prop) {
symbol = prop;
}
}
}
}
@ -646,11 +639,14 @@ function getRealNodeSymbol(checker, node) {
// }
// function Foo(arg: Props) {}
// Foo( { pr/*1*/op1: 10, prop2: false })
var element = getContainingObjectLiteralElement(node);
if (element && checker.getContextualType(element.parent)) {
var propertySymbols = getPropertySymbolsFromContextualType(checker, element);
if (propertySymbols) {
symbol = propertySymbols[0];
const element = getContainingObjectLiteralElement(node);
if (element) {
const contextualType = element && checker.getContextualType(element.parent);
if (contextualType) {
const propertySymbols = getPropertySymbolsFromContextualType(element, checker, contextualType, /*unionSymbolOk*/ false);
if (propertySymbols) {
symbol = propertySymbols[0];
}
}
}
}
@ -661,17 +657,16 @@ function getRealNodeSymbol(checker, node) {
}
/** Get the token whose text contains the position */
function getTokenAtPosition(sourceFile, position, allowPositionInLeadingTrivia, includeEndPosition) {
var current = sourceFile;
let current = sourceFile;
outer: while (true) {
// find the child that contains 'position'
for (var _i = 0, _a = current.getChildren(); _i < _a.length; _i++) {
var child = _a[_i];
var start = allowPositionInLeadingTrivia ? child.getFullStart() : child.getStart(sourceFile, /*includeJsDoc*/ true);
for (const child of current.getChildren()) {
const start = allowPositionInLeadingTrivia ? child.getFullStart() : child.getStart(sourceFile, /*includeJsDoc*/ true);
if (start > position) {
// If this child begins after position, then all subsequent children will as well.
break;
}
var end = child.getEnd();
const end = child.getEnd();
if (position < end || (position === end && (child.kind === ts.SyntaxKind.EndOfFileToken || includeEndPosition))) {
current = child;
continue outer;

View file

@ -36,10 +36,14 @@ export interface ITreeShakingOptions {
* e.g. `lib.d.ts`, `lib.es2015.collection.d.ts`
*/
libs: string[];
/**
* Other .d.ts files
*/
typings: string[];
/**
* TypeScript compiler options.
*/
compilerOptions: ts.CompilerOptions;
compilerOptions?: any;
/**
* The shake level to perform.
*/
@ -56,8 +60,43 @@ export interface ITreeShakingResult {
[file: string]: string;
}
function printDiagnostics(diagnostics: ReadonlyArray<ts.Diagnostic>): void {
for (let i = 0; i < diagnostics.length; i++) {
const diag = diagnostics[i];
let result = '';
if (diag.file) {
result += `${diag.file.fileName}: `;
}
if (diag.file && diag.start) {
let location = diag.file.getLineAndCharacterOfPosition(diag.start);
result += `- ${location.line + 1},${location.character} - `
}
result += JSON.stringify(diag.messageText);
console.log(result);
}
}
export function shake(options: ITreeShakingOptions): ITreeShakingResult {
const languageService = createTypeScriptLanguageService(options);
const program = languageService.getProgram()!;
const globalDiagnostics = program.getGlobalDiagnostics();
if (globalDiagnostics.length > 0) {
printDiagnostics(globalDiagnostics);
throw new Error(`Compilation Errors encountered.`);
}
const syntacticDiagnostics = program.getSyntacticDiagnostics();
if (syntacticDiagnostics.length > 0) {
printDiagnostics(syntacticDiagnostics);
throw new Error(`Compilation Errors encountered.`);
}
const semanticDiagnostics = program.getSemanticDiagnostics();
if (semanticDiagnostics.length > 0) {
printDiagnostics(semanticDiagnostics);
throw new Error(`Compilation Errors encountered.`);
}
markNodes(languageService, options);
@ -74,6 +113,12 @@ function createTypeScriptLanguageService(options: ITreeShakingOptions): ts.Langu
FILES[`inlineEntryPoint:${index}.ts`] = inlineEntryPoint;
});
// Add additional typings
options.typings.forEach((typing) => {
const filePath = path.join(options.sourcesRoot, typing);
FILES[typing] = fs.readFileSync(filePath).toString();
});
// Resolve libs
const RESOLVED_LIBS: ILibMap = {};
options.libs.forEach((filename) => {
@ -81,7 +126,7 @@ function createTypeScriptLanguageService(options: ITreeShakingOptions): ts.Langu
RESOLVED_LIBS[`defaultLib:${filename}`] = fs.readFileSync(filepath).toString();
});
const host = new TypeScriptLanguageServiceHost(RESOLVED_LIBS, FILES, options.compilerOptions);
const host = new TypeScriptLanguageServiceHost(RESOLVED_LIBS, FILES, ts.convertCompilerOptionsFromJson(options.compilerOptions, ``).options);
return ts.createLanguageService(host);
}
@ -105,11 +150,11 @@ function discoverAndReadFiles(options: ITreeShakingOptions): IFileMap {
options.entryPoints.forEach((entryPoint) => enqueue(entryPoint));
while (queue.length > 0) {
const moduleId = queue.shift();
const moduleId = queue.shift()!;
const dts_filename = path.join(options.sourcesRoot, moduleId + '.d.ts');
if (fs.existsSync(dts_filename)) {
const dts_filecontents = fs.readFileSync(dts_filename).toString();
FILES[moduleId + '.d.ts'] = dts_filecontents;
FILES[`${moduleId}.d.ts`] = dts_filecontents;
continue;
}
@ -136,7 +181,7 @@ function discoverAndReadFiles(options: ITreeShakingOptions): IFileMap {
enqueue(importedModuleId);
}
FILES[moduleId + '.ts'] = ts_filecontents;
FILES[`${moduleId}.ts`] = ts_filecontents;
}
return FILES;
@ -167,12 +212,12 @@ class TypeScriptLanguageServiceHost implements ts.LanguageServiceHost {
}
getScriptFileNames(): string[] {
return (
[]
([] as string[])
.concat(Object.keys(this._libs))
.concat(Object.keys(this._files))
);
}
getScriptVersion(fileName: string): string {
getScriptVersion(_fileName: string): string {
return '1';
}
getProjectVersion(): string {
@ -187,13 +232,13 @@ class TypeScriptLanguageServiceHost implements ts.LanguageServiceHost {
return ts.ScriptSnapshot.fromString('');
}
}
getScriptKind(fileName: string): ts.ScriptKind {
getScriptKind(_fileName: string): ts.ScriptKind {
return ts.ScriptKind.TS;
}
getCurrentDirectory(): string {
return '';
}
getDefaultLibFileName(options: ts.CompilerOptions): string {
getDefaultLibFileName(_options: ts.CompilerOptions): string {
return 'defaultLib:lib.d.ts';
}
isDefaultLibFileName(fileName: string): boolean {
@ -240,6 +285,9 @@ function nodeOrChildIsBlack(node: ts.Node): boolean {
function markNodes(languageService: ts.LanguageService, options: ITreeShakingOptions) {
const program = languageService.getProgram();
if (!program) {
throw new Error('Could not get program from language service');
}
if (options.shakeLevel === ShakeLevel.Files) {
// Mark all source files Black
@ -266,7 +314,7 @@ function markNodes(languageService: ts.LanguageService, options: ITreeShakingOpt
}
if (ts.isExportDeclaration(node)) {
if (ts.isStringLiteral(node.moduleSpecifier)) {
if (node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) {
setColor(node, NodeColor.Black);
enqueueImport(node, node.moduleSpecifier.text);
}
@ -349,7 +397,11 @@ function markNodes(languageService: ts.LanguageService, options: ITreeShakingOpt
if (references) {
for (let i = 0, len = references.length; i < len; i++) {
const reference = references[i];
const referenceSourceFile = program.getSourceFile(reference.fileName);
const referenceSourceFile = program!.getSourceFile(reference.fileName);
if (!referenceSourceFile) {
continue;
}
const referenceNode = getTokenAtPosition(referenceSourceFile, reference.textSpan.start, false, false);
if (
ts.isMethodDeclaration(referenceNode.parent)
@ -365,7 +417,7 @@ function markNodes(languageService: ts.LanguageService, options: ITreeShakingOpt
}
function enqueueFile(filename: string): void {
const sourceFile = program.getSourceFile(filename);
const sourceFile = program!.getSourceFile(filename);
if (!sourceFile) {
console.warn(`Cannot find source file ${filename}`);
return;
@ -401,7 +453,7 @@ function markNodes(languageService: ts.LanguageService, options: ITreeShakingOpt
let node: ts.Node;
if (step % 100 === 0) {
console.log(`${step}/${step+black_queue.length+gray_queue.length} (${black_queue.length}, ${gray_queue.length})`);
console.log(`${step}/${step + black_queue.length + gray_queue.length} (${black_queue.length}, ${gray_queue.length})`);
}
if (black_queue.length === 0) {
@ -418,7 +470,7 @@ function markNodes(languageService: ts.LanguageService, options: ITreeShakingOpt
}
if (black_queue.length > 0) {
node = black_queue.shift();
node = black_queue.shift()!;
} else {
// only gray nodes remaining...
break;
@ -441,7 +493,7 @@ function markNodes(languageService: ts.LanguageService, options: ITreeShakingOpt
}
if (options.shakeLevel === ShakeLevel.ClassMembers && (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration))) {
enqueue_black(declaration.name);
enqueue_black(declaration.name!);
for (let j = 0; j < declaration.members.length; j++) {
const member = declaration.members[j];
@ -493,6 +545,9 @@ function nodeIsInItsOwnDeclaration(nodeSourceFile: ts.SourceFile, node: ts.Node,
function generateResult(languageService: ts.LanguageService, shakeLevel: ShakeLevel): ITreeShakingResult {
const program = languageService.getProgram();
if (!program) {
throw new Error('Could not get program from language service');
}
let result: ITreeShakingResult = {};
const writeFile = (filePath: string, contents: string): void => {
@ -556,12 +611,12 @@ function generateResult(languageService: ts.LanguageService, shakeLevel: ShakeLe
const leadingTriviaWidth = node.getLeadingTriviaWidth();
const leadingTrivia = sourceFile.text.substr(node.pos, leadingTriviaWidth);
if (survivingImports.length > 0) {
if (node.importClause && getColor(node.importClause) === NodeColor.Black) {
if (node.importClause && node.importClause.name && getColor(node.importClause) === NodeColor.Black) {
return write(`${leadingTrivia}import ${node.importClause.name.text}, {${survivingImports.join(',')} } from${node.moduleSpecifier.getFullText(sourceFile)};`);
}
return write(`${leadingTrivia}import {${survivingImports.join(',')} } from${node.moduleSpecifier.getFullText(sourceFile)};`);
} else {
if (node.importClause && getColor(node.importClause) === NodeColor.Black) {
if (node.importClause && node.importClause.name && getColor(node.importClause) === NodeColor.Black) {
return write(`${leadingTrivia}import ${node.importClause.name.text} from${node.moduleSpecifier.getFullText(sourceFile)};`);
}
}
@ -577,7 +632,7 @@ function generateResult(languageService: ts.LanguageService, shakeLevel: ShakeLe
let toWrite = node.getFullText();
for (let i = node.members.length - 1; i >= 0; i--) {
const member = node.members[i];
if (getColor(member) === NodeColor.Black) {
if (getColor(member) === NodeColor.Black || !member.name) {
// keep method
continue;
}
@ -625,74 +680,13 @@ function generateResult(languageService: ts.LanguageService, shakeLevel: ShakeLe
/**
* Returns the node's symbol and the `import` node (if the symbol resolved from a different module)
*/
function getRealNodeSymbol(checker: ts.TypeChecker, node: ts.Node): [ts.Symbol, ts.Declaration] {
/**
* Returns the containing object literal property declaration given a possible name node, e.g. "a" in x = { "a": 1 }
*/
/* @internal */
function getContainingObjectLiteralElement(node: ts.Node): ts.ObjectLiteralElement | undefined {
switch (node.kind) {
case ts.SyntaxKind.StringLiteral:
case ts.SyntaxKind.NumericLiteral:
if (node.parent.kind === ts.SyntaxKind.ComputedPropertyName) {
return ts.isObjectLiteralElement(node.parent.parent) ? node.parent.parent : undefined;
}
// falls through
case ts.SyntaxKind.Identifier:
return ts.isObjectLiteralElement(node.parent) &&
(node.parent.parent.kind === ts.SyntaxKind.ObjectLiteralExpression || node.parent.parent.kind === ts.SyntaxKind.JsxAttributes) &&
node.parent.name === node ? node.parent : undefined;
}
return undefined;
}
function getRealNodeSymbol(checker: ts.TypeChecker, node: ts.Node): [ts.Symbol | null, ts.Declaration | null] {
function getPropertySymbolsFromType(type: ts.Type, propName: ts.PropertyName) {
function getTextOfPropertyName(name: ts.PropertyName): string {
function isStringOrNumericLiteral(node: ts.Node): node is ts.StringLiteral | ts.NumericLiteral {
const kind = node.kind;
return kind === ts.SyntaxKind.StringLiteral
|| kind === ts.SyntaxKind.NumericLiteral;
}
switch (name.kind) {
case ts.SyntaxKind.Identifier:
return name.text;
case ts.SyntaxKind.StringLiteral:
case ts.SyntaxKind.NumericLiteral:
return name.text;
case ts.SyntaxKind.ComputedPropertyName:
return isStringOrNumericLiteral(name.expression) ? name.expression.text : undefined!;
}
}
const name = getTextOfPropertyName(propName);
if (name && type) {
const result: ts.Symbol[] = [];
const symbol = type.getProperty(name);
if (type.flags & ts.TypeFlags.Union) {
for (const t of (<ts.UnionType>type).types) {
const symbol = t.getProperty(name);
if (symbol) {
result.push(symbol);
}
}
return result;
}
if (symbol) {
result.push(symbol);
return result;
}
}
return undefined;
}
function getPropertySymbolsFromContextualType(typeChecker: ts.TypeChecker, node: ts.ObjectLiteralElement): ts.Symbol[] {
const objectLiteral = <ts.ObjectLiteralExpression | ts.JsxAttributes>node.parent;
const contextualType = typeChecker.getContextualType(objectLiteral)!;
return getPropertySymbolsFromType(contextualType, node.name!)!;
}
// Use some TypeScript internals to avoid code duplication
type ObjectLiteralElementWithName = ts.ObjectLiteralElement & { name: ts.PropertyName; parent: ts.ObjectLiteralExpression | ts.JsxAttributes };
const getPropertySymbolsFromContextualType: (node: ObjectLiteralElementWithName, checker: ts.TypeChecker, contextualType: ts.Type, unionSymbolOk: boolean) => ReadonlyArray<ts.Symbol> = (<any>ts).getPropertySymbolsFromContextualType;
const getContainingObjectLiteralElement: (node: ts.Node) => ObjectLiteralElementWithName | undefined = (<any>ts).getContainingObjectLiteralElement;
const getNameFromPropertyName: (name: ts.PropertyName) => string | undefined = (<any>ts).getNameFromPropertyName;
// Go to the original declaration for cases:
//
@ -723,8 +717,14 @@ function getRealNodeSymbol(checker: ts.TypeChecker, node: ts.Node): [ts.Symbol,
}
}
const { parent } = node;
let symbol = checker.getSymbolAtLocation(node);
let importNode: ts.Declaration = null;
let importNode: ts.Declaration | null = null;
// If this is an alias, and the request came at the declaration location
// get the aliased symbol instead. This allows for goto def on an import e.g.
// import {A, B} from "mod";
// to jump to the implementation directly.
if (symbol && symbol.flags & ts.SymbolFlags.Alias && shouldSkipAlias(node, symbol.declarations[0])) {
const aliased = checker.getAliasedSymbol(symbol);
if (aliased.declarations) {
@ -755,13 +755,21 @@ function getRealNodeSymbol(checker: ts.TypeChecker, node: ts.Node): [ts.Symbol,
// pr/*destination*/op1: number
// }
// bar<Test>(({pr/*goto*/op1})=>{});
if (ts.isPropertyName(node) && ts.isBindingElement(node.parent) && ts.isObjectBindingPattern(node.parent.parent) &&
(node === (node.parent.propertyName || node.parent.name))) {
const type = checker.getTypeAtLocation(node.parent.parent);
if (type) {
const propSymbols = getPropertySymbolsFromType(type, node);
if (propSymbols) {
symbol = propSymbols[0];
if (ts.isPropertyName(node) && ts.isBindingElement(parent) && ts.isObjectBindingPattern(parent.parent) &&
(node === (parent.propertyName || parent.name))) {
const name = getNameFromPropertyName(node);
const type = checker.getTypeAtLocation(parent.parent);
if (name && type) {
if (type.isUnion()) {
const prop = type.types[0].getProperty(name);
if (prop) {
symbol = prop;
}
} else {
const prop = type.getProperty(name);
if (prop) {
symbol = prop;
}
}
}
}
@ -776,10 +784,13 @@ function getRealNodeSymbol(checker: ts.TypeChecker, node: ts.Node): [ts.Symbol,
// function Foo(arg: Props) {}
// Foo( { pr/*1*/op1: 10, prop2: false })
const element = getContainingObjectLiteralElement(node);
if (element && checker.getContextualType(element.parent as ts.Expression)) {
const propertySymbols = getPropertySymbolsFromContextualType(checker, element);
if (propertySymbols) {
symbol = propertySymbols[0];
if (element) {
const contextualType = element && checker.getContextualType(element.parent);
if (contextualType) {
const propertySymbols = getPropertySymbolsFromContextualType(element, checker, contextualType, /*unionSymbolOk*/ false);
if (propertySymbols) {
symbol = propertySymbols[0];
}
}
}
}

View file

@ -3,51 +3,30 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var path_1 = require("path");
var Lint = require("tslint");
var Rule = /** @class */ (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
const path_1 = require("path");
const Lint = require("tslint");
class Rule extends Lint.Rules.AbstractRule {
apply(sourceFile) {
return this.applyWithWalker(new ImportPatterns(sourceFile, this.getOptions()));
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
var ImportPatterns = /** @class */ (function (_super) {
__extends(ImportPatterns, _super);
function ImportPatterns(file, opts) {
var _this = _super.call(this, file, opts) || this;
_this.imports = Object.create(null);
return _this;
}
ImportPatterns.prototype.visitImportDeclaration = function (node) {
var path = node.moduleSpecifier.getText();
}
exports.Rule = Rule;
class ImportPatterns extends Lint.RuleWalker {
constructor(file, opts) {
super(file, opts);
this.imports = Object.create(null);
}
visitImportDeclaration(node) {
let path = node.moduleSpecifier.getText();
// remove quotes
path = path.slice(1, -1);
if (path[0] === '.') {
path = path_1.join(path_1.dirname(node.getSourceFile().fileName), path);
}
if (this.imports[path]) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), "Duplicate imports for '" + path + "'."));
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), `Duplicate imports for '${path}'.`));
}
this.imports[path] = true;
};
return ImportPatterns;
}(Lint.RuleWalker));
}
}

View file

@ -3,82 +3,60 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var Lint = require("tslint");
var minimatch = require("minimatch");
var path_1 = require("path");
var Rule = /** @class */ (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
var configs = this.getOptions().ruleArguments;
for (var _i = 0, configs_1 = configs; _i < configs_1.length; _i++) {
var config = configs_1[_i];
const ts = require("typescript");
const Lint = require("tslint");
const minimatch = require("minimatch");
const path_1 = require("path");
class Rule extends Lint.Rules.AbstractRule {
apply(sourceFile) {
const configs = this.getOptions().ruleArguments;
for (const config of configs) {
if (minimatch(sourceFile.fileName, config.target)) {
return this.applyWithWalker(new ImportPatterns(sourceFile, this.getOptions(), config));
}
}
return [];
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
var ImportPatterns = /** @class */ (function (_super) {
__extends(ImportPatterns, _super);
function ImportPatterns(file, opts, _config) {
var _this = _super.call(this, file, opts) || this;
_this._config = _config;
return _this;
}
ImportPatterns.prototype.visitImportEqualsDeclaration = function (node) {
}
exports.Rule = Rule;
class ImportPatterns extends Lint.RuleWalker {
constructor(file, opts, _config) {
super(file, opts);
this._config = _config;
}
visitImportEqualsDeclaration(node) {
if (node.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference) {
this._validateImport(node.moduleReference.expression.getText(), node);
}
};
ImportPatterns.prototype.visitImportDeclaration = function (node) {
}
visitImportDeclaration(node) {
this._validateImport(node.moduleSpecifier.getText(), node);
};
ImportPatterns.prototype.visitCallExpression = function (node) {
_super.prototype.visitCallExpression.call(this, node);
}
visitCallExpression(node) {
super.visitCallExpression(node);
// import('foo') statements inside the code
if (node.expression.kind === ts.SyntaxKind.ImportKeyword) {
var path = node.arguments[0];
const [path] = node.arguments;
this._validateImport(path.getText(), node);
}
};
ImportPatterns.prototype._validateImport = function (path, node) {
}
_validateImport(path, node) {
// remove quotes
path = path.slice(1, -1);
// resolve relative paths
if (path[0] === '.') {
path = path_1.join(this.getSourceFile().fileName, path);
}
var restrictions;
let restrictions;
if (typeof this._config.restrictions === 'string') {
restrictions = [this._config.restrictions];
}
else {
restrictions = this._config.restrictions;
}
var matched = false;
for (var _i = 0, restrictions_1 = restrictions; _i < restrictions_1.length; _i++) {
var pattern = restrictions_1[_i];
let matched = false;
for (const pattern of restrictions) {
if (minimatch(path, pattern)) {
matched = true;
break;
@ -86,8 +64,7 @@ var ImportPatterns = /** @class */ (function (_super) {
}
if (!matched) {
// None of the restrictions matched
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), "Imports violates '" + restrictions.join(' or ') + "' restrictions. See https://github.com/Microsoft/vscode/wiki/Code-Organization"));
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), `Imports violates '${restrictions.join(' or ')}' restrictions. See https://github.com/Microsoft/vscode/wiki/Code-Organization`));
}
};
return ImportPatterns;
}(Lint.RuleWalker));
}
}

View file

@ -3,39 +3,22 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var Lint = require("tslint");
var path_1 = require("path");
var Rule = /** @class */ (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
var parts = path_1.dirname(sourceFile.fileName).split(/\\|\//);
var ruleArgs = this.getOptions().ruleArguments[0];
var config;
for (var i = parts.length - 1; i >= 0; i--) {
const ts = require("typescript");
const Lint = require("tslint");
const path_1 = require("path");
class Rule extends Lint.Rules.AbstractRule {
apply(sourceFile) {
const parts = path_1.dirname(sourceFile.fileName).split(/\\|\//);
const ruleArgs = this.getOptions().ruleArguments[0];
let config;
for (let i = parts.length - 1; i >= 0; i--) {
if (ruleArgs[parts[i]]) {
config = {
allowed: new Set(ruleArgs[parts[i]]).add(parts[i]),
disallowed: new Set()
};
Object.keys(ruleArgs).forEach(function (key) {
Object.keys(ruleArgs).forEach(key => {
if (!config.allowed.has(key)) {
config.disallowed.add(key);
}
@ -47,58 +30,54 @@ var Rule = /** @class */ (function (_super) {
return [];
}
return this.applyWithWalker(new LayeringRule(sourceFile, config, this.getOptions()));
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
var LayeringRule = /** @class */ (function (_super) {
__extends(LayeringRule, _super);
function LayeringRule(file, config, opts) {
var _this = _super.call(this, file, opts) || this;
_this._config = config;
return _this;
}
LayeringRule.prototype.visitImportEqualsDeclaration = function (node) {
}
exports.Rule = Rule;
class LayeringRule extends Lint.RuleWalker {
constructor(file, config, opts) {
super(file, opts);
this._config = config;
}
visitImportEqualsDeclaration(node) {
if (node.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference) {
this._validateImport(node.moduleReference.expression.getText(), node);
}
};
LayeringRule.prototype.visitImportDeclaration = function (node) {
}
visitImportDeclaration(node) {
this._validateImport(node.moduleSpecifier.getText(), node);
};
LayeringRule.prototype.visitCallExpression = function (node) {
_super.prototype.visitCallExpression.call(this, node);
}
visitCallExpression(node) {
super.visitCallExpression(node);
// import('foo') statements inside the code
if (node.expression.kind === ts.SyntaxKind.ImportKeyword) {
var path = node.arguments[0];
const [path] = node.arguments;
this._validateImport(path.getText(), node);
}
};
LayeringRule.prototype._validateImport = function (path, node) {
}
_validateImport(path, node) {
// remove quotes
path = path.slice(1, -1);
if (path[0] === '.') {
path = path_1.join(path_1.dirname(node.getSourceFile().fileName), path);
}
var parts = path_1.dirname(path).split(/\\|\//);
for (var i = parts.length - 1; i >= 0; i--) {
var part = parts[i];
const parts = path_1.dirname(path).split(/\\|\//);
for (let i = parts.length - 1; i >= 0; i--) {
const part = parts[i];
if (this._config.allowed.has(part)) {
// GOOD - same layer
return;
}
if (this._config.disallowed.has(part)) {
// BAD - wrong layer
var message = "Bad layering. You are not allowed to access '" + part + "' from here, allowed layers are: [" + LayeringRule._print(this._config.allowed) + "]";
const message = `Bad layering. You are not allowed to access '${part}' from here, allowed layers are: [${LayeringRule._print(this._config.allowed)}]`;
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), message));
return;
}
}
};
LayeringRule._print = function (set) {
var r = [];
set.forEach(function (e) { return r.push(e); });
}
static _print(set) {
const r = [];
set.forEach(e => r.push(e));
return r.join(', ');
};
return LayeringRule;
}(Lint.RuleWalker));
}
}

View file

@ -16,9 +16,9 @@ export class Rule extends Lint.Rules.AbstractRule {
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
const parts = dirname(sourceFile.fileName).split(/\\|\//);
let ruleArgs = this.getOptions().ruleArguments[0];
const ruleArgs = this.getOptions().ruleArguments[0];
let config: Config;
let config: Config | undefined;
for (let i = parts.length - 1; i >= 0; i--) {
if (ruleArgs[parts[i]]) {
config = {
@ -26,8 +26,8 @@ export class Rule extends Lint.Rules.AbstractRule {
disallowed: new Set<string>()
};
Object.keys(ruleArgs).forEach(key => {
if (!config.allowed.has(key)) {
config.disallowed.add(key);
if (!config!.allowed.has(key)) {
config!.disallowed.add(key);
}
});
break;
@ -98,7 +98,7 @@ class LayeringRule extends Lint.RuleWalker {
}
static _print(set: Set<string>): string {
let r: string[] = [];
const r: string[] = [];
set.forEach(e => r.push(e));
return r.join(', ');
}

View file

@ -3,60 +3,41 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var Lint = require("tslint");
var path_1 = require("path");
var Rule = /** @class */ (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
const ts = require("typescript");
const Lint = require("tslint");
const path_1 = require("path");
class Rule extends Lint.Rules.AbstractRule {
apply(sourceFile) {
if (/vs(\/|\\)editor/.test(sourceFile.fileName)) {
// the vs/editor folder is allowed to use the standalone editor
return [];
}
return this.applyWithWalker(new NoStandaloneEditorRuleWalker(sourceFile, this.getOptions()));
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
var NoStandaloneEditorRuleWalker = /** @class */ (function (_super) {
__extends(NoStandaloneEditorRuleWalker, _super);
function NoStandaloneEditorRuleWalker(file, opts) {
return _super.call(this, file, opts) || this;
}
NoStandaloneEditorRuleWalker.prototype.visitImportEqualsDeclaration = function (node) {
}
exports.Rule = Rule;
class NoStandaloneEditorRuleWalker extends Lint.RuleWalker {
constructor(file, opts) {
super(file, opts);
}
visitImportEqualsDeclaration(node) {
if (node.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference) {
this._validateImport(node.moduleReference.expression.getText(), node);
}
};
NoStandaloneEditorRuleWalker.prototype.visitImportDeclaration = function (node) {
}
visitImportDeclaration(node) {
this._validateImport(node.moduleSpecifier.getText(), node);
};
NoStandaloneEditorRuleWalker.prototype.visitCallExpression = function (node) {
_super.prototype.visitCallExpression.call(this, node);
}
visitCallExpression(node) {
super.visitCallExpression(node);
// import('foo') statements inside the code
if (node.expression.kind === ts.SyntaxKind.ImportKeyword) {
var path = node.arguments[0];
const [path] = node.arguments;
this._validateImport(path.getText(), node);
}
};
NoStandaloneEditorRuleWalker.prototype._validateImport = function (path, node) {
}
_validateImport(path, node) {
// remove quotes
path = path.slice(1, -1);
// resolve relative paths
@ -68,8 +49,7 @@ var NoStandaloneEditorRuleWalker = /** @class */ (function (_super) {
|| /vs(\/|\\)editor(\/|\\)editor.api/.test(path)
|| /vs(\/|\\)editor(\/|\\)editor.main/.test(path)
|| /vs(\/|\\)editor(\/|\\)editor.worker/.test(path)) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), "Not allowed to import standalone editor modules. See https://github.com/Microsoft/vscode/wiki/Code-Organization"));
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), `Not allowed to import standalone editor modules. See https://github.com/Microsoft/vscode/wiki/Code-Organization`));
}
};
return NoStandaloneEditorRuleWalker;
}(Lint.RuleWalker));
}
}

View file

@ -3,35 +3,17 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var Lint = require("tslint");
const ts = require("typescript");
const Lint = require("tslint");
/**
* Implementation of the no-unexternalized-strings rule.
*/
var Rule = /** @class */ (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
class Rule extends Lint.Rules.AbstractRule {
apply(sourceFile) {
return this.applyWithWalker(new NoUnexternalizedStringsRuleWalker(sourceFile, this.getOptions()));
};
return Rule;
}(Lint.Rules.AbstractRule));
}
}
exports.Rule = Rule;
function isStringLiteral(node) {
return node && node.kind === ts.SyntaxKind.StringLiteral;
@ -42,73 +24,70 @@ function isObjectLiteral(node) {
function isPropertyAssignment(node) {
return node && node.kind === ts.SyntaxKind.PropertyAssignment;
}
var NoUnexternalizedStringsRuleWalker = /** @class */ (function (_super) {
__extends(NoUnexternalizedStringsRuleWalker, _super);
function NoUnexternalizedStringsRuleWalker(file, opts) {
var _this = _super.call(this, file, opts) || this;
_this.signatures = Object.create(null);
_this.ignores = Object.create(null);
_this.messageIndex = undefined;
_this.keyIndex = undefined;
_this.usedKeys = Object.create(null);
var options = _this.getOptions();
var first = options && options.length > 0 ? options[0] : null;
class NoUnexternalizedStringsRuleWalker extends Lint.RuleWalker {
constructor(file, opts) {
super(file, opts);
this.signatures = Object.create(null);
this.ignores = Object.create(null);
this.messageIndex = undefined;
this.keyIndex = undefined;
this.usedKeys = Object.create(null);
const options = this.getOptions();
const first = options && options.length > 0 ? options[0] : null;
if (first) {
if (Array.isArray(first.signatures)) {
first.signatures.forEach(function (signature) { return _this.signatures[signature] = true; });
first.signatures.forEach((signature) => this.signatures[signature] = true);
}
if (Array.isArray(first.ignores)) {
first.ignores.forEach(function (ignore) { return _this.ignores[ignore] = true; });
first.ignores.forEach((ignore) => this.ignores[ignore] = true);
}
if (typeof first.messageIndex !== 'undefined') {
_this.messageIndex = first.messageIndex;
this.messageIndex = first.messageIndex;
}
if (typeof first.keyIndex !== 'undefined') {
_this.keyIndex = first.keyIndex;
this.keyIndex = first.keyIndex;
}
}
return _this;
}
NoUnexternalizedStringsRuleWalker.prototype.visitSourceFile = function (node) {
var _this = this;
_super.prototype.visitSourceFile.call(this, node);
Object.keys(this.usedKeys).forEach(function (key) {
var occurrences = _this.usedKeys[key];
visitSourceFile(node) {
super.visitSourceFile(node);
Object.keys(this.usedKeys).forEach(key => {
const occurrences = this.usedKeys[key];
if (occurrences.length > 1) {
occurrences.forEach(function (occurrence) {
_this.addFailure((_this.createFailure(occurrence.key.getStart(), occurrence.key.getWidth(), "Duplicate key " + occurrence.key.getText() + " with different message value.")));
occurrences.forEach(occurrence => {
this.addFailure((this.createFailure(occurrence.key.getStart(), occurrence.key.getWidth(), `Duplicate key ${occurrence.key.getText()} with different message value.`)));
});
}
});
};
NoUnexternalizedStringsRuleWalker.prototype.visitStringLiteral = function (node) {
}
visitStringLiteral(node) {
this.checkStringLiteral(node);
_super.prototype.visitStringLiteral.call(this, node);
};
NoUnexternalizedStringsRuleWalker.prototype.checkStringLiteral = function (node) {
var text = node.getText();
var doubleQuoted = text.length >= 2 && text[0] === NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE && text[text.length - 1] === NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE;
var info = this.findDescribingParent(node);
super.visitStringLiteral(node);
}
checkStringLiteral(node) {
const text = node.getText();
const doubleQuoted = text.length >= 2 && text[0] === NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE && text[text.length - 1] === NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE;
const info = this.findDescribingParent(node);
// Ignore strings in import and export nodes.
if (info && info.isImport && doubleQuoted) {
var fix = [
const fix = [
Lint.Replacement.replaceFromTo(node.getStart(), 1, '\''),
Lint.Replacement.replaceFromTo(node.getStart() + text.length - 1, 1, '\''),
];
this.addFailureAtNode(node, NoUnexternalizedStringsRuleWalker.ImportFailureMessage, fix);
return;
}
var callInfo = info ? info.callInfo : null;
var functionName = callInfo ? callInfo.callExpression.expression.getText() : null;
const callInfo = info ? info.callInfo : null;
const functionName = callInfo ? callInfo.callExpression.expression.getText() : null;
if (functionName && this.ignores[functionName]) {
return;
}
if (doubleQuoted && (!callInfo || callInfo.argIndex === -1 || !this.signatures[functionName])) {
var s = node.getText();
var fix = [
Lint.Replacement.replaceFromTo(node.getStart(), node.getWidth(), "nls.localize('KEY-" + s.substring(1, s.length - 1) + "', " + s + ")"),
const s = node.getText();
const fix = [
Lint.Replacement.replaceFromTo(node.getStart(), node.getWidth(), `nls.localize('KEY-${s.substring(1, s.length - 1)}', ${s})`),
];
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), "Unexternalized string found: " + node.getText(), fix));
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), `Unexternalized string found: ${node.getText()}`, fix));
return;
}
// We have a single quoted string outside a localize function name.
@ -116,22 +95,22 @@ var NoUnexternalizedStringsRuleWalker = /** @class */ (function (_super) {
return;
}
// We have a string that is a direct argument into the localize call.
var keyArg = callInfo.argIndex === this.keyIndex
const keyArg = callInfo && callInfo.argIndex === this.keyIndex
? callInfo.callExpression.arguments[this.keyIndex]
: null;
if (keyArg) {
if (isStringLiteral(keyArg)) {
this.recordKey(keyArg, this.messageIndex ? callInfo.callExpression.arguments[this.messageIndex] : undefined);
this.recordKey(keyArg, this.messageIndex && callInfo ? callInfo.callExpression.arguments[this.messageIndex] : undefined);
}
else if (isObjectLiteral(keyArg)) {
for (var i = 0; i < keyArg.properties.length; i++) {
var property = keyArg.properties[i];
for (let i = 0; i < keyArg.properties.length; i++) {
const property = keyArg.properties[i];
if (isPropertyAssignment(property)) {
var name_1 = property.name.getText();
if (name_1 === 'key') {
var initializer = property.initializer;
const name = property.name.getText();
if (name === 'key') {
const initializer = property.initializer;
if (isStringLiteral(initializer)) {
this.recordKey(initializer, this.messageIndex ? callInfo.callExpression.arguments[this.messageIndex] : undefined);
this.recordKey(initializer, this.messageIndex && callInfo ? callInfo.callExpression.arguments[this.messageIndex] : undefined);
}
break;
}
@ -139,42 +118,42 @@ var NoUnexternalizedStringsRuleWalker = /** @class */ (function (_super) {
}
}
}
var messageArg = callInfo.callExpression.arguments[this.messageIndex];
const messageArg = callInfo.callExpression.arguments[this.messageIndex];
if (messageArg && messageArg.kind !== ts.SyntaxKind.StringLiteral) {
this.addFailure(this.createFailure(messageArg.getStart(), messageArg.getWidth(), "Message argument to '" + callInfo.callExpression.expression.getText() + "' must be a string literal."));
this.addFailure(this.createFailure(messageArg.getStart(), messageArg.getWidth(), `Message argument to '${callInfo.callExpression.expression.getText()}' must be a string literal.`));
return;
}
};
NoUnexternalizedStringsRuleWalker.prototype.recordKey = function (keyNode, messageNode) {
var text = keyNode.getText();
}
recordKey(keyNode, messageNode) {
const text = keyNode.getText();
// We have an empty key
if (text.match(/(['"]) *\1/)) {
if (messageNode) {
this.addFailureAtNode(keyNode, "Key is empty for message: " + messageNode.getText());
this.addFailureAtNode(keyNode, `Key is empty for message: ${messageNode.getText()}`);
}
else {
this.addFailureAtNode(keyNode, "Key is empty.");
this.addFailureAtNode(keyNode, `Key is empty.`);
}
return;
}
var occurrences = this.usedKeys[text];
let occurrences = this.usedKeys[text];
if (!occurrences) {
occurrences = [];
this.usedKeys[text] = occurrences;
}
if (messageNode) {
if (occurrences.some(function (pair) { return pair.message ? pair.message.getText() === messageNode.getText() : false; })) {
if (occurrences.some(pair => pair.message ? pair.message.getText() === messageNode.getText() : false)) {
return;
}
}
occurrences.push({ key: keyNode, message: messageNode });
};
NoUnexternalizedStringsRuleWalker.prototype.findDescribingParent = function (node) {
var parent;
}
findDescribingParent(node) {
let parent;
while ((parent = node.parent)) {
var kind = parent.kind;
const kind = parent.kind;
if (kind === ts.SyntaxKind.CallExpression) {
var callExpression = parent;
const callExpression = parent;
return { callInfo: { callExpression: callExpression, argIndex: callExpression.arguments.indexOf(node) } };
}
else if (kind === ts.SyntaxKind.ImportEqualsDeclaration || kind === ts.SyntaxKind.ImportDeclaration || kind === ts.SyntaxKind.ExportDeclaration) {
@ -188,8 +167,8 @@ var NoUnexternalizedStringsRuleWalker = /** @class */ (function (_super) {
}
node = parent;
}
};
NoUnexternalizedStringsRuleWalker.ImportFailureMessage = 'Do not use double quotes for imports.';
NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE = '"';
return NoUnexternalizedStringsRuleWalker;
}(Lint.RuleWalker));
return null;
}
}
NoUnexternalizedStringsRuleWalker.ImportFailureMessage = 'Do not use double quotes for imports.';
NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE = '"';

View file

@ -40,7 +40,7 @@ function isPropertyAssignment(node: ts.Node): node is ts.PropertyAssignment {
interface KeyMessagePair {
key: ts.StringLiteral;
message: ts.Node;
message: ts.Node | undefined;
}
class NoUnexternalizedStringsRuleWalker extends Lint.RuleWalker {
@ -50,8 +50,8 @@ class NoUnexternalizedStringsRuleWalker extends Lint.RuleWalker {
private static DOUBLE_QUOTE: string = '"';
private signatures: Map<boolean>;
private messageIndex: number;
private keyIndex: number;
private messageIndex: number | undefined;
private keyIndex: number | undefined;
private ignores: Map<boolean>;
private usedKeys: Map<KeyMessagePair[]>;
@ -63,8 +63,8 @@ class NoUnexternalizedStringsRuleWalker extends Lint.RuleWalker {
this.messageIndex = undefined;
this.keyIndex = undefined;
this.usedKeys = Object.create(null);
let options: any[] = this.getOptions();
let first: UnexternalizedStringsOptions = options && options.length > 0 ? options[0] : null;
const options: any[] = this.getOptions();
const first: UnexternalizedStringsOptions = options && options.length > 0 ? options[0] : null;
if (first) {
if (Array.isArray(first.signatures)) {
first.signatures.forEach((signature: string) => this.signatures[signature] = true);
@ -84,7 +84,7 @@ class NoUnexternalizedStringsRuleWalker extends Lint.RuleWalker {
protected visitSourceFile(node: ts.SourceFile): void {
super.visitSourceFile(node);
Object.keys(this.usedKeys).forEach(key => {
let occurrences = this.usedKeys[key];
const occurrences = this.usedKeys[key];
if (occurrences.length > 1) {
occurrences.forEach(occurrence => {
this.addFailure((this.createFailure(occurrence.key.getStart(), occurrence.key.getWidth(), `Duplicate key ${occurrence.key.getText()} with different message value.`)));
@ -99,9 +99,9 @@ class NoUnexternalizedStringsRuleWalker extends Lint.RuleWalker {
}
private checkStringLiteral(node: ts.StringLiteral): void {
let text = node.getText();
let doubleQuoted = text.length >= 2 && text[0] === NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE && text[text.length - 1] === NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE;
let info = this.findDescribingParent(node);
const text = node.getText();
const doubleQuoted = text.length >= 2 && text[0] === NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE && text[text.length - 1] === NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE;
const info = this.findDescribingParent(node);
// Ignore strings in import and export nodes.
if (info && info.isImport && doubleQuoted) {
const fix = [
@ -115,13 +115,13 @@ class NoUnexternalizedStringsRuleWalker extends Lint.RuleWalker {
);
return;
}
let callInfo = info ? info.callInfo : null;
let functionName = callInfo ? callInfo.callExpression.expression.getText() : null;
const callInfo = info ? info.callInfo : null;
const functionName = callInfo ? callInfo.callExpression.expression.getText() : null;
if (functionName && this.ignores[functionName]) {
return;
}
if (doubleQuoted && (!callInfo || callInfo.argIndex === -1 || !this.signatures[functionName])) {
if (doubleQuoted && (!callInfo || callInfo.argIndex === -1 || !this.signatures[functionName!])) {
const s = node.getText();
const fix = [
Lint.Replacement.replaceFromTo(node.getStart(), node.getWidth(), `nls.localize('KEY-${s.substring(1, s.length - 1)}', ${s})`),
@ -130,25 +130,25 @@ class NoUnexternalizedStringsRuleWalker extends Lint.RuleWalker {
return;
}
// We have a single quoted string outside a localize function name.
if (!doubleQuoted && !this.signatures[functionName]) {
if (!doubleQuoted && !this.signatures[functionName!]) {
return;
}
// We have a string that is a direct argument into the localize call.
let keyArg: ts.Expression = callInfo.argIndex === this.keyIndex
const keyArg: ts.Expression | null = callInfo && callInfo.argIndex === this.keyIndex
? callInfo.callExpression.arguments[this.keyIndex]
: null;
if (keyArg) {
if (isStringLiteral(keyArg)) {
this.recordKey(keyArg, this.messageIndex ? callInfo.callExpression.arguments[this.messageIndex] : undefined);
this.recordKey(keyArg, this.messageIndex && callInfo ? callInfo.callExpression.arguments[this.messageIndex] : undefined);
} else if (isObjectLiteral(keyArg)) {
for (let i = 0; i < keyArg.properties.length; i++) {
let property = keyArg.properties[i];
const property = keyArg.properties[i];
if (isPropertyAssignment(property)) {
let name = property.name.getText();
const name = property.name.getText();
if (name === 'key') {
let initializer = property.initializer;
const initializer = property.initializer;
if (isStringLiteral(initializer)) {
this.recordKey(initializer, this.messageIndex ? callInfo.callExpression.arguments[this.messageIndex] : undefined);
this.recordKey(initializer, this.messageIndex && callInfo ? callInfo.callExpression.arguments[this.messageIndex] : undefined);
}
break;
}
@ -157,18 +157,18 @@ class NoUnexternalizedStringsRuleWalker extends Lint.RuleWalker {
}
}
const messageArg = callInfo.callExpression.arguments[this.messageIndex];
const messageArg = callInfo!.callExpression.arguments[this.messageIndex!];
if (messageArg && messageArg.kind !== ts.SyntaxKind.StringLiteral) {
this.addFailure(this.createFailure(
messageArg.getStart(), messageArg.getWidth(),
`Message argument to '${callInfo.callExpression.expression.getText()}' must be a string literal.`));
`Message argument to '${callInfo!.callExpression.expression.getText()}' must be a string literal.`));
return;
}
}
private recordKey(keyNode: ts.StringLiteral, messageNode: ts.Node) {
let text = keyNode.getText();
private recordKey(keyNode: ts.StringLiteral, messageNode: ts.Node | undefined) {
const text = keyNode.getText();
// We have an empty key
if (text.match(/(['"]) *\1/)) {
if (messageNode) {
@ -191,12 +191,12 @@ class NoUnexternalizedStringsRuleWalker extends Lint.RuleWalker {
occurrences.push({ key: keyNode, message: messageNode });
}
private findDescribingParent(node: ts.Node): { callInfo?: { callExpression: ts.CallExpression, argIndex: number }, isImport?: boolean; } {
private findDescribingParent(node: ts.Node): { callInfo?: { callExpression: ts.CallExpression, argIndex: number }, isImport?: boolean; } | null {
let parent: ts.Node;
while ((parent = node.parent)) {
let kind = parent.kind;
const kind = parent.kind;
if (kind === ts.SyntaxKind.CallExpression) {
let callExpression = parent as ts.CallExpression;
const callExpression = parent as ts.CallExpression;
return { callInfo: { callExpression: callExpression, argIndex: callExpression.arguments.indexOf(<any>node) } };
} else if (kind === ts.SyntaxKind.ImportEqualsDeclaration || kind === ts.SyntaxKind.ImportDeclaration || kind === ts.SyntaxKind.ExportDeclaration) {
return { isImport: true };
@ -208,5 +208,6 @@ class NoUnexternalizedStringsRuleWalker extends Lint.RuleWalker {
}
node = parent;
}
return null;
}
}

View file

@ -3,62 +3,43 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var Lint = require("tslint");
var fs = require("fs");
var Rule = /** @class */ (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
const Lint = require("tslint");
const fs = require("fs");
class Rule extends Lint.Rules.AbstractRule {
apply(sourceFile) {
return this.applyWithWalker(new TranslationRemindRuleWalker(sourceFile, this.getOptions()));
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
var TranslationRemindRuleWalker = /** @class */ (function (_super) {
__extends(TranslationRemindRuleWalker, _super);
function TranslationRemindRuleWalker(file, opts) {
return _super.call(this, file, opts) || this;
}
TranslationRemindRuleWalker.prototype.visitImportDeclaration = function (node) {
var declaration = node.moduleSpecifier.getText();
if (declaration !== "'" + TranslationRemindRuleWalker.NLS_MODULE + "'") {
}
exports.Rule = Rule;
class TranslationRemindRuleWalker extends Lint.RuleWalker {
constructor(file, opts) {
super(file, opts);
}
visitImportDeclaration(node) {
const declaration = node.moduleSpecifier.getText();
if (declaration !== `'${TranslationRemindRuleWalker.NLS_MODULE}'`) {
return;
}
this.visitImportLikeDeclaration(node);
};
TranslationRemindRuleWalker.prototype.visitImportEqualsDeclaration = function (node) {
var reference = node.moduleReference.getText();
if (reference !== "require('" + TranslationRemindRuleWalker.NLS_MODULE + "')") {
}
visitImportEqualsDeclaration(node) {
const reference = node.moduleReference.getText();
if (reference !== `require('${TranslationRemindRuleWalker.NLS_MODULE}')`) {
return;
}
this.visitImportLikeDeclaration(node);
};
TranslationRemindRuleWalker.prototype.visitImportLikeDeclaration = function (node) {
var currentFile = node.getSourceFile().fileName;
var matchService = currentFile.match(/vs\/workbench\/services\/\w+/);
var matchPart = currentFile.match(/vs\/workbench\/parts\/\w+/);
}
visitImportLikeDeclaration(node) {
const currentFile = node.getSourceFile().fileName;
const matchService = currentFile.match(/vs\/workbench\/services\/\w+/);
const matchPart = currentFile.match(/vs\/workbench\/parts\/\w+/);
if (!matchService && !matchPart) {
return;
}
var resource = matchService ? matchService[0] : matchPart[0];
var resourceDefined = false;
var json;
const resource = matchService ? matchService[0] : matchPart[0];
let resourceDefined = false;
let json;
try {
json = fs.readFileSync('./build/lib/i18n.resources.json', 'utf8');
}
@ -66,17 +47,16 @@ var TranslationRemindRuleWalker = /** @class */ (function (_super) {
console.error('[translation-remind rule]: File with resources to pull from Transifex was not found. Aborting translation resource check for newly defined workbench part/service.');
return;
}
var workbenchResources = JSON.parse(json).workbench;
workbenchResources.forEach(function (existingResource) {
const workbenchResources = JSON.parse(json).workbench;
workbenchResources.forEach((existingResource) => {
if (existingResource.name === resource) {
resourceDefined = true;
return;
}
});
if (!resourceDefined) {
this.addFailureAtNode(node, "Please add '" + resource + "' to ./build/lib/i18n.resources.json file to use translations here.");
this.addFailureAtNode(node, `Please add '${resource}' to ./build/lib/i18n.resources.json file to use translations here.`);
}
};
TranslationRemindRuleWalker.NLS_MODULE = 'vs/nls';
return TranslationRemindRuleWalker;
}(Lint.RuleWalker));
}
}
TranslationRemindRuleWalker.NLS_MODULE = 'vs/nls';

View file

@ -30,7 +30,7 @@ class TranslationRemindRuleWalker extends Lint.RuleWalker {
this.visitImportLikeDeclaration(node);
}
protected visitImportEqualsDeclaration(node: ts.ImportEqualsDeclaration): void {
protected visitImportEqualsDeclaration(node: ts.ImportEqualsDeclaration): void {
const reference = node.moduleReference.getText();
if (reference !== `require('${TranslationRemindRuleWalker.NLS_MODULE}')`) {
return;
@ -47,7 +47,7 @@ class TranslationRemindRuleWalker extends Lint.RuleWalker {
return;
}
const resource = matchService ? matchService[0] : matchPart[0];
const resource = matchService ? matchService[0] : matchPart![0];
let resourceDefined = false;
let json;
@ -59,7 +59,7 @@ class TranslationRemindRuleWalker extends Lint.RuleWalker {
}
const workbenchResources = JSON.parse(json).workbench;
workbenchResources.forEach(existingResource => {
workbenchResources.forEach((existingResource: any) => {
if (existingResource.name === resource) {
resourceDefined = true;
return;

View file

@ -1,361 +0,0 @@
// Type definitions for Q
// Project: https://github.com/kriskowal/q
// Definitions by: Barrie Nemetchek <https://github.com/bnemetchek>, Andrew Gaspar <https://github.com/AndrewGaspar/>, John Reilly <https://github.com/johnnyreilly>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
/**
* If value is a Q promise, returns the promise.
* If value is a promise from another library it is coerced into a Q promise (where possible).
*/
declare function Q<T>(promise: Q.IPromise<T>): Q.Promise<T>;
/**
* If value is not a promise, returns a promise that is fulfilled with value.
*/
declare function Q<T>(value: T): Q.Promise<T>;
/**
* Calling with nothing at all creates a void promise
*/
declare function Q(): Q.Promise<void>;
declare namespace Q {
type IWhenable<T> = IPromise<T> | T;
interface IPromise<T> {
then<U>(onFulfill?: (value: T) => IWhenable<U>, onReject?: (error: any) => IWhenable<U>): IPromise<U>;
}
interface Deferred<T> {
promise: Promise<T>;
resolve(value?: IWhenable<T>): void;
reject(reason: any): void;
notify(value: any): void;
makeNodeResolver(): (reason: any, value: T) => void;
}
interface Promise<T> {
/**
* Like a finally clause, allows you to observe either the fulfillment or rejection of a promise, but to do so without modifying the final value. This is useful for collecting resources regardless of whether a job succeeded, like closing a database connection, shutting a server down, or deleting an unneeded key from an object.
* finally returns a promise, which will become resolved with the same fulfillment value or rejection reason as promise. However, if callback returns a promise, the resolution of the returned promise will be delayed until the promise returned from callback is finished.
*/
fin(finallyCallback: () => any): Promise<T>;
/**
* Like a finally clause, allows you to observe either the fulfillment or rejection of a promise, but to do so without modifying the final value. This is useful for collecting resources regardless of whether a job succeeded, like closing a database connection, shutting a server down, or deleting an unneeded key from an object.
* finally returns a promise, which will become resolved with the same fulfillment value or rejection reason as promise. However, if callback returns a promise, the resolution of the returned promise will be delayed until the promise returned from callback is finished.
*/
finally(finallyCallback: () => any): Promise<T>;
/**
* The then method from the Promises/A+ specification, with an additional progress handler.
*/
then<U>(onFulfill?: (value: T) => IWhenable<U>, onReject?: (error: any) => IWhenable<U>, onProgress?: Function): Promise<U>;
/**
* Like then, but "spreads" the array into a variadic fulfillment handler. If any of the promises in the array are rejected, instead calls onRejected with the first rejected promise's rejection reason.
*
* This is especially useful in conjunction with all
*/
spread<U>(onFulfill: (...args: any[]) => IWhenable<U>, onReject?: (reason: any) => IWhenable<U>): Promise<U>;
fail<U>(onRejected: (reason: any) => IWhenable<U>): Promise<U>;
/**
* A sugar method, equivalent to promise.then(undefined, onRejected).
*/
catch<U>(onRejected: (reason: any) => IWhenable<U>): Promise<U>;
/**
* A sugar method, equivalent to promise.then(undefined, undefined, onProgress).
*/
progress(onProgress: (progress: any) => any): Promise<T>;
/**
* Much like then, but with different behavior around unhandled rejection. If there is an unhandled rejection, either because promise is rejected and no onRejected callback was provided, or because onFulfilled or onRejected threw an error or returned a rejected promise, the resulting rejection reason is thrown as an exception in a future turn of the event loop.
*
* This method should be used to terminate chains of promises that will not be passed elsewhere. Since exceptions thrown in then callbacks are consumed and transformed into rejections, exceptions at the end of the chain are easy to accidentally, silently ignore. By arranging for the exception to be thrown in a future turn of the event loop, so that it won't be caught, it causes an onerror event on the browser window, or an uncaughtException event on Node.js's process object.
*
* Exceptions thrown by done will have long stack traces, if Q.longStackSupport is set to true. If Q.onerror is set, exceptions will be delivered there instead of thrown in a future turn.
*
* The Golden Rule of done vs. then usage is: either return your promise to someone else, or if the chain ends with you, call done to terminate it.
*/
done(onFulfilled?: (value: T) => any, onRejected?: (reason: any) => any, onProgress?: (progress: any) => any): void;
/**
* If callback is a function, assumes it's a Node.js-style callback, and calls it as either callback(rejectionReason) when/if promise becomes rejected, or as callback(null, fulfillmentValue) when/if promise becomes fulfilled. If callback is not a function, simply returns promise.
*/
nodeify(callback: (reason: any, value: any) => void): Promise<T>;
/**
* Returns a promise to get the named property of an object. Essentially equivalent to
*
* promise.then(function (o) {
* return o[propertyName];
* });
*/
get<U>(propertyName: String): Promise<U>;
set<U>(propertyName: String, value: any): Promise<U>;
delete<U>(propertyName: String): Promise<U>;
/**
* Returns a promise for the result of calling the named method of an object with the given array of arguments. The object itself is this in the function, just like a synchronous method call. Essentially equivalent to
*
* promise.then(function (o) {
* return o[methodName].apply(o, args);
* });
*/
post<U>(methodName: String, args: any[]): Promise<U>;
/**
* Returns a promise for the result of calling the named method of an object with the given variadic arguments. The object itself is this in the function, just like a synchronous method call.
*/
invoke<U>(methodName: String, ...args: any[]): Promise<U>;
fapply<U>(args: any[]): Promise<U>;
fcall<U>(...args: any[]): Promise<U>;
/**
* Returns a promise for an array of the property names of an object. Essentially equivalent to
*
* promise.then(function (o) {
* return Object.keys(o);
* });
*/
keys(): Promise<string[]>;
/**
* A sugar method, equivalent to promise.then(function () { return value; }).
*/
thenResolve<U>(value: U): Promise<U>;
/**
* A sugar method, equivalent to promise.then(function () { throw reason; }).
*/
thenReject(reason: any): Promise<T>;
/**
* Attaches a handler that will observe the value of the promise when it becomes fulfilled, returning a promise for that same value, perhaps deferred but not replaced by the promise returned by the onFulfilled handler.
*/
tap(onFulfilled: (value: T) => any): Promise<T>;
timeout(ms: number, message?: string): Promise<T>;
/**
* Returns a promise that will have the same result as promise, but will only be fulfilled or rejected after at least ms milliseconds have passed.
*/
delay(ms: number): Promise<T>;
/**
* Returns whether a given promise is in the fulfilled state. When the static version is used on non-promises, the result is always true.
*/
isFulfilled(): boolean;
/**
* Returns whether a given promise is in the rejected state. When the static version is used on non-promises, the result is always false.
*/
isRejected(): boolean;
/**
* Returns whether a given promise is in the pending state. When the static version is used on non-promises, the result is always false.
*/
isPending(): boolean;
valueOf(): any;
/**
* Returns a "state snapshot" object, which will be in one of three forms:
*
* - { state: "pending" }
* - { state: "fulfilled", value: <fulfllment value> }
* - { state: "rejected", reason: <rejection reason> }
*/
inspect(): PromiseState<T>;
}
interface PromiseState<T> {
/**
* "fulfilled", "rejected", "pending"
*/
state: string;
value?: T;
reason?: any;
}
// If no value provided, returned promise will be of void type
export function when(): Promise<void>;
// if no fulfill, reject, or progress provided, returned promise will be of same type
export function when<T>(value: IWhenable<T>): Promise<T>;
// If a non-promise value is provided, it will not reject or progress
export function when<T, U>(value: IWhenable<T>, onFulfilled: (val: T) => IWhenable<U>, onRejected?: (reason: any) => IWhenable<U>, onProgress?: (progress: any) => any): Promise<U>;
/**
* Currently "impossible" (and I use the term loosely) to implement due to TypeScript limitations as it is now.
* See: https://github.com/Microsoft/TypeScript/issues/1784 for discussion on it.
*/
// export function try(method: Function, ...args: any[]): Promise<any>;
export function fbind<T>(method: (...args: any[]) => IWhenable<T>, ...args: any[]): (...args: any[]) => Promise<T>;
export function fcall<T>(method: (...args: any[]) => T, ...args: any[]): Promise<T>;
export function send<T>(obj: any, functionName: string, ...args: any[]): Promise<T>;
export function invoke<T>(obj: any, functionName: string, ...args: any[]): Promise<T>;
export function mcall<T>(obj: any, functionName: string, ...args: any[]): Promise<T>;
export function denodeify<T>(nodeFunction: Function, ...args: any[]): (...args: any[]) => Promise<T>;
export function nbind<T>(nodeFunction: Function, thisArg: any, ...args: any[]): (...args: any[]) => Promise<T>;
export function nfbind<T>(nodeFunction: Function, ...args: any[]): (...args: any[]) => Promise<T>;
export function nfcall<T>(nodeFunction: Function, ...args: any[]): Promise<T>;
export function nfapply<T>(nodeFunction: Function, args: any[]): Promise<T>;
export function ninvoke<T>(nodeModule: any, functionName: string, ...args: any[]): Promise<T>;
export function npost<T>(nodeModule: any, functionName: string, args: any[]): Promise<T>;
export function nsend<T>(nodeModule: any, functionName: string, ...args: any[]): Promise<T>;
export function nmcall<T>(nodeModule: any, functionName: string, ...args: any[]): Promise<T>;
/**
* Returns a promise that is fulfilled with an array containing the fulfillment value of each promise, or is rejected with the same rejection reason as the first promise to be rejected.
*/
export function all<A, B, C, D, E, F>(promises: IWhenable<[IWhenable<A>, IWhenable<B>, IWhenable<C>, IWhenable<D>, IWhenable<E>, IWhenable<F>]>): Promise<[A, B, C, D, E, F]>;
/**
* Returns a promise that is fulfilled with an array containing the fulfillment value of each promise, or is rejected with the same rejection reason as the first promise to be rejected.
*/
export function all<A, B, C, D, E>(promises: IWhenable<[IWhenable<A>, IWhenable<B>, IWhenable<C>, IWhenable<D>, IWhenable<E>]>): Promise<[A, B, C, D, E]>;
/**
* Returns a promise that is fulfilled with an array containing the fulfillment value of each promise, or is rejected with the same rejection reason as the first promise to be rejected.
*/
export function all<A, B, C, D>(promises: IWhenable<[IWhenable<A>, IWhenable<B>, IWhenable<C>, IWhenable<D>]>): Promise<[A, B, C, D]>;
/**
* Returns a promise that is fulfilled with an array containing the fulfillment value of each promise, or is rejected with the same rejection reason as the first promise to be rejected.
*/
export function all<A, B, C>(promises: IWhenable<[IWhenable<A>, IWhenable<B>, IWhenable<C>]>): Promise<[A, B, C]>;
/**
* Returns a promise that is fulfilled with an array containing the fulfillment value of each promise, or is rejected with the same rejection reason as the first promise to be rejected.
*/
export function all<A, B>(promises: IWhenable<[IWhenable<A>, IWhenable<B>]>): Promise<[A, B]>;
/**
* Returns a promise that is fulfilled with an array containing the fulfillment value of each promise, or is rejected with the same rejection reason as the first promise to be rejected.
*/
export function all<T>(promises: IWhenable<IWhenable<T>[]>): Promise<T[]>;
/**
* Returns a promise for the first of an array of promises to become settled.
*/
export function race<T>(promises: IWhenable<T>[]): Promise<T>;
/**
* Returns a promise that is fulfilled with an array of promise state snapshots, but only after all the original promises have settled, i.e. become either fulfilled or rejected.
*/
export function allSettled<T>(promises: IWhenable<IWhenable<T>[]>): Promise<PromiseState<T>[]>;
export function allResolved<T>(promises: IWhenable<IWhenable<T>[]>): Promise<Promise<T>[]>;
/**
* Like then, but "spreads" the array into a variadic fulfillment handler. If any of the promises in the array are rejected, instead calls onRejected with the first rejected promise's rejection reason.
* This is especially useful in conjunction with all.
*/
export function spread<T, U>(promises: IWhenable<T>[], onFulfilled: (...args: T[]) => IWhenable<U>, onRejected?: (reason: any) => IWhenable<U>): Promise<U>;
/**
* Returns a promise that will have the same result as promise, except that if promise is not fulfilled or rejected before ms milliseconds, the returned promise will be rejected with an Error with the given message. If message is not supplied, the message will be "Timed out after " + ms + " ms".
*/
export function timeout<T>(promise: Promise<T>, ms: number, message?: string): Promise<T>;
/**
* Returns a promise that will have the same result as promise, but will only be fulfilled or rejected after at least ms milliseconds have passed.
*/
export function delay<T>(promise: Promise<T>, ms: number): Promise<T>;
/**
* Returns a promise that will have the same result as promise, but will only be fulfilled or rejected after at least ms milliseconds have passed.
*/
export function delay<T>(value: T, ms: number): Promise<T>;
/**
* Returns a promise that will be fulfilled with undefined after at least ms milliseconds have passed.
*/
export function delay(ms: number): Promise <void>;
/**
* Returns whether a given promise is in the fulfilled state. When the static version is used on non-promises, the result is always true.
*/
export function isFulfilled(promise: Promise<any>): boolean;
/**
* Returns whether a given promise is in the rejected state. When the static version is used on non-promises, the result is always false.
*/
export function isRejected(promise: Promise<any>): boolean;
/**
* Returns whether a given promise is in the pending state. When the static version is used on non-promises, the result is always false.
*/
export function isPending(promise: Promise<any>): boolean;
/**
* Returns a "deferred" object with a:
* promise property
* resolve(value) method
* reject(reason) method
* notify(value) method
* makeNodeResolver() method
*/
export function defer<T>(): Deferred<T>;
/**
* Returns a promise that is rejected with reason.
*/
export function reject<T>(reason?: any): Promise<T>;
export function Promise<T>(resolver: (resolve: (val: IWhenable<T>) => void , reject: (reason: any) => void , notify: (progress: any) => void ) => void ): Promise<T>;
/**
* Creates a new version of func that accepts any combination of promise and non-promise values, converting them to their fulfillment values before calling the original func. The returned version also always returns a promise: if func does a return or throw, then Q.promised(func) will return fulfilled or rejected promise, respectively.
*
* This can be useful for creating functions that accept either promises or non-promise values, and for ensuring that the function always returns a promise even in the face of unintentional thrown exceptions.
*/
export function promised<T>(callback: (...args: any[]) => T): (...args: any[]) => Promise<T>;
/**
* Returns whether the given value is a Q promise.
*/
export function isPromise(object: any): boolean;
/**
* Returns whether the given value is a promise (i.e. it's an object with a then function).
*/
export function isPromiseAlike(object: any): boolean;
/**
* Returns whether a given promise is in the pending state. When the static version is used on non-promises, the result is always false.
*/
export function isPending(object: any): boolean;
/**
* If an object is not a promise, it is as "near" as possible.
* If a promise is rejected, it is as "near" as possible too.
* If its a fulfilled promise, the fulfillment value is nearer.
* If its a deferred promise and the deferred has been resolved, the
* resolution is "nearer".
*/
export function nearer<T>(promise: Promise<T>): T;
/**
* This is an experimental tool for converting a generator function into a deferred function. This has the potential of reducing nested callbacks in engines that support yield.
*/
export function async<T>(generatorFunction: any): (...args: any[]) => Promise<T>;
export function nextTick(callback: Function): void;
/**
* A settable property that will intercept any uncaught errors that would otherwise be thrown in the next tick of the event loop, usually as a result of done. Can be useful for getting the full stack trace of an error in browsers, which is not usually possible with window.onerror.
*/
export var onerror: (reason: any) => void;
/**
* A settable property that lets you turn on long stack trace support. If turned on, "stack jumps" will be tracked across asynchronous promise operations, so that if an uncaught error is thrown by done or a rejection reason's stack property is inspected in a rejection callback, a long stack trace is produced.
*/
export var longStackSupport: boolean;
/**
* Calling resolve with a pending promise causes promise to wait on the passed promise, becoming fulfilled with its fulfillment value or rejected with its rejection reason (or staying pending forever, if the passed promise does).
* Calling resolve with a rejected promise causes promise to be rejected with the passed promise's rejection reason.
* Calling resolve with a fulfilled promise causes promise to be fulfilled with the passed promise's fulfillment value.
* Calling resolve with a non-promise value causes promise to be fulfilled with that value.
*/
export function resolve<T>(object: IWhenable<T>): Promise<T>;
/**
* Resets the global "Q" variable to the value it has before Q was loaded.
* This will either be undefined if there was no version or the version of Q which was already loaded before.
* @returns { The last version of Q. }
*/
export function noConflict(): typeof Q;
}
declare module "q" {
export = Q;
}

View file

@ -1,121 +0,0 @@
// Type definitions for chalk v0.4.0
// Project: https://github.com/sindresorhus/chalk
// Definitions by: Diullei Gomes <https://github.com/Diullei>, Bart van der Schoor <https://github.com/Bartvds>, Nico Jansen <https://github.com/nicojs>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
declare namespace Chalk {
export var enabled: boolean;
export var supportsColor: boolean;
export var styles: ChalkStyleMap;
export function stripColor(value: string): any;
export function hasColor(str: string): boolean;
export interface ChalkChain extends ChalkStyle {
(...text: string[]): string;
}
export interface ChalkStyleElement {
open: string;
close: string;
}
// General
export var reset: ChalkChain;
export var bold: ChalkChain;
export var italic: ChalkChain;
export var underline: ChalkChain;
export var inverse: ChalkChain;
export var strikethrough: ChalkChain;
// Text colors
export var black: ChalkChain;
export var red: ChalkChain;
export var green: ChalkChain;
export var yellow: ChalkChain;
export var blue: ChalkChain;
export var magenta: ChalkChain;
export var cyan: ChalkChain;
export var white: ChalkChain;
export var gray: ChalkChain;
export var grey: ChalkChain;
// Background colors
export var bgBlack: ChalkChain;
export var bgRed: ChalkChain;
export var bgGreen: ChalkChain;
export var bgYellow: ChalkChain;
export var bgBlue: ChalkChain;
export var bgMagenta: ChalkChain;
export var bgCyan: ChalkChain;
export var bgWhite: ChalkChain;
export interface ChalkStyle {
// General
reset: ChalkChain;
bold: ChalkChain;
italic: ChalkChain;
underline: ChalkChain;
inverse: ChalkChain;
strikethrough: ChalkChain;
// Text colors
black: ChalkChain;
red: ChalkChain;
green: ChalkChain;
yellow: ChalkChain;
blue: ChalkChain;
magenta: ChalkChain;
cyan: ChalkChain;
white: ChalkChain;
gray: ChalkChain;
grey: ChalkChain;
// Background colors
bgBlack: ChalkChain;
bgRed: ChalkChain;
bgGreen: ChalkChain;
bgYellow: ChalkChain;
bgBlue: ChalkChain;
bgMagenta: ChalkChain;
bgCyan: ChalkChain;
bgWhite: ChalkChain;
}
export interface ChalkStyleMap {
// General
reset: ChalkStyleElement;
bold: ChalkStyleElement;
italic: ChalkStyleElement;
underline: ChalkStyleElement;
inverse: ChalkStyleElement;
strikethrough: ChalkStyleElement;
// Text colors
black: ChalkStyleElement;
red: ChalkStyleElement;
green: ChalkStyleElement;
yellow: ChalkStyleElement;
blue: ChalkStyleElement;
magenta: ChalkStyleElement;
cyan: ChalkStyleElement;
white: ChalkStyleElement;
gray: ChalkStyleElement;
// Background colors
bgBlack: ChalkStyleElement;
bgRed: ChalkStyleElement;
bgGreen: ChalkStyleElement;
bgYellow: ChalkStyleElement;
bgBlue: ChalkStyleElement;
bgMagenta: ChalkStyleElement;
bgCyan: ChalkStyleElement;
bgWhite: ChalkStyleElement;
}
}
declare module "chalk" {
export = Chalk;
}

View file

@ -1,18 +0,0 @@
// Type definitions for compose-function
// Project: https://github.com/component/debounce
// Definitions by: Denis Sokolov <https://github.com/denis-sokolov>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
declare module "debounce" {
// Overload on boolean constants would allow us to narrow further,
// but it is not implemented for TypeScript yet
function f<A extends Function>(f: A, interval?: number, immediate?: boolean): A
/**
* This is required as per:
* https://github.com/Microsoft/TypeScript/issues/5073
*/
namespace f {}
export = f;
}

View file

@ -1,12 +1,11 @@
declare module "event-stream" {
import { Stream } from 'stream';
import { ThroughStream as _ThroughStream} from 'through';
import { MapStream } from 'map-stream';
import { ThroughStream as _ThroughStream } from 'through';
import * as File from 'vinyl';
export interface ThroughStream extends _ThroughStream {
queue(data: File | null);
push(data: File | null);
queue(data: File | null): any;
push(data: File | null): any;
paused: boolean;
}
@ -15,14 +14,14 @@ declare module "event-stream" {
function concat(...stream: Stream[]): ThroughStream;
function duplex(istream: Stream, ostream: Stream): ThroughStream;
function through(write?: (data: any) => void, end?: () => void,
opts?: {autoDestroy: boolean; }): ThroughStream;
function through(write?: (this: ThroughStream, data: any) => void, end?: (this: ThroughStream) => void,
opts?: { autoDestroy: boolean; }): ThroughStream;
function readArray<T>(array: T[]): ThroughStream;
function writeArray<T>(cb: (err:Error, array:T[]) => void): ThroughStream;
function writeArray<T>(cb: (err: Error, array: T[]) => void): ThroughStream;
function mapSync<I,O>(cb: (data:I) => O): ThroughStream;
function map<I,O>(cb: (data:I, cb:(err?:Error, data?: O)=>void) => O): ThroughStream;
function mapSync<I, O>(cb: (data: I) => O): ThroughStream;
function map<I, O>(cb: (data: I, cb: (err?: Error, data?: O) => void) => O): ThroughStream;
function readable(asyncFunction: Function): MapStream;
function readable(asyncFunction: (this: ThroughStream, ...args: any[]) => any): any;
}

View file

@ -0,0 +1,3 @@
declare module 'github-releases' {
}

View file

@ -1,43 +0,0 @@
// Type definitions for gulp-concat
// Project: http://github.com/wearefractal/gulp-concat
// Definitions by: Keita Kagurazaka <https://github.com/k-kagurazaka>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
declare module "gulp-concat" {
interface IOptions {
newLine: string;
}
interface IFsStats {
dev?: number;
ino?: number;
mode?: number;
nlink?: number;
uid?: number;
gid?: number;
rdev?: number;
size?: number;
blksize?: number;
blocks?: number;
atime?: Date;
mtime?: Date;
ctime?: Date;
}
interface IVinylOptions {
cwd?: string;
base?: string;
path?: string;
stat?: IFsStats;
contents?: NodeJS.ReadableStream | Buffer;
}
interface IConcat {
(filename: string, options?: IOptions): NodeJS.ReadWriteStream;
(options: IVinylOptions): NodeJS.ReadWriteStream;
}
var _tmp: IConcat;
export = _tmp;
}

View file

@ -1,29 +0,0 @@
// Type definitions for gulp-filter v3.0.1
// Project: https://github.com/sindresorhus/gulp-filter
// Definitions by: Tanguy Krotoff <https://github.com/tkrotoff>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
declare module 'gulp-filter' {
import File = require('vinyl');
import * as Minimatch from 'minimatch';
namespace filter {
interface FileFunction {
(file: File): boolean;
}
interface Options extends Minimatch.IOptions {
restore?: boolean;
passthrough?: boolean;
}
// A transform stream with a .restore object
interface Filter extends NodeJS.ReadWriteStream {
restore: NodeJS.ReadWriteStream
}
}
function filter(pattern: string | string[] | filter.FileFunction, options?: filter.Options): filter.Filter;
export = filter;
}

View file

@ -1,29 +0,0 @@
// Type definitions for gulp-rename
// Project: https://github.com/hparra/gulp-rename
// Definitions by: Asana <https://asana.com>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
declare module "gulp-rename" {
interface ParsedPath {
dirname?: string;
basename?: string;
extname?: string;
}
interface Options extends ParsedPath {
prefix?: string;
suffix?: string;
}
function rename(name: string): NodeJS.ReadWriteStream;
function rename(callback: (path: ParsedPath) => any): NodeJS.ReadWriteStream;
function rename(opts: Options): NodeJS.ReadWriteStream;
/**
* This is required as per:
* https://github.com/Microsoft/TypeScript/issues/5073
*/
namespace rename {}
export = rename;
}

View file

@ -1,27 +0,0 @@
// Type definitions for gulp-sourcemaps
// Project: https://github.com/floridoo/gulp-sourcemaps
// Definitions by: Asana <https://asana.com>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
declare module "gulp-sourcemaps" {
interface InitOptions {
loadMaps?: boolean;
debug?: boolean;
}
interface WriteMapper {
(file: string): string;
}
interface WriteOptions {
addComment?: boolean;
includeContent?: boolean;
sourceRoot?: string | WriteMapper;
sourceMappingURLPrefix?: string | WriteMapper;
sourceMappingURL?: (f:{relative:string})=>string;
}
export function init(opts?: InitOptions): NodeJS.ReadWriteStream;
export function write(path?: string, opts?: WriteOptions): NodeJS.ReadWriteStream;
export function write(opts?: WriteOptions): NodeJS.ReadWriteStream;
}

View file

@ -1,133 +0,0 @@
// Type definitions for gulp-util v3.0.x
// Project: https://github.com/gulpjs/gulp-util
// Definitions by: jedmao <https://github.com/jedmao>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
declare module 'gulp-util' {
import vinyl = require('vinyl');
import chalk = require('chalk');
import through2 = require('through2');
export class File extends vinyl { }
/**
* Replaces a file extension in a path. Returns the new path.
*/
export function replaceExtension(npath: string, ext: string): string;
export var colors: typeof chalk;
export var date: {
(now?: Date, mask?: string, convertLocalTimeToUTC?: boolean): any;
(date?: string, mask?: string, convertLocalTimeToUTC?: boolean): any;
masks: any;
};
/**
* Logs stuff. Already prefixed with [gulp] and all that. Use the right colors
* for values. If you pass in multiple arguments it will join them by a space.
*/
export function log(message?: any, ...optionalParams: any[]): void;
/**
* This is a lodash.template function wrapper. You must pass in a valid gulp
* file object so it is available to the user or it will error. You can not
* configure any of the delimiters. Look at the lodash docs for more info.
*/
export function template(tmpl: string): (opt: { file: { path: string } }) => string;
export function template(tmpl: string, opt: { file: { path: string } }): string;
export var env: any;
export function beep(): void;
/**
* Returns a stream that does nothing but pass data straight through.
*/
export var noop: typeof through2;
export function isStream(obj: any): boolean;
export function isBuffer(obj: any): boolean;
export function isNull(obj: any): boolean;
export var linefeed: string;
export function combine(streams: NodeJS.ReadWriteStream[]): () => NodeJS.ReadWriteStream;
export function combine(...streams: NodeJS.ReadWriteStream[]): () => NodeJS.ReadWriteStream;
/**
* This is similar to es.wait but instead of buffering text into one string
* it buffers anything into an array (so very useful for file objects).
*/
export function buffer(cb?: (err: Error, data: any[]) => void): NodeJS.ReadWriteStream;
export class PluginError implements Error, PluginErrorOptions {
constructor(options?: PluginErrorOptions);
constructor(pluginName: string, options?: PluginErrorOptions);
constructor(pluginName: string, message: string, options?: PluginErrorOptions);
constructor(pluginName: string, message: Error, options?: PluginErrorOptions);
/**
* The module name of your plugin.
*/
name: string;
/**
* Can be a string or an existing error.
*/
message: any;
fileName: string;
lineNumber: number;
/**
* You need to include the message along with this stack. If you pass an
* error in as the message the stack will be pulled from that, otherwise one
* will be created.
*/
stack: string;
/**
* By default the stack will not be shown. Set this to true if you think the
* stack is important for your error.
*/
showStack: boolean;
/**
* Error properties will be included in err.toString(). Can be omitted by
* setting this to false.
*/
showProperties: boolean;
plugin: string;
error: Error;
}
}
interface PluginErrorOptions {
/**
* The module name of your plugin.
*/
name?: string;
/**
* Can be a string or an existing error.
*/
message?: any;
fileName?: string;
lineNumber?: number;
/**
* You need to include the message along with this stack. If you pass an
* error in as the message the stack will be pulled from that, otherwise one
* will be created.
*/
stack?: string;
/**
* By default the stack will not be shown. Set this to true if you think the
* stack is important for your error.
*/
showStack?: boolean;
/**
* Error properties will be included in err.toString(). Can be omitted by
* setting this to false.
*/
showProperties?: boolean;
plugin?: string;
error?: Error;
}

View file

@ -1,293 +0,0 @@
// Type definitions for Gulp v3.8.x
// Project: http://gulpjs.com
// Definitions by: Drew Noakes <https://drewnoakes.com>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
declare module "gulp" {
import Orchestrator = require("orchestrator");
import VinylFile = require("vinyl");
namespace gulp {
interface Gulp extends Orchestrator {
/**
* Define a task
* @param name The name of the task.
* @param deps An array of task names to be executed and completed before your task will run.
* @param fn The function that performs the task's operations. For asynchronous tasks, you need to provide a hint when the task is complete:
* <ul>
* <li>Take in a callback</li>
* <li>Return a stream or a promise</li>
* </ul>
*/
task: Orchestrator.AddMethod;
/**
* Emits files matching provided glob or an array of globs. Returns a stream of Vinyl files that can be piped to plugins.
* @param glob Glob or array of globs to read.
* @param opt Options to pass to node-glob through glob-stream.
*/
src: SrcMethod;
/**
* Can be piped to and it will write files. Re-emits all data passed to it so you can pipe to multiple folders.
* Folders that don't exist will be created.
*
* @param outFolder The path (output folder) to write files to. Or a function that returns it, the function will be provided a vinyl File instance.
* @param opt
*/
dest: DestMethod;
/**
* Watch files and do something when a file changes. This always returns an EventEmitter that emits change events.
*
* @param glob a single glob or array of globs that indicate which files to watch for changes.
* @param opt options, that are passed to the gaze library.
* @param fn a callback or array of callbacks to be called on each change, or names of task(s) to run when a file changes, added with task().
*/
watch: WatchMethod;
}
interface GulpPlugin {
(...args: any[]): NodeJS.ReadWriteStream;
}
interface WatchMethod {
/**
* Watch files and do something when a file changes. This always returns an EventEmitter that emits change events.
*
* @param glob a single glob or array of globs that indicate which files to watch for changes.
* @param fn a callback or array of callbacks to be called on each change, or names of task(s) to run when a file changes, added with task().
*/
(glob: string|string[], fn: (WatchCallback|string)): NodeJS.EventEmitter;
/**
* Watch files and do something when a file changes. This always returns an EventEmitter that emits change events.
*
* @param glob a single glob or array of globs that indicate which files to watch for changes.
* @param fn a callback or array of callbacks to be called on each change, or names of task(s) to run when a file changes, added with task().
*/
(glob: string|string[], fn: (WatchCallback|string)[]): NodeJS.EventEmitter;
/**
* Watch files and do something when a file changes. This always returns an EventEmitter that emits change events.
*
* @param glob a single glob or array of globs that indicate which files to watch for changes.
* @param opt options, that are passed to the gaze library.
* @param fn a callback or array of callbacks to be called on each change, or names of task(s) to run when a file changes, added with task().
*/
(glob: string|string[], opt: WatchOptions, fn: (WatchCallback|string)): NodeJS.EventEmitter;
/**
* Watch files and do something when a file changes. This always returns an EventEmitter that emits change events.
*
* @param glob a single glob or array of globs that indicate which files to watch for changes.
* @param opt options, that are passed to the gaze library.
* @param fn a callback or array of callbacks to be called on each change, or names of task(s) to run when a file changes, added with task().
*/
(glob: string|string[], opt: WatchOptions, fn: (WatchCallback|string)[]): NodeJS.EventEmitter;
}
interface DestMethod {
/**
* Can be piped to and it will write files. Re-emits all data passed to it so you can pipe to multiple folders.
* Folders that don't exist will be created.
*
* @param outFolder The path (output folder) to write files to. Or a function that returns it, the function will be provided a vinyl File instance.
* @param opt
*/
(outFolder: string|((file: VinylFile) => string), opt?: DestOptions): NodeJS.ReadWriteStream;
}
interface SrcMethod {
/**
* Emits files matching provided glob or an array of globs. Returns a stream of Vinyl files that can be piped to plugins.
* @param glob Glob or array of globs to read.
* @param opt Options to pass to node-glob through glob-stream.
*/
(glob: string|string[], opt?: SrcOptions): NodeJS.ReadWriteStream;
}
/**
* Options to pass to node-glob through glob-stream.
* Specifies two options in addition to those used by node-glob:
* https://github.com/isaacs/node-glob#options
*/
interface SrcOptions {
/**
* Setting this to <code>false</code> will return <code>file.contents</code> as <code>null</code>
* and not read the file at all.
* Default: <code>true</code>.
*/
read?: boolean;
/**
* Setting this to false will return <code>file.contents</code> as a stream and not buffer files.
* This is useful when working with large files.
* Note: Plugins might not implement support for streams.
* Default: <code>true</code>.
*/
buffer?: boolean;
/**
* The base path of a glob.
*
* Default is everything before a glob starts.
*/
base?: string;
/**
* The current working directory in which to search.
* Defaults to process.cwd().
*/
cwd?: string;
/**
* The place where patterns starting with / will be mounted onto.
* Defaults to path.resolve(options.cwd, "/") (/ on Unix systems, and C:\ or some such on Windows.)
*/
root?: string;
/**
* Include .dot files in normal matches and globstar matches.
* Note that an explicit dot in a portion of the pattern will always match dot files.
*/
dot?: boolean;
/**
* Set to match only fles, not directories. Set this flag to prevent copying empty directories
*/
nodir?: boolean;
/**
* By default, a pattern starting with a forward-slash will be "mounted" onto the root setting, so that a valid
* filesystem path is returned. Set this flag to disable that behavior.
*/
nomount?: boolean;
/**
* Add a / character to directory matches. Note that this requires additional stat calls.
*/
mark?: boolean;
/**
* Don't sort the results.
*/
nosort?: boolean;
/**
* Set to true to stat all results. This reduces performance somewhat, and is completely unnecessary, unless
* readdir is presumed to be an untrustworthy indicator of file existence. It will cause ELOOP to be triggered one
* level sooner in the case of cyclical symbolic links.
*/
stat?: boolean;
/**
* When an unusual error is encountered when attempting to read a directory, a warning will be printed to stderr.
* Set the silent option to true to suppress these warnings.
*/
silent?: boolean;
/**
* When an unusual error is encountered when attempting to read a directory, the process will just continue on in
* search of other matches. Set the strict option to raise an error in these cases.
*/
strict?: boolean;
/**
* See cache property above. Pass in a previously generated cache object to save some fs calls.
*/
cache?: boolean;
/**
* A cache of results of filesystem information, to prevent unnecessary stat calls.
* While it should not normally be necessary to set this, you may pass the statCache from one glob() call to the
* options object of another, if you know that the filesystem will not change between calls.
*/
statCache?: boolean;
/**
* Perform a synchronous glob search.
*/
sync?: boolean;
/**
* In some cases, brace-expanded patterns can result in the same file showing up multiple times in the result set.
* By default, this implementation prevents duplicates in the result set. Set this flag to disable that behavior.
*/
nounique?: boolean;
/**
* Set to never return an empty set, instead returning a set containing the pattern itself.
* This is the default in glob(3).
*/
nonull?: boolean;
/**
* Perform a case-insensitive match. Note that case-insensitive filesystems will sometimes result in glob returning
* results that are case-insensitively matched anyway, since readdir and stat will not raise an error.
*/
nocase?: boolean;
/**
* Set to enable debug logging in minimatch and glob.
*/
debug?: boolean;
/**
* Set to enable debug logging in glob, but not minimatch.
*/
globDebug?: boolean;
}
interface DestOptions {
/**
* The output folder. Only has an effect if provided output folder is relative.
* Default: process.cwd()
*/
cwd?: string;
/**
* Octal permission string specifying mode for any folders that need to be created for output folder.
* Default: 0777.
*/
mode?: string;
}
/**
* Options that are passed to <code>gaze</code>.
* https://github.com/shama/gaze
*/
interface WatchOptions {
/** Interval to pass to fs.watchFile. */
interval?: number;
/** Delay for events called in succession for the same file/event. */
debounceDelay?: number;
/** Force the watch mode. Either 'auto' (default), 'watch' (force native events), or 'poll' (force stat polling). */
mode?: string;
/** The current working directory to base file patterns from. Default is process.cwd().. */
cwd?: string;
}
interface WatchEvent {
/** The type of change that occurred, either added, changed or deleted. */
type: string;
/** The path to the file that triggered the event. */
path: string;
}
/**
* Callback to be called on each watched file change.
*/
interface WatchCallback {
(event: WatchEvent): void;
}
interface TaskCallback {
/**
* Defines a task.
* Tasks may be made asynchronous if they are passing a callback or return a promise or a stream.
* @param cb callback used to signal asynchronous completion. Caller includes <code>err</code> in case of error.
*/
(cb?: (err?: any) => void): any;
}
}
var gulp: gulp.Gulp;
export = gulp;
}

View file

@ -18,7 +18,7 @@ declare module Lazy {
function on<T>(eventType: string): Sequence<T>;
function readFile(path: string): StringLikeSequence;
function makeHttpRequest(path: string): StringLikeSequence;
interface StrictLazy {
(value: string): StringLikeSequence;
<T>(value: T[]): ArrayLikeSequence<T>;
@ -87,7 +87,7 @@ declare module Lazy {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
interface Iterator<T> {
new (sequence: Sequence<T>): Iterator<T>;
new(sequence: Sequence<T>): Iterator<T>;
current(): T;
moveNext(): boolean;
}
@ -159,6 +159,9 @@ declare module Lazy {
map<U>(mapFn: MapCallback<T, U[]>): ArraySequence<U>;
map<U>(mapFn: MapCallback<T, U>): Sequence<U>;
// TODO: vscode addition to workaround strict null errors
flatten(): Sequence<any>;
max(valueFn?: NumberCallback<T>): T;
min(valueFn?: NumberCallback<T>): T;
none(valueFn?: TestCallback<T>): boolean;

View file

@ -1,64 +0,0 @@
// Type definitions for Minimatch 2.0.8
// Project: https://github.com/isaacs/minimatch
// Definitions by: vvakame <https://github.com/vvakame/>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
declare module "minimatch" {
function M(target: string, pattern: string, options?: M.IOptions): boolean;
namespace M {
function match(list: string[], pattern: string, options?: IOptions): string[];
function filter(pattern: string, options?: IOptions): (element: string, indexed: number, array: string[]) => boolean;
function makeRe(pattern: string, options?: IOptions): RegExp;
var Minimatch: IMinimatchStatic;
interface IOptions {
debug?: boolean;
nobrace?: boolean;
noglobstar?: boolean;
dot?: boolean;
noext?: boolean;
nocase?: boolean;
nonull?: boolean;
matchBase?: boolean;
nocomment?: boolean;
nonegate?: boolean;
flipNegate?: boolean;
}
interface IMinimatchStatic {
new (pattern: string, options?: IOptions): IMinimatch;
prototype: IMinimatch;
}
interface IMinimatch {
pattern: string;
options: IOptions;
/** 2-dimensional array of regexp or string expressions. */
set: any[][]; // (RegExp | string)[][]
regexp: RegExp;
negate: boolean;
comment: boolean;
empty: boolean;
makeRe(): RegExp; // regexp or boolean
match(fname: string): boolean;
matchOne(files: string[], pattern: string[], partial: boolean): boolean;
/** Deprecated. For internal use. */
debug(): void;
/** Deprecated. For internal use. */
make(): void;
/** Deprecated. For internal use. */
parseNegate(): void;
/** Deprecated. For internal use. */
braceExpand(pattern: string, options: IOptions): void;
/** Deprecated. For internal use. */
parse(pattern: string, isSub?: boolean): void;
}
}
export = M;
}

View file

@ -1,4 +0,0 @@
declare module 'object-assign' {
function fn(target: any, ...sources: any[]): any;
export = fn;
}

View file

@ -1,125 +0,0 @@
// Type definitions for Orchestrator
// Project: https://github.com/orchestrator/orchestrator
// Definitions by: Qubo <https://github.com/tkQubo>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
declare type Strings = string|string[];
declare module "orchestrator" {
class Orchestrator {
add: Orchestrator.AddMethod;
/**
* Have you defined a task with this name?
* @param name The task name to query
*/
hasTask(name: string): boolean;
start: Orchestrator.StartMethod;
stop(): void;
/**
* Listen to orchestrator internals
* @param event Event name to listen to:
* <ul>
* <li>start: from start() method, shows you the task sequence
* <li>stop: from stop() method, the queue finished successfully
* <li>err: from stop() method, the queue was aborted due to a task error
* <li>task_start: from _runTask() method, task was started
* <li>task_stop: from _runTask() method, task completed successfully
* <li>task_err: from _runTask() method, task errored
* <li>task_not_found: from start() method, you're trying to start a task that doesn't exist
* <li>task_recursion: from start() method, there are recursive dependencies in your task list
* </ul>
* @param cb Passes single argument: e: event details
*/
on(event: string, cb: (e: Orchestrator.OnCallbackEvent) => any): Orchestrator;
/**
* Listen to all orchestrator events from one callback
* @param cb Passes single argument: e: event details
*/
onAll(cb: (e: Orchestrator.OnAllCallbackEvent) => any): void;
}
namespace Orchestrator {
interface AddMethodCallback {
/**
* Accept a callback
* @param callback
*/
(callback?: Function): any;
/**
* Return a promise
*/
(): Q.Promise<any>;
/**
* Return a stream: (task is marked complete when stream ends)
*/
(): any; //TODO: stream type should be here e.g. map-stream
}
/**
* Define a task
*/
interface AddMethod {
/**
* Define a task
* @param name The name of the task.
* @param deps An array of task names to be executed and completed before your task will run.
* @param fn The function that performs the task's operations. For asynchronous tasks, you need to provide a hint when the task is complete:
* <ul>
* <li>Take in a callback</li>
* <li>Return a stream or a promise</li>
* </ul>
*/
(name: string, deps?: string[], fn?: AddMethodCallback|Function): Orchestrator;
/**
* Define a task
* @param name The name of the task.
* @param fn The function that performs the task's operations. For asynchronous tasks, you need to provide a hint when the task is complete:
* <ul>
* <li>Take in a callback</li>
* <li>Return a stream or a promise</li>
* </ul>
*/
(name: string, fn?: AddMethodCallback|Function): Orchestrator;
}
/**
* Start running the tasks
*/
interface StartMethod {
/**
* Start running the tasks
* @param tasks Tasks to be executed. You may pass any number of tasks as individual arguments.
* @param cb Callback to call after run completed.
*/
(tasks: Strings, cb?: (error?: any) => any): Orchestrator;
/**
* Start running the tasks
* @param tasks Tasks to be executed. You may pass any number of tasks as individual arguments.
* @param cb Callback to call after run completed.
*/
(...tasks: Strings[]/*, cb?: (error: any) => any */): Orchestrator;
//TODO: TypeScript 1.5.3 cannot express varargs followed by callback as a last argument...
(task1: Strings, task2: Strings, cb?: (error?: any) => any): Orchestrator;
(task1: Strings, task2: Strings, task3: Strings, cb?: (error?: any) => any): Orchestrator;
(task1: Strings, task2: Strings, task3: Strings, task4: Strings, cb?: (error?: any) => any): Orchestrator;
(task1: Strings, task2: Strings, task3: Strings, task4: Strings, task5: Strings, cb?: (error?: any) => any): Orchestrator;
(task1: Strings, task2: Strings, task3: Strings, task4: Strings, task5: Strings, task6: Strings, cb?: (error?: any) => any): Orchestrator;
}
interface OnCallbackEvent {
message: string;
task: string;
err: any;
duration?: number;
}
interface OnAllCallbackEvent extends OnCallbackEvent {
src: string;
}
}
export = Orchestrator;
}

View file

@ -1,23 +0,0 @@
declare module 'pump' {
function f(
str1:NodeJS.WritableStream,
str2:NodeJS.WritableStream,
str3:NodeJS.WritableStream,
str4:NodeJS.WritableStream,
str5:NodeJS.WritableStream,
str6:NodeJS.WritableStream,
str7:NodeJS.WritableStream,
str8:NodeJS.WritableStream,
str9:NodeJS.WritableStream,
str10:NodeJS.WritableStream,
cb:(err:any)=>void
): NodeJS.WritableStream;
/**
* This is required as per:
* https://github.com/Microsoft/TypeScript/issues/5073
*/
namespace f {}
export = f;
}

View file

@ -1,17 +0,0 @@
// Type definitions for rimraf
// Project: https://github.com/isaacs/rimraf
// Definitions by: Carlos Ballesteros Velasco <https://github.com/soywiz>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// Imported from: https://github.com/soywiz/typescript-node-definitions/rimraf.d.ts
declare module "rimraf" {
function rimraf(path: string, callback: (error: Error) => void): void;
function rimraf(path: string, opts:{}, callback: (error: Error) => void): void;
namespace rimraf {
export function sync(path: string): void;
export var EMFILE_MAX: number;
export var BUSYTRIES_MAX: number;
}
export = rimraf;
}

View file

@ -1,91 +0,0 @@
// Type definitions for source-map v0.1.38
// Project: https://github.com/mozilla/source-map
// Definitions by: Morten Houston Ludvigsen <https://github.com/MortenHoustonLudvigsen>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
declare namespace SourceMap {
interface StartOfSourceMap {
file?: string;
sourceRoot?: string;
}
interface RawSourceMap extends StartOfSourceMap {
version: string|number;
sources: Array<string>;
names: Array<string>;
sourcesContent?: string[];
mappings: string;
}
interface Position {
line: number;
column: number;
}
interface MappedPosition extends Position {
source: string;
name?: string;
}
interface MappingItem {
source: string;
generatedLine: number;
generatedColumn: number;
originalLine: number;
originalColumn: number;
name: string;
}
interface Mapping {
generated: Position;
original: Position;
source: string;
name?: string;
}
interface CodeWithSourceMap {
code: string;
map: SourceMapGenerator;
}
class SourceMapConsumer {
public static GENERATED_ORDER: number;
public static ORIGINAL_ORDER: number;
constructor(rawSourceMap: RawSourceMap);
public originalPositionFor(generatedPosition: Position): MappedPosition;
public generatedPositionFor(originalPosition: MappedPosition): Position;
public sourceContentFor(source: string): string;
public eachMapping(callback: (mapping: MappingItem) => void, context?: any, order?: number): void;
}
class SourceMapGenerator {
constructor(startOfSourceMap?: StartOfSourceMap);
public static fromSourceMap(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator;
public addMapping(mapping: Mapping): void;
public setSourceContent(sourceFile: string, sourceContent: string): void;
public applySourceMap(sourceMapConsumer: SourceMapConsumer, sourceFile?: string, sourceMapPath?: string): void;
public toString(): string;
public toJSON(): RawSourceMap;
}
class SourceNode {
constructor();
constructor(line: number, column: number, source: string);
constructor(line: number, column: number, source: string, chunk?: string, name?: string);
public static fromStringWithSourceMap(code: string, sourceMapConsumer: SourceMapConsumer, relativePath?: string): SourceNode;
public add(chunk: any): SourceNode;
public prepend(chunk: any): SourceNode;
public setSourceContent(sourceFile: string, sourceContent: string): void;
public walk(fn: (chunk: string, mapping: MappedPosition) => void): void;
public walkSourceContents(fn: (file: string, content: string) => void): void;
public join(sep: string): SourceNode;
public replaceRight(pattern: string, replacement: string): SourceNode;
public toString(): string;
public toStringWithSourceMap(startOfSourceMap?: StartOfSourceMap): CodeWithSourceMap;
}
}
declare module 'source-map' {
export = SourceMap;
}

View file

@ -1,22 +0,0 @@
// Type definitions for through
// Project: https://github.com/dominictarr/through
// Definitions by: Andrew Gaspar <https://github.com/AndrewGaspar/>
// Definitions: https://github.com/borisyankov/DefinitelyTyped
declare module "through" {
import stream = require("stream");
function through(write?: (data:any) => void,
end?: () => void,
opts?: {
autoDestroy: boolean;
}): through.ThroughStream;
module through {
export interface ThroughStream extends stream.Transform {
autoDestroy: boolean;
}
}
export = through;
}

View file

@ -1,38 +0,0 @@
// Type definitions for through2 v 2.0.0
// Project: https://github.com/rvagg/through2
// Definitions by: Bart van der Schoor <https://github.com/Bartvds>, jedmao <https://github.com/jedmao>, Georgios Valotasios <https://github.com/valotas>, Ben Chauvette <https://github.com/bdchauvette>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
declare module 'through2' {
import stream = require('stream');
type TransformCallback = (err?: any, data?: any) => void;
type TransformFunction = (chunk: any, enc: string, callback: TransformCallback) => void;
type FlushCallback = (flushCallback: () => void) => void;
function through2(transform?: TransformFunction, flush?: FlushCallback): stream.Transform;
function through2(opts?: stream.DuplexOptions, transform?: TransformFunction, flush?: FlushCallback): stream.Transform;
namespace through2 {
export interface Through2Constructor extends stream.Transform {
new(opts?: stream.DuplexOptions): stream.Transform;
(opts?: stream.DuplexOptions): stream.Transform;
}
/**
* Convenvience method for creating object streams
*/
export function obj(transform?: TransformFunction, flush?: FlushCallback): stream.Transform;
/**
* Creates a constructor for a custom Transform. This is useful when you
* want to use the same transform logic in multiple instances.
*/
export function ctor(opts?: stream.DuplexOptions, transfrom?: TransformFunction, flush?: FlushCallback): Through2Constructor;
}
export = through2;
}

File diff suppressed because it is too large Load diff

View file

@ -4,29 +4,29 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var es = require("event-stream");
var debounce = require("debounce");
var _filter = require("gulp-filter");
var rename = require("gulp-rename");
var _ = require("underscore");
var path = require("path");
var fs = require("fs");
var _rimraf = require("rimraf");
var git = require("./git");
var VinylFile = require("vinyl");
var NoCancellationToken = { isCancellationRequested: function () { return false; } };
const es = require("event-stream");
const debounce = require("debounce");
const _filter = require("gulp-filter");
const rename = require("gulp-rename");
const _ = require("underscore");
const path = require("path");
const fs = require("fs");
const _rimraf = require("rimraf");
const git = require("./git");
const VinylFile = require("vinyl");
const NoCancellationToken = { isCancellationRequested: () => false };
function incremental(streamProvider, initial, supportsCancellation) {
var input = es.through();
var output = es.through();
var state = 'idle';
var buffer = Object.create(null);
var token = !supportsCancellation ? null : { isCancellationRequested: function () { return Object.keys(buffer).length > 0; } };
var run = function (input, isCancellable) {
const input = es.through();
const output = es.through();
let state = 'idle';
let buffer = Object.create(null);
const token = !supportsCancellation ? undefined : { isCancellationRequested: () => Object.keys(buffer).length > 0 };
const run = (input, isCancellable) => {
state = 'running';
var stream = !supportsCancellation ? streamProvider() : streamProvider(isCancellable ? token : NoCancellationToken);
const stream = !supportsCancellation ? streamProvider() : streamProvider(isCancellable ? token : NoCancellationToken);
input
.pipe(stream)
.pipe(es.through(null, function () {
.pipe(es.through(undefined, () => {
state = 'idle';
eventuallyRun();
}))
@ -35,16 +35,16 @@ function incremental(streamProvider, initial, supportsCancellation) {
if (initial) {
run(initial, false);
}
var eventuallyRun = debounce(function () {
var paths = Object.keys(buffer);
const eventuallyRun = debounce(() => {
const paths = Object.keys(buffer);
if (paths.length === 0) {
return;
}
var data = paths.map(function (path) { return buffer[path]; });
const data = paths.map(path => buffer[path]);
buffer = Object.create(null);
run(es.readArray(data), true);
}, 500);
input.on('data', function (f) {
input.on('data', (f) => {
buffer[f.path] = f;
if (state === 'idle') {
eventuallyRun();
@ -57,7 +57,7 @@ function fixWin32DirectoryPermissions() {
if (!/win32/.test(process.platform)) {
return es.through();
}
return es.mapSync(function (f) {
return es.mapSync(f => {
if (f.stat && f.stat.isDirectory && f.stat.isDirectory()) {
f.stat.mode = 16877;
}
@ -66,16 +66,16 @@ function fixWin32DirectoryPermissions() {
}
exports.fixWin32DirectoryPermissions = fixWin32DirectoryPermissions;
function setExecutableBit(pattern) {
var setBit = es.mapSync(function (f) {
const setBit = es.mapSync(f => {
f.stat.mode = /* 100755 */ 33261;
return f;
});
if (!pattern) {
return setBit;
}
var input = es.through();
var filter = _filter(pattern, { restore: true });
var output = input
const input = es.through();
const filter = _filter(pattern, { restore: true });
const output = input
.pipe(filter)
.pipe(setBit)
.pipe(filter.restore);
@ -83,7 +83,7 @@ function setExecutableBit(pattern) {
}
exports.setExecutableBit = setExecutableBit;
function toFileUri(filePath) {
var match = filePath.match(/^([a-z])\:(.*)$/i);
const match = filePath.match(/^([a-z])\:(.*)$/i);
if (match) {
filePath = '/' + match[1].toUpperCase() + ':' + match[2];
}
@ -91,7 +91,7 @@ function toFileUri(filePath) {
}
exports.toFileUri = toFileUri;
function skipDirectories() {
return es.mapSync(function (f) {
return es.mapSync(f => {
if (!f.isDirectory()) {
return f;
}
@ -99,15 +99,15 @@ function skipDirectories() {
}
exports.skipDirectories = skipDirectories;
function cleanNodeModule(name, excludes, includes) {
var toGlob = function (path) { return '**/node_modules/' + name + (path ? '/' + path : ''); };
var negate = function (str) { return '!' + str; };
var allFilter = _filter(toGlob('**'), { restore: true });
var globs = [toGlob('**')].concat(excludes.map(_.compose(negate, toGlob)));
var input = es.through();
var nodeModuleInput = input.pipe(allFilter);
var output = nodeModuleInput.pipe(_filter(globs));
const toGlob = (path) => '**/node_modules/' + name + (path ? '/' + path : '');
const negate = (str) => '!' + str;
const allFilter = _filter(toGlob('**'), { restore: true });
const globs = [toGlob('**')].concat(excludes.map(_.compose(negate, toGlob)));
const input = es.through();
const nodeModuleInput = input.pipe(allFilter);
let output = nodeModuleInput.pipe(_filter(globs));
if (includes) {
var includeGlobs = includes.map(toGlob);
const includeGlobs = includes.map(toGlob);
output = es.merge(output, nodeModuleInput.pipe(_filter(includeGlobs)));
}
output = output.pipe(allFilter.restore);
@ -115,51 +115,52 @@ function cleanNodeModule(name, excludes, includes) {
}
exports.cleanNodeModule = cleanNodeModule;
function loadSourcemaps() {
var input = es.through();
var output = input
.pipe(es.map(function (f, cb) {
const input = es.through();
const output = input
.pipe(es.map((f, cb) => {
if (f.sourceMap) {
cb(null, f);
cb(undefined, f);
return;
}
if (!f.contents) {
cb(new Error('empty file'));
return;
}
var contents = f.contents.toString('utf8');
var reg = /\/\/# sourceMappingURL=(.*)$/g;
var lastMatch = null, match = null;
const contents = f.contents.toString('utf8');
const reg = /\/\/# sourceMappingURL=(.*)$/g;
let lastMatch = null;
let match = null;
while (match = reg.exec(contents)) {
lastMatch = match;
}
if (!lastMatch) {
f.sourceMap = {
version: 3,
version: '3',
names: [],
mappings: '',
sources: [f.relative.replace(/\//g, '/')],
sourcesContent: [contents]
};
cb(null, f);
cb(undefined, f);
return;
}
f.contents = Buffer.from(contents.replace(/\/\/# sourceMappingURL=(.*)$/g, ''), 'utf8');
fs.readFile(path.join(path.dirname(f.path), lastMatch[1]), 'utf8', function (err, contents) {
fs.readFile(path.join(path.dirname(f.path), lastMatch[1]), 'utf8', (err, contents) => {
if (err) {
return cb(err);
}
f.sourceMap = JSON.parse(contents);
cb(null, f);
cb(undefined, f);
});
}));
return es.duplex(input, output);
}
exports.loadSourcemaps = loadSourcemaps;
function stripSourceMappingURL() {
var input = es.through();
var output = input
.pipe(es.mapSync(function (f) {
var contents = f.contents.toString('utf8');
const input = es.through();
const output = input
.pipe(es.mapSync(f => {
const contents = f.contents.toString('utf8');
f.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, ''), 'utf8');
return f;
}));
@ -167,23 +168,23 @@ function stripSourceMappingURL() {
}
exports.stripSourceMappingURL = stripSourceMappingURL;
function rimraf(dir) {
var retries = 0;
var retry = function (cb) {
_rimraf(dir, { maxBusyTries: 1 }, function (err) {
let retries = 0;
const retry = (cb) => {
_rimraf(dir, { maxBusyTries: 1 }, (err) => {
if (!err) {
return cb();
}
if (err.code === 'ENOTEMPTY' && ++retries < 5) {
return setTimeout(function () { return retry(cb); }, 10);
return setTimeout(() => retry(cb), 10);
}
return cb(err);
});
};
return function (cb) { return retry(cb); };
return cb => retry(cb);
}
exports.rimraf = rimraf;
function getVersion(root) {
var version = process.env['BUILD_SOURCEVERSION'];
let version = process.env['BUILD_SOURCEVERSION'];
if (!version || !/^[0-9a-f]{40}$/i.test(version)) {
version = git.getVersion(root);
}
@ -191,14 +192,14 @@ function getVersion(root) {
}
exports.getVersion = getVersion;
function rebase(count) {
return rename(function (f) {
var parts = f.dirname.split(/[\/\\]/);
return rename(f => {
const parts = f.dirname ? f.dirname.split(/[\/\\]/) : [];
f.dirname = parts.slice(count).join(path.sep);
});
}
exports.rebase = rebase;
function filter(fn) {
var result = es.through(function (data) {
const result = es.through(function (data) {
if (fn(data)) {
this.emit('data', data);
}
@ -211,8 +212,8 @@ function filter(fn) {
}
exports.filter = filter;
function versionStringToNumber(versionStr) {
var semverRegex = /(\d+)\.(\d+)\.(\d+)/;
var match = versionStr.match(semverRegex);
const semverRegex = /(\d+)\.(\d+)\.(\d+)/;
const match = versionStr.match(semverRegex);
if (!match) {
throw new Error('Version string is not properly formatted: ' + versionStr);
}

View file

@ -6,7 +6,7 @@
'use strict';
import * as es from 'event-stream';
import * as debounce from 'debounce';
import debounce = require('debounce');
import * as _filter from 'gulp-filter';
import * as rename from 'gulp-rename';
import * as _ from 'underscore';
@ -34,16 +34,16 @@ export function incremental(streamProvider: IStreamProvider, initial: NodeJS.Rea
let state = 'idle';
let buffer = Object.create(null);
const token: ICancellationToken = !supportsCancellation ? null : { isCancellationRequested: () => Object.keys(buffer).length > 0 };
const token: ICancellationToken | undefined = !supportsCancellation ? undefined : { isCancellationRequested: () => Object.keys(buffer).length > 0 };
const run = (input, isCancellable) => {
const run = (input: NodeJS.ReadWriteStream, isCancellable: boolean) => {
state = 'running';
const stream = !supportsCancellation ? streamProvider() : streamProvider(isCancellable ? token : NoCancellationToken);
input
.pipe(stream)
.pipe(es.through(null, () => {
.pipe(es.through(undefined, () => {
state = 'idle';
eventuallyRun();
}))
@ -92,7 +92,7 @@ export function fixWin32DirectoryPermissions(): NodeJS.ReadWriteStream {
}
export function setExecutableBit(pattern: string | string[]): NodeJS.ReadWriteStream {
var setBit = es.mapSync<VinylFile, VinylFile>(f => {
const setBit = es.mapSync<VinylFile, VinylFile>(f => {
f.stat.mode = /* 100755 */ 33261;
return f;
});
@ -101,9 +101,9 @@ export function setExecutableBit(pattern: string | string[]): NodeJS.ReadWriteSt
return setBit;
}
var input = es.through();
var filter = _filter(pattern, { restore: true });
var output = input
const input = es.through();
const filter = _filter(pattern, { restore: true });
const output = input
.pipe(filter)
.pipe(setBit)
.pipe(filter.restore);
@ -122,7 +122,7 @@ export function toFileUri(filePath: string): string {
}
export function skipDirectories(): NodeJS.ReadWriteStream {
return es.mapSync<VinylFile, VinylFile>(f => {
return es.mapSync<VinylFile, VinylFile | undefined>(f => {
if (!f.isDirectory()) {
return f;
}
@ -134,7 +134,7 @@ export function cleanNodeModule(name: string, excludes: string[], includes?: str
const negate = (str: string) => '!' + str;
const allFilter = _filter(toGlob('**'), { restore: true });
const globs = [toGlob('**')].concat(excludes.map(_.compose(negate, toGlob)));
const globs = [toGlob('**')].concat(excludes.map(_.compose(negate, toGlob) as (x: string) => string));
const input = es.through();
const nodeModuleInput = input.pipe(allFilter);
@ -157,9 +157,9 @@ export function loadSourcemaps(): NodeJS.ReadWriteStream {
const input = es.through();
const output = input
.pipe(es.map<FileSourceMap, FileSourceMap>((f, cb): FileSourceMap => {
.pipe(es.map<FileSourceMap, FileSourceMap | undefined>((f, cb): FileSourceMap | undefined => {
if (f.sourceMap) {
cb(null, f);
cb(undefined, f);
return;
}
@ -171,7 +171,8 @@ export function loadSourcemaps(): NodeJS.ReadWriteStream {
const contents = (<Buffer>f.contents).toString('utf8');
const reg = /\/\/# sourceMappingURL=(.*)$/g;
let lastMatch = null, match = null;
let lastMatch: RegExpMatchArray | null = null;
let match: RegExpMatchArray | null = null;
while (match = reg.exec(contents)) {
lastMatch = match;
@ -179,14 +180,14 @@ export function loadSourcemaps(): NodeJS.ReadWriteStream {
if (!lastMatch) {
f.sourceMap = {
version: 3,
version: '3',
names: [],
mappings: '',
sources: [f.relative.replace(/\//g, '/')],
sourcesContent: [contents]
};
cb(null, f);
cb(undefined, f);
return;
}
@ -196,7 +197,7 @@ export function loadSourcemaps(): NodeJS.ReadWriteStream {
if (err) { return cb(err); }
f.sourceMap = JSON.parse(contents);
cb(null, f);
cb(undefined, f);
});
}));
@ -219,7 +220,7 @@ export function stripSourceMappingURL(): NodeJS.ReadWriteStream {
export function rimraf(dir: string): (cb: any) => void {
let retries = 0;
const retry = cb => {
const retry = (cb: (err?: any) => void) => {
_rimraf(dir, { maxBusyTries: 1 }, (err: any) => {
if (!err) {
return cb();
@ -236,7 +237,7 @@ export function rimraf(dir: string): (cb: any) => void {
return cb => retry(cb);
}
export function getVersion(root: string): string {
export function getVersion(root: string): string | undefined {
let version = process.env['BUILD_SOURCEVERSION'];
if (!version || !/^[0-9a-f]{40}$/i.test(version)) {
@ -248,7 +249,7 @@ export function getVersion(root: string): string {
export function rebase(count: number): NodeJS.ReadWriteStream {
return rename(f => {
const parts = f.dirname.split(/[\/\\]/);
const parts = f.dirname ? f.dirname.split(/[\/\\]/) : [];
f.dirname = parts.slice(count).join(path.sep);
});
}

File diff suppressed because it is too large Load diff

View file

@ -4,30 +4,22 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
var fs = require("fs");
var ts = require("typescript");
var path = require("path");
var tsfmt = require('../../tsfmt.json');
var util = require('gulp-util');
function log(message) {
var rest = [];
for (var _i = 1; _i < arguments.length; _i++) {
rest[_i - 1] = arguments[_i];
}
util.log.apply(util, [util.colors.cyan('[monaco.d.ts]'), message].concat(rest));
const fs = require("fs");
const ts = require("typescript");
const path = require("path");
const util = require("gulp-util");
const tsfmt = require('../../tsfmt.json');
function log(message, ...rest) {
util.log(util.colors.cyan('[monaco.d.ts]'), message, ...rest);
}
var SRC = path.join(__dirname, '../../src');
var OUT_ROOT = path.join(__dirname, '../../');
var RECIPE_PATH = path.join(__dirname, './monaco.d.ts.recipe');
var DECLARATION_PATH = path.join(__dirname, '../../src/vs/monaco.d.ts');
const SRC = path.join(__dirname, '../../src');
const OUT_ROOT = path.join(__dirname, '../../');
exports.RECIPE_PATH = path.join(__dirname, './monaco.d.ts.recipe');
const DECLARATION_PATH = path.join(__dirname, '../../src/vs/monaco.d.ts');
var CURRENT_PROCESSING_RULE = '';
function logErr(message) {
var rest = [];
for (var _i = 1; _i < arguments.length; _i++) {
rest[_i - 1] = arguments[_i];
}
function logErr(message, ...rest) {
util.log(util.colors.red('[monaco.d.ts]'), 'WHILE HANDLING RULE: ', CURRENT_PROCESSING_RULE);
util.log.apply(util, [util.colors.red('[monaco.d.ts]'), message].concat(rest));
util.log(util.colors.red('[monaco.d.ts]'), message, ...rest);
}
function moduleIdToPath(out, moduleId) {
if (/\.d\.ts/.test(moduleId)) {
@ -35,20 +27,6 @@ function moduleIdToPath(out, moduleId) {
}
return path.join(OUT_ROOT, out, moduleId) + '.d.ts';
}
var SOURCE_FILE_MAP = {};
function getSourceFile(out, inputFiles, moduleId) {
if (!SOURCE_FILE_MAP[moduleId]) {
var filePath = path.normalize(moduleIdToPath(out, moduleId));
if (!inputFiles.hasOwnProperty(filePath)) {
logErr('CANNOT FIND FILE ' + filePath + '. YOU MIGHT NEED TO RESTART gulp');
return null;
}
var fileContents = inputFiles[filePath];
var sourceFile = ts.createSourceFile(filePath, fileContents, ts.ScriptTarget.ES5);
SOURCE_FILE_MAP[moduleId] = sourceFile;
}
return SOURCE_FILE_MAP[moduleId];
}
function isDeclaration(a) {
return (a.kind === ts.SyntaxKind.InterfaceDeclaration
|| a.kind === ts.SyntaxKind.EnumDeclaration
@ -58,8 +36,8 @@ function isDeclaration(a) {
|| a.kind === ts.SyntaxKind.ModuleDeclaration);
}
function visitTopLevelDeclarations(sourceFile, visitor) {
var stop = false;
var visit = function (node) {
let stop = false;
let visit = (node) => {
if (stop) {
return;
}
@ -73,12 +51,6 @@ function visitTopLevelDeclarations(sourceFile, visitor) {
case ts.SyntaxKind.ModuleDeclaration:
stop = visitor(node);
}
// if (node.kind !== ts.SyntaxKind.SourceFile) {
// if (getNodeText(sourceFile, node).indexOf('SymbolKind') >= 0) {
// console.log('FOUND TEXT IN NODE: ' + ts.SyntaxKind[node.kind]);
// console.log(getNodeText(sourceFile, node));
// }
// }
if (stop) {
return;
}
@ -87,23 +59,19 @@ function visitTopLevelDeclarations(sourceFile, visitor) {
visit(sourceFile);
}
function getAllTopLevelDeclarations(sourceFile) {
var all = [];
visitTopLevelDeclarations(sourceFile, function (node) {
let all = [];
visitTopLevelDeclarations(sourceFile, (node) => {
if (node.kind === ts.SyntaxKind.InterfaceDeclaration || node.kind === ts.SyntaxKind.ClassDeclaration || node.kind === ts.SyntaxKind.ModuleDeclaration) {
var interfaceDeclaration = node;
var triviaStart = interfaceDeclaration.pos;
var triviaEnd = interfaceDeclaration.name.pos;
var triviaText = getNodeText(sourceFile, { pos: triviaStart, end: triviaEnd });
// // let nodeText = getNodeText(sourceFile, node);
// if (getNodeText(sourceFile, node).indexOf('SymbolKind') >= 0) {
// console.log('TRIVIA: ', triviaText);
// }
let interfaceDeclaration = node;
let triviaStart = interfaceDeclaration.pos;
let triviaEnd = interfaceDeclaration.name.pos;
let triviaText = getNodeText(sourceFile, { pos: triviaStart, end: triviaEnd });
if (triviaText.indexOf('@internal') === -1) {
all.push(node);
}
}
else {
var nodeText = getNodeText(sourceFile, node);
let nodeText = getNodeText(sourceFile, node);
if (nodeText.indexOf('@internal') === -1) {
all.push(node);
}
@ -113,9 +81,9 @@ function getAllTopLevelDeclarations(sourceFile) {
return all;
}
function getTopLevelDeclaration(sourceFile, typeName) {
var result = null;
visitTopLevelDeclarations(sourceFile, function (node) {
if (isDeclaration(node)) {
let result = null;
visitTopLevelDeclarations(sourceFile, (node) => {
if (isDeclaration(node) && node.name) {
if (node.name.text === typeName) {
result = node;
return true /*stop*/;
@ -136,8 +104,8 @@ function getNodeText(sourceFile, node) {
}
function hasModifier(modifiers, kind) {
if (modifiers) {
for (var i = 0; i < modifiers.length; i++) {
var mod = modifiers[i];
for (let i = 0; i < modifiers.length; i++) {
let mod = modifiers[i];
if (mod.kind === kind) {
return true;
}
@ -152,42 +120,36 @@ function isDefaultExport(declaration) {
return (hasModifier(declaration.modifiers, ts.SyntaxKind.DefaultKeyword)
&& hasModifier(declaration.modifiers, ts.SyntaxKind.ExportKeyword));
}
function getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage) {
var result = getNodeText(sourceFile, declaration);
// if (result.indexOf('MonacoWorker') >= 0) {
// console.log('here!');
// // console.log(ts.SyntaxKind[declaration.kind]);
// }
function getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage, enums) {
let result = getNodeText(sourceFile, declaration);
if (declaration.kind === ts.SyntaxKind.InterfaceDeclaration || declaration.kind === ts.SyntaxKind.ClassDeclaration) {
var interfaceDeclaration = declaration;
var staticTypeName_1 = (isDefaultExport(interfaceDeclaration)
? importName + ".default"
: importName + "." + declaration.name.text);
var instanceTypeName_1 = staticTypeName_1;
var typeParametersCnt = (interfaceDeclaration.typeParameters ? interfaceDeclaration.typeParameters.length : 0);
let interfaceDeclaration = declaration;
const staticTypeName = (isDefaultExport(interfaceDeclaration)
? `${importName}.default`
: `${importName}.${declaration.name.text}`);
let instanceTypeName = staticTypeName;
const typeParametersCnt = (interfaceDeclaration.typeParameters ? interfaceDeclaration.typeParameters.length : 0);
if (typeParametersCnt > 0) {
var arr = [];
for (var i = 0; i < typeParametersCnt; i++) {
let arr = [];
for (let i = 0; i < typeParametersCnt; i++) {
arr.push('any');
}
instanceTypeName_1 = instanceTypeName_1 + "<" + arr.join(',') + ">";
instanceTypeName = `${instanceTypeName}<${arr.join(',')}>`;
}
var members = interfaceDeclaration.members;
members.forEach(function (member) {
const members = interfaceDeclaration.members;
members.forEach((member) => {
try {
var memberText = getNodeText(sourceFile, member);
let memberText = getNodeText(sourceFile, member);
if (memberText.indexOf('@internal') >= 0 || memberText.indexOf('private') >= 0) {
// console.log('BEFORE: ', result);
result = result.replace(memberText, '');
// console.log('AFTER: ', result);
}
else {
var memberName = member.name.text;
const memberName = member.name.text;
if (isStatic(member)) {
usage.push("a = " + staticTypeName_1 + "." + memberName + ";");
usage.push(`a = ${staticTypeName}.${memberName};`);
}
else {
usage.push("a = (<" + instanceTypeName_1 + ">b)." + memberName + ";");
usage.push(`a = (<${instanceTypeName}>b).${memberName};`);
}
}
}
@ -198,15 +160,115 @@ function getMassagedTopLevelDeclarationText(sourceFile, declaration, importName,
}
result = result.replace(/export default/g, 'export');
result = result.replace(/export declare/g, 'export');
if (declaration.kind === ts.SyntaxKind.EnumDeclaration) {
result = result.replace(/const enum/, 'enum');
enums.push(result);
}
return result;
}
function format(text) {
function format(text, endl) {
const REALLY_FORMAT = false;
text = preformat(text, endl);
if (!REALLY_FORMAT) {
return text;
}
// Parse the source text
var sourceFile = ts.createSourceFile('file.ts', text, ts.ScriptTarget.Latest, /*setParentPointers*/ true);
let sourceFile = ts.createSourceFile('file.ts', text, ts.ScriptTarget.Latest, /*setParentPointers*/ true);
// Get the formatting edits on the input sources
var edits = ts.formatting.formatDocument(sourceFile, getRuleProvider(tsfmt), tsfmt);
let edits = ts.formatting.formatDocument(sourceFile, getRuleProvider(tsfmt), tsfmt);
// Apply the edits on the input code
return applyEdits(text, edits);
function countParensCurly(text) {
let cnt = 0;
for (let i = 0; i < text.length; i++) {
if (text.charAt(i) === '(' || text.charAt(i) === '{') {
cnt++;
}
if (text.charAt(i) === ')' || text.charAt(i) === '}') {
cnt--;
}
}
return cnt;
}
function repeatStr(s, cnt) {
let r = '';
for (let i = 0; i < cnt; i++) {
r += s;
}
return r;
}
function preformat(text, endl) {
let lines = text.split(endl);
let inComment = false;
let inCommentDeltaIndent = 0;
let indent = 0;
for (let i = 0; i < lines.length; i++) {
let line = lines[i].replace(/\s$/, '');
let repeat = false;
let lineIndent = 0;
do {
repeat = false;
if (line.substring(0, 4) === ' ') {
line = line.substring(4);
lineIndent++;
repeat = true;
}
if (line.charAt(0) === '\t') {
line = line.substring(1);
lineIndent++;
repeat = true;
}
} while (repeat);
if (line.length === 0) {
continue;
}
if (inComment) {
if (/\*\//.test(line)) {
inComment = false;
}
lines[i] = repeatStr('\t', lineIndent + inCommentDeltaIndent) + line;
continue;
}
if (/\/\*/.test(line)) {
inComment = true;
inCommentDeltaIndent = indent - lineIndent;
lines[i] = repeatStr('\t', indent) + line;
continue;
}
const cnt = countParensCurly(line);
let shouldUnindentAfter = false;
let shouldUnindentBefore = false;
if (cnt < 0) {
if (/[({]/.test(line)) {
shouldUnindentAfter = true;
}
else {
shouldUnindentBefore = true;
}
}
else if (cnt === 0) {
shouldUnindentBefore = /^\}/.test(line);
}
let shouldIndentAfter = false;
if (cnt > 0) {
shouldIndentAfter = true;
}
else if (cnt === 0) {
shouldIndentAfter = /{$/.test(line);
}
if (shouldUnindentBefore) {
indent--;
}
lines[i] = repeatStr('\t', indent) + line;
if (shouldUnindentAfter) {
indent--;
}
if (shouldIndentAfter) {
indent++;
}
}
return lines.join(endl);
}
function getRuleProvider(options) {
// Share this between multiple formatters using the same options.
// This represents the bulk of the space the formatter uses.
@ -214,11 +276,11 @@ function format(text) {
}
function applyEdits(text, edits) {
// Apply edits in reverse on the existing text
var result = text;
for (var i = edits.length - 1; i >= 0; i--) {
var change = edits[i];
var head = result.slice(0, change.span.start);
var tail = result.slice(change.span.start + change.span.length);
let result = text;
for (let i = edits.length - 1; i >= 0; i--) {
let change = edits[i];
let head = result.slice(0, change.span.start);
let tail = result.slice(change.span.start + change.span.length);
result = head + change.newText + tail;
}
return result;
@ -226,186 +288,223 @@ function format(text) {
}
function createReplacer(data) {
data = data || '';
var rawDirectives = data.split(';');
var directives = [];
rawDirectives.forEach(function (rawDirective) {
let rawDirectives = data.split(';');
let directives = [];
rawDirectives.forEach((rawDirective) => {
if (rawDirective.length === 0) {
return;
}
var pieces = rawDirective.split('=>');
var findStr = pieces[0];
var replaceStr = pieces[1];
let pieces = rawDirective.split('=>');
let findStr = pieces[0];
let replaceStr = pieces[1];
findStr = findStr.replace(/[\-\\\{\}\*\+\?\|\^\$\.\,\[\]\(\)\#\s]/g, '\\$&');
findStr = '\\b' + findStr + '\\b';
directives.push([new RegExp(findStr, 'g'), replaceStr]);
});
return function (str) {
for (var i = 0; i < directives.length; i++) {
return (str) => {
for (let i = 0; i < directives.length; i++) {
str = str.replace(directives[i][0], directives[i][1]);
}
return str;
};
}
function generateDeclarationFile(out, inputFiles, recipe) {
var endl = /\r\n/.test(recipe) ? '\r\n' : '\n';
var lines = recipe.split(endl);
var result = [];
var usageCounter = 0;
var usageImports = [];
var usage = [];
usage.push("var a;");
usage.push("var b;");
var generateUsageImport = function (moduleId) {
var importName = 'm' + (++usageCounter);
usageImports.push("import * as " + importName + " from '" + moduleId.replace(/\.d\.ts$/, '') + "';");
function generateDeclarationFile(recipe, sourceFileGetter) {
const endl = /\r\n/.test(recipe) ? '\r\n' : '\n';
let lines = recipe.split(endl);
let result = [];
let usageCounter = 0;
let usageImports = [];
let usage = [];
usage.push(`var a;`);
usage.push(`var b;`);
const generateUsageImport = (moduleId) => {
let importName = 'm' + (++usageCounter);
usageImports.push(`import * as ${importName} from './${moduleId.replace(/\.d\.ts$/, '')}';`);
return importName;
};
lines.forEach(function (line) {
var m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
let enums = [];
lines.forEach(line => {
let m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
if (m1) {
CURRENT_PROCESSING_RULE = line;
var moduleId = m1[1];
var sourceFile_1 = getSourceFile(out, inputFiles, moduleId);
if (!sourceFile_1) {
let moduleId = m1[1];
const sourceFile = sourceFileGetter(moduleId);
if (!sourceFile) {
return;
}
var importName_1 = generateUsageImport(moduleId);
var replacer_1 = createReplacer(m1[2]);
var typeNames = m1[3].split(/,/);
typeNames.forEach(function (typeName) {
const importName = generateUsageImport(moduleId);
let replacer = createReplacer(m1[2]);
let typeNames = m1[3].split(/,/);
typeNames.forEach((typeName) => {
typeName = typeName.trim();
if (typeName.length === 0) {
return;
}
var declaration = getTopLevelDeclaration(sourceFile_1, typeName);
let declaration = getTopLevelDeclaration(sourceFile, typeName);
if (!declaration) {
logErr('Cannot find type ' + typeName);
return;
}
result.push(replacer_1(getMassagedTopLevelDeclarationText(sourceFile_1, declaration, importName_1, usage)));
result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage, enums)));
});
return;
}
var m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
let m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
if (m2) {
CURRENT_PROCESSING_RULE = line;
var moduleId = m2[1];
var sourceFile_2 = getSourceFile(out, inputFiles, moduleId);
if (!sourceFile_2) {
let moduleId = m2[1];
const sourceFile = sourceFileGetter(moduleId);
if (!sourceFile) {
return;
}
var importName_2 = generateUsageImport(moduleId);
var replacer_2 = createReplacer(m2[2]);
var typeNames = m2[3].split(/,/);
var typesToExcludeMap_1 = {};
var typesToExcludeArr_1 = [];
typeNames.forEach(function (typeName) {
const importName = generateUsageImport(moduleId);
let replacer = createReplacer(m2[2]);
let typeNames = m2[3].split(/,/);
let typesToExcludeMap = {};
let typesToExcludeArr = [];
typeNames.forEach((typeName) => {
typeName = typeName.trim();
if (typeName.length === 0) {
return;
}
typesToExcludeMap_1[typeName] = true;
typesToExcludeArr_1.push(typeName);
typesToExcludeMap[typeName] = true;
typesToExcludeArr.push(typeName);
});
getAllTopLevelDeclarations(sourceFile_2).forEach(function (declaration) {
if (isDeclaration(declaration)) {
if (typesToExcludeMap_1[declaration.name.text]) {
getAllTopLevelDeclarations(sourceFile).forEach((declaration) => {
if (isDeclaration(declaration) && declaration.name) {
if (typesToExcludeMap[declaration.name.text]) {
return;
}
}
else {
// node is ts.VariableStatement
var nodeText = getNodeText(sourceFile_2, declaration);
for (var i = 0; i < typesToExcludeArr_1.length; i++) {
if (nodeText.indexOf(typesToExcludeArr_1[i]) >= 0) {
let nodeText = getNodeText(sourceFile, declaration);
for (let i = 0; i < typesToExcludeArr.length; i++) {
if (nodeText.indexOf(typesToExcludeArr[i]) >= 0) {
return;
}
}
}
result.push(replacer_2(getMassagedTopLevelDeclarationText(sourceFile_2, declaration, importName_2, usage)));
result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage, enums)));
});
return;
}
result.push(line);
});
var resultTxt = result.join(endl);
let resultTxt = result.join(endl);
resultTxt = resultTxt.replace(/\bURI\b/g, 'Uri');
resultTxt = resultTxt.replace(/\bEvent</g, 'IEvent<');
resultTxt = resultTxt.replace(/\bTPromise</g, 'Promise<');
resultTxt = format(resultTxt);
resultTxt = format(resultTxt, endl);
let resultEnums = [
'/*---------------------------------------------------------------------------------------------',
' * Copyright (c) Microsoft Corporation. All rights reserved.',
' * Licensed under the MIT License. See License.txt in the project root for license information.',
' *--------------------------------------------------------------------------------------------*/',
'',
'// THIS IS A GENERATED FILE. DO NOT EDIT DIRECTLY.',
''
].concat(enums).join(endl);
resultEnums = format(resultEnums, endl);
return [
resultTxt,
usageImports.join('\n') + "\n\n" + usage.join('\n')
`${usageImports.join('\n')}\n\n${usage.join('\n')}`,
resultEnums
];
}
function getIncludesInRecipe() {
var recipe = fs.readFileSync(RECIPE_PATH).toString();
var lines = recipe.split(/\r\n|\n|\r/);
var result = [];
lines.forEach(function (line) {
var m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
let recipe = fs.readFileSync(exports.RECIPE_PATH).toString();
let lines = recipe.split(/\r\n|\n|\r/);
let result = [];
lines.forEach(line => {
let m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
if (m1) {
var moduleId = m1[1];
let moduleId = m1[1];
result.push(moduleId);
return;
}
var m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
let m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
if (m2) {
var moduleId = m2[1];
let moduleId = m2[1];
result.push(moduleId);
return;
}
});
return result;
}
exports.getIncludesInRecipe = getIncludesInRecipe;
function getFilesToWatch(out) {
return getIncludesInRecipe().map(function (moduleId) { return moduleIdToPath(out, moduleId); });
return getIncludesInRecipe().map((moduleId) => moduleIdToPath(out, moduleId));
}
exports.getFilesToWatch = getFilesToWatch;
function run(out, inputFiles) {
function _run(sourceFileGetter) {
log('Starting monaco.d.ts generation');
SOURCE_FILE_MAP = {};
var recipe = fs.readFileSync(RECIPE_PATH).toString();
var _a = generateDeclarationFile(out, inputFiles, recipe), result = _a[0], usageContent = _a[1];
var currentContent = fs.readFileSync(DECLARATION_PATH).toString();
const recipe = fs.readFileSync(exports.RECIPE_PATH).toString();
const [result, usageContent, enums] = generateDeclarationFile(recipe, sourceFileGetter);
const currentContent = fs.readFileSync(DECLARATION_PATH).toString();
const one = currentContent.replace(/\r\n/gm, '\n');
const other = result.replace(/\r\n/gm, '\n');
const isTheSame = (one === other);
log('Finished monaco.d.ts generation');
var one = currentContent.replace(/\r\n/gm, '\n');
var other = result.replace(/\r\n/gm, '\n');
var isTheSame = one === other;
return {
content: result,
usageContent: usageContent,
enums: enums,
filePath: DECLARATION_PATH,
isTheSame: isTheSame
isTheSame
};
}
function run(out, inputFiles) {
let SOURCE_FILE_MAP = {};
const sourceFileGetter = (moduleId) => {
if (!SOURCE_FILE_MAP[moduleId]) {
let filePath = path.normalize(moduleIdToPath(out, moduleId));
if (!inputFiles.hasOwnProperty(filePath)) {
logErr('CANNOT FIND FILE ' + filePath + '. YOU MIGHT NEED TO RESTART gulp');
return null;
}
let fileContents = inputFiles[filePath];
let sourceFile = ts.createSourceFile(filePath, fileContents, ts.ScriptTarget.ES5);
SOURCE_FILE_MAP[moduleId] = sourceFile;
}
return SOURCE_FILE_MAP[moduleId];
};
return _run(sourceFileGetter);
}
exports.run = run;
function run2(out, sourceFileMap) {
const sourceFileGetter = (moduleId) => {
let filePath = path.normalize(moduleIdToPath(out, moduleId));
return sourceFileMap[filePath];
};
return _run(sourceFileGetter);
}
exports.run2 = run2;
function complainErrors() {
logErr('Not running monaco.d.ts generation due to compile errors');
}
exports.complainErrors = complainErrors;
var TypeScriptLanguageServiceHost = /** @class */ (function () {
function TypeScriptLanguageServiceHost(libs, files, compilerOptions) {
class TypeScriptLanguageServiceHost {
constructor(libs, files, compilerOptions) {
this._libs = libs;
this._files = files;
this._compilerOptions = compilerOptions;
}
// --- language service host ---------------
TypeScriptLanguageServiceHost.prototype.getCompilationSettings = function () {
getCompilationSettings() {
return this._compilerOptions;
};
TypeScriptLanguageServiceHost.prototype.getScriptFileNames = function () {
}
getScriptFileNames() {
return ([]
.concat(Object.keys(this._libs))
.concat(Object.keys(this._files)));
};
TypeScriptLanguageServiceHost.prototype.getScriptVersion = function (fileName) {
}
getScriptVersion(_fileName) {
return '1';
};
TypeScriptLanguageServiceHost.prototype.getProjectVersion = function () {
}
getProjectVersion() {
return '1';
};
TypeScriptLanguageServiceHost.prototype.getScriptSnapshot = function (fileName) {
}
getScriptSnapshot(fileName) {
if (this._files.hasOwnProperty(fileName)) {
return ts.ScriptSnapshot.fromString(this._files[fileName]);
}
@ -415,47 +514,42 @@ var TypeScriptLanguageServiceHost = /** @class */ (function () {
else {
return ts.ScriptSnapshot.fromString('');
}
};
TypeScriptLanguageServiceHost.prototype.getScriptKind = function (fileName) {
}
getScriptKind(_fileName) {
return ts.ScriptKind.TS;
};
TypeScriptLanguageServiceHost.prototype.getCurrentDirectory = function () {
}
getCurrentDirectory() {
return '';
};
TypeScriptLanguageServiceHost.prototype.getDefaultLibFileName = function (options) {
}
getDefaultLibFileName(_options) {
return 'defaultLib:es5';
};
TypeScriptLanguageServiceHost.prototype.isDefaultLibFileName = function (fileName) {
}
isDefaultLibFileName(fileName) {
return fileName === this.getDefaultLibFileName(this._compilerOptions);
};
return TypeScriptLanguageServiceHost;
}());
}
}
exports.TypeScriptLanguageServiceHost = TypeScriptLanguageServiceHost;
function execute() {
var OUTPUT_FILES = {};
var SRC_FILES = {};
var SRC_FILE_TO_EXPECTED_NAME = {};
getIncludesInRecipe().forEach(function (moduleId) {
const OUTPUT_FILES = {};
const SRC_FILES = {};
const SRC_FILE_TO_EXPECTED_NAME = {};
getIncludesInRecipe().forEach((moduleId) => {
if (/\.d\.ts$/.test(moduleId)) {
var fileName_1 = path.join(SRC, moduleId);
OUTPUT_FILES[moduleIdToPath('src', moduleId)] = fs.readFileSync(fileName_1).toString();
let fileName = path.join(SRC, moduleId);
OUTPUT_FILES[moduleIdToPath('src', moduleId)] = fs.readFileSync(fileName).toString();
return;
}
var fileName = path.join(SRC, moduleId) + '.ts';
let fileName = path.join(SRC, moduleId) + '.ts';
SRC_FILES[fileName] = fs.readFileSync(fileName).toString();
SRC_FILE_TO_EXPECTED_NAME[fileName] = moduleIdToPath('src', moduleId);
});
var languageService = ts.createLanguageService(new TypeScriptLanguageServiceHost({}, SRC_FILES, {}));
const languageService = ts.createLanguageService(new TypeScriptLanguageServiceHost({}, SRC_FILES, {}));
var t1 = Date.now();
Object.keys(SRC_FILES).forEach(function (fileName) {
var t = Date.now();
var emitOutput = languageService.getEmitOutput(fileName, true);
Object.keys(SRC_FILES).forEach((fileName) => {
const emitOutput = languageService.getEmitOutput(fileName, true);
OUTPUT_FILES[SRC_FILE_TO_EXPECTED_NAME[fileName]] = emitOutput.outputFiles[0].text;
// console.log(`Generating .d.ts for ${fileName} took ${Date.now() - t} ms`);
});
console.log("Generating .d.ts took " + (Date.now() - t1) + " ms");
// console.log(result.filePath);
// fs.writeFileSync(result.filePath, result.content.replace(/\r\n/gm, '\n'));
// fs.writeFileSync(path.join(SRC, 'user.ts'), result.usageContent.replace(/\r\n/gm, '\n'));
console.log(`Generating .d.ts took ${Date.now() - t1} ms`);
return run('src', OUTPUT_FILES);
}
exports.execute = execute;

View file

@ -3,19 +3,20 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import fs = require('fs');
import ts = require('typescript');
import path = require('path');
import * as fs from 'fs';
import * as ts from 'typescript';
import * as path from 'path';
import * as util from 'gulp-util';
const tsfmt = require('../../tsfmt.json');
var util = require('gulp-util');
function log(message: any, ...rest: any[]): void {
util.log(util.colors.cyan('[monaco.d.ts]'), message, ...rest);
}
const SRC = path.join(__dirname, '../../src');
const OUT_ROOT = path.join(__dirname, '../../');
const RECIPE_PATH = path.join(__dirname, './monaco.d.ts.recipe');
export const RECIPE_PATH = path.join(__dirname, './monaco.d.ts.recipe');
const DECLARATION_PATH = path.join(__dirname, '../../src/vs/monaco.d.ts');
var CURRENT_PROCESSING_RULE = '';
@ -31,24 +32,10 @@ function moduleIdToPath(out: string, moduleId: string): string {
return path.join(OUT_ROOT, out, moduleId) + '.d.ts';
}
let SOURCE_FILE_MAP: { [moduleId: string]: ts.SourceFile; } = {};
function getSourceFile(out: string, inputFiles: { [file: string]: string; }, moduleId: string): ts.SourceFile {
if (!SOURCE_FILE_MAP[moduleId]) {
let filePath = path.normalize(moduleIdToPath(out, moduleId));
if (!inputFiles.hasOwnProperty(filePath)) {
logErr('CANNOT FIND FILE ' + filePath + '. YOU MIGHT NEED TO RESTART gulp');
return null;
}
let fileContents = inputFiles[filePath];
let sourceFile = ts.createSourceFile(filePath, fileContents, ts.ScriptTarget.ES5);
SOURCE_FILE_MAP[moduleId] = sourceFile;
}
return SOURCE_FILE_MAP[moduleId];
export interface ISourceFileMap {
[moduleId: string]: ts.SourceFile;
}
export type SourceFileGetter = (moduleId: string) => ts.SourceFile | null;
type TSTopLevelDeclaration = ts.InterfaceDeclaration | ts.EnumDeclaration | ts.ClassDeclaration | ts.TypeAliasDeclaration | ts.FunctionDeclaration | ts.ModuleDeclaration;
type TSTopLevelDeclare = TSTopLevelDeclaration | ts.VariableStatement;
@ -83,13 +70,6 @@ function visitTopLevelDeclarations(sourceFile: ts.SourceFile, visitor: (node: TS
stop = visitor(<TSTopLevelDeclare>node);
}
// if (node.kind !== ts.SyntaxKind.SourceFile) {
// if (getNodeText(sourceFile, node).indexOf('SymbolKind') >= 0) {
// console.log('FOUND TEXT IN NODE: ' + ts.SyntaxKind[node.kind]);
// console.log(getNodeText(sourceFile, node));
// }
// }
if (stop) {
return;
}
@ -109,10 +89,6 @@ function getAllTopLevelDeclarations(sourceFile: ts.SourceFile): TSTopLevelDeclar
let triviaEnd = interfaceDeclaration.name.pos;
let triviaText = getNodeText(sourceFile, { pos: triviaStart, end: triviaEnd });
// // let nodeText = getNodeText(sourceFile, node);
// if (getNodeText(sourceFile, node).indexOf('SymbolKind') >= 0) {
// console.log('TRIVIA: ', triviaText);
// }
if (triviaText.indexOf('@internal') === -1) {
all.push(node);
}
@ -128,10 +104,10 @@ function getAllTopLevelDeclarations(sourceFile: ts.SourceFile): TSTopLevelDeclar
}
function getTopLevelDeclaration(sourceFile: ts.SourceFile, typeName: string): TSTopLevelDeclare {
let result: TSTopLevelDeclare = null;
function getTopLevelDeclaration(sourceFile: ts.SourceFile, typeName: string): TSTopLevelDeclare | null {
let result: TSTopLevelDeclare | null = null;
visitTopLevelDeclarations(sourceFile, (node) => {
if (isDeclaration(node)) {
if (isDeclaration(node) && node.name) {
if (node.name.text === typeName) {
result = node;
return true /*stop*/;
@ -153,7 +129,7 @@ function getNodeText(sourceFile: ts.SourceFile, node: { pos: number; end: number
return sourceFile.getFullText().substring(node.pos, node.end);
}
function hasModifier(modifiers: ts.NodeArray<ts.Modifier>, kind: ts.SyntaxKind): boolean {
function hasModifier(modifiers: ts.NodeArray<ts.Modifier> | undefined, kind: ts.SyntaxKind): boolean {
if (modifiers) {
for (let i = 0; i < modifiers.length; i++) {
let mod = modifiers[i];
@ -176,19 +152,15 @@ function isDefaultExport(declaration: ts.InterfaceDeclaration | ts.ClassDeclarat
);
}
function getMassagedTopLevelDeclarationText(sourceFile: ts.SourceFile, declaration: TSTopLevelDeclare, importName: string, usage: string[]): string {
function getMassagedTopLevelDeclarationText(sourceFile: ts.SourceFile, declaration: TSTopLevelDeclare, importName: string, usage: string[], enums: string[]): string {
let result = getNodeText(sourceFile, declaration);
// if (result.indexOf('MonacoWorker') >= 0) {
// console.log('here!');
// // console.log(ts.SyntaxKind[declaration.kind]);
// }
if (declaration.kind === ts.SyntaxKind.InterfaceDeclaration || declaration.kind === ts.SyntaxKind.ClassDeclaration) {
let interfaceDeclaration = <ts.InterfaceDeclaration | ts.ClassDeclaration>declaration;
const staticTypeName = (
isDefaultExport(interfaceDeclaration)
? `${importName}.default`
: `${importName}.${declaration.name.text}`
: `${importName}.${declaration.name!.text}`
);
let instanceTypeName = staticTypeName;
@ -206,9 +178,7 @@ function getMassagedTopLevelDeclarationText(sourceFile: ts.SourceFile, declarati
try {
let memberText = getNodeText(sourceFile, member);
if (memberText.indexOf('@internal') >= 0 || memberText.indexOf('private') >= 0) {
// console.log('BEFORE: ', result);
result = result.replace(memberText, '');
// console.log('AFTER: ', result);
} else {
const memberName = (<ts.Identifier | ts.StringLiteral>member.name).text;
if (isStatic(member)) {
@ -224,10 +194,22 @@ function getMassagedTopLevelDeclarationText(sourceFile: ts.SourceFile, declarati
}
result = result.replace(/export default/g, 'export');
result = result.replace(/export declare/g, 'export');
if (declaration.kind === ts.SyntaxKind.EnumDeclaration) {
result = result.replace(/const enum/, 'enum');
enums.push(result);
}
return result;
}
function format(text: string): string {
function format(text: string, endl: string): string {
const REALLY_FORMAT = false;
text = preformat(text, endl);
if (!REALLY_FORMAT) {
return text;
}
// Parse the source text
let sourceFile = ts.createSourceFile('file.ts', text, ts.ScriptTarget.Latest, /*setParentPointers*/ true);
@ -238,6 +220,104 @@ function format(text: string): string {
// Apply the edits on the input code
return applyEdits(text, edits);
function countParensCurly(text: string): number {
let cnt = 0;
for (let i = 0; i < text.length; i++) {
if (text.charAt(i) === '(' || text.charAt(i) === '{') {
cnt++;
}
if (text.charAt(i) === ')' || text.charAt(i) === '}') {
cnt--;
}
}
return cnt;
}
function repeatStr(s: string, cnt: number): string {
let r = '';
for (let i = 0; i < cnt; i++) {
r += s;
}
return r;
}
function preformat(text: string, endl: string): string {
let lines = text.split(endl);
let inComment = false;
let inCommentDeltaIndent = 0;
let indent = 0;
for (let i = 0; i < lines.length; i++) {
let line = lines[i].replace(/\s$/, '');
let repeat = false;
let lineIndent = 0;
do {
repeat = false;
if (line.substring(0, 4) === ' ') {
line = line.substring(4);
lineIndent++;
repeat = true;
}
if (line.charAt(0) === '\t') {
line = line.substring(1);
lineIndent++;
repeat = true;
}
} while (repeat);
if (line.length === 0) {
continue;
}
if (inComment) {
if (/\*\//.test(line)) {
inComment = false;
}
lines[i] = repeatStr('\t', lineIndent + inCommentDeltaIndent) + line;
continue;
}
if (/\/\*/.test(line)) {
inComment = true;
inCommentDeltaIndent = indent - lineIndent;
lines[i] = repeatStr('\t', indent) + line;
continue;
}
const cnt = countParensCurly(line);
let shouldUnindentAfter = false;
let shouldUnindentBefore = false;
if (cnt < 0) {
if (/[({]/.test(line)) {
shouldUnindentAfter = true;
} else {
shouldUnindentBefore = true;
}
} else if (cnt === 0) {
shouldUnindentBefore = /^\}/.test(line);
}
let shouldIndentAfter = false;
if (cnt > 0) {
shouldIndentAfter = true;
} else if (cnt === 0) {
shouldIndentAfter = /{$/.test(line);
}
if (shouldUnindentBefore) {
indent--;
}
lines[i] = repeatStr('\t', indent) + line;
if (shouldUnindentAfter) {
indent--;
}
if (shouldIndentAfter) {
indent++;
}
}
return lines.join(endl);
}
function getRuleProvider(options: ts.FormatCodeSettings) {
// Share this between multiple formatters using the same options.
// This represents the bulk of the space the formatter uses.
@ -282,7 +362,7 @@ function createReplacer(data: string): (str: string) => string {
};
}
function generateDeclarationFile(out: string, inputFiles: { [file: string]: string; }, recipe: string): [string, string] {
function generateDeclarationFile(recipe: string, sourceFileGetter: SourceFileGetter): [string, string, string] {
const endl = /\r\n/.test(recipe) ? '\r\n' : '\n';
let lines = recipe.split(endl);
@ -297,17 +377,19 @@ function generateDeclarationFile(out: string, inputFiles: { [file: string]: stri
const generateUsageImport = (moduleId: string) => {
let importName = 'm' + (++usageCounter);
usageImports.push(`import * as ${importName} from '${moduleId.replace(/\.d\.ts$/, '')}';`);
usageImports.push(`import * as ${importName} from './${moduleId.replace(/\.d\.ts$/, '')}';`);
return importName;
};
let enums: string[] = [];
lines.forEach(line => {
let m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
if (m1) {
CURRENT_PROCESSING_RULE = line;
let moduleId = m1[1];
let sourceFile = getSourceFile(out, inputFiles, moduleId);
const sourceFile = sourceFileGetter(moduleId);
if (!sourceFile) {
return;
}
@ -327,7 +409,7 @@ function generateDeclarationFile(out: string, inputFiles: { [file: string]: stri
logErr('Cannot find type ' + typeName);
return;
}
result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage)));
result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage, enums)));
});
return;
}
@ -336,7 +418,7 @@ function generateDeclarationFile(out: string, inputFiles: { [file: string]: stri
if (m2) {
CURRENT_PROCESSING_RULE = line;
let moduleId = m2[1];
let sourceFile = getSourceFile(out, inputFiles, moduleId);
const sourceFile = sourceFileGetter(moduleId);
if (!sourceFile) {
return;
}
@ -358,7 +440,7 @@ function generateDeclarationFile(out: string, inputFiles: { [file: string]: stri
});
getAllTopLevelDeclarations(sourceFile).forEach((declaration) => {
if (isDeclaration(declaration)) {
if (isDeclaration(declaration) && declaration.name) {
if (typesToExcludeMap[declaration.name.text]) {
return;
}
@ -371,7 +453,7 @@ function generateDeclarationFile(out: string, inputFiles: { [file: string]: stri
}
}
}
result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage)));
result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage, enums)));
});
return;
}
@ -382,20 +464,30 @@ function generateDeclarationFile(out: string, inputFiles: { [file: string]: stri
let resultTxt = result.join(endl);
resultTxt = resultTxt.replace(/\bURI\b/g, 'Uri');
resultTxt = resultTxt.replace(/\bEvent</g, 'IEvent<');
resultTxt = resultTxt.replace(/\bTPromise</g, 'Promise<');
resultTxt = format(resultTxt, endl);
resultTxt = format(resultTxt);
let resultEnums = [
'/*---------------------------------------------------------------------------------------------',
' * Copyright (c) Microsoft Corporation. All rights reserved.',
' * Licensed under the MIT License. See License.txt in the project root for license information.',
' *--------------------------------------------------------------------------------------------*/',
'',
'// THIS IS A GENERATED FILE. DO NOT EDIT DIRECTLY.',
''
].concat(enums).join(endl);
resultEnums = format(resultEnums, endl);
return [
resultTxt,
`${usageImports.join('\n')}\n\n${usage.join('\n')}`
`${usageImports.join('\n')}\n\n${usage.join('\n')}`,
resultEnums
];
}
function getIncludesInRecipe(): string[] {
export function getIncludesInRecipe(): string[] {
let recipe = fs.readFileSync(RECIPE_PATH).toString();
let lines = recipe.split(/\r\n|\n|\r/);
let result = [];
let result: string[] = [];
lines.forEach(line => {
@ -424,32 +516,65 @@ export function getFilesToWatch(out: string): string[] {
export interface IMonacoDeclarationResult {
content: string;
usageContent: string;
enums: string;
filePath: string;
isTheSame: boolean;
}
export function run(out: string, inputFiles: { [file: string]: string; }): IMonacoDeclarationResult {
function _run(sourceFileGetter: SourceFileGetter): IMonacoDeclarationResult {
log('Starting monaco.d.ts generation');
SOURCE_FILE_MAP = {};
let recipe = fs.readFileSync(RECIPE_PATH).toString();
let [result, usageContent] = generateDeclarationFile(out, inputFiles, recipe);
let currentContent = fs.readFileSync(DECLARATION_PATH).toString();
log('Finished monaco.d.ts generation');
const recipe = fs.readFileSync(RECIPE_PATH).toString();
const [result, usageContent, enums] = generateDeclarationFile(recipe, sourceFileGetter);
const currentContent = fs.readFileSync(DECLARATION_PATH).toString();
const one = currentContent.replace(/\r\n/gm, '\n');
const other = result.replace(/\r\n/gm, '\n');
const isTheSame = one === other;
const isTheSame = (one === other);
log('Finished monaco.d.ts generation');
return {
content: result,
usageContent: usageContent,
enums: enums,
filePath: DECLARATION_PATH,
isTheSame
};
}
export function run(out: string, inputFiles: { [file: string]: string; }): IMonacoDeclarationResult {
let SOURCE_FILE_MAP: { [moduleId: string]: ts.SourceFile; } = {};
const sourceFileGetter = (moduleId: string): ts.SourceFile | null => {
if (!SOURCE_FILE_MAP[moduleId]) {
let filePath = path.normalize(moduleIdToPath(out, moduleId));
if (!inputFiles.hasOwnProperty(filePath)) {
logErr('CANNOT FIND FILE ' + filePath + '. YOU MIGHT NEED TO RESTART gulp');
return null;
}
let fileContents = inputFiles[filePath];
let sourceFile = ts.createSourceFile(filePath, fileContents, ts.ScriptTarget.ES5);
SOURCE_FILE_MAP[moduleId] = sourceFile;
}
return SOURCE_FILE_MAP[moduleId];
};
return _run(sourceFileGetter);
}
export function run2(out: string, sourceFileMap: ISourceFileMap): IMonacoDeclarationResult {
const sourceFileGetter = (moduleId: string): ts.SourceFile | null => {
let filePath = path.normalize(moduleIdToPath(out, moduleId));
return sourceFileMap[filePath];
};
return _run(sourceFileGetter);
}
export function complainErrors() {
logErr('Not running monaco.d.ts generation due to compile errors');
}
@ -459,7 +584,7 @@ export function complainErrors() {
interface ILibMap { [libName: string]: string; }
interface IFileMap { [fileName: string]: string; }
class TypeScriptLanguageServiceHost implements ts.LanguageServiceHost {
export class TypeScriptLanguageServiceHost implements ts.LanguageServiceHost {
private readonly _libs: ILibMap;
private readonly _files: IFileMap;
@ -478,12 +603,12 @@ class TypeScriptLanguageServiceHost implements ts.LanguageServiceHost {
}
getScriptFileNames(): string[] {
return (
[]
([] as string[])
.concat(Object.keys(this._libs))
.concat(Object.keys(this._files))
);
}
getScriptVersion(fileName: string): string {
getScriptVersion(_fileName: string): string {
return '1';
}
getProjectVersion(): string {
@ -498,13 +623,13 @@ class TypeScriptLanguageServiceHost implements ts.LanguageServiceHost {
return ts.ScriptSnapshot.fromString('');
}
}
getScriptKind(fileName: string): ts.ScriptKind {
getScriptKind(_fileName: string): ts.ScriptKind {
return ts.ScriptKind.TS;
}
getCurrentDirectory(): string {
return '';
}
getDefaultLibFileName(options: ts.CompilerOptions): string {
getDefaultLibFileName(_options: ts.CompilerOptions): string {
return 'defaultLib:es5';
}
isDefaultLibFileName(fileName: string): boolean {
@ -533,16 +658,10 @@ export function execute(): IMonacoDeclarationResult {
var t1 = Date.now();
Object.keys(SRC_FILES).forEach((fileName) => {
var t = Date.now();
const emitOutput = languageService.getEmitOutput(fileName, true);
OUTPUT_FILES[SRC_FILE_TO_EXPECTED_NAME[fileName]] = emitOutput.outputFiles[0].text;
// console.log(`Generating .d.ts for ${fileName} took ${Date.now() - t} ms`);
});
console.log(`Generating .d.ts took ${Date.now() - t1} ms`);
// console.log(result.filePath);
// fs.writeFileSync(result.filePath, result.content.replace(/\r\n/gm, '\n'));
// fs.writeFileSync(path.join(SRC, 'user.ts'), result.usageContent.replace(/\r\n/gm, '\n'));
return run('src', OUTPUT_FILES);
}

View file

@ -25,21 +25,12 @@ declare namespace monaco {
dispose(): void;
}
export enum MarkerTag {
Unnecessary = 1,
}
export enum MarkerSeverity {
Hint = 1,
Info = 2,
Warning = 4,
Error = 8,
}
#include(vs/platform/markers/common/markers): MarkerTag, MarkerSeverity
#include(vs/base/common/winjs.base.d.ts): Promise
#include(vs/base/common/cancellation): CancellationTokenSource, CancellationToken
#include(vs/base/common/uri): URI, UriComponents
#include(vs/editor/common/standalone/standaloneBase): KeyCode, KeyMod
#include(vs/base/common/keyCodes): KeyCode
#include(vs/editor/common/standalone/standaloneBase): KeyMod
#include(vs/base/common/htmlContent): IMarkdownString
#include(vs/base/browser/keyboardEvent): IKeyboardEvent
#include(vs/base/browser/mouseEvent): IMouseEvent
@ -58,7 +49,7 @@ declare namespace monaco.editor {
#include(vs/editor/common/services/webWorker): MonacoWebWorker, IWebWorkerOptions
#include(vs/editor/standalone/browser/standaloneCodeEditor): IActionDescriptor, IEditorConstructionOptions, IDiffEditorConstructionOptions, IStandaloneCodeEditor, IStandaloneDiffEditor
export interface ICommandHandler {
(...args:any[]): void;
(...args: any[]): void;
}
#include(vs/platform/contextkey/common/contextkey): IContextKey
#include(vs/editor/standalone/browser/standaloneServices): IEditorOverrideServices

View file

@ -1,19 +1,19 @@
// This file is adding references to various symbols which should not be removed via tree shaking
import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { IHighlight } from 'vs/base/parts/quickopen/browser/quickOpenModel';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge';
import { SimpleWorkerClient, create as create1 } from 'vs/base/common/worker/simpleWorker';
import { create as create2 } from 'vs/editor/common/services/editorSimpleWorker';
import { QuickOpenWidget } from 'vs/base/parts/quickopen/browser/quickOpenWidget';
import { SyncDescriptor0, SyncDescriptor1, SyncDescriptor2, SyncDescriptor3, SyncDescriptor4, SyncDescriptor5, SyncDescriptor6, SyncDescriptor7, SyncDescriptor8 } from 'vs/platform/instantiation/common/descriptors';
import { PolyfillPromise } from 'vs/base/common/winjs.polyfill.promise';
import { DiffNavigator } from 'vs/editor/browser/widget/diffNavigator';
import * as editorAPI from 'vs/editor/editor.api';
import { ServiceIdentifier } from './vs/platform/instantiation/common/instantiation';
import { IContextViewService } from './vs/platform/contextview/browser/contextView';
import { IHighlight } from './vs/base/parts/quickopen/browser/quickOpenModel';
import { IWorkspaceContextService } from './vs/platform/workspace/common/workspace';
import { IEnvironmentService } from './vs/platform/environment/common/environment';
import { CountBadge } from './vs/base/browser/ui/countBadge/countBadge';
import { SimpleWorkerClient, create as create1 } from './vs/base/common/worker/simpleWorker';
import { create as create2 } from './vs/editor/common/services/editorSimpleWorker';
import { QuickOpenWidget } from './vs/base/parts/quickopen/browser/quickOpenWidget';
import { SyncDescriptor0, SyncDescriptor1, SyncDescriptor2, SyncDescriptor3, SyncDescriptor4, SyncDescriptor5, SyncDescriptor6, SyncDescriptor7, SyncDescriptor8 } from './vs/platform/instantiation/common/descriptors';
import { PolyfillPromise } from './vs/base/common/winjs.polyfill.promise';
import { DiffNavigator } from './vs/editor/browser/widget/diffNavigator';
import * as editorAPI from './vs/editor/editor.api';
(function () {
var a: any;

View file

@ -8,6 +8,10 @@ const path = require('path');
const fs = require('fs');
const yarn = process.platform === 'win32' ? 'yarn.cmd' : 'yarn';
/**
* @param {string} location
* @param {*} [opts]
*/
function yarnInstall(location, opts) {
opts = opts || {};
opts.cwd = location;

View file

@ -5,10 +5,21 @@
let err = false;
const major = parseInt(/^(\d+)\./.exec(process.versions.node)[1]);
const majorNodeVersion = parseInt(/^(\d+)\./.exec(process.versions.node)[1]);
if (major < 8) {
console.error('\033[1;31m*** Please use node>=8.\033[0;0m');
if (majorNodeVersion < 8 || majorNodeVersion >= 9) {
console.error('\033[1;31m*** Please use node >=8 and <9.\033[0;0m');
err = true;
}
const cp = require('child_process');
const yarnVersion = cp.execSync('yarn -v', { encoding: 'utf8' }).trim();
const parsedYarnVersion = /^(\d+)\.(\d+)\./.exec(yarnVersion);
const majorYarnVersion = parseInt(parsedYarnVersion[1]);
const minorYarnVersion = parseInt(parsedYarnVersion[2]);
if (majorYarnVersion < 1 || minorYarnVersion < 10) {
console.error('\033[1;31m*** Please use yarn >=1.10.1.\033[0;0m');
err = true;
}

View file

@ -7,6 +7,9 @@ const cp = require('child_process');
const fs = require('fs');
const path = require('path');
/**
* @param {string} location
*/
function updateGrammar(location) {
const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
const result = cp.spawnSync(npm, ['run', 'update-grammar'], {

View file

@ -12,6 +12,9 @@ var cson = require('cson-parser');
var https = require('https');
var url = require('url');
/**
* @param {string} urlString
*/
function getOptions(urlString) {
var _url = url.parse(urlString);
var headers = {
@ -19,7 +22,7 @@ function getOptions(urlString) {
};
var token = process.env['GITHUB_TOKEN'];
if (token) {
headers['Authorization'] = 'token ' + token
headers['Authorization'] = 'token ' + token;
}
return {
protocol: _url.protocol,
@ -30,6 +33,10 @@ function getOptions(urlString) {
};
}
/**
* @param {string} url
* @param {number} redirectCount
*/
function download(url, redirectCount) {
return new Promise((c, e) => {
var content = '';

View file

@ -3,21 +3,38 @@
"version": "1.0.0",
"devDependencies": {
"@types/azure": "0.9.19",
"@types/debounce": "^1.0.0",
"@types/documentdb": "1.10.2",
"@types/es6-collections": "0.5.31",
"@types/es6-promise": "0.0.33",
"@types/glob": "^7.1.1",
"@types/gulp": "^4.0.5",
"@types/gulp-concat": "^0.0.32",
"@types/gulp-filter": "^3.0.32",
"@types/gulp-json-editor": "^2.2.31",
"@types/gulp-rename": "^0.0.33",
"@types/gulp-sourcemaps": "^0.0.32",
"@types/gulp-uglify": "^3.0.5",
"@types/gulp-util": "^3.0.34",
"@types/mime": "0.0.29",
"@types/minimatch": "^3.0.3",
"@types/node": "8.0.33",
"@types/xml2js": "0.0.33",
"@types/pump": "^1.0.1",
"@types/request": "^2.47.0",
"@types/rimraf": "^2.0.2",
"@types/through": "^0.0.29",
"@types/through2": "^2.0.34",
"@types/uglify-es": "^3.0.0",
"@types/underscore": "^1.8.9",
"@types/xml2js": "0.0.33",
"azure-storage": "^2.1.0",
"documentdb": "1.13.0",
"github-releases": "^0.4.1",
"gulp-bom": "^1.0.0",
"gulp-sourcemaps": "^1.11.0",
"mime": "^1.3.4",
"minimist": "^1.2.0",
"typescript": "3.0.3",
"xml2js": "^0.4.17",
"github-releases": "^0.4.1",
"request": "^2.85.0"
"request": "^2.85.0",
"typescript": "3.1.1",
"xml2js": "^0.4.17"
},
"scripts": {
"compile": "tsc -p tsconfig.build.json",
@ -25,4 +42,4 @@
"postinstall": "npm run compile",
"npmCheckJs": "tsc --noEmit"
}
}
}

View file

@ -3,10 +3,10 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const cp = require('child_process');
import * as cp from 'child_process';
function yarnInstall(package: string): void {
cp.execSync(`yarn add --no-lockfile ${package}`);
function yarnInstall(packageName: string): void {
cp.execSync(`yarn add --no-lockfile ${packageName}`);
}
const product = require('../../../product.json');

View file

@ -43,7 +43,7 @@ function createDefaultConfig(quality: string): Config {
}
function getConfig(quality: string): Promise<Config> {
const client = new DocumentClient(process.env['AZURE_DOCUMENTDB_ENDPOINT'], { masterKey: process.env['AZURE_DOCUMENTDB_MASTERKEY'] });
const client = new DocumentClient(process.env['AZURE_DOCUMENTDB_ENDPOINT']!, { masterKey: process.env['AZURE_DOCUMENTDB_MASTERKEY'] });
const collection = 'dbs/builds/colls/config';
const query = {
query: `SELECT TOP 1 * FROM c WHERE c.id = @quality`,
@ -73,7 +73,7 @@ interface Asset {
}
function createOrUpdate(commit: string, quality: string, platform: string, type: string, release: NewDocument, asset: Asset, isUpdate: boolean): Promise<void> {
const client = new DocumentClient(process.env['AZURE_DOCUMENTDB_ENDPOINT'], { masterKey: process.env['AZURE_DOCUMENTDB_MASTERKEY'] });
const client = new DocumentClient(process.env['AZURE_DOCUMENTDB_ENDPOINT']!, { masterKey: process.env['AZURE_DOCUMENTDB_MASTERKEY'] });
const collection = 'dbs/builds/colls/' + quality;
const updateQuery = {
query: 'SELECT TOP 1 * FROM c WHERE c.id = @id',
@ -127,7 +127,7 @@ async function assertContainer(blobService: azure.BlobService, quality: string):
await new Promise((c, e) => blobService.createContainerIfNotExists(quality, { publicAccessLevel: 'blob' }, err => err ? e(err) : c()));
}
async function doesAssetExist(blobService: azure.BlobService, quality: string, blobName: string): Promise<boolean> {
async function doesAssetExist(blobService: azure.BlobService, quality: string, blobName: string): Promise<boolean | undefined> {
const existsResult = await new Promise<azure.BlobService.BlobResult>((c, e) => blobService.doesBlobExist(quality, blobName, (err, r) => err ? e(err) : c(r)));
return existsResult.exists;
}
@ -150,8 +150,8 @@ interface PublishOptions {
async function publish(commit: string, quality: string, platform: string, type: string, name: string, version: string, _isUpdate: string, file: string, opts: PublishOptions): Promise<void> {
const isUpdate = _isUpdate === 'true';
const queuedBy = process.env['BUILD_QUEUEDBY'];
const sourceBranch = process.env['BUILD_SOURCEBRANCH'];
const queuedBy = process.env['BUILD_QUEUEDBY']!;
const sourceBranch = process.env['BUILD_SOURCEBRANCH']!;
const isReleased = quality === 'insider'
&& /^master$|^refs\/heads\/master$/.test(sourceBranch)
&& /Project Collection Service Accounts|Microsoft.VisualStudio.Services.TFS/.test(queuedBy);
@ -179,12 +179,12 @@ async function publish(commit: string, quality: string, platform: string, type:
console.log('SHA256:', sha256hash);
const blobName = commit + '/' + name;
const storageAccount = process.env['AZURE_STORAGE_ACCOUNT_2'];
const storageAccount = process.env['AZURE_STORAGE_ACCOUNT_2']!;
const blobService = azure.createBlobService(storageAccount, process.env['AZURE_STORAGE_ACCESS_KEY_2'])
const blobService = azure.createBlobService(storageAccount, process.env['AZURE_STORAGE_ACCESS_KEY_2']!)
.withFilter(new azure.ExponentialRetryPolicyFilter(20));
const mooncakeBlobService = azure.createBlobService(storageAccount, process.env['MOONCAKE_STORAGE_ACCESS_KEY'], `${storageAccount}.blob.core.chinacloudapi.cn`)
const mooncakeBlobService = azure.createBlobService(storageAccount, process.env['MOONCAKE_STORAGE_ACCESS_KEY']!, `${storageAccount}.blob.core.chinacloudapi.cn`)
.withFilter(new azure.ExponentialRetryPolicyFilter(20));
// mooncake is fussy and far away, this is needed!
@ -200,7 +200,7 @@ async function publish(commit: string, quality: string, platform: string, type:
doesAssetExist(mooncakeBlobService, quality, blobName)
]);
const promises = [];
const promises: Array<Promise<void>> = [];
if (!blobExists) {
promises.push(uploadBlob(blobService, quality, blobName, file));
@ -249,7 +249,7 @@ async function publish(commit: string, quality: string, platform: string, type:
isReleased: config.frozen ? false : isReleased,
sourceBranch,
queuedBy,
assets: [],
assets: [] as Array<Asset>,
updates: {} as any
};

View file

@ -97,7 +97,7 @@ function updateVersion(accessor: IVersionAccessor, symbolsPath: string) {
function asyncRequest<T>(options: request.UrlOptions & request.CoreOptions): Promise<T> {
return new Promise<T>((resolve, reject) => {
request(options, (error, response, body) => {
request(options, (error, _response, body) => {
if (error) {
reject(error);
} else {
@ -107,17 +107,17 @@ function asyncRequest<T>(options: request.UrlOptions & request.CoreOptions): Pro
});
}
function downloadAsset(repository, assetName: string, targetPath: string, electronVersion: string) {
function downloadAsset(repository: any, assetName: string, targetPath: string, electronVersion: string) {
return new Promise((resolve, reject) => {
repository.getReleases({ tag_name: `v${electronVersion}` }, (err, releases) => {
repository.getReleases({ tag_name: `v${electronVersion}` }, (err: any, releases: any) => {
if (err) {
reject(err);
} else {
const asset = releases[0].assets.filter(asset => asset.name === assetName)[0];
const asset = releases[0].assets.filter((asset: any) => asset.name === assetName)[0];
if (!asset) {
reject(new Error(`Asset with name ${assetName} not found`));
} else {
repository.downloadAsset(asset, (err, reader) => {
repository.downloadAsset(asset, (err: any, reader: any) => {
if (err) {
reject(err);
} else {
@ -156,7 +156,7 @@ async function ensureVersionAndSymbols(options: IOptions) {
const symbolsName = symbolsZipName(options.platform, options.versions.electron, options.versions.insiders);
const symbolsPath = await tmpFile('symbols.zip');
console.log(`HockeyApp: downloading symbols ${symbolsName} for electron ${options.versions.electron} (${options.platform}) into ${symbolsPath}`);
await downloadAsset(new github({ repo: options.repository, token: options.access.githubToken }), symbolsName, symbolsPath, options.versions.electron);
await downloadAsset(new (github as any)({ repo: options.repository, token: options.access.githubToken }), symbolsName, symbolsPath, options.versions.electron);
// Create version
console.log(`HockeyApp: creating new version ${options.versions.code} (${options.platform})`);

View file

@ -1,10 +1,10 @@
steps:
- task: NodeTool@0
inputs:
versionSpec: "8.9.1"
versionSpec: "8.12.0"
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2
inputs:
versionSpec: "1.9.4"
versionSpec: "1.10.1"
- script: |
yarn
displayName: Install Dependencies
@ -17,6 +17,9 @@ steps:
- script: |
yarn monaco-compile-check
displayName: Run Monaco Editor Checks
- script: |
yarn strict-null-check
displayName: Run Strict Null Checks
- script: |
yarn compile
displayName: Compile Sources
@ -29,17 +32,6 @@ steps:
- script: |
./scripts/test-integration.sh --tfs "Integration Tests"
displayName: Run Integration Tests
- script: |
yarn smoketest --screenshots "$(Build.ArtifactStagingDirectory)/artifacts" --log "$(Build.ArtifactStagingDirectory)/artifacts/smoketest.log"
displayName: Run Smoke Tests
continueOnError: true
- task: PublishBuildArtifacts@1
displayName: Publish Smoketest Artifacts
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts'
ArtifactName: build-artifacts-darwin
publishLocation: Container
condition: eq(variables['System.PullRequest.IsFork'], 'False')
- task: PublishTestResults@2
displayName: Publish Tests Results
inputs:

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