Merge branch 'master' into joh/electron4tests

This commit is contained in:
Johannes Rieken 2017-03-09 12:34:03 +01:00 committed by GitHub
commit 334fcb8e08
1349 changed files with 34066 additions and 19794 deletions

View file

@ -19,6 +19,8 @@ addons:
- g++-4.9-multilib
- zip
- libgtk2.0-0
- libx11-dev
- libxkbfile-dev
before_install:
- git submodule update --init --recursive

View file

@ -1,7 +1,7 @@
# Visual Studio Code - Open Source
[![Build Status](https://travis-ci.org/Microsoft/vscode.svg?branch=master)](https://travis-ci.org/Microsoft/vscode)
[![Build status](https://ci.appveyor.com/api/projects/status/vuhlhg80tj3e2a0l?svg=true)](https://ci.appveyor.com/project/VSCode/vscode)
[![Build Status](https://ci.appveyor.com/api/projects/status/vuhlhg80tj3e2a0l/branch/master?svg=true)](https://ci.appveyor.com/project/VSCode/vscode)
[![Coverage Status](https://img.shields.io/coveralls/Microsoft/vscode/master.svg)](https://coveralls.io/github/Microsoft/vscode?branch=master)
[![Gitter](https://img.shields.io/badge/chat-on%20gitter-blue.svg)](https://gitter.im/Microsoft/vscode)

View file

@ -1,3 +1,5 @@
===================BEGIN GENERATOR LOG
===================END GENERATOR LOG
microsoft-vscode
THIRD-PARTY SOFTWARE NOTICES AND INFORMATION
@ -6,62 +8,63 @@ Do Not Translate or Localize
This project incorporates components from the projects listed below. The original copyright notices and the licenses under which Microsoft received such components are set forth below. Microsoft reserves all rights not expressly granted herein, whether by implication, estoppel or otherwise.
1. atom/language-c version 0.51.3 (https://github.com/atom/language-c)
2. atom/language-sass version 0.52.0 (https://github.com/atom/language-sass)
3. atom/language-xml (https://github.com/atom/language-xml)
4. Benvie/JavaScriptNext.tmLanguage (https://github.com/Benvie/JavaScriptNext.tmLanguage)
5. chjj-marked version 0.3.2 (https://github.com/npmcomponent/chjj-marked)
6. chriskempson/tomorrow-theme (https://github.com/chriskempson/tomorrow-theme)
7. Colorsublime-Themes version 0.1.0 (https://github.com/Colorsublime/Colorsublime-Themes)
8. daaain/Handlebars (https://github.com/daaain/Handlebars)
9. davidrios/jade-tmbundle (https://github.com/davidrios/jade-tmbundle)
10. definitelytyped (https://github.com/DefinitelyTyped/DefinitelyTyped)
11. demyte/language-cshtml (https://github.com/demyte/language-cshtml)
12. freebroccolo/atom-language-swift (https://github.com/freebroccolo/atom-language-swift)
13. HTML 5.1 W3C Working Draft version 08 October 2015 (http://www.w3.org/TR/2015/WD-html51-20151008/)
14. Ionic documentation version 1.2.4 (https://github.com/driftyco/ionic-site)
15. ionide/ionide-fsgrammar (https://github.com/ionide/ionide-fsgrammar)
16. js-beautify version 1.6.8 (https://github.com/beautify-web/js-beautify)
17. Jxck/assert version 1.0.0 (https://github.com/Jxck/assert)
18. language-docker (https://github.com/docker/docker)
19. language-go version 0.39.0 (https://github.com/atom/language-go)
20. language-less (https://github.com/atom/language-less)
21. language-php (https://github.com/atom/language-php)
22. language-rust version 0.4.4 (https://github.com/zargony/atom-language-rust)
23. MagicStack/MagicPython (https://github.com/MagicStack/MagicPython)
24. Microsoft/TypeScript-TmLanguage version 0.0.1 (https://github.com/Microsoft/TypeScript-TmLanguage)
25. mmcgrana/textmate-clojure (https://github.com/mmcgrana/textmate-clojure)
26. octicons-code version 3.1.0 (https://octicons.github.com)
27. octicons-font version 3.1.0 (https://octicons.github.com)
28. seti-ui version 0.1.0 (https://github.com/jesseweed/seti-ui)
29. string_scorer version 0.1.20 (https://github.com/joshaven/string_score)
30. sublimehq/Packages (https://github.com/sublimehq/Packages)
31. SublimeText/PowerShell (https://github.com/SublimeText/PowerShell)
32. textmate/asp.vb.net.tmbundle (https://github.com/textmate/asp.vb.net.tmbundle)
33. textmate/c.tmbundle (https://github.com/textmate/c.tmbundle)
34. textmate/coffee-script.tmbundle (https://github.com/textmate/coffee-script.tmbundle)
35. textmate/css.tmbundle (https://github.com/textmate/css.tmbundle)
36. textmate/diff.tmbundle (https://github.com/textmate/diff.tmbundle)
37. textmate/git.tmbundle (https://github.com/textmate/git.tmbundle)
38. textmate/groovy.tmbundle (https://github.com/textmate/groovy.tmbundle)
39. textmate/html.tmbundle (https://github.com/textmate/html.tmbundle)
40. textmate/ini.tmbundle (https://github.com/textmate/ini.tmbundle)
41. textmate/java.tmbundle (https://github.com/textmate/java.tmbundle)
42. textmate/javadoc.tmbundle (https://github.com/textmate/javadoc.tmbundle)
43. textmate/javascript.tmbundle (https://github.com/textmate/javascript.tmbundle)
44. textmate/lua.tmbundle (https://github.com/textmate/lua.tmbundle)
45. textmate/make.tmbundle (https://github.com/textmate/make.tmbundle)
46. textmate/markdown.tmbundle (https://github.com/textmate/markdown.tmbundle)
47. textmate/objective-c.tmbundle (https://github.com/textmate/objective-c.tmbundle)
48. textmate/perl.tmbundle (https://github.com/textmate/perl.tmbundle)
49. textmate/r.tmbundle (https://github.com/textmate/r.tmbundle)
50. textmate/ruby.tmbundle (https://github.com/textmate/ruby.tmbundle)
51. textmate/shellscript.tmbundle (https://github.com/textmate/shellscript.tmbundle)
52. textmate/sql.tmbundle (https://github.com/textmate/sql.tmbundle)
53. textmate/yaml.tmbundle (https://github.com/textmate/yaml.tmbundle)
54. typescript-legacy version 1.5 (https://github.com/Microsoft/TypeScript)
55. TypeScript-TmLanguage version 0.1.8 (https://github.com/Microsoft/TypeScript-TmLanguage)
56. unity-shader-files version 0.1.0 (https://github.com/nadege/unity-shader-files)
57. vscode-swift version 0.0.1 (https://github.com/owensd/vscode-swift)
2. atom/language-clojure (https://github.com/atom/language-clojure)
3. atom/language-coffee-script (https://github.com/atom/language-coffee-script)
4. atom/language-css (https://github.com/atom/language-css)
5. atom/language-objective-c (https://github.com/atom/language-objective-c)
6. atom/language-sass version 0.52.0 (https://github.com/atom/language-sass)
7. atom/language-xml (https://github.com/atom/language-xml)
8. Benvie/JavaScriptNext.tmLanguage (https://github.com/Benvie/JavaScriptNext.tmLanguage)
9. chjj-marked version 0.3.2 (https://github.com/npmcomponent/chjj-marked)
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/jade-tmbundle (https://github.com/davidrios/jade-tmbundle)
14. definitelytyped (https://github.com/DefinitelyTyped/DefinitelyTyped)
15. demyte/language-cshtml (https://github.com/demyte/language-cshtml)
16. dotnet/csharp-tmLanguage version 0.1.0 (https://github.com/dotnet/csharp-tmLanguage)
17. freebroccolo/atom-language-swift (https://github.com/freebroccolo/atom-language-swift)
18. HTML 5.1 W3C Working Draft version 08 October 2015 (http://www.w3.org/TR/2015/WD-html51-20151008/)
19. Ionic documentation version 1.2.4 (https://github.com/driftyco/ionic-site)
20. ionide/ionide-fsgrammar (https://github.com/ionide/ionide-fsgrammar)
21. js-beautify version 1.6.8 (https://github.com/beautify-web/js-beautify)
22. Jxck/assert version 1.0.0 (https://github.com/Jxck/assert)
23. language-docker (https://github.com/docker/docker)
24. language-go version 0.39.0 (https://github.com/atom/language-go)
25. language-less (https://github.com/atom/language-less)
26. language-php (https://github.com/atom/language-php)
27. language-rust version 0.4.9 (https://github.com/zargony/atom-language-rust)
28. MagicStack/MagicPython (https://github.com/MagicStack/MagicPython)
29. Microsoft/TypeScript-TmLanguage version 0.0.1 (https://github.com/Microsoft/TypeScript-TmLanguage)
30. octicons-code version 3.1.0 (https://octicons.github.com)
31. octicons-font version 3.1.0 (https://octicons.github.com)
32. seti-ui version 0.1.0 (https://github.com/jesseweed/seti-ui)
33. shaders-tmLanguage version 0.1.0 (https://github.com/tgjones/shaders-tmLanguage)
34. string_scorer version 0.1.20 (https://github.com/joshaven/string_score)
35. sublimehq/Packages (https://github.com/sublimehq/Packages)
36. SublimeText/PowerShell (https://github.com/SublimeText/PowerShell)
37. textmate/asp.vb.net.tmbundle (https://github.com/textmate/asp.vb.net.tmbundle)
38. textmate/c.tmbundle (https://github.com/textmate/c.tmbundle)
39. textmate/diff.tmbundle (https://github.com/textmate/diff.tmbundle)
40. textmate/git.tmbundle (https://github.com/textmate/git.tmbundle)
41. textmate/groovy.tmbundle (https://github.com/textmate/groovy.tmbundle)
42. textmate/html.tmbundle (https://github.com/textmate/html.tmbundle)
43. textmate/ini.tmbundle (https://github.com/textmate/ini.tmbundle)
44. textmate/java.tmbundle (https://github.com/textmate/java.tmbundle)
45. textmate/javadoc.tmbundle (https://github.com/textmate/javadoc.tmbundle)
46. textmate/javascript.tmbundle (https://github.com/textmate/javascript.tmbundle)
47. textmate/lua.tmbundle (https://github.com/textmate/lua.tmbundle)
48. textmate/make.tmbundle (https://github.com/textmate/make.tmbundle)
49. textmate/markdown.tmbundle (https://github.com/textmate/markdown.tmbundle)
50. textmate/perl.tmbundle (https://github.com/textmate/perl.tmbundle)
51. textmate/r.tmbundle (https://github.com/textmate/r.tmbundle)
52. textmate/ruby.tmbundle (https://github.com/textmate/ruby.tmbundle)
53. textmate/shellscript.tmbundle (https://github.com/textmate/shellscript.tmbundle)
54. textmate/sql.tmbundle (https://github.com/textmate/sql.tmbundle)
55. textmate/yaml.tmbundle (https://github.com/textmate/yaml.tmbundle)
56. typescript-legacy version 1.5 (https://github.com/Microsoft/TypeScript)
57. TypeScript-TmLanguage version 0.1.8 (https://github.com/Microsoft/TypeScript-TmLanguage)
58. vscode-swift version 0.0.1 (https://github.com/owensd/vscode-swift)
%% atom/language-c NOTICES AND INFORMATION BEGIN HERE
@ -101,6 +104,187 @@ suitability for any purpose.
=========================================
END OF atom/language-c NOTICES AND INFORMATION
%% atom/language-clojure NOTICES AND INFORMATION BEGIN HERE
=========================================
Copyright (c) 2014 GitHub Inc.
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.
This package was derived from a TextMate bundle located at
https://github.com/mmcgrana/textmate-clojure and distributed under the
following license, located in `LICENSE.md`:
The MIT License (MIT)
Copyright (c) 2010- Mark McGranaghan
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 atom/language-clojure NOTICES AND INFORMATION
%% atom/language-coffee-script NOTICES AND INFORMATION BEGIN HERE
=========================================
The MIT License (MIT)
Copyright (c) 2014 GitHub Inc.
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.
This package was derived from a TextMate bundle located at
https://github.com/jashkenas/coffee-script-tmbundle and distributed under the
following license, located in `LICENSE`:
Copyright (c) 2009-2014 Jeremy Ashkenas
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 atom/language-coffee-script NOTICES AND INFORMATION
%% atom/language-css NOTICES AND INFORMATION BEGIN HERE
=========================================
The MIT License (MIT)
Copyright (c) 2014 GitHub Inc.
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.
This package was derived from a TextMate bundle located at
https://github.com/textmate/css.tmbundle and distributed under the following
license, located in `README.mdown`:
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.
=========================================
END OF atom/language-css NOTICES AND INFORMATION
%% atom/language-objective-c NOTICES AND INFORMATION BEGIN HERE
=========================================
The MIT License (MIT)
Copyright (c) 2014 GitHub Inc.
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.
This package was derived from a TextMate bundle located at
https://github.com/textmate/objective-c.tmbundle and distributed under the following
license, located in `README.mdown`:
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.
=========================================
END OF atom/language-objective-c NOTICES AND INFORMATION
%% atom/language-sass NOTICES AND INFORMATION BEGIN HERE
=========================================
The MIT License (MIT)
@ -365,6 +549,32 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
=========================================
END OF demyte/language-cshtml NOTICES AND INFORMATION
%% dotnet/csharp-tmLanguage NOTICES AND INFORMATION BEGIN HERE
=========================================
MIT License
Copyright (c) 2016 .NET Foundation
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 dotnet/csharp-tmLanguage NOTICES AND INFORMATION
%% freebroccolo/atom-language-swift NOTICES AND INFORMATION BEGIN HERE
=========================================
The MIT License (MIT)
@ -717,7 +927,7 @@ Apache License
END OF TERMS AND CONDITIONS
Copyright 2013-2016 Docker, Inc.
Copyright 2013-2017 Docker, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -1133,32 +1343,6 @@ Copyright (c) Microsoft Corporation. All rights reserved.
=========================================
END OF Microsoft/TypeScript-TmLanguage NOTICES AND INFORMATION
%% mmcgrana/textmate-clojure NOTICES AND INFORMATION BEGIN HERE
=========================================
The MIT License (MIT)
Copyright (c) 2010- Mark McGranaghan
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 mmcgrana/textmate-clojure NOTICES AND INFORMATION
%% octicons-code NOTICES AND INFORMATION BEGIN HERE
=========================================
The MIT License (MIT)
@ -1301,6 +1485,32 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
=========================================
END OF seti-ui NOTICES AND INFORMATION
%% shaders-tmLanguage NOTICES AND INFORMATION BEGIN HERE
=========================================
MIT License
Copyright (c) 2017 Tim Jones
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 shaders-tmLanguage NOTICES AND INFORMATION
%% string_scorer NOTICES AND INFORMATION BEGIN HERE
=========================================
This software is released under the MIT license:
@ -1394,51 +1604,6 @@ to the base-name name of the original file, and an extension of txt, html, or si
=========================================
END OF textmate/c.tmbundle NOTICES AND INFORMATION
%% textmate/coffee-script.tmbundle NOTICES AND INFORMATION BEGIN HERE
=========================================
Copyright (c) 2009-2014 Jeremy Ashkenas
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 textmate/coffee-script.tmbundle NOTICES AND INFORMATION
%% textmate/css.tmbundle NOTICES AND INFORMATION BEGIN HERE
=========================================
Copyright (c) textmate-css.tmbundle project authors
If not otherwise specified (see below), files in this folder fall under the following license:
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/css.tmbundle NOTICES AND INFORMATION
%% textmate/diff.tmbundle NOTICES AND INFORMATION BEGIN HERE
=========================================
Copyright (c) textmate-diff.tmbundle project authors
@ -1646,24 +1811,6 @@ to the base-name name of the original file, and an extension of txt, html, or si
=========================================
END OF textmate/markdown.tmbundle NOTICES AND INFORMATION
%% textmate/objective-c.tmbundle NOTICES AND INFORMATION BEGIN HERE
=========================================
Copyright (c) textmate-objective-c.tmbundle project authors
If not otherwise specified (see below), files in this repository fall under the following license:
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/objective-c.tmbundle NOTICES AND INFORMATION
%% textmate/perl.tmbundle NOTICES AND INFORMATION BEGIN HERE
=========================================
Copyright (c) textmate-perl.tmbundle project authors
@ -2017,34 +2164,6 @@ Copyright (c) Microsoft Corporation. All rights reserved.
=========================================
END OF TypeScript-TmLanguage NOTICES AND INFORMATION
%% unity-shader-files NOTICES AND INFORMATION BEGIN HERE
=========================================
The MIT License (MIT)
Copyright (c) 2014 Teddy Bradford (for original ./Grammars/shaderlab.cson file)
Copyright (c) 2015 Nadège Michel
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 unity-shader-files NOTICES AND INFORMATION
%% vscode-swift NOTICES AND INFORMATION BEGIN HERE
=========================================
The MIT License (MIT)

View file

@ -32,7 +32,7 @@ gulp.task('mixin', function () {
}
const url = `https://github.com/${repo}/archive/${pkg.distro}.zip`;
const opts = { base: '' };
const opts = { base: url };
const username = process.env['VSCODE_MIXIN_USERNAME'];
const password = process.env['VSCODE_MIXIN_PASSWORD'];
@ -42,7 +42,7 @@ gulp.task('mixin', function () {
console.log('Mixing in sources from \'' + url + '\':');
let all = remote(url, opts)
let all = remote('', opts)
.pipe(zip.src())
.pipe(filter(function (f) { return !f.isDirectory(); }))
.pipe(util.rebase(1));

View file

@ -40,8 +40,8 @@ const nodeModules = ['electron', 'original-fs']
// Build
const builtInExtensions = [
{ name: 'ms-vscode.node-debug', version: '1.10.14' },
{ name: 'ms-vscode.node-debug2', version: '1.10.0' }
{ name: 'ms-vscode.node-debug', version: '1.11.3' },
{ name: 'ms-vscode.node-debug2', version: '1.11.2' }
];
const vscodeEntryPoints = _.flatten([
@ -57,24 +57,22 @@ const vscodeResources = [
'out-build/bootstrap.js',
'out-build/bootstrap-amd.js',
'out-build/paths.js',
'out-build/vs/**/*.{svg,png,cur}',
'out-build/vs/**/*.{svg,png,cur,html}',
'out-build/vs/base/node/{stdForkStart.js,terminateProcess.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/git/**/*.html',
'out-build/vs/workbench/parts/git/**/*.sh',
'out-build/vs/workbench/parts/html/browser/webview.html',
'out-build/vs/workbench/parts/html/browser/webview-pre.js',
'out-build/vs/**/markdown.css',
'out-build/vs/workbench/parts/tasks/**/*.json',
'out-build/vs/workbench/parts/terminal/electron-browser/terminalProcess.js',
'out-build/vs/workbench/parts/welcome/walkThrough/**/*.md',
'out-build/vs/workbench/parts/welcome/page/**/*.html',
'out-build/vs/workbench/services/files/**/*.exe',
'out-build/vs/workbench/services/files/**/*.md',
'out-build/vs/code/electron-browser/sharedProcess.js',
'!**/test/**'
];
@ -272,7 +270,8 @@ function packageTask(platform, arch, opts) {
.pipe(util.cleanNodeModule('native-keymap', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node']))
.pipe(util.cleanNodeModule('windows-foreground-love', ['binding.gyp', 'build/**', 'src/**'], ['**/*.node']))
.pipe(util.cleanNodeModule('gc-signals', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node', 'src/index.js']))
.pipe(util.cleanNodeModule('node-pty', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['build/Release/**']));
.pipe(util.cleanNodeModule('v8-profiler', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node', 'src/index.js']))
.pipe(util.cleanNodeModule('node-pty', ['binding.gyp', 'build/**', 'src/**', 'tools/**'], ['build/Release/**']));
let all = es.merge(
packageJsonStream,

View file

@ -169,11 +169,13 @@ function prepareRpmPackage(arch) {
function buildRpmPackage(arch) {
const rpmArch = getRpmPackageArch(arch);
const rpmBuildPath = getRpmBuildPath(rpmArch);
const rpmOut = rpmBuildPath + '/RPMS/' + rpmArch;
const destination = '.build/linux/rpm/' + rpmArch;
return shell.task([
'mkdir -p ' + destination,
'HOME="$(pwd)/' + destination + '" fakeroot rpmbuild -bb ' + rpmBuildPath + '/SPECS/' + product.applicationName + '.spec --target=' + rpmArch
'HOME="$(pwd)/' + destination + '" fakeroot rpmbuild -bb ' + rpmBuildPath + '/SPECS/' + product.applicationName + '.spec --target=' + rpmArch,
'cp "' + rpmOut + '/$(ls ' + rpmOut + ')" ' + destination + '/'
]);
}

View file

@ -1,451 +1,452 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
"use strict";
var fs = require("fs");
var path = require("path");
var vm = require("vm");
/**
* Bundle `entryPoints` given config `config`.
*/
function bundle(entryPoints, config, callback) {
var entryPointsMap = {};
entryPoints.forEach(function (module) {
entryPointsMap[module.name] = module;
});
var allMentionedModulesMap = {};
entryPoints.forEach(function (module) {
allMentionedModulesMap[module.name] = true;
(module.include || []).forEach(function (includedModule) {
allMentionedModulesMap[includedModule] = true;
});
(module.exclude || []).forEach(function (excludedModule) {
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: {} };
r.call({}, require, loaderModule, loaderModule.exports);
var loader = loaderModule.exports;
config.isBuild = true;
loader.config(config);
loader(['require'], function (localRequire) {
var resolvePath = function (path) {
var r = localRequire.toUrl(path);
if (!/\.js/.test(r)) {
return r + '.js';
}
return r;
};
for (var moduleId in entryPointsMap) {
var entryPoint = entryPointsMap[moduleId];
if (entryPoint.append) {
entryPoint.append = entryPoint.append.map(resolvePath);
}
if (entryPoint.prepend) {
entryPoint.prepend = entryPoint.prepend.map(resolvePath);
}
}
});
loader(Object.keys(allMentionedModulesMap), function () {
var modules = loader.getBuildInfo();
var partialResult = emitEntryPoints(modules, entryPointsMap);
var cssInlinedResources = loader('vs/css').getInlinedResources();
callback(null, {
files: partialResult.files,
cssInlinedResources: cssInlinedResources,
bundleData: partialResult.bundleData
});
}, function (err) { return callback(err, null); });
}
exports.bundle = bundle;
function emitEntryPoints(modules, entryPoints) {
var modulesMap = {};
modules.forEach(function (m) {
modulesMap[m.id] = m;
});
var modulesGraph = {};
modules.forEach(function (m) {
modulesGraph[m.id] = m.dependencies;
});
var sortedModules = topologicalSort(modulesGraph);
var result = [];
var usedPlugins = {};
var 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) {
delete allDependencies[exclude];
});
});
var includedModules = sortedModules.filter(function (module) {
return allDependencies[module];
});
bundleData.bundles[moduleToBundle] = includedModules;
var res = emitEntryPoint(modulesMap, modulesGraph, moduleToBundle, includedModules, info.prepend, info.append, info.dest);
result = result.concat(res.files);
for (var pluginName in res.usedPlugins) {
usedPlugins[pluginName] = usedPlugins[pluginName] || res.usedPlugins[pluginName];
}
});
Object.keys(usedPlugins).forEach(function (pluginName) {
var plugin = usedPlugins[pluginName];
if (typeof plugin.finishBuild === 'function') {
var write = function (filename, contents) {
result.push({
dest: filename,
sources: [{
path: null,
contents: contents
}]
});
};
plugin.finishBuild(write);
}
});
return {
files: extractStrings(removeDuplicateTSBoilerplate(result)),
bundleData: bundleData
};
}
function extractStrings(destFiles) {
var parseDefineCall = function (moduleMatch, depsMatch) {
var module = moduleMatch.replace(/^"|"$/g, '');
var deps = depsMatch.split(',');
deps = deps.map(function (dep) {
dep = dep.trim();
dep = dep.replace(/^"|"$/g, '');
dep = dep.replace(/^'|'$/g, '');
var prefix = null;
var _path = null;
var pieces = dep.split('!');
if (pieces.length > 1) {
prefix = pieces[0] + '!';
_path = pieces[1];
}
else {
prefix = '';
_path = pieces[0];
}
if (/^\.\//.test(_path) || /^\.\.\//.test(_path)) {
var res = path.join(path.dirname(module), _path).replace(/\\/g, '/');
return prefix + res;
}
return prefix + _path;
});
return {
module: module,
deps: deps
};
};
destFiles.forEach(function (destFile, index) {
if (!/\.js$/.test(destFile.dest)) {
return;
}
if (/\.nls\.js$/.test(destFile.dest)) {
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*\[(((, )?("|')[^"']+("|'))+)\]/);
if (!matches) {
return;
}
var defineCall = parseDefineCall(matches[1], matches[2]);
useCounts[defineCall.module] = (useCounts[defineCall.module] || 0) + 1;
defineCall.deps.forEach(function (dep) {
useCounts[dep] = (useCounts[dep] || 0) + 1;
});
});
var sortedByUseModules = Object.keys(useCounts);
sortedByUseModules.sort(function (a, b) {
return useCounts[b] - useCounts[a];
});
var replacementMap = {};
sortedByUseModules.forEach(function (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.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;",
"};"
].join('\n')
});
destFile.sources.push({
path: null,
contents: '}).call(this);'
});
});
return destFiles;
}
function removeDuplicateTSBoilerplate(destFiles) {
// Taken from typescript compiler => emitFiles
var BOILERPLATE = [
{ start: /^var __extends/, end: /^};$/ },
{ start: /^var __assign/, end: /^};$/ },
{ start: /^var __decorate/, end: /^};$/ },
{ start: /^var __metadata/, end: /^};$/ },
{ start: /^var __param/, end: /^};$/ },
{ start: /^var __awaiter/, 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];
if (IS_REMOVING_BOILERPLATE) {
newLines.push('');
if (END_BOILERPLATE.test(line)) {
IS_REMOVING_BOILERPLATE = false;
}
}
else {
for (var j = 0; j < BOILERPLATE.length; j++) {
var boilerplate = BOILERPLATE[j];
if (boilerplate.start.test(line)) {
if (SEEN_BOILERPLATE[j]) {
IS_REMOVING_BOILERPLATE = true;
END_BOILERPLATE = boilerplate.end;
}
else {
SEEN_BOILERPLATE[j] = true;
}
}
}
if (IS_REMOVING_BOILERPLATE) {
newLines.push('');
}
else {
newLines.push(line);
}
}
}
source.contents = newLines.join('\n');
});
});
return destFiles;
}
function emitEntryPoint(modulesMap, deps, entryPoint, includedModules, prepend, append, dest) {
if (!dest) {
dest = entryPoint + '.js';
}
var mainResult = {
sources: [],
dest: dest
}, results = [mainResult];
var usedPlugins = {};
var getLoaderPlugin = function (pluginName) {
if (!usedPlugins[pluginName]) {
usedPlugins[pluginName] = modulesMap[pluginName].exports;
}
return usedPlugins[pluginName];
};
includedModules.forEach(function (c) {
var bangIndex = c.indexOf('!');
if (bangIndex >= 0) {
var pluginName = c.substr(0, bangIndex);
var plugin = getLoaderPlugin(pluginName);
mainResult.sources.push(emitPlugin(entryPoint, plugin, pluginName, c.substr(bangIndex + 1)));
return;
}
var module = modulesMap[c];
if (module.path === 'empty:') {
return;
}
var 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));
}
});
Object.keys(usedPlugins).forEach(function (pluginName) {
var plugin = usedPlugins[pluginName];
if (typeof plugin.writeFile === 'function') {
var req = (function () {
throw new Error('no-no!');
});
req.toUrl = function (something) { return something; };
var write = function (filename, contents) {
results.push({
dest: filename,
sources: [{
path: null,
contents: contents
}]
});
};
plugin.writeFile(pluginName, entryPoint, req, write, {});
}
});
var toIFile = function (path) {
var contents = readFileAndRemoveBOM(path);
return {
path: path,
contents: contents
};
};
var toPrepend = (prepend || []).map(toIFile);
var toAppend = (append || []).map(toIFile);
mainResult.sources = toPrepend.concat(mainResult.sources).concat(toAppend);
return {
files: results,
usedPlugins: usedPlugins
};
}
function readFileAndRemoveBOM(path) {
var BOM_CHAR_CODE = 65279;
var contents = fs.readFileSync(path, 'utf8');
// Remove BOM
if (contents.charCodeAt(0) === BOM_CHAR_CODE) {
contents = contents.substring(1);
}
return contents;
}
function emitPlugin(entryPoint, plugin, pluginName, moduleName) {
var result = '';
if (typeof plugin.write === 'function') {
var write = (function (what) {
result += what;
});
write.getEntryPoint = function () {
return entryPoint;
};
write.asModule = function (moduleId, code) {
code = code.replace(/^define\(/, 'define("' + moduleId + '",');
result += code;
};
plugin.write(pluginName, moduleName, write);
}
return {
path: null,
contents: result
};
}
function emitNamedModule(moduleId, myDeps, defineCallPosition, path, contents) {
// `defineCallPosition` is the position in code: |define()
var defineCallOffset = positionToOffset(contents, defineCallPosition.line, defineCallPosition.col);
// `parensOffset` is the position in code: define|()
var parensOffset = contents.indexOf('(', defineCallOffset);
var 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 + ');';
return {
path: path,
contents: contents + '\n;\n' + strDefine
};
}
/**
* Convert a position (line:col) to (offset) in string `str`
*/
function positionToOffset(str, desiredLine, desiredCol) {
if (desiredLine === 1) {
return desiredCol - 1;
}
var line = 1, lastNewLineOffset = -1;
do {
if (desiredLine === line) {
return lastNewLineOffset + 1 + desiredCol - 1;
}
lastNewLineOffset = str.indexOf('\n', lastNewLineOffset + 1);
line++;
} while (lastNewLineOffset >= 0);
return -1;
}
/**
* Return a set of reachable nodes in `graph` starting from `rootNodes`
*/
function visit(rootNodes, graph) {
var result = {}, queue = rootNodes;
rootNodes.forEach(function (node) {
result[node] = true;
});
while (queue.length > 0) {
var el = queue.shift();
var myEdges = graph[el] || [];
myEdges.forEach(function (toNode) {
if (!result[toNode]) {
result[toNode] = true;
queue.push(toNode);
}
});
}
return result;
}
/**
* Perform a topological sort on `graph`
*/
function topologicalSort(graph) {
var allNodes = {}, outgoingEdgeCount = {}, inverseEdges = {};
Object.keys(graph).forEach(function (fromNode) {
allNodes[fromNode] = true;
outgoingEdgeCount[fromNode] = graph[fromNode].length;
graph[fromNode].forEach(function (toNode) {
allNodes[toNode] = true;
outgoingEdgeCount[toNode] = outgoingEdgeCount[toNode] || 0;
inverseEdges[toNode] = inverseEdges[toNode] || [];
inverseEdges[toNode].push(fromNode);
});
});
// https://en.wikipedia.org/wiki/Topological_sorting
var S = [], L = [];
Object.keys(allNodes).forEach(function (node) {
if (outgoingEdgeCount[node] === 0) {
delete outgoingEdgeCount[node];
S.push(node);
}
});
while (S.length > 0) {
// Ensure the exact same order all the time with the same inputs
S.sort();
var n = S.shift();
L.push(n);
var myInverseEdges = inverseEdges[n] || [];
myInverseEdges.forEach(function (m) {
outgoingEdgeCount[m]--;
if (outgoingEdgeCount[m] === 0) {
delete outgoingEdgeCount[m];
S.push(m);
}
});
}
if (Object.keys(outgoingEdgeCount).length > 0) {
throw new Error('Cannot do topological sort on cyclic graph, remaining nodes: ' + Object.keys(outgoingEdgeCount));
}
return L;
}
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var fs = require("fs");
var path = require("path");
var vm = require("vm");
/**
* Bundle `entryPoints` given config `config`.
*/
function bundle(entryPoints, config, callback) {
var entryPointsMap = {};
entryPoints.forEach(function (module) {
entryPointsMap[module.name] = module;
});
var allMentionedModulesMap = {};
entryPoints.forEach(function (module) {
allMentionedModulesMap[module.name] = true;
(module.include || []).forEach(function (includedModule) {
allMentionedModulesMap[includedModule] = true;
});
(module.exclude || []).forEach(function (excludedModule) {
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: {} };
r.call({}, require, loaderModule, loaderModule.exports);
var loader = loaderModule.exports;
config.isBuild = true;
loader.config(config);
loader(['require'], function (localRequire) {
var resolvePath = function (path) {
var r = localRequire.toUrl(path);
if (!/\.js/.test(r)) {
return r + '.js';
}
return r;
};
for (var moduleId in entryPointsMap) {
var entryPoint = entryPointsMap[moduleId];
if (entryPoint.append) {
entryPoint.append = entryPoint.append.map(resolvePath);
}
if (entryPoint.prepend) {
entryPoint.prepend = entryPoint.prepend.map(resolvePath);
}
}
});
loader(Object.keys(allMentionedModulesMap), function () {
var modules = loader.getBuildInfo();
var partialResult = emitEntryPoints(modules, entryPointsMap);
var cssInlinedResources = loader('vs/css').getInlinedResources();
callback(null, {
files: partialResult.files,
cssInlinedResources: cssInlinedResources,
bundleData: partialResult.bundleData
});
}, function (err) { return callback(err, null); });
}
exports.bundle = bundle;
function emitEntryPoints(modules, entryPoints) {
var modulesMap = {};
modules.forEach(function (m) {
modulesMap[m.id] = m;
});
var modulesGraph = {};
modules.forEach(function (m) {
modulesGraph[m.id] = m.dependencies;
});
var sortedModules = topologicalSort(modulesGraph);
var result = [];
var usedPlugins = {};
var 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) {
delete allDependencies[exclude];
});
});
var includedModules = sortedModules.filter(function (module) {
return allDependencies[module];
});
bundleData.bundles[moduleToBundle] = includedModules;
var res = emitEntryPoint(modulesMap, modulesGraph, moduleToBundle, includedModules, info.prepend, info.append, info.dest);
result = result.concat(res.files);
for (var pluginName in res.usedPlugins) {
usedPlugins[pluginName] = usedPlugins[pluginName] || res.usedPlugins[pluginName];
}
});
Object.keys(usedPlugins).forEach(function (pluginName) {
var plugin = usedPlugins[pluginName];
if (typeof plugin.finishBuild === 'function') {
var write = function (filename, contents) {
result.push({
dest: filename,
sources: [{
path: null,
contents: contents
}]
});
};
plugin.finishBuild(write);
}
});
return {
files: extractStrings(removeDuplicateTSBoilerplate(result)),
bundleData: bundleData
};
}
function extractStrings(destFiles) {
var parseDefineCall = function (moduleMatch, depsMatch) {
var module = moduleMatch.replace(/^"|"$/g, '');
var deps = depsMatch.split(',');
deps = deps.map(function (dep) {
dep = dep.trim();
dep = dep.replace(/^"|"$/g, '');
dep = dep.replace(/^'|'$/g, '');
var prefix = null;
var _path = null;
var pieces = dep.split('!');
if (pieces.length > 1) {
prefix = pieces[0] + '!';
_path = pieces[1];
}
else {
prefix = '';
_path = pieces[0];
}
if (/^\.\//.test(_path) || /^\.\.\//.test(_path)) {
var res = path.join(path.dirname(module), _path).replace(/\\/g, '/');
return prefix + res;
}
return prefix + _path;
});
return {
module: module,
deps: deps
};
};
destFiles.forEach(function (destFile, index) {
if (!/\.js$/.test(destFile.dest)) {
return;
}
if (/\.nls\.js$/.test(destFile.dest)) {
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*\[(((, )?("|')[^"']+("|'))+)\]/);
if (!matches) {
return;
}
var defineCall = parseDefineCall(matches[1], matches[2]);
useCounts[defineCall.module] = (useCounts[defineCall.module] || 0) + 1;
defineCall.deps.forEach(function (dep) {
useCounts[dep] = (useCounts[dep] || 0) + 1;
});
});
var sortedByUseModules = Object.keys(useCounts);
sortedByUseModules.sort(function (a, b) {
return useCounts[b] - useCounts[a];
});
var replacementMap = {};
sortedByUseModules.forEach(function (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.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;",
"};"
].join('\n')
});
destFile.sources.push({
path: null,
contents: '}).call(this);'
});
});
return destFiles;
}
function removeDuplicateTSBoilerplate(destFiles) {
// Taken from typescript compiler => emitFiles
var BOILERPLATE = [
{ start: /^var __extends/, end: /^};$/ },
{ start: /^var __assign/, end: /^};$/ },
{ start: /^var __decorate/, end: /^};$/ },
{ start: /^var __metadata/, end: /^};$/ },
{ start: /^var __param/, end: /^};$/ },
{ start: /^var __awaiter/, 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];
if (IS_REMOVING_BOILERPLATE) {
newLines.push('');
if (END_BOILERPLATE.test(line)) {
IS_REMOVING_BOILERPLATE = false;
}
}
else {
for (var j = 0; j < BOILERPLATE.length; j++) {
var boilerplate = BOILERPLATE[j];
if (boilerplate.start.test(line)) {
if (SEEN_BOILERPLATE[j]) {
IS_REMOVING_BOILERPLATE = true;
END_BOILERPLATE = boilerplate.end;
}
else {
SEEN_BOILERPLATE[j] = true;
}
}
}
if (IS_REMOVING_BOILERPLATE) {
newLines.push('');
}
else {
newLines.push(line);
}
}
}
source.contents = newLines.join('\n');
});
});
return destFiles;
}
function emitEntryPoint(modulesMap, deps, entryPoint, includedModules, prepend, append, dest) {
if (!dest) {
dest = entryPoint + '.js';
}
var mainResult = {
sources: [],
dest: dest
}, results = [mainResult];
var usedPlugins = {};
var getLoaderPlugin = function (pluginName) {
if (!usedPlugins[pluginName]) {
usedPlugins[pluginName] = modulesMap[pluginName].exports;
}
return usedPlugins[pluginName];
};
includedModules.forEach(function (c) {
var bangIndex = c.indexOf('!');
if (bangIndex >= 0) {
var pluginName = c.substr(0, bangIndex);
var plugin = getLoaderPlugin(pluginName);
mainResult.sources.push(emitPlugin(entryPoint, plugin, pluginName, c.substr(bangIndex + 1)));
return;
}
var module = modulesMap[c];
if (module.path === 'empty:') {
return;
}
var 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));
}
});
Object.keys(usedPlugins).forEach(function (pluginName) {
var plugin = usedPlugins[pluginName];
if (typeof plugin.writeFile === 'function') {
var req = (function () {
throw new Error('no-no!');
});
req.toUrl = function (something) { return something; };
var write = function (filename, contents) {
results.push({
dest: filename,
sources: [{
path: null,
contents: contents
}]
});
};
plugin.writeFile(pluginName, entryPoint, req, write, {});
}
});
var toIFile = function (path) {
var contents = readFileAndRemoveBOM(path);
return {
path: path,
contents: contents
};
};
var toPrepend = (prepend || []).map(toIFile);
var toAppend = (append || []).map(toIFile);
mainResult.sources = toPrepend.concat(mainResult.sources).concat(toAppend);
return {
files: results,
usedPlugins: usedPlugins
};
}
function readFileAndRemoveBOM(path) {
var BOM_CHAR_CODE = 65279;
var contents = fs.readFileSync(path, 'utf8');
// Remove BOM
if (contents.charCodeAt(0) === BOM_CHAR_CODE) {
contents = contents.substring(1);
}
return contents;
}
function emitPlugin(entryPoint, plugin, pluginName, moduleName) {
var result = '';
if (typeof plugin.write === 'function') {
var write = (function (what) {
result += what;
});
write.getEntryPoint = function () {
return entryPoint;
};
write.asModule = function (moduleId, code) {
code = code.replace(/^define\(/, 'define("' + moduleId + '",');
result += code;
};
plugin.write(pluginName, moduleName, write);
}
return {
path: null,
contents: result
};
}
function emitNamedModule(moduleId, myDeps, defineCallPosition, path, contents) {
// `defineCallPosition` is the position in code: |define()
var defineCallOffset = positionToOffset(contents, defineCallPosition.line, defineCallPosition.col);
// `parensOffset` is the position in code: define|()
var parensOffset = contents.indexOf('(', defineCallOffset);
var 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 + ');';
return {
path: path,
contents: contents + '\n;\n' + strDefine
};
}
/**
* Convert a position (line:col) to (offset) in string `str`
*/
function positionToOffset(str, desiredLine, desiredCol) {
if (desiredLine === 1) {
return desiredCol - 1;
}
var line = 1, lastNewLineOffset = -1;
do {
if (desiredLine === line) {
return lastNewLineOffset + 1 + desiredCol - 1;
}
lastNewLineOffset = str.indexOf('\n', lastNewLineOffset + 1);
line++;
} while (lastNewLineOffset >= 0);
return -1;
}
/**
* Return a set of reachable nodes in `graph` starting from `rootNodes`
*/
function visit(rootNodes, graph) {
var result = {}, queue = rootNodes;
rootNodes.forEach(function (node) {
result[node] = true;
});
while (queue.length > 0) {
var el = queue.shift();
var myEdges = graph[el] || [];
myEdges.forEach(function (toNode) {
if (!result[toNode]) {
result[toNode] = true;
queue.push(toNode);
}
});
}
return result;
}
/**
* Perform a topological sort on `graph`
*/
function topologicalSort(graph) {
var allNodes = {}, outgoingEdgeCount = {}, inverseEdges = {};
Object.keys(graph).forEach(function (fromNode) {
allNodes[fromNode] = true;
outgoingEdgeCount[fromNode] = graph[fromNode].length;
graph[fromNode].forEach(function (toNode) {
allNodes[toNode] = true;
outgoingEdgeCount[toNode] = outgoingEdgeCount[toNode] || 0;
inverseEdges[toNode] = inverseEdges[toNode] || [];
inverseEdges[toNode].push(fromNode);
});
});
// https://en.wikipedia.org/wiki/Topological_sorting
var S = [], L = [];
Object.keys(allNodes).forEach(function (node) {
if (outgoingEdgeCount[node] === 0) {
delete outgoingEdgeCount[node];
S.push(node);
}
});
while (S.length > 0) {
// Ensure the exact same order all the time with the same inputs
S.sort();
var n = S.shift();
L.push(n);
var myInverseEdges = inverseEdges[n] || [];
myInverseEdges.forEach(function (m) {
outgoingEdgeCount[m]--;
if (outgoingEdgeCount[m] === 0) {
delete outgoingEdgeCount[m];
S.push(m);
}
});
}
if (Object.keys(outgoingEdgeCount).length > 0) {
throw new Error('Cannot do topological sort on cyclic graph, remaining nodes: ' + Object.keys(outgoingEdgeCount));
}
return L;
}

View file

@ -22,24 +22,24 @@ interface IBuildModuleInfo {
}
interface IBuildModuleInfoMap {
[moduleId:string]: IBuildModuleInfo;
[moduleId: string]: IBuildModuleInfo;
}
interface ILoaderPlugin {
write(pluginName:string, moduleName:string, write:ILoaderPluginWriteFunc): void;
writeFile(pluginName:string, entryPoint:string, req:ILoaderPluginReqFunc, write:(filename:string, contents:string)=>void, config:any): void;
finishBuild(write:(filename:string, contents:string)=>void): void;
write(pluginName: string, moduleName: string, write: ILoaderPluginWriteFunc): void;
writeFile(pluginName: string, entryPoint: string, req: ILoaderPluginReqFunc, write: (filename: string, contents: string) => void, config: any): void;
finishBuild(write: (filename: string, contents: string) => void): void;
}
interface ILoaderPluginWriteFunc {
(something:string): void;
(something: string): void;
getEntryPoint(): string;
asModule(moduleId:string, code:string): void;
asModule(moduleId: string, code: string): void;
}
interface ILoaderPluginReqFunc {
(something:string): void;
toUrl(something:string): string;
(something: string): void;
toUrl(something: string): string;
}
export interface IEntryPoint {
@ -52,15 +52,15 @@ export interface IEntryPoint {
}
interface IEntryPointMap {
[moduleId:string]: IEntryPoint;
[moduleId: string]: IEntryPoint;
}
export interface IGraph {
[node:string]: string[];
[node: string]: string[];
}
interface INodeSet {
[node:string]: boolean;
[node: string]: boolean;
}
export interface IFile {
@ -75,7 +75,7 @@ export interface IConcatFile {
export interface IBundleData {
graph: IGraph;
bundles: {[moduleId:string]:string[];};
bundles: { [moduleId: string]: string[]; };
}
export interface IBundleResult {
@ -96,35 +96,35 @@ 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 = {};
entryPoints.forEach((module:IEntryPoint) => {
export function bundle(entryPoints: IEntryPoint[], config: ILoaderConfig, callback: (err: any, result: IBundleResult) => void): void {
let entryPointsMap: IEntryPointMap = {};
entryPoints.forEach((module: IEntryPoint) => {
entryPointsMap[module.name] = module;
});
let allMentionedModulesMap: {[modules:string]:boolean;} = {};
entryPoints.forEach((module:IEntryPoint) => {
let allMentionedModulesMap: { [modules: string]: boolean; } = {};
entryPoints.forEach((module: IEntryPoint) => {
allMentionedModulesMap[module.name] = true;
(module.include||[]).forEach(function(includedModule) {
(module.include || []).forEach(function (includedModule) {
allMentionedModulesMap[includedModule] = true;
});
(module.exclude||[]).forEach(function(excludedModule) {
(module.exclude || []).forEach(function (excludedModule) {
allMentionedModulesMap[excludedModule] = true;
});
});
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 r: Function = <any>vm.runInThisContext('(function(require, module, exports) { ' + code + '\n});');
var loaderModule = { exports: {} };
r.call({}, require, loaderModule, loaderModule.exports);
var loader:any = loaderModule.exports;
var loader: any = loaderModule.exports;
config.isBuild = true;
loader.config(config);
loader(['require'], (localRequire) => {
let resolvePath = (path:string) => {
let resolvePath = (path: string) => {
let r = localRequire.toUrl(path);
if (!/\.js/.test(r)) {
return r + '.js';
@ -154,14 +154,14 @@ export function bundle(entryPoints:IEntryPoint[], config:ILoaderConfig, callback
}, (err) => callback(err, null));
}
function emitEntryPoints(modules:IBuildModuleInfo[], entryPoints:IEntryPointMap): IPartialBundleResult {
function emitEntryPoints(modules: IBuildModuleInfo[], entryPoints: IEntryPointMap): IPartialBundleResult {
let modulesMap: IBuildModuleInfoMap = {};
modules.forEach((m:IBuildModuleInfo) => {
modules.forEach((m: IBuildModuleInfo) => {
modulesMap[m.id] = m;
});
let modulesGraph:IGraph = {};
modules.forEach((m:IBuildModuleInfo) => {
let modulesGraph: IGraph = {};
modules.forEach((m: IBuildModuleInfo) => {
modulesGraph[m.id] = m.dependencies;
});
@ -169,25 +169,25 @@ function emitEntryPoints(modules:IBuildModuleInfo[], entryPoints:IEntryPointMap)
let result: IConcatFile[] = [];
let usedPlugins: IPluginMap = {};
let bundleData:IBundleData = {
let bundleData: IBundleData = {
graph: modulesGraph,
bundles: {}
};
Object.keys(entryPoints).forEach((moduleToBundle:string) => {
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 || []);
let excludes: string[] = ['require', 'exports', 'module'].concat(info.exclude || []);
excludes.forEach((excludeRoot:string) => {
excludes.forEach((excludeRoot: string) => {
let allExcludes = visit([excludeRoot], modulesGraph);
Object.keys(allExcludes).forEach((exclude:string) => {
Object.keys(allExcludes).forEach((exclude: string) => {
delete allDependencies[exclude];
});
});
let includedModules = sortedModules.filter((module:string) => {
let includedModules = sortedModules.filter((module: string) => {
return allDependencies[module];
});
@ -209,10 +209,10 @@ function emitEntryPoints(modules:IBuildModuleInfo[], entryPoints:IEntryPointMap)
}
});
Object.keys(usedPlugins).forEach((pluginName:string) => {
Object.keys(usedPlugins).forEach((pluginName: string) => {
let plugin = usedPlugins[pluginName];
if (typeof plugin.finishBuild === 'function') {
let write = (filename:string, contents:string) => {
let write = (filename: string, contents: string) => {
result.push({
dest: filename,
sources: [{
@ -231,16 +231,16 @@ function emitEntryPoints(modules:IBuildModuleInfo[], entryPoints:IEntryPointMap)
};
}
function extractStrings(destFiles:IConcatFile[]):IConcatFile[] {
let parseDefineCall = (moduleMatch:string, depsMatch:string) => {
function extractStrings(destFiles: IConcatFile[]): IConcatFile[] {
let parseDefineCall = (moduleMatch: string, depsMatch: string) => {
let 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 prefix: string = null;
let _path: string = null;
let pieces = dep.split('!');
if (pieces.length > 1) {
prefix = pieces[0] + '!';
@ -271,7 +271,7 @@ function extractStrings(destFiles:IConcatFile[]):IConcatFile[] {
}
// Do one pass to record the usage counts for each module id
let useCounts: {[moduleId:string]:number;} = {};
let useCounts: { [moduleId: string]: number; } = {};
destFile.sources.forEach((source) => {
let matches = source.contents.match(/define\(("[^"]+"),\s*\[(((, )?("|')[^"']+("|'))+)\]/);
if (!matches) {
@ -290,7 +290,7 @@ function extractStrings(destFiles:IConcatFile[]):IConcatFile[] {
return useCounts[b] - useCounts[a];
});
let replacementMap: {[moduleId:string]:number;} = {};
let replacementMap: { [moduleId: string]: number; } = {};
sortedByUseModules.forEach((module, index) => {
replacementMap[module] = index;
});
@ -325,7 +325,7 @@ function extractStrings(destFiles:IConcatFile[]):IConcatFile[] {
return destFiles;
}
function removeDuplicateTSBoilerplate(destFiles:IConcatFile[]):IConcatFile[] {
function removeDuplicateTSBoilerplate(destFiles: IConcatFile[]): IConcatFile[] {
// Taken from typescript compiler => emitFiles
let BOILERPLATE = [
{ start: /^var __extends/, end: /^};$/ },
@ -377,7 +377,7 @@ function removeDuplicateTSBoilerplate(destFiles:IConcatFile[]):IConcatFile[] {
}
interface IPluginMap {
[moduleId:string]:ILoaderPlugin;
[moduleId: string]: ILoaderPlugin;
}
interface IEmitEntryPointResult {
@ -386,10 +386,10 @@ interface IEmitEntryPointResult {
}
function emitEntryPoint(
modulesMap:IBuildModuleInfoMap,
deps:IGraph,
entryPoint:string,
includedModules:string[],
modulesMap: IBuildModuleInfoMap,
deps: IGraph,
entryPoint: string,
includedModules: string[],
prepend: string[],
append: string[],
dest: string
@ -398,20 +398,20 @@ function emitEntryPoint(
dest = entryPoint + '.js';
}
let mainResult: IConcatFile = {
sources: [],
dest: dest
},
sources: [],
dest: dest
},
results: IConcatFile[] = [mainResult];
let usedPlugins: IPluginMap = {};
let getLoaderPlugin = (pluginName:string):ILoaderPlugin => {
let getLoaderPlugin = (pluginName: string): ILoaderPlugin => {
if (!usedPlugins[pluginName]) {
usedPlugins[pluginName] = modulesMap[pluginName].exports;
}
return usedPlugins[pluginName];
};
includedModules.forEach((c:string) => {
includedModules.forEach((c: string) => {
let bangIndex = c.indexOf('!');
if (bangIndex >= 0) {
@ -436,15 +436,15 @@ function emitEntryPoint(
}
});
Object.keys(usedPlugins).forEach((pluginName:string) => {
Object.keys(usedPlugins).forEach((pluginName: string) => {
let plugin = usedPlugins[pluginName];
if (typeof plugin.writeFile === 'function') {
let req:ILoaderPluginReqFunc = <any>(() => {
let req: ILoaderPluginReqFunc = <any>(() => {
throw new Error('no-no!');
});
req.toUrl = something => something;
let write = (filename:string, contents:string) => {
let write = (filename: string, contents: string) => {
results.push({
dest: filename,
sources: [{
@ -457,7 +457,7 @@ function emitEntryPoint(
}
});
let toIFile = (path):IFile => {
let toIFile = (path): IFile => {
let contents = readFileAndRemoveBOM(path);
return {
path: path,
@ -465,8 +465,8 @@ function emitEntryPoint(
};
};
let toPrepend = (prepend||[]).map(toIFile);
let toAppend = (append||[]).map(toIFile);
let toPrepend = (prepend || []).map(toIFile);
let toAppend = (append || []).map(toIFile);
mainResult.sources = toPrepend.concat(mainResult.sources).concat(toAppend);
@ -476,7 +476,7 @@ function emitEntryPoint(
};
}
function readFileAndRemoveBOM(path:string): string {
function readFileAndRemoveBOM(path: string): string {
var BOM_CHAR_CODE = 65279;
var contents = fs.readFileSync(path, 'utf8');
// Remove BOM
@ -486,7 +486,7 @@ function readFileAndRemoveBOM(path:string): string {
return contents;
}
function emitPlugin(entryPoint:string, plugin:ILoaderPlugin, pluginName:string, moduleName:string): IFile {
function emitPlugin(entryPoint: string, plugin: ILoaderPlugin, pluginName: string, moduleName: string): IFile {
let result = '';
if (typeof plugin.write === 'function') {
let write: ILoaderPluginWriteFunc = <any>((what) => {
@ -495,8 +495,8 @@ function emitPlugin(entryPoint:string, plugin:ILoaderPlugin, pluginName:string,
write.getEntryPoint = () => {
return entryPoint;
};
write.asModule = (moduleId:string, code:string) => {
code = code.replace(/^define\(/, 'define("'+moduleId+'",');
write.asModule = (moduleId: string, code: string) => {
code = code.replace(/^define\(/, 'define("' + moduleId + '",');
result += code;
};
plugin.write(pluginName, moduleName, write);
@ -507,7 +507,7 @@ function emitPlugin(entryPoint:string, plugin:ILoaderPlugin, pluginName:string,
};
}
function emitNamedModule(moduleId:string, myDeps:string[], defineCallPosition:IPosition, path:string, contents:string): IFile {
function emitNamedModule(moduleId: string, myDeps: string[], defineCallPosition: IPosition, path: string, contents: string): IFile {
// `defineCallPosition` is the position in code: |define()
let defineCallOffset = positionToOffset(contents, defineCallPosition.line, defineCallPosition.col);
@ -523,7 +523,7 @@ function emitNamedModule(moduleId:string, myDeps:string[], defineCallPosition:IP
};
}
function emitShimmedModule(moduleId:string, myDeps:string[], factory:string, path:string, contents:string): IFile {
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 + ');';
return {
@ -535,7 +535,7 @@ function emitShimmedModule(moduleId:string, myDeps:string[], factory:string, pat
/**
* Convert a position (line:col) to (offset) in string `str`
*/
function positionToOffset(str:string, desiredLine:number, desiredCol:number): number {
function positionToOffset(str: string, desiredLine: number, desiredCol: number): number {
if (desiredLine === 1) {
return desiredCol - 1;
}
@ -558,8 +558,8 @@ function positionToOffset(str:string, desiredLine:number, desiredCol:number): nu
/**
* Return a set of reachable nodes in `graph` starting from `rootNodes`
*/
function visit(rootNodes:string[], graph:IGraph):INodeSet {
let result:INodeSet = {},
function visit(rootNodes: string[], graph: IGraph): INodeSet {
let result: INodeSet = {},
queue = rootNodes;
rootNodes.forEach((node) => {
@ -583,13 +583,13 @@ function visit(rootNodes:string[], graph:IGraph):INodeSet {
/**
* Perform a topological sort on `graph`
*/
function topologicalSort(graph:IGraph): string[] {
function topologicalSort(graph: IGraph): string[] {
let allNodes:INodeSet = {},
outgoingEdgeCount:{[node:string]:number;} = {},
inverseEdges:IGraph = {};
let allNodes: INodeSet = {},
outgoingEdgeCount: { [node: string]: number; } = {},
inverseEdges: IGraph = {};
Object.keys(graph).forEach((fromNode:string) => {
Object.keys(graph).forEach((fromNode: string) => {
allNodes[fromNode] = true;
outgoingEdgeCount[fromNode] = graph[fromNode].length;
@ -606,7 +606,7 @@ function topologicalSort(graph:IGraph): string[] {
let S: string[] = [],
L: string[] = [];
Object.keys(allNodes).forEach((node:string) => {
Object.keys(allNodes).forEach((node: string) => {
if (outgoingEdgeCount[node] === 0) {
delete outgoingEdgeCount[node];
S.push(node);
@ -617,11 +617,11 @@ function topologicalSort(graph:IGraph): string[] {
// Ensure the exact same order all the time with the same inputs
S.sort();
let n:string = S.shift();
let n: string = S.shift();
L.push(n);
let myInverseEdges = inverseEdges[n] || [];
myInverseEdges.forEach((m:string) => {
myInverseEdges.forEach((m: string) => {
outgoingEdgeCount[m]--;
if (outgoingEdgeCount[m] === 0) {
delete outgoingEdgeCount[m];

View file

@ -1,134 +1,171 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
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();
var rootDir = path.join(__dirname, '../../src');
var options = require('../../src/tsconfig.json').compilerOptions;
options.verbose = false;
options.sourceMap = true;
options.rootDir = rootDir;
options.sourceRoot = util.toFileUri(rootDir);
function createCompile(build, emitError) {
var opts = _.clone(options);
opts.inlineSources = !!build;
opts.noFilesystemLookup = true;
var ts = tsb.create(opts, null, null, function (err) { return 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
.pipe(utf8Filter)
.pipe(bom())
.pipe(utf8Filter.restore)
.pipe(tsFilter)
.pipe(util.loadSourcemaps())
.pipe(ts(token))
.pipe(noDeclarationsFilter)
.pipe(build ? nls() : es.through())
.pipe(noDeclarationsFilter.restore)
.pipe(sourcemaps.write('.', {
addComment: false,
includeContent: !!build,
sourceRoot: options.sourceRoot
}))
.pipe(tsFilter.restore)
.pipe(reporter.end(emitError));
return es.duplex(input, output);
};
}
function compileTask(out, build) {
var compile = createCompile(build, true);
return function () {
var src = es.merge(gulp.src('src/**', { base: 'src' }), gulp.src('node_modules/typescript/lib/lib.d.ts'), gulp.src('node_modules/@types/**/index.d.ts'));
return src
.pipe(compile())
.pipe(gulp.dest(out))
.pipe(monacodtsTask(out, false));
};
}
exports.compileTask = compileTask;
function watchTask(out, build) {
var compile = createCompile(build);
return function () {
var src = es.merge(gulp.src('src/**', { base: 'src' }), gulp.src('node_modules/typescript/lib/lib.d.ts'), gulp.src('node_modules/@types/**/index.d.ts'));
var watchSrc = watch('src/**', { base: 'src' });
return watchSrc
.pipe(util.incremental(compile, src, true))
.pipe(gulp.dest(out))
.pipe(monacodtsTask(out, true));
};
}
exports.watchTask = watchTask;
function monacodtsTask(out, isWatch) {
var timer = null;
var runSoon = function (howSoon) {
if (timer !== null) {
clearTimeout(timer);
timer = null;
}
timer = setTimeout(function () {
timer = null;
runNow();
}, howSoon);
};
var runNow = function () {
if (timer !== null) {
clearTimeout(timer);
timer = null;
}
// if (reporter.hasErrors()) {
// monacodts.complainErrors();
// return;
// }
var result = monacodts.run(out);
if (!result.isTheSame) {
if (isWatch) {
fs.writeFileSync(result.filePath, result.content);
}
else {
resultStream.emit('error', 'monaco.d.ts is no longer up to date. Please run gulp watch and commit the new file.');
}
}
};
var resultStream;
if (isWatch) {
var filesToWatchMap_1 = {};
monacodts.getFilesToWatch(out).forEach(function (filePath) {
filesToWatchMap_1[path.normalize(filePath)] = true;
});
watch('build/monaco/*').pipe(es.through(function () {
runSoon(5000);
}));
resultStream = es.through(function (data) {
var filePath = path.normalize(data.path);
if (filesToWatchMap_1[filePath]) {
runSoon(5000);
}
this.emit('data', data);
});
}
else {
resultStream = es.through(null, function () {
runNow();
this.emit('end');
});
}
return resultStream;
}
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'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();
var rootDir = path.join(__dirname, '../../src');
var options = require('../../src/tsconfig.json').compilerOptions;
options.verbose = false;
options.sourceMap = true;
options.rootDir = rootDir;
options.sourceRoot = util.toFileUri(rootDir);
function createCompile(build, emitError) {
var opts = _.clone(options);
opts.inlineSources = !!build;
opts.noFilesystemLookup = true;
var ts = tsb.create(opts, null, null, function (err) { return 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
.pipe(utf8Filter)
.pipe(bom())
.pipe(utf8Filter.restore)
.pipe(tsFilter)
.pipe(util.loadSourcemaps())
.pipe(ts(token))
.pipe(build ? reloadTypeScriptNodeModule() : es.through())
.pipe(noDeclarationsFilter)
.pipe(build ? nls() : es.through())
.pipe(noDeclarationsFilter.restore)
.pipe(sourcemaps.write('.', {
addComment: false,
includeContent: !!build,
sourceRoot: options.sourceRoot
}))
.pipe(tsFilter.restore)
.pipe(reporter.end(emitError));
return es.duplex(input, output);
};
}
function compileTask(out, build) {
return function () {
var compile = createCompile(build, true);
var src = es.merge(gulp.src('src/**', { base: 'src' }), gulp.src('node_modules/typescript/lib/lib.d.ts'), gulp.src('node_modules/@types/**/index.d.ts'));
return src
.pipe(compile())
.pipe(gulp.dest(out))
.pipe(monacodtsTask(out, false));
};
}
exports.compileTask = compileTask;
function watchTask(out, build) {
return function () {
var compile = createCompile(build);
var src = es.merge(gulp.src('src/**', { base: 'src' }), gulp.src('node_modules/typescript/lib/lib.d.ts'), gulp.src('node_modules/@types/**/index.d.ts'));
var watchSrc = watch('src/**', { base: 'src' });
return watchSrc
.pipe(util.incremental(compile, src, true))
.pipe(gulp.dest(out))
.pipe(monacodtsTask(out, true));
};
}
exports.watchTask = watchTask;
function reloadTypeScriptNodeModule() {
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('[memory watch dog]'), message].concat(rest));
}
function heapUsed() {
return (process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2) + ' MB';
}
return es.through(function (data) {
this.emit('data', data);
}, function () {
log('memory usage after compilation finished: ' + heapUsed());
// It appears we are running into some variant of
// https://bugs.chromium.org/p/v8/issues/detail?id=2073
//
// Even though all references are dropped, some
// optimized methods in the TS compiler end up holding references
// to the entire TypeScript language host (>600MB)
//
// The idea is to force v8 to drop references to these
// optimized methods, by "reloading" the typescript node module
log('Reloading typescript node module...');
var resolvedName = require.resolve('typescript');
var originalModule = require.cache[resolvedName];
delete require.cache[resolvedName];
var newExports = require('typescript');
require.cache[resolvedName] = originalModule;
for (var prop in newExports) {
if (newExports.hasOwnProperty(prop)) {
originalModule.exports[prop] = newExports[prop];
}
}
log('typescript node module reloaded.');
this.emit('end');
});
}
function monacodtsTask(out, isWatch) {
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);
}
else {
resultStream.emit('error', 'monaco.d.ts is no longer up to date. Please run gulp watch and commit the new file.');
}
}
};
var resultStream;
if (isWatch) {
watch('build/monaco/*').pipe(es.through(function () {
run();
}));
}
resultStream = es.through(function (data) {
var filePath = path.normalize(data.path);
if (neededFiles[filePath]) {
setInputFile(filePath, data.contents.toString());
}
this.emit('data', data);
});
return resultStream;
}

View file

@ -36,6 +36,7 @@ function createCompile(build: boolean, emitError?: boolean): (token?: util.ICanc
const ts = tsb.create(opts, null, null, err => reporter(err.toString()));
return function (token?: util.ICancellationToken) {
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)));
@ -48,6 +49,7 @@ function createCompile(build: boolean, emitError?: boolean): (token?: util.ICanc
.pipe(tsFilter)
.pipe(util.loadSourcemaps())
.pipe(ts(token))
.pipe(build ? reloadTypeScriptNodeModule() : es.through())
.pipe(noDeclarationsFilter)
.pipe(build ? nls() : es.through())
.pipe(noDeclarationsFilter.restore)
@ -64,9 +66,10 @@ function createCompile(build: boolean, emitError?: boolean): (token?: util.ICanc
}
export function compileTask(out: string, build: boolean): () => NodeJS.ReadWriteStream {
const compile = createCompile(build, true);
return function () {
const compile = createCompile(build, true);
const src = es.merge(
gulp.src('src/**', { base: 'src' }),
gulp.src('node_modules/typescript/lib/lib.d.ts'),
@ -81,9 +84,10 @@ export function compileTask(out: string, build: boolean): () => NodeJS.ReadWrite
}
export function watchTask(out: string, build: boolean): () => NodeJS.ReadWriteStream {
const compile = createCompile(build);
return function () {
const compile = createCompile(build);
const src = es.merge(
gulp.src('src/**', { base: 'src' }),
gulp.src('node_modules/typescript/lib/lib.d.ts'),
@ -98,30 +102,84 @@ export function watchTask(out: string, build: boolean): () => NodeJS.ReadWriteSt
};
}
function monacodtsTask(out: string, isWatch: boolean): NodeJS.ReadWriteStream {
let timer: NodeJS.Timer = null;
function reloadTypeScriptNodeModule(): NodeJS.ReadWriteStream {
var util = require('gulp-util');
function log(message: any, ...rest: any[]): void {
util.log(util.colors.cyan('[memory watch dog]'), message, ...rest);
}
const runSoon = function (howSoon: number) {
if (timer !== null) {
clearTimeout(timer);
timer = null;
function heapUsed(): string {
return (process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2) + ' MB';
}
return es.through(function (data) {
this.emit('data', data);
}, function () {
log('memory usage after compilation finished: ' + heapUsed());
// It appears we are running into some variant of
// https://bugs.chromium.org/p/v8/issues/detail?id=2073
//
// Even though all references are dropped, some
// optimized methods in the TS compiler end up holding references
// to the entire TypeScript language host (>600MB)
//
// The idea is to force v8 to drop references to these
// optimized methods, by "reloading" the typescript node module
log('Reloading typescript node module...');
var resolvedName = require.resolve('typescript');
var originalModule = require.cache[resolvedName];
delete require.cache[resolvedName];
var newExports = require('typescript');
require.cache[resolvedName] = originalModule;
for (var prop in newExports) {
if (newExports.hasOwnProperty(prop)) {
originalModule.exports[prop] = newExports[prop];
}
}
log('typescript node module reloaded.');
this.emit('end');
});
}
function monacodtsTask(out: string, isWatch: boolean): NodeJS.ReadWriteStream {
const neededFiles: { [file: string]: boolean; } = {};
monacodts.getFilesToWatch(out).forEach(function (filePath) {
filePath = path.normalize(filePath);
neededFiles[filePath] = true;
});
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();
}
}
const setInputFile = (filePath: string, contents: string) => {
if (inputFiles[filePath] === contents) {
// no change
return;
}
inputFiles[filePath] = contents;
const neededInputFilesCount = Object.keys(neededFiles).length;
const availableInputFilesCount = Object.keys(inputFiles).length;
if (neededInputFilesCount === availableInputFilesCount) {
run();
}
timer = setTimeout(function () {
timer = null;
runNow();
}, howSoon);
};
const runNow = function () {
if (timer !== null) {
clearTimeout(timer);
timer = null;
}
// if (reporter.hasErrors()) {
// monacodts.complainErrors();
// return;
// }
const result = monacodts.run(out);
const run = () => {
const result = monacodts.run(out, inputFiles);
if (!result.isTheSame) {
if (isWatch) {
fs.writeFileSync(result.filePath, result.content);
@ -134,32 +192,18 @@ function monacodtsTask(out: string, isWatch: boolean): NodeJS.ReadWriteStream {
let resultStream: NodeJS.ReadWriteStream;
if (isWatch) {
const filesToWatchMap: { [file: string]: boolean; } = {};
monacodts.getFilesToWatch(out).forEach(function (filePath) {
filesToWatchMap[path.normalize(filePath)] = true;
});
watch('build/monaco/*').pipe(es.through(function () {
runSoon(5000);
run();
}));
resultStream = es.through(function (data) {
const filePath = path.normalize(data.path);
if (filesToWatchMap[filePath]) {
runSoon(5000);
}
this.emit('data', data);
});
} else {
resultStream = es.through(null, function () {
runNow();
this.emit('end');
});
}
resultStream = es.through(function (data) {
const filePath = path.normalize(data.path);
if (neededFiles[filePath]) {
setInputFile(filePath, data.contents.toString());
}
this.emit('data', data);
});
return resultStream;
}

View file

@ -1,95 +1,96 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
"use strict";
var event_stream_1 = require("event-stream");
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');
function error(err) {
var result = event_stream_1.through();
setTimeout(function () { return result.emit('error', err); });
return result;
}
var baseHeaders = {
'X-Market-Client-Id': 'VSCode Build',
'User-Agent': 'VSCode Build',
};
function src(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',
requestOptions: {
method: 'POST',
gzip: true,
headers: headers,
body: body
}
};
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);
}));
}));
}
exports.src = src;
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var event_stream_1 = require("event-stream");
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');
function error(err) {
var result = event_stream_1.through();
setTimeout(function () { return result.emit('error', err); });
return result;
}
var baseHeaders = {
'X-Market-Client-Id': 'VSCode Build',
'User-Agent': 'VSCode Build',
};
function src(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',
requestOptions: {
method: 'POST',
gzip: true,
headers: headers,
body: body
}
};
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);
}));
}));
}
exports.src = src;

View file

@ -61,7 +61,7 @@ export function src(extensionName: string, version: string): Stream {
const result = JSON.parse(rawResult);
const extension = result.results[0].extensions[0];
if (!extension) {
return error(`No such extension: ${ extension }`);
return error(`No such extension: ${extension}`);
}
const metadata = {
@ -72,15 +72,15 @@ export function src(extensionName: string, version: string): Stream {
const extensionVersion = extension.versions.filter(v => v.version === version)[0];
if (!extensionVersion) {
return error(`No such extension version: ${ extensionName } @ ${ version }`);
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 }`);
return error(`No VSIX found for extension version: ${extensionName} @ ${version}`);
}
util.log('Downloading extension:', util.colors.yellow(`${ extensionName }@${ version }`), '...');
util.log('Downloading extension:', util.colors.yellow(`${extensionName}@${version}`), '...');
const options = {
base: asset.source,

View file

@ -1,51 +1,53 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
"use strict";
var path = require("path");
var 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;
try {
head = fs.readFileSync(headPath, 'utf8').trim();
}
catch (e) {
return void 0;
}
if (/^[0-9a-f]{40}$/i.test(head)) {
return head;
}
var refMatch = /^ref: (.*)$/.exec(head);
if (!refMatch) {
return void 0;
}
var ref = refMatch[1];
var refPath = path.join(git, ref);
try {
return fs.readFileSync(refPath, 'utf8').trim();
}
catch (e) {
}
var packedRefsPath = path.join(git, 'packed-refs');
var 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 = {};
while (refsMatch = refsRegex.exec(refsRaw)) {
refs[refsMatch[2]] = refsMatch[1];
}
return refs[ref];
}
exports.getVersion = getVersion;
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var path = require("path");
var 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;
try {
head = fs.readFileSync(headPath, 'utf8').trim();
}
catch (e) {
return void 0;
}
if (/^[0-9a-f]{40}$/i.test(head)) {
return head;
}
var refMatch = /^ref: (.*)$/.exec(head);
if (!refMatch) {
return void 0;
}
var ref = refMatch[1];
var refPath = path.join(git, ref);
try {
return fs.readFileSync(refPath, 'utf8').trim();
}
catch (e) {
// noop
}
var packedRefsPath = path.join(git, 'packed-refs');
var 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 = {};
while (refsMatch = refsRegex.exec(refsRaw)) {
refs[refsMatch[2]] = refsMatch[1];
}
return refs[ref];
}
exports.getVersion = getVersion;

View file

@ -2,7 +2,7 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
"use strict";
'use strict';
import * as path from 'path';
import * as fs from 'fs';
@ -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 {
const git = path.join(repo, '.git');
const headPath = path.join(git, 'HEAD');
let head: string;
@ -41,7 +41,7 @@ export function getVersion(repo:string): string {
}
const packedRefsPath = path.join(git, 'packed-refs');
let refsRaw:string;
let refsRaw: string;
try {
refsRaw = fs.readFileSync(packedRefsPath, 'utf8').trim();
@ -51,7 +51,7 @@ export function getVersion(repo:string): string {
const refsRegex = /^([0-9a-f]{40})\s+(.+)$/gm;
let refsMatch: RegExpExecArray;
let refs:{[ref:string]:string} = {};
let refs: { [ref: string]: string } = {};
while (refsMatch = refsRegex.exec(refsRaw)) {
refs[refsMatch[2]] = refsMatch[1];

View file

@ -1,289 +1,290 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
"use strict";
var path = require("path");
var fs = require("fs");
var event_stream_1 = require("event-stream");
var File = require("vinyl");
var Is = require("is");
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.green('[i18n]'), message].concat(rest));
}
var LocalizeInfo;
(function (LocalizeInfo) {
function is(value) {
var candidate = value;
return Is.defined(candidate) && Is.string(candidate.key) && (Is.undef(candidate.comment) || (Is.array(candidate.comment) && candidate.comment.every(function (element) { return Is.string(element); })));
}
LocalizeInfo.is = is;
})(LocalizeInfo || (LocalizeInfo = {}));
var BundledFormat;
(function (BundledFormat) {
function is(value) {
if (Is.undef(value)) {
return false;
}
var candidate = value;
var length = Object.keys(value).length;
return length === 3 && Is.defined(candidate.keys) && Is.defined(candidate.messages) && Is.defined(candidate.bundles);
}
BundledFormat.is = is;
})(BundledFormat || (BundledFormat = {}));
var vscodeLanguages = [
'chs',
'cht',
'jpn',
'kor',
'deu',
'fra',
'esn',
'rus',
'ita'
];
var iso639_3_to_2 = {
'chs': 'zh-cn',
'cht': 'zh-tw',
'csy': 'cs-cz',
'deu': 'de',
'enu': 'en',
'esn': 'es',
'fra': 'fr',
'hun': 'hu',
'ita': 'it',
'jpn': 'ja',
'kor': 'ko',
'nld': 'nl',
'plk': 'pl',
'ptb': 'pt-br',
'ptg': 'pt',
'rus': 'ru',
'sve': 'sv-se',
'trk': 'tr'
};
function sortLanguages(directoryNames) {
return directoryNames.map(function (dirName) {
var lower = dirName.toLowerCase();
return {
name: lower,
iso639_2: iso639_3_to_2[lower]
};
}).sort(function (a, b) {
if (!a.iso639_2 && !b.iso639_2) {
return 0;
}
if (!a.iso639_2) {
return -1;
}
if (!b.iso639_2) {
return 1;
}
return a.iso639_2 < b.iso639_2 ? -1 : (a.iso639_2 > b.iso639_2 ? 1 : 0);
});
}
function stripComments(content) {
/**
* First capturing group matches double quoted string
* Second matches single quotes string
* Third matches block comments
* Fourth matches line comments
*/
var regexp = /("(?:[^\\\"]*(?:\\.)?)*")|('(?:[^\\\']*(?:\\.)?)*')|(\/\*(?:\r?\n|.)*?\*\/)|(\/{2,}.*?(?:(?:\r?\n)|$))/g;
var result = content.replace(regexp, function (match, m1, m2, m3, m4) {
// Only one of m1, m2, m3, m4 matches
if (m3) {
// A block comment. Replace with nothing
return '';
}
else if (m4) {
// A line comment. If it ends in \r?\n then keep it.
var length_1 = m4.length;
if (length_1 > 2 && m4[length_1 - 1] === '\n') {
return m4[length_1 - 2] === '\r' ? '\r\n' : '\n';
}
else {
return '';
}
}
else {
// We match a string
return match;
}
});
return result;
}
;
function escapeCharacters(value) {
var result = [];
for (var i = 0; i < value.length; i++) {
var ch = value.charAt(i);
switch (ch) {
case '\'':
result.push('\\\'');
break;
case '"':
result.push('\\"');
break;
case '\\':
result.push('\\\\');
break;
case '\n':
result.push('\\n');
break;
case '\r':
result.push('\\r');
break;
case '\t':
result.push('\\t');
break;
case '\b':
result.push('\\b');
break;
case '\f':
result.push('\\f');
break;
default:
result.push(ch);
}
}
return result.join('');
}
function processCoreBundleFormat(fileHeader, json, emitter) {
var keysSection = json.keys;
var messageSection = json.messages;
var bundleSection = json.bundles;
var statistics = Object.create(null);
var total = 0;
var defaultMessages = Object.create(null);
var modules = Object.keys(keysSection);
modules.forEach(function (module) {
var keys = keysSection[module];
var messages = messageSection[module];
if (!messages || keys.length !== messages.length) {
emitter.emit('error', "Message for module " + module + " corrupted. Mismatch in number of keys and messages.");
return;
}
var messageMap = Object.create(null);
defaultMessages[module] = messageMap;
keys.map(function (key, i) {
total++;
if (Is.string(key)) {
messageMap[key] = messages[i];
}
else {
messageMap[key.key] = messages[i];
}
});
});
var languageDirectory = path.join(__dirname, '..', '..', 'i18n');
var languages = sortLanguages(fs.readdirSync(languageDirectory).filter(function (item) { return fs.statSync(path.join(languageDirectory, item)).isDirectory(); }));
languages.forEach(function (language) {
if (!language.iso639_2) {
return;
}
if (process.env['VSCODE_BUILD_VERBOSE']) {
log("Generating nls bundles for: " + language.iso639_2);
}
statistics[language.iso639_2] = 0;
var localizedModules = Object.create(null);
var cwd = path.join(languageDirectory, language.name, 'src');
modules.forEach(function (module) {
var order = keysSection[module];
var i18nFile = path.join(cwd, module) + '.i18n.json';
var messages = null;
if (fs.existsSync(i18nFile)) {
var content = stripComments(fs.readFileSync(i18nFile, 'utf8'));
messages = JSON.parse(content);
}
else {
if (process.env['VSCODE_BUILD_VERBOSE']) {
log("No localized messages found for module " + module + ". Using default messages.");
}
messages = defaultMessages[module];
statistics[language.iso639_2] = statistics[language.iso639_2] + Object.keys(messages).length;
}
var localizedMessages = [];
order.forEach(function (keyInfo) {
var key = null;
if (Is.string(keyInfo)) {
key = keyInfo;
}
else {
key = keyInfo.key;
}
var message = messages[key];
if (!message) {
if (process.env['VSCODE_BUILD_VERBOSE']) {
log("No localized message found for key " + key + " in module " + module + ". Using default message.");
}
message = defaultMessages[module][key];
statistics[language.iso639_2] = statistics[language.iso639_2] + 1;
}
localizedMessages.push(message);
});
localizedModules[module] = localizedMessages;
});
Object.keys(bundleSection).forEach(function (bundle) {
var modules = bundleSection[bundle];
var contents = [
fileHeader,
"define(\"" + bundle + ".nls." + language.iso639_2 + "\", {"
];
modules.forEach(function (module, index) {
contents.push("\t\"" + module + "\": [");
var messages = localizedModules[module];
if (!messages) {
emitter.emit('error', "Didn't find messages for module " + module + ".");
return;
}
messages.forEach(function (message, index) {
contents.push("\t\t\"" + escapeCharacters(message) + (index < messages.length ? '",' : '"'));
});
contents.push(index < modules.length - 1 ? '\t],' : '\t]');
});
contents.push('});');
emitter.emit('data', new File({ path: bundle + '.nls.' + language.iso639_2 + '.js', contents: new Buffer(contents.join('\n'), 'utf-8') }));
});
});
Object.keys(statistics).forEach(function (key) {
var value = statistics[key];
log(key + " has " + value + " untranslated strings.");
});
vscodeLanguages.forEach(function (language) {
var iso639_2 = iso639_3_to_2[language];
if (!iso639_2) {
log("\tCouldn't find iso639 2 mapping for language " + language + ". Using default language instead.");
}
else {
var stats = statistics[iso639_2];
if (Is.undef(stats)) {
log("\tNo translations found for language " + language + ". Using default language instead.");
}
}
});
}
function processNlsFiles(opts) {
return event_stream_1.through(function (file) {
var fileName = path.basename(file.path);
if (fileName === 'nls.metadata.json') {
var json = null;
if (file.isBuffer()) {
json = JSON.parse(file.contents.toString('utf8'));
}
else {
this.emit('error', "Failed to read component file: " + file.relative);
}
if (BundledFormat.is(json)) {
processCoreBundleFormat(opts.fileHeader, json, this);
}
}
this.emit('data', file);
});
}
exports.processNlsFiles = processNlsFiles;
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var path = require("path");
var fs = require("fs");
var event_stream_1 = require("event-stream");
var File = require("vinyl");
var Is = require("is");
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.green('[i18n]'), message].concat(rest));
}
var LocalizeInfo;
(function (LocalizeInfo) {
function is(value) {
var candidate = value;
return Is.defined(candidate) && Is.string(candidate.key) && (Is.undef(candidate.comment) || (Is.array(candidate.comment) && candidate.comment.every(function (element) { return Is.string(element); })));
}
LocalizeInfo.is = is;
})(LocalizeInfo || (LocalizeInfo = {}));
var BundledFormat;
(function (BundledFormat) {
function is(value) {
if (Is.undef(value)) {
return false;
}
var candidate = value;
var length = Object.keys(value).length;
return length === 3 && Is.defined(candidate.keys) && Is.defined(candidate.messages) && Is.defined(candidate.bundles);
}
BundledFormat.is = is;
})(BundledFormat || (BundledFormat = {}));
var vscodeLanguages = [
'chs',
'cht',
'jpn',
'kor',
'deu',
'fra',
'esn',
'rus',
'ita'
];
var iso639_3_to_2 = {
'chs': 'zh-cn',
'cht': 'zh-tw',
'csy': 'cs-cz',
'deu': 'de',
'enu': 'en',
'esn': 'es',
'fra': 'fr',
'hun': 'hu',
'ita': 'it',
'jpn': 'ja',
'kor': 'ko',
'nld': 'nl',
'plk': 'pl',
'ptb': 'pt-br',
'ptg': 'pt',
'rus': 'ru',
'sve': 'sv-se',
'trk': 'tr'
};
function sortLanguages(directoryNames) {
return directoryNames.map(function (dirName) {
var lower = dirName.toLowerCase();
return {
name: lower,
iso639_2: iso639_3_to_2[lower]
};
}).sort(function (a, b) {
if (!a.iso639_2 && !b.iso639_2) {
return 0;
}
if (!a.iso639_2) {
return -1;
}
if (!b.iso639_2) {
return 1;
}
return a.iso639_2 < b.iso639_2 ? -1 : (a.iso639_2 > b.iso639_2 ? 1 : 0);
});
}
function stripComments(content) {
/**
* First capturing group matches double quoted string
* Second matches single quotes string
* Third matches block comments
* Fourth matches line comments
*/
var regexp = /("(?:[^\\\"]*(?:\\.)?)*")|('(?:[^\\\']*(?:\\.)?)*')|(\/\*(?:\r?\n|.)*?\*\/)|(\/{2,}.*?(?:(?:\r?\n)|$))/g;
var result = content.replace(regexp, function (match, m1, m2, m3, m4) {
// Only one of m1, m2, m3, m4 matches
if (m3) {
// A block comment. Replace with nothing
return '';
}
else if (m4) {
// A line comment. If it ends in \r?\n then keep it.
var length_1 = m4.length;
if (length_1 > 2 && m4[length_1 - 1] === '\n') {
return m4[length_1 - 2] === '\r' ? '\r\n' : '\n';
}
else {
return '';
}
}
else {
// We match a string
return match;
}
});
return result;
}
;
function escapeCharacters(value) {
var result = [];
for (var i = 0; i < value.length; i++) {
var ch = value.charAt(i);
switch (ch) {
case '\'':
result.push('\\\'');
break;
case '"':
result.push('\\"');
break;
case '\\':
result.push('\\\\');
break;
case '\n':
result.push('\\n');
break;
case '\r':
result.push('\\r');
break;
case '\t':
result.push('\\t');
break;
case '\b':
result.push('\\b');
break;
case '\f':
result.push('\\f');
break;
default:
result.push(ch);
}
}
return result.join('');
}
function processCoreBundleFormat(fileHeader, json, emitter) {
var keysSection = json.keys;
var messageSection = json.messages;
var bundleSection = json.bundles;
var statistics = Object.create(null);
var total = 0;
var defaultMessages = Object.create(null);
var modules = Object.keys(keysSection);
modules.forEach(function (module) {
var keys = keysSection[module];
var messages = messageSection[module];
if (!messages || keys.length !== messages.length) {
emitter.emit('error', "Message for module " + module + " corrupted. Mismatch in number of keys and messages.");
return;
}
var messageMap = Object.create(null);
defaultMessages[module] = messageMap;
keys.map(function (key, i) {
total++;
if (Is.string(key)) {
messageMap[key] = messages[i];
}
else {
messageMap[key.key] = messages[i];
}
});
});
var languageDirectory = path.join(__dirname, '..', '..', 'i18n');
var languages = sortLanguages(fs.readdirSync(languageDirectory).filter(function (item) { return fs.statSync(path.join(languageDirectory, item)).isDirectory(); }));
languages.forEach(function (language) {
if (!language.iso639_2) {
return;
}
if (process.env['VSCODE_BUILD_VERBOSE']) {
log("Generating nls bundles for: " + language.iso639_2);
}
statistics[language.iso639_2] = 0;
var localizedModules = Object.create(null);
var cwd = path.join(languageDirectory, language.name, 'src');
modules.forEach(function (module) {
var order = keysSection[module];
var i18nFile = path.join(cwd, module) + '.i18n.json';
var messages = null;
if (fs.existsSync(i18nFile)) {
var content = stripComments(fs.readFileSync(i18nFile, 'utf8'));
messages = JSON.parse(content);
}
else {
if (process.env['VSCODE_BUILD_VERBOSE']) {
log("No localized messages found for module " + module + ". Using default messages.");
}
messages = defaultMessages[module];
statistics[language.iso639_2] = statistics[language.iso639_2] + Object.keys(messages).length;
}
var localizedMessages = [];
order.forEach(function (keyInfo) {
var key = null;
if (Is.string(keyInfo)) {
key = keyInfo;
}
else {
key = keyInfo.key;
}
var message = messages[key];
if (!message) {
if (process.env['VSCODE_BUILD_VERBOSE']) {
log("No localized message found for key " + key + " in module " + module + ". Using default message.");
}
message = defaultMessages[module][key];
statistics[language.iso639_2] = statistics[language.iso639_2] + 1;
}
localizedMessages.push(message);
});
localizedModules[module] = localizedMessages;
});
Object.keys(bundleSection).forEach(function (bundle) {
var modules = bundleSection[bundle];
var contents = [
fileHeader,
"define(\"" + bundle + ".nls." + language.iso639_2 + "\", {"
];
modules.forEach(function (module, index) {
contents.push("\t\"" + module + "\": [");
var messages = localizedModules[module];
if (!messages) {
emitter.emit('error', "Didn't find messages for module " + module + ".");
return;
}
messages.forEach(function (message, index) {
contents.push("\t\t\"" + escapeCharacters(message) + (index < messages.length ? '",' : '"'));
});
contents.push(index < modules.length - 1 ? '\t],' : '\t]');
});
contents.push('});');
emitter.emit('data', new File({ path: bundle + '.nls.' + language.iso639_2 + '.js', contents: new Buffer(contents.join('\n'), 'utf-8') }));
});
});
Object.keys(statistics).forEach(function (key) {
var value = statistics[key];
log(key + " has " + value + " untranslated strings.");
});
vscodeLanguages.forEach(function (language) {
var iso639_2 = iso639_3_to_2[language];
if (!iso639_2) {
log("\tCouldn't find iso639 2 mapping for language " + language + ". Using default language instead.");
}
else {
var stats = statistics[iso639_2];
if (Is.undef(stats)) {
log("\tNo translations found for language " + language + ". Using default language instead.");
}
}
});
}
function processNlsFiles(opts) {
return event_stream_1.through(function (file) {
var fileName = path.basename(file.path);
if (fileName === 'nls.metadata.json') {
var json = null;
if (file.isBuffer()) {
json = JSON.parse(file.contents.toString('utf8'));
}
else {
this.emit('error', "Failed to read component file: " + file.relative);
}
if (BundledFormat.is(json)) {
processCoreBundleFormat(opts.fileHeader, json, this);
}
}
this.emit('data', file);
});
}
exports.processNlsFiles = processNlsFiles;

View file

@ -1,355 +1,355 @@
"use strict";
var ts = require("./typescript/typescriptServices");
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");
var CollectStepResult;
(function (CollectStepResult) {
CollectStepResult[CollectStepResult["Yes"] = 0] = "Yes";
CollectStepResult[CollectStepResult["YesAndRecurse"] = 1] = "YesAndRecurse";
CollectStepResult[CollectStepResult["No"] = 2] = "No";
CollectStepResult[CollectStepResult["NoAndRecurse"] = 3] = "NoAndRecurse";
})(CollectStepResult || (CollectStepResult = {}));
function collect(node, fn) {
var result = [];
function loop(node) {
var stepResult = fn(node);
if (stepResult === CollectStepResult.Yes || stepResult === CollectStepResult.YesAndRecurse) {
result.push(node);
}
if (stepResult === CollectStepResult.YesAndRecurse || stepResult === CollectStepResult.NoAndRecurse) {
ts.forEachChild(node, loop);
}
}
loop(node);
return result;
}
function clone(object) {
var result = {};
for (var id in object) {
result[id] = object[id];
}
return result;
}
function template(lines) {
var 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) + "]);";
}
/**
* 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;
if (!f.sourceMap) {
return this.emit('error', new Error("File " + f.relative + " does not have sourcemaps."));
}
var 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."));
}
var root = f.sourceMap.sourceRoot;
if (root) {
source = path.join(root, source);
}
var 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."));
}
nls.patchFiles(f, typescript).forEach(function (f) { return _this.emit('data', f); });
}));
return event_stream_1.duplex(input, output);
}
function isImportNode(node) {
return node.kind === 212 /* ImportDeclaration */ || node.kind === 211 /* ImportEqualsDeclaration */;
}
(function (nls_1) {
function fileFrom(file, contents, path) {
if (path === void 0) { path = file.path; }
return new File({
contents: new Buffer(contents),
base: file.base,
cwd: file.cwd,
path: path
});
}
nls_1.fileFrom = fileFrom;
function mappedPositionFrom(source, lc) {
return { source: 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 = (function () {
function SingleFileServiceHost(options, filename, contents) {
var _this = this;
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.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)) {
return CollectStepResult.No;
}
return node.kind === 160 /* 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 = service.getSourceFile(filename);
// all imports
var imports = lazy(collect(sourceFile, function (n) { return isImportNode(n) ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse; }));
// import nls = require('vs/nls');
var importEqualsDeclarations = imports
.filter(function (n) { return n.kind === 211 /* ImportEqualsDeclaration */; })
.map(function (n) { return n; })
.filter(function (d) { return d.moduleReference.kind === 222 /* ExternalModuleReference */; })
.filter(function (d) { return d.moduleReference.expression.getText() === '\'vs/nls\''; });
// import ... from 'vs/nls';
var importDeclarations = imports
.filter(function (n) { return n.kind === 212 /* ImportDeclaration */; })
.map(function (n) { return n; })
.filter(function (d) { return d.moduleSpecifier.kind === 8 /* 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 ({
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 === 214 /* NamespaceImport */; })
.map(function (d) { return d.importClause.namedBindings.name; })
.concat(importEqualsDeclarations.map(function (d) { return d.name; }))
.map(function (n) { return service.getReferencesAtPosition(filename, n.pos + 1); })
.flatten()
.filter(function (r) { return !r.isWriteAccess; })
.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; })
.filter(function (n) { return n.expression.kind === 158 /* PropertyAccessExpression */ && n.expression.name.getText() === 'localize'; });
// `localize` named imports
var allLocalizeImportDeclarations = importDeclarations
.filter(function (d) { return d.importClause.namedBindings.kind === 215 /* NamedImports */; })
.map(function (d) { return 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); })
.flatten()
.filter(function (r) { return !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); })
.flatten()
.filter(function (r) { return !r.isWriteAccess; });
// find the deepest call expressions AST nodes that contain those references
var 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; });
// collect everything
var 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 ({
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 = (function () {
function TextModel(contents) {
var regex = /\r\n|\r|\n/g;
var index = 0;
var match;
this.lines = [];
this.lineEndings = [];
while (match = regex.exec(contents)) {
this.lines.push(contents.substring(index, match.index));
this.lineEndings.push(match[0]);
index = regex.lastIndex;
}
if (contents.length > 0) {
this.lines.push(contents.substring(index, contents.length));
this.lineEndings.push('');
}
}
TextModel.prototype.get = function (index) {
return this.lines[index];
};
TextModel.prototype.set = function (index, line) {
this.lines[index] = line;
};
Object.defineProperty(TextModel.prototype, "lineCount", {
get: function () {
return this.lines.length;
},
enumerable: true,
configurable: true
});
/**
* 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] || '';
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++) {
this.lines[i] = '';
}
};
TextModel.prototype.toString = function () {
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);
// patch the localize calls
lazy(patches).reverse().each(function (p) { return 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");
model.set(0, patchedFirstLine);
return model.toString();
}
nls_1.patchJavascript = patchJavascript;
function patchSourcemap(patches, rsm, smc) {
var 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 };
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;
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 });
}, null, sm.SourceMapConsumer.GENERATED_ORDER);
if (source) {
smg.setSourceContent(source, smc.sourceContentFor(source));
}
return JSON.parse(smg.toString());
}
nls_1.patchSourcemap = patchSourcemap;
function patch(moduleId, typescript, javascript, sourcemap) {
var _a = analyze(typescript), localizeCalls = _a.localizeCalls, nlsExpressions = _a.nlsExpressions;
if (localizeCalls.length === 0) {
return { javascript: javascript, sourcemap: 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;
// build patches
var patches = lazy(localizeCalls)
.map(function (lc) { return ([
{ 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 };
})
.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");
});
}
sourcemap = patchSourcemap(patches, sourcemap, smc);
return { javascript: javascript, sourcemap: sourcemap, nlsKeys: nlsKeys, nls: nls };
}
nls_1.patch = patch;
function patchFiles(javascriptFile, typescript) {
// hack?
var 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)];
result[0].sourceMap = sourcemap;
if (nlsKeys) {
result.push(fileFrom(javascriptFile, nlsKeys, javascriptFile.path.replace(/\.js$/, '.nls.keys.js')));
}
if (nls) {
result.push(fileFrom(javascriptFile, nls, javascriptFile.path.replace(/\.js$/, '.nls.js')));
}
return result;
}
nls_1.patchFiles = patchFiles;
})(nls || (nls = {}));
module.exports = nls;
"use strict";
var ts = require("./typescript/typescriptServices");
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");
var CollectStepResult;
(function (CollectStepResult) {
CollectStepResult[CollectStepResult["Yes"] = 0] = "Yes";
CollectStepResult[CollectStepResult["YesAndRecurse"] = 1] = "YesAndRecurse";
CollectStepResult[CollectStepResult["No"] = 2] = "No";
CollectStepResult[CollectStepResult["NoAndRecurse"] = 3] = "NoAndRecurse";
})(CollectStepResult || (CollectStepResult = {}));
function collect(node, fn) {
var result = [];
function loop(node) {
var stepResult = fn(node);
if (stepResult === CollectStepResult.Yes || stepResult === CollectStepResult.YesAndRecurse) {
result.push(node);
}
if (stepResult === CollectStepResult.YesAndRecurse || stepResult === CollectStepResult.NoAndRecurse) {
ts.forEachChild(node, loop);
}
}
loop(node);
return result;
}
function clone(object) {
var result = {};
for (var id in object) {
result[id] = object[id];
}
return result;
}
function template(lines) {
var 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) + "]);";
}
/**
* 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;
if (!f.sourceMap) {
return this.emit('error', new Error("File " + f.relative + " does not have sourcemaps."));
}
var 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."));
}
var root = f.sourceMap.sourceRoot;
if (root) {
source = path.join(root, source);
}
var 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."));
}
nls.patchFiles(f, typescript).forEach(function (f) { return _this.emit('data', f); });
}));
return event_stream_1.duplex(input, output);
}
function isImportNode(node) {
return node.kind === 212 /* ImportDeclaration */ || node.kind === 211 /* ImportEqualsDeclaration */;
}
(function (nls_1) {
function fileFrom(file, contents, path) {
if (path === void 0) { path = file.path; }
return new File({
contents: new Buffer(contents),
base: file.base,
cwd: file.cwd,
path: path
});
}
nls_1.fileFrom = fileFrom;
function mappedPositionFrom(source, lc) {
return { source: 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 = (function () {
function SingleFileServiceHost(options, filename, contents) {
var _this = this;
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.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)) {
return CollectStepResult.No;
}
return node.kind === 160 /* 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 = service.getSourceFile(filename);
// all imports
var imports = lazy(collect(sourceFile, function (n) { return isImportNode(n) ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse; }));
// import nls = require('vs/nls');
var importEqualsDeclarations = imports
.filter(function (n) { return n.kind === 211 /* ImportEqualsDeclaration */; })
.map(function (n) { return n; })
.filter(function (d) { return d.moduleReference.kind === 222 /* ExternalModuleReference */; })
.filter(function (d) { return d.moduleReference.expression.getText() === '\'vs/nls\''; });
// import ... from 'vs/nls';
var importDeclarations = imports
.filter(function (n) { return n.kind === 212 /* ImportDeclaration */; })
.map(function (n) { return n; })
.filter(function (d) { return d.moduleSpecifier.kind === 8 /* 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 ({
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 === 214 /* NamespaceImport */; })
.map(function (d) { return d.importClause.namedBindings.name; })
.concat(importEqualsDeclarations.map(function (d) { return d.name; }))
.map(function (n) { return service.getReferencesAtPosition(filename, n.pos + 1); })
.flatten()
.filter(function (r) { return !r.isWriteAccess; })
.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; })
.filter(function (n) { return n.expression.kind === 158 /* PropertyAccessExpression */ && n.expression.name.getText() === 'localize'; });
// `localize` named imports
var allLocalizeImportDeclarations = importDeclarations
.filter(function (d) { return d.importClause.namedBindings.kind === 215 /* NamedImports */; })
.map(function (d) { return 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); })
.flatten()
.filter(function (r) { return !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); })
.flatten()
.filter(function (r) { return !r.isWriteAccess; });
// find the deepest call expressions AST nodes that contain those references
var 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; });
// collect everything
var 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 ({
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 = (function () {
function TextModel(contents) {
var regex = /\r\n|\r|\n/g;
var index = 0;
var match;
this.lines = [];
this.lineEndings = [];
while (match = regex.exec(contents)) {
this.lines.push(contents.substring(index, match.index));
this.lineEndings.push(match[0]);
index = regex.lastIndex;
}
if (contents.length > 0) {
this.lines.push(contents.substring(index, contents.length));
this.lineEndings.push('');
}
}
TextModel.prototype.get = function (index) {
return this.lines[index];
};
TextModel.prototype.set = function (index, line) {
this.lines[index] = line;
};
Object.defineProperty(TextModel.prototype, "lineCount", {
get: function () {
return this.lines.length;
},
enumerable: true,
configurable: true
});
/**
* 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] || '';
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++) {
this.lines[i] = '';
}
};
TextModel.prototype.toString = function () {
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);
// patch the localize calls
lazy(patches).reverse().each(function (p) { return 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");
model.set(0, patchedFirstLine);
return model.toString();
}
nls_1.patchJavascript = patchJavascript;
function patchSourcemap(patches, rsm, smc) {
var 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 };
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;
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 });
}, null, sm.SourceMapConsumer.GENERATED_ORDER);
if (source) {
smg.setSourceContent(source, smc.sourceContentFor(source));
}
return JSON.parse(smg.toString());
}
nls_1.patchSourcemap = patchSourcemap;
function patch(moduleId, typescript, javascript, sourcemap) {
var _a = analyze(typescript), localizeCalls = _a.localizeCalls, nlsExpressions = _a.nlsExpressions;
if (localizeCalls.length === 0) {
return { javascript: javascript, sourcemap: 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;
// build patches
var patches = lazy(localizeCalls)
.map(function (lc) { return ([
{ 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 };
})
.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");
});
}
sourcemap = patchSourcemap(patches, sourcemap, smc);
return { javascript: javascript, sourcemap: sourcemap, nlsKeys: nlsKeys, nls: nls };
}
nls_1.patch = patch;
function patchFiles(javascriptFile, typescript) {
// hack?
var 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)];
result[0].sourceMap = sourcemap;
if (nlsKeys) {
result.push(fileFrom(javascriptFile, nlsKeys, javascriptFile.path.replace(/\.js$/, '.nls.keys.js')));
}
if (nls) {
result.push(fileFrom(javascriptFile, nls, javascriptFile.path.replace(/\.js$/, '.nls.js')));
}
return result;
}
nls_1.patchFiles = patchFiles;
})(nls || (nls = {}));
module.exports = nls;

View file

@ -1,7 +1,6 @@
import * as ts from './typescript/typescriptServices';
import * as lazy from 'lazy.js';
import { duplex, through } from 'event-stream';
import { Stream } from 'stream';
import File = require('vinyl');
import * as sm from 'source-map';
import assign = require('object-assign');
@ -37,7 +36,7 @@ function collect(node: ts.Node, fn: (node: ts.Node) => CollectStepResult): ts.No
return result;
}
function clone<T>(object:T): T {
function clone<T>(object: T): T {
var result = <T>{};
for (var id in object) {
result[id] = object[id];
@ -56,7 +55,7 @@ function template(lines: string[]): string {
return `/*---------------------------------------------------------
* Copyright (C) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------*/
define([], [${ wrap + lines.map(l => indent + l).join(',\n') + wrap }]);`;
define([], [${ wrap + lines.map(l => indent + l).join(',\n') + wrap}]);`;
}
/**
@ -66,12 +65,12 @@ function nls(): NodeJS.ReadWriteStream {
var input = through();
var output = input.pipe(through(function (f: FileSourceMap) {
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.`));
}
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.`));
}
const root = f.sourceMap.sourceRoot;
@ -81,7 +80,7 @@ function nls(): NodeJS.ReadWriteStream {
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(f => this.emit('data', f));
@ -152,12 +151,12 @@ module nls {
this.lib = ts.ScriptSnapshot.fromString('');
}
getCompilationSettings = () => this.options;
getScriptFileNames = () => [this.filename];
getScriptVersion = () => '1';
getScriptSnapshot = (name: string) => name === this.filename ? this.file : this.lib;
getCurrentDirectory = () => '';
getDefaultLibFileName = () => 'lib.d.ts';
getCompilationSettings = () => this.options;
getScriptFileNames = () => [this.filename];
getScriptVersion = () => '1';
getScriptSnapshot = (name: string) => name === this.filename ? this.file : this.lib;
getCurrentDirectory = () => '';
getDefaultLibFileName = () => 'lib.d.ts';
}
function isCallExpressionWithinTextSpanCollectStep(textSpan: ts.TextSpan, node: ts.Node): CollectStepResult {
@ -180,14 +179,14 @@ module nls {
// import nls = require('vs/nls');
const importEqualsDeclarations = imports
.filter(n => n.kind === ts.SyntaxKind.ImportEqualsDeclaration)
.map(n => <ts.ImportEqualsDeclaration> n)
.map(n => <ts.ImportEqualsDeclaration>n)
.filter(d => d.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference)
.filter(d => (<ts.ExternalModuleReference>d.moduleReference).expression.getText() === '\'vs/nls\'');
// import ... from 'vs/nls';
const importDeclarations = imports
.filter(n => n.kind === ts.SyntaxKind.ImportDeclaration)
.map(n => <ts.ImportDeclaration> n)
.map(n => <ts.ImportDeclaration>n)
.filter(d => d.moduleSpecifier.kind === ts.SyntaxKind.StringLiteral)
.filter(d => d.moduleSpecifier.getText() === '\'vs/nls\'')
.filter(d => !!d.importClause && !!d.importClause.namedBindings);
@ -203,7 +202,7 @@ 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)
.map(d => (<ts.NamespaceImport>d.importClause.namedBindings).name)
.concat(importEqualsDeclarations.map(d => d.name))
// find read-only references to `nls`
@ -215,15 +214,15 @@ module nls {
.map(r => collect(sourceFile, n => isCallExpressionWithinTextSpanCollectStep(r.textSpan, n)))
.map(a => lazy(a).last())
.filter(n => !!n)
.map(n => <ts.CallExpression> n)
.map(n => <ts.CallExpression>n)
// only `localize` calls
.filter(n => n.expression.kind === ts.SyntaxKind.PropertyAccessExpression && (<ts.PropertyAccessExpression> n.expression).name.getText() === 'localize');
.filter(n => n.expression.kind === ts.SyntaxKind.PropertyAccessExpression && (<ts.PropertyAccessExpression>n.expression).name.getText() === 'localize');
// `localize` named imports
const allLocalizeImportDeclarations = importDeclarations
.filter(d => d.importClause.namedBindings.kind === ts.SyntaxKind.NamedImports)
.map(d => (<ts.NamedImports> d.importClause.namedBindings).elements)
.map(d => (<ts.NamedImports>d.importClause.namedBindings).elements)
.flatten();
// `localize` read-only references
@ -246,7 +245,7 @@ module nls {
.map(r => collect(sourceFile, n => isCallExpressionWithinTextSpanCollectStep(r.textSpan, n)))
.map(a => lazy(a).last())
.filter(n => !!n)
.map(n => <ts.CallExpression> n);
.map(n => <ts.CallExpression>n);
// collect everything
const localizeCalls = nlsLocalizeCallExpressions
@ -341,7 +340,7 @@ module nls {
// patch the 'vs/nls' imports
const firstLine = model.get(0);
const patchedFirstLine = firstLine.replace(/(['"])vs\/nls\1/g, `$1vs/nls!${ moduleId }$1`);
const patchedFirstLine = firstLine.replace(/(['"])vs\/nls\1/g, `$1vs/nls!${moduleId}$1`);
model.set(0, patchedFirstLine);
return model.toString();
@ -382,7 +381,7 @@ module nls {
source = rsm.sourceRoot ? path.relative(rsm.sourceRoot, m.source) : m.source;
source = source.replace(/\\/g, '/');
smg.addMapping({ source, name: m.name, original, generated});
smg.addMapping({ source, name: m.name, original, generated });
}, null, sm.SourceMapConsumer.GENERATED_ORDER);
if (source) {
@ -425,7 +424,7 @@ module nls {
// we must do this MacGyver style
if (nlsExpressions.length) {
javascript = javascript.replace(/^define\(.*$/m, line => {
return line.replace(/(['"])vs\/nls\1/g, `$1vs/nls!${ moduleId }$1`);
return line.replace(/(['"])vs\/nls\1/g, `$1vs/nls!${moduleId}$1`);
});
}

View file

@ -1,229 +1,230 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
var path = require("path");
var gulp = require("gulp");
var sourcemaps = require("gulp-sourcemaps");
var filter = require("gulp-filter");
var minifyCSS = require("gulp-cssnano");
var uglify = require("gulp-uglify");
var es = require("event-stream");
var concat = require("gulp-concat");
var VinylFile = require("vinyl");
var bundle = require("./bundle");
var util = require("./util");
var i18n = require("./i18n");
var gulpUtil = require("gulp-util");
var flatmap = require("gulp-flatmap");
var pump = require("pump");
var REPO_ROOT_PATH = path.join(__dirname, '../..');
function log(prefix, message) {
gulpUtil.log(gulpUtil.colors.cyan('[' + prefix + ']'), message);
}
function loaderConfig(emptyPaths) {
var result = {
paths: {
'vs': 'out-build/vs',
'vscode': 'empty:'
},
nodeModules: emptyPaths || []
};
result['vs/css'] = { inlineResources: true };
return result;
}
exports.loaderConfig = loaderConfig;
var IS_OUR_COPYRIGHT_REGEXP = /Copyright \(C\) Microsoft Corporation/i;
function loader(bundledFileHeader, bundleLoader) {
var sources = [
'out-build/vs/loader.js'
];
if (bundleLoader) {
sources = sources.concat([
'out-build/vs/css.js',
'out-build/vs/nls.js'
]);
}
var isFirst = true;
return (gulp
.src(sources, { base: 'out-build' })
.pipe(es.through(function (data) {
if (isFirst) {
isFirst = false;
this.emit('data', new VinylFile({
path: 'fake',
base: '',
contents: new Buffer(bundledFileHeader)
}));
this.emit('data', data);
}
else {
this.emit('data', data);
}
}))
.pipe(util.loadSourcemaps())
.pipe(concat('vs/loader.js'))
.pipe(es.mapSync(function (f) {
f.sourceMap.sourceRoot = util.toFileUri(path.join(REPO_ROOT_PATH, 'src'));
return f;
})));
}
function toConcatStream(bundledFileHeader, sources, dest) {
var 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;
if (IS_OUR_COPYRIGHT_REGEXP.test(fileContents)) {
containsOurCopyright = true;
break;
}
}
if (containsOurCopyright) {
sources.unshift({
path: null,
contents: bundledFileHeader
});
}
var treatedSources = sources.map(function (source) {
var root = source.path ? REPO_ROOT_PATH.replace(/\\/g, '/') : '';
var base = source.path ? root + '/out-build' : '';
return new VinylFile({
path: source.path ? root + '/' + source.path.replace(/\\/g, '/') : 'fake',
base: base,
contents: new Buffer(source.contents)
});
});
return es.readArray(treatedSources)
.pipe(useSourcemaps ? util.loadSourcemaps() : es.through())
.pipe(concat(dest));
}
function toBundleStream(bundledFileHeader, bundles) {
return es.merge(bundles.map(function (bundle) {
return toConcatStream(bundledFileHeader, bundle.sources, bundle.dest);
}));
}
function optimizeTask(opts) {
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;
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
bundle.bundle(entryPoints, loaderConfig, function (err, result) {
if (err) {
return bundlesStream.emit('error', JSON.stringify(err));
}
toBundleStream(bundledFileHeader, result.files).pipe(bundlesStream);
// Remove css inlined resources
var 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: 'out-build' }).pipe(resourcesStream);
var bundleInfoArray = [];
if (opts.bundleInfo) {
bundleInfoArray.push(new VinylFile({
path: 'bundleInfo.json',
base: '.',
contents: new Buffer(JSON.stringify(result.bundleData, null, '\t'))
}));
}
es.readArray(bundleInfoArray).pipe(bundleInfoStream);
});
var otherSourcesStream = es.through();
var otherSourcesStreamArr = [];
gulp.src(otherSources, { base: 'out-build' })
.pipe(es.through(function (data) {
otherSourcesStreamArr.push(toConcatStream(bundledFileHeader, [data], data.relative));
}, function () {
if (!otherSourcesStreamArr.length) {
setTimeout(function () { otherSourcesStream.emit('end'); }, 0);
}
else {
es.merge(otherSourcesStreamArr).pipe(otherSourcesStream);
}
}));
var result = es.merge(loader(bundledFileHeader, bundleLoader), bundlesStream, otherSourcesStream, resourcesStream, bundleInfoStream);
return result
.pipe(sourcemaps.write('./', {
sourceRoot: null,
addComment: true,
includeContent: true
}))
.pipe(i18n.processNlsFiles({
fileHeader: bundledFileHeader
}))
.pipe(gulp.dest(out));
};
}
exports.optimizeTask = optimizeTask;
;
/**
* Wrap around uglify and allow the preserveComments function
* 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;
if (/@minifier_do_not_preserve/.test(text)) {
return false;
}
var isOurCopyright = IS_OUR_COPYRIGHT_REGEXP.test(text);
if (isOurCopyright) {
if (f.__hasOurCopyright) {
return false;
}
f.__hasOurCopyright = true;
return true;
}
if ('comment2' === type) {
// check for /*!. Note that text doesn't contain leading /*
return (text.length > 0 && text[0] === '!') || /@preserve|license|@cc_on|copyright/i.test(text);
}
else if ('comment1' === type) {
return /license|copyright/i.test(text);
}
return false;
};
};
var input = es.through();
var output = input
.pipe(flatmap(function (stream, f) {
return stream
.pipe(uglify({ preserveComments: preserveComments(f) }));
}));
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 });
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,
includeContent: true,
addComment: true
}), gulp.dest(src + '-min'), function (err) {
if (err instanceof uglify.GulpUglifyError) {
console.error("Uglify error in '" + (err.cause && err.cause.filename) + "'");
}
cb(err);
});
};
}
exports.minifyTask = minifyTask;
;
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var path = require("path");
var gulp = require("gulp");
var sourcemaps = require("gulp-sourcemaps");
var filter = require("gulp-filter");
var minifyCSS = require("gulp-cssnano");
var uglify = require("gulp-uglify");
var es = require("event-stream");
var concat = require("gulp-concat");
var VinylFile = require("vinyl");
var bundle = require("./bundle");
var util = require("./util");
var i18n = require("./i18n");
var gulpUtil = require("gulp-util");
var flatmap = require("gulp-flatmap");
var pump = require("pump");
var REPO_ROOT_PATH = path.join(__dirname, '../..');
function log(prefix, message) {
gulpUtil.log(gulpUtil.colors.cyan('[' + prefix + ']'), message);
}
function loaderConfig(emptyPaths) {
var result = {
paths: {
'vs': 'out-build/vs',
'vscode': 'empty:'
},
nodeModules: emptyPaths || []
};
result['vs/css'] = { inlineResources: true };
return result;
}
exports.loaderConfig = loaderConfig;
var IS_OUR_COPYRIGHT_REGEXP = /Copyright \(C\) Microsoft Corporation/i;
function loader(bundledFileHeader, bundleLoader) {
var sources = [
'out-build/vs/loader.js'
];
if (bundleLoader) {
sources = sources.concat([
'out-build/vs/css.js',
'out-build/vs/nls.js'
]);
}
var isFirst = true;
return (gulp
.src(sources, { base: 'out-build' })
.pipe(es.through(function (data) {
if (isFirst) {
isFirst = false;
this.emit('data', new VinylFile({
path: 'fake',
base: '',
contents: new Buffer(bundledFileHeader)
}));
this.emit('data', data);
}
else {
this.emit('data', data);
}
}))
.pipe(util.loadSourcemaps())
.pipe(concat('vs/loader.js'))
.pipe(es.mapSync(function (f) {
f.sourceMap.sourceRoot = util.toFileUri(path.join(REPO_ROOT_PATH, 'src'));
return f;
})));
}
function toConcatStream(bundledFileHeader, sources, dest) {
var 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;
if (IS_OUR_COPYRIGHT_REGEXP.test(fileContents)) {
containsOurCopyright = true;
break;
}
}
if (containsOurCopyright) {
sources.unshift({
path: null,
contents: bundledFileHeader
});
}
var treatedSources = sources.map(function (source) {
var root = source.path ? REPO_ROOT_PATH.replace(/\\/g, '/') : '';
var base = source.path ? root + '/out-build' : '';
return new VinylFile({
path: source.path ? root + '/' + source.path.replace(/\\/g, '/') : 'fake',
base: base,
contents: new Buffer(source.contents)
});
});
return es.readArray(treatedSources)
.pipe(useSourcemaps ? util.loadSourcemaps() : es.through())
.pipe(concat(dest));
}
function toBundleStream(bundledFileHeader, bundles) {
return es.merge(bundles.map(function (bundle) {
return toConcatStream(bundledFileHeader, bundle.sources, bundle.dest);
}));
}
function optimizeTask(opts) {
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;
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
bundle.bundle(entryPoints, loaderConfig, function (err, result) {
if (err) {
return bundlesStream.emit('error', JSON.stringify(err));
}
toBundleStream(bundledFileHeader, result.files).pipe(bundlesStream);
// Remove css inlined resources
var 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: 'out-build' }).pipe(resourcesStream);
var bundleInfoArray = [];
if (opts.bundleInfo) {
bundleInfoArray.push(new VinylFile({
path: 'bundleInfo.json',
base: '.',
contents: new Buffer(JSON.stringify(result.bundleData, null, '\t'))
}));
}
es.readArray(bundleInfoArray).pipe(bundleInfoStream);
});
var otherSourcesStream = es.through();
var otherSourcesStreamArr = [];
gulp.src(otherSources, { base: 'out-build' })
.pipe(es.through(function (data) {
otherSourcesStreamArr.push(toConcatStream(bundledFileHeader, [data], data.relative));
}, function () {
if (!otherSourcesStreamArr.length) {
setTimeout(function () { otherSourcesStream.emit('end'); }, 0);
}
else {
es.merge(otherSourcesStreamArr).pipe(otherSourcesStream);
}
}));
var result = es.merge(loader(bundledFileHeader, bundleLoader), bundlesStream, otherSourcesStream, resourcesStream, bundleInfoStream);
return result
.pipe(sourcemaps.write('./', {
sourceRoot: null,
addComment: true,
includeContent: true
}))
.pipe(i18n.processNlsFiles({
fileHeader: bundledFileHeader
}))
.pipe(gulp.dest(out));
};
}
exports.optimizeTask = optimizeTask;
;
/**
* Wrap around uglify and allow the preserveComments function
* 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;
if (/@minifier_do_not_preserve/.test(text)) {
return false;
}
var isOurCopyright = IS_OUR_COPYRIGHT_REGEXP.test(text);
if (isOurCopyright) {
if (f.__hasOurCopyright) {
return false;
}
f.__hasOurCopyright = true;
return true;
}
if ('comment2' === type) {
// check for /*!. Note that text doesn't contain leading /*
return (text.length > 0 && text[0] === '!') || /@preserve|license|@cc_on|copyright/i.test(text);
}
else if ('comment1' === type) {
return /license|copyright/i.test(text);
}
return false;
};
};
var input = es.through();
var output = input
.pipe(flatmap(function (stream, f) {
return stream
.pipe(uglify({ preserveComments: preserveComments(f) }));
}));
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 });
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,
includeContent: true,
addComment: true
}), gulp.dest(src + '-min'), function (err) {
if (err instanceof uglify.GulpUglifyError) {
console.error("Uglify error in '" + (err.cause && err.cause.filename) + "'");
}
cb(err);
});
};
}
exports.minifyTask = minifyTask;
;

View file

@ -1,80 +1,83 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
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;
function onStart() {
if (count++ > 0) {
return;
}
startTime = new Date().getTime();
util.log("Starting " + util.colors.green('compilation') + "...");
}
function onEnd() {
if (--count > 0) {
return;
}
log();
}
var buildLogPath = path.join(path.dirname(path.dirname(__dirname)), '.build', 'log');
try {
fs.mkdirSync(path.dirname(buildLogPath));
}
catch (err) {
}
function log() {
var errors = _.flatten(allErrors);
errors.map(function (err) { return 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: Number.parseInt(line), column: Number.parseInt(column), message: message });
});
try {
fs.writeFileSync(buildLogPath, JSON.stringify(messages));
}
catch (err) {
}
util.log("Finished " + util.colors.green('compilation') + " with " + errors.length + " errors after " + util.colors.magenta((new Date().getTime() - startTime) + ' ms'));
}
function createReporter() {
var errors = [];
allErrors.push(errors);
var ReportFunc = (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) {
log();
this.emit('error');
}
else {
this.emit('end');
}
});
};
return ReportFunc;
}());
return ReportFunc;
}
exports.createReporter = createReporter;
;
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'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;
function onStart() {
if (count++ > 0) {
return;
}
startTime = new Date().getTime();
util.log("Starting " + util.colors.green('compilation') + "...");
}
function onEnd() {
if (--count > 0) {
return;
}
log();
}
var buildLogPath = path.join(path.dirname(path.dirname(__dirname)), '.build', 'log');
try {
fs.mkdirSync(path.dirname(buildLogPath));
}
catch (err) {
// ignore
}
function log() {
var errors = _.flatten(allErrors);
errors.map(function (err) { return 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: Number.parseInt(line), column: Number.parseInt(column), message: 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'));
}
function createReporter() {
var errors = [];
allErrors.push(errors);
var ReportFunc = (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) {
log();
this.emit('error');
}
else {
this.emit('end');
}
});
};
return ReportFunc;
}());
return ReportFunc;
}
exports.createReporter = createReporter;
;

View file

@ -1,44 +1,50 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
"use strict";
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var path_1 = require("path");
var Lint = require("tslint");
var Rule = (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
return this.applyWithWalker(new ImportPatterns(sourceFile, this.getOptions()));
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
var ImportPatterns = (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();
// 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.imports[path] = true;
};
return ImportPatterns;
}(Lint.RuleWalker));
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
"use strict";
var __extends = (this && this.__extends) || (function () {
var 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 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 = (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
return this.applyWithWalker(new ImportPatterns(sourceFile, this.getOptions()));
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
var ImportPatterns = (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();
// 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.imports[path] = true;
};
return ImportPatterns;
}(Lint.RuleWalker));

View file

@ -1,51 +1,57 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
"use strict";
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var Lint = require("tslint");
var minimatch = require("minimatch");
var Rule = (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];
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 = (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.visitImportDeclaration = function (node) {
var path = node.moduleSpecifier.getText();
// remove quotes
path = path.slice(1, -1);
// ignore relative paths
if (path[0] === '.') {
return;
}
if (!minimatch(path, this._config.restrictions)) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), "Imports violates '" + this._config.restrictions + "'-restriction."));
}
};
return ImportPatterns;
}(Lint.RuleWalker));
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
"use strict";
var __extends = (this && this.__extends) || (function () {
var 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 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 minimatch = require("minimatch");
var Rule = (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];
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 = (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.visitImportDeclaration = function (node) {
var path = node.moduleSpecifier.getText();
// remove quotes
path = path.slice(1, -1);
// ignore relative paths
if (path[0] === '.') {
return;
}
if (!minimatch(path, this._config.restrictions)) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), "Imports violates '" + this._config.restrictions + "'-restriction."));
}
};
return ImportPatterns;
}(Lint.RuleWalker));

View file

@ -12,7 +12,6 @@ interface ImportPatternsConfig {
restrictions: string;
}
export class Rule extends Lint.Rules.AbstractRule {
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {

View file

@ -1,79 +1,85 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
"use strict";
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var Lint = require("tslint");
var path_1 = require("path");
var Rule = (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--) {
if (ruleArgs[parts[i]]) {
config = {
allowed: new Set(ruleArgs[parts[i]]).add(parts[i]),
disallowed: new Set()
};
Object.keys(ruleArgs).forEach(function (key) {
if (!config.allowed.has(key)) {
config.disallowed.add(key);
}
});
break;
}
}
if (!config) {
return [];
}
return this.applyWithWalker(new LayeringRule(sourceFile, config, this.getOptions()));
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
var LayeringRule = (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.visitImportDeclaration = function (node) {
var 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);
}
var parts = path_1.dirname(path).split(/\\|\//);
for (var i = parts.length - 1; i >= 0; i--) {
var 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) + "]";
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), message));
return;
}
}
};
LayeringRule._print = function (set) {
var r = [];
set.forEach(function (e) { return r.push(e); });
return r.join(', ');
};
return LayeringRule;
}(Lint.RuleWalker));
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
"use strict";
var __extends = (this && this.__extends) || (function () {
var 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 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 path_1 = require("path");
var Rule = (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--) {
if (ruleArgs[parts[i]]) {
config = {
allowed: new Set(ruleArgs[parts[i]]).add(parts[i]),
disallowed: new Set()
};
Object.keys(ruleArgs).forEach(function (key) {
if (!config.allowed.has(key)) {
config.disallowed.add(key);
}
});
break;
}
}
if (!config) {
return [];
}
return this.applyWithWalker(new LayeringRule(sourceFile, config, this.getOptions()));
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
var LayeringRule = (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.visitImportDeclaration = function (node) {
var 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);
}
var parts = path_1.dirname(path).split(/\\|\//);
for (var i = parts.length - 1; i >= 0; i--) {
var 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) + "]";
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), message));
return;
}
}
};
LayeringRule._print = function (set) {
var r = [];
set.forEach(function (e) { return r.push(e); });
return r.join(', ');
};
return LayeringRule;
}(Lint.RuleWalker));

View file

@ -1,171 +1,177 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
"use strict";
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var ts = require("typescript");
var Lint = require("tslint");
/**
* Implementation of the no-unexternalized-strings rule.
*/
var Rule = (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (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;
}
function isObjectLiteral(node) {
return node && node.kind === ts.SyntaxKind.ObjectLiteralExpression;
}
function isPropertyAssignment(node) {
return node && node.kind === ts.SyntaxKind.PropertyAssignment;
}
var NoUnexternalizedStringsRuleWalker = (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;
if (first) {
if (Array.isArray(first.signatures)) {
first.signatures.forEach(function (signature) { return _this.signatures[signature] = true; });
}
if (Array.isArray(first.ignores)) {
first.ignores.forEach(function (ignore) { return _this.ignores[ignore] = true; });
}
if (typeof first.messageIndex !== 'undefined') {
_this.messageIndex = first.messageIndex;
}
if (typeof first.keyIndex !== 'undefined') {
_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 occurences = _this.usedKeys[key];
if (occurences.length > 1) {
occurences.forEach(function (occurence) {
_this.addFailure((_this.createFailure(occurence.key.getStart(), occurence.key.getWidth(), "Duplicate key " + occurence.key.getText() + " with different message value.")));
});
}
});
};
NoUnexternalizedStringsRuleWalker.prototype.visitStringLiteral = function (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);
// Ignore strings in import and export nodes.
if (info && info.ignoreUsage) {
return;
}
var callInfo = info ? info.callInfo : null;
var 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 replacement = new Lint.Replacement(node.getStart(), node.getWidth(), "nls.localize('KEY-" + s.substring(1, s.length - 1) + "', " + s + ")");
var fix = new Lint.Fix("Unexternalitzed string", [replacement]);
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.
if (!doubleQuoted && !this.signatures[functionName]) {
return;
}
// We have a string that is a direct argument into the localize call.
var keyArg = 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);
}
else if (isObjectLiteral(keyArg)) {
for (var i = 0; i < keyArg.properties.length; i++) {
var property = keyArg.properties[i];
if (isPropertyAssignment(property)) {
var name_1 = property.name.getText();
if (name_1 === 'key') {
var initializer = property.initializer;
if (isStringLiteral(initializer)) {
this.recordKey(initializer, this.messageIndex ? callInfo.callExpression.arguments[this.messageIndex] : undefined);
}
break;
}
}
}
}
}
var messageArg = callInfo.argIndex === this.messageIndex
? callInfo.callExpression.arguments[this.messageIndex]
: null;
if (messageArg && messageArg !== node) {
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();
var occurences = this.usedKeys[text];
if (!occurences) {
occurences = [];
this.usedKeys[text] = occurences;
}
if (messageNode) {
if (occurences.some(function (pair) { return pair.message ? pair.message.getText() === messageNode.getText() : false; })) {
return;
}
}
occurences.push({ key: keyNode, message: messageNode });
};
NoUnexternalizedStringsRuleWalker.prototype.findDescribingParent = function (node) {
var parent;
while ((parent = node.parent)) {
var kind = parent.kind;
if (kind === ts.SyntaxKind.CallExpression) {
var 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) {
return { ignoreUsage: true };
}
else if (kind === ts.SyntaxKind.VariableDeclaration || kind === ts.SyntaxKind.FunctionDeclaration || kind === ts.SyntaxKind.PropertyDeclaration
|| kind === ts.SyntaxKind.MethodDeclaration || kind === ts.SyntaxKind.VariableDeclarationList || kind === ts.SyntaxKind.InterfaceDeclaration
|| kind === ts.SyntaxKind.ClassDeclaration || kind === ts.SyntaxKind.EnumDeclaration || kind === ts.SyntaxKind.ModuleDeclaration
|| kind === ts.SyntaxKind.TypeAliasDeclaration || kind === ts.SyntaxKind.SourceFile) {
return null;
}
node = parent;
}
};
return NoUnexternalizedStringsRuleWalker;
}(Lint.RuleWalker));
NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE = '"';
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
"use strict";
var __extends = (this && this.__extends) || (function () {
var 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 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");
/**
* Implementation of the no-unexternalized-strings rule.
*/
var Rule = (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (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;
}
function isObjectLiteral(node) {
return node && node.kind === ts.SyntaxKind.ObjectLiteralExpression;
}
function isPropertyAssignment(node) {
return node && node.kind === ts.SyntaxKind.PropertyAssignment;
}
var NoUnexternalizedStringsRuleWalker = (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;
if (first) {
if (Array.isArray(first.signatures)) {
first.signatures.forEach(function (signature) { return _this.signatures[signature] = true; });
}
if (Array.isArray(first.ignores)) {
first.ignores.forEach(function (ignore) { return _this.ignores[ignore] = true; });
}
if (typeof first.messageIndex !== 'undefined') {
_this.messageIndex = first.messageIndex;
}
if (typeof first.keyIndex !== 'undefined') {
_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 occurences = _this.usedKeys[key];
if (occurences.length > 1) {
occurences.forEach(function (occurence) {
_this.addFailure((_this.createFailure(occurence.key.getStart(), occurence.key.getWidth(), "Duplicate key " + occurence.key.getText() + " with different message value.")));
});
}
});
};
NoUnexternalizedStringsRuleWalker.prototype.visitStringLiteral = function (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);
// Ignore strings in import and export nodes.
if (info && info.ignoreUsage) {
return;
}
var callInfo = info ? info.callInfo : null;
var 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 replacement = new Lint.Replacement(node.getStart(), node.getWidth(), "nls.localize('KEY-" + s.substring(1, s.length - 1) + "', " + s + ")");
var fix = new Lint.Fix('Unexternalitzed string', [replacement]);
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.
if (!doubleQuoted && !this.signatures[functionName]) {
return;
}
// We have a string that is a direct argument into the localize call.
var keyArg = 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);
}
else if (isObjectLiteral(keyArg)) {
for (var i = 0; i < keyArg.properties.length; i++) {
var property = keyArg.properties[i];
if (isPropertyAssignment(property)) {
var name_1 = property.name.getText();
if (name_1 === 'key') {
var initializer = property.initializer;
if (isStringLiteral(initializer)) {
this.recordKey(initializer, this.messageIndex ? callInfo.callExpression.arguments[this.messageIndex] : undefined);
}
break;
}
}
}
}
}
var messageArg = callInfo.argIndex === this.messageIndex
? callInfo.callExpression.arguments[this.messageIndex]
: null;
if (messageArg && messageArg !== node) {
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();
var occurences = this.usedKeys[text];
if (!occurences) {
occurences = [];
this.usedKeys[text] = occurences;
}
if (messageNode) {
if (occurences.some(function (pair) { return pair.message ? pair.message.getText() === messageNode.getText() : false; })) {
return;
}
}
occurences.push({ key: keyNode, message: messageNode });
};
NoUnexternalizedStringsRuleWalker.prototype.findDescribingParent = function (node) {
var parent;
while ((parent = node.parent)) {
var kind = parent.kind;
if (kind === ts.SyntaxKind.CallExpression) {
var 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) {
return { ignoreUsage: true };
}
else if (kind === ts.SyntaxKind.VariableDeclaration || kind === ts.SyntaxKind.FunctionDeclaration || kind === ts.SyntaxKind.PropertyDeclaration
|| kind === ts.SyntaxKind.MethodDeclaration || kind === ts.SyntaxKind.VariableDeclarationList || kind === ts.SyntaxKind.InterfaceDeclaration
|| kind === ts.SyntaxKind.ClassDeclaration || kind === ts.SyntaxKind.EnumDeclaration || kind === ts.SyntaxKind.ModuleDeclaration
|| kind === ts.SyntaxKind.TypeAliasDeclaration || kind === ts.SyntaxKind.SourceFile) {
return null;
}
node = parent;
}
};
return NoUnexternalizedStringsRuleWalker;
}(Lint.RuleWalker));
NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE = '"';

View file

@ -113,7 +113,7 @@ class NoUnexternalizedStringsRuleWalker extends Lint.RuleWalker {
if (doubleQuoted && (!callInfo || callInfo.argIndex === -1 || !this.signatures[functionName])) {
const s = node.getText();
const replacement = new Lint.Replacement(node.getStart(), node.getWidth(), `nls.localize('KEY-${s.substring(1, s.length - 1)}', ${s})`);
const fix = new Lint.Fix("Unexternalitzed string", [replacement]);
const fix = new Lint.Fix('Unexternalitzed string', [replacement]);
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), `Unexternalized string found: ${node.getText()}`, fix));
return;
}

View file

@ -1,210 +1,213 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
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; } };
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) {
state = 'running';
var stream = !supportsCancellation ? streamProvider() : streamProvider(isCancellable ? token : NoCancellationToken);
input
.pipe(stream)
.pipe(es.through(null, function () {
state = 'idle';
eventuallyRun();
}))
.pipe(output);
};
if (initial) {
run(initial, false);
}
var eventuallyRun = debounce(function () {
var paths = Object.keys(buffer);
if (paths.length === 0) {
return;
}
var data = paths.map(function (path) { return buffer[path]; });
buffer = Object.create(null);
run(es.readArray(data), true);
}, 500);
input.on('data', function (f) {
buffer[f.path] = f;
if (state === 'idle') {
eventuallyRun();
}
});
return es.duplex(input, output);
}
exports.incremental = incremental;
function fixWin32DirectoryPermissions() {
if (!/win32/.test(process.platform)) {
return es.through();
}
return es.mapSync(function (f) {
if (f.stat && f.stat.isDirectory && f.stat.isDirectory()) {
f.stat.mode = 16877;
}
return f;
});
}
exports.fixWin32DirectoryPermissions = fixWin32DirectoryPermissions;
function setExecutableBit(pattern) {
var setBit = es.mapSync(function (f) {
f.stat.mode = 33261;
return f;
});
if (!pattern) {
return setBit;
}
var input = es.through();
var filter = _filter(pattern, { restore: true });
var output = input
.pipe(filter)
.pipe(setBit)
.pipe(filter.restore);
return es.duplex(input, output);
}
exports.setExecutableBit = setExecutableBit;
function toFileUri(filePath) {
var match = filePath.match(/^([a-z])\:(.*)$/i);
if (match) {
filePath = '/' + match[1].toUpperCase() + ':' + match[2];
}
return 'file://' + filePath.replace(/\\/g, '/');
}
exports.toFileUri = toFileUri;
function skipDirectories() {
return es.mapSync(function (f) {
if (!f.isDirectory()) {
return f;
}
});
}
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));
if (includes) {
var includeGlobs = includes.map(toGlob);
output = es.merge(output, nodeModuleInput.pipe(_filter(includeGlobs)));
}
output = output.pipe(allFilter.restore);
return es.duplex(input, output);
}
exports.cleanNodeModule = cleanNodeModule;
function loadSourcemaps() {
var input = es.through();
var output = input
.pipe(es.map(function (f, cb) {
if (f.sourceMap) {
cb(null, 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;
while (match = reg.exec(contents)) {
lastMatch = match;
}
if (!lastMatch) {
f.sourceMap = {
version: 3,
names: [],
mappings: '',
sources: [f.relative.replace(/\//g, '/')],
sourcesContent: [contents]
};
cb(null, f);
return;
}
f.contents = new Buffer(contents.replace(/\/\/# sourceMappingURL=(.*)$/g, ''), 'utf8');
fs.readFile(path.join(path.dirname(f.path), lastMatch[1]), 'utf8', function (err, contents) {
if (err) {
return cb(err);
}
f.sourceMap = JSON.parse(contents);
cb(null, 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');
f.contents = new Buffer(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, ''), 'utf8');
return f;
}));
return es.duplex(input, output);
}
exports.stripSourceMappingURL = stripSourceMappingURL;
function rimraf(dir) {
var retries = 0;
var retry = function (cb) {
_rimraf(dir, { maxBusyTries: 1 }, function (err) {
if (!err)
return cb();
if (err.code === 'ENOTEMPTY' && ++retries < 5)
return setTimeout(function () { return retry(cb); }, 10);
else
return cb(err);
});
};
return function (cb) { return retry(cb); };
}
exports.rimraf = rimraf;
function getVersion(root) {
var version = process.env['BUILD_SOURCEVERSION'];
if (!version || !/^[0-9a-f]{40}$/i.test(version)) {
version = git.getVersion(root);
}
return version;
}
exports.getVersion = getVersion;
function rebase(count) {
return rename(function (f) {
var parts = f.dirname.split(/[\/\\]/);
f.dirname = parts.slice(count).join(path.sep);
});
}
exports.rebase = rebase;
function filter(fn) {
var result = es.through(function (data) {
if (fn(data)) {
this.emit('data', data);
}
else {
result.restore.push(data);
}
});
result.restore = es.through();
return result;
}
exports.filter = filter;
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'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; } };
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) {
state = 'running';
var stream = !supportsCancellation ? streamProvider() : streamProvider(isCancellable ? token : NoCancellationToken);
input
.pipe(stream)
.pipe(es.through(null, function () {
state = 'idle';
eventuallyRun();
}))
.pipe(output);
};
if (initial) {
run(initial, false);
}
var eventuallyRun = debounce(function () {
var paths = Object.keys(buffer);
if (paths.length === 0) {
return;
}
var data = paths.map(function (path) { return buffer[path]; });
buffer = Object.create(null);
run(es.readArray(data), true);
}, 500);
input.on('data', function (f) {
buffer[f.path] = f;
if (state === 'idle') {
eventuallyRun();
}
});
return es.duplex(input, output);
}
exports.incremental = incremental;
function fixWin32DirectoryPermissions() {
if (!/win32/.test(process.platform)) {
return es.through();
}
return es.mapSync(function (f) {
if (f.stat && f.stat.isDirectory && f.stat.isDirectory()) {
f.stat.mode = 16877;
}
return f;
});
}
exports.fixWin32DirectoryPermissions = fixWin32DirectoryPermissions;
function setExecutableBit(pattern) {
var setBit = es.mapSync(function (f) {
f.stat.mode = 33261;
return f;
});
if (!pattern) {
return setBit;
}
var input = es.through();
var filter = _filter(pattern, { restore: true });
var output = input
.pipe(filter)
.pipe(setBit)
.pipe(filter.restore);
return es.duplex(input, output);
}
exports.setExecutableBit = setExecutableBit;
function toFileUri(filePath) {
var match = filePath.match(/^([a-z])\:(.*)$/i);
if (match) {
filePath = '/' + match[1].toUpperCase() + ':' + match[2];
}
return 'file://' + filePath.replace(/\\/g, '/');
}
exports.toFileUri = toFileUri;
function skipDirectories() {
return es.mapSync(function (f) {
if (!f.isDirectory()) {
return f;
}
});
}
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));
if (includes) {
var includeGlobs = includes.map(toGlob);
output = es.merge(output, nodeModuleInput.pipe(_filter(includeGlobs)));
}
output = output.pipe(allFilter.restore);
return es.duplex(input, output);
}
exports.cleanNodeModule = cleanNodeModule;
function loadSourcemaps() {
var input = es.through();
var output = input
.pipe(es.map(function (f, cb) {
if (f.sourceMap) {
cb(null, 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;
while (match = reg.exec(contents)) {
lastMatch = match;
}
if (!lastMatch) {
f.sourceMap = {
version: 3,
names: [],
mappings: '',
sources: [f.relative.replace(/\//g, '/')],
sourcesContent: [contents]
};
cb(null, f);
return;
}
f.contents = new Buffer(contents.replace(/\/\/# sourceMappingURL=(.*)$/g, ''), 'utf8');
fs.readFile(path.join(path.dirname(f.path), lastMatch[1]), 'utf8', function (err, contents) {
if (err) {
return cb(err);
}
f.sourceMap = JSON.parse(contents);
cb(null, 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');
f.contents = new Buffer(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, ''), 'utf8');
return f;
}));
return es.duplex(input, output);
}
exports.stripSourceMappingURL = stripSourceMappingURL;
function rimraf(dir) {
var retries = 0;
var retry = function (cb) {
_rimraf(dir, { maxBusyTries: 1 }, function (err) {
if (!err) {
return cb();
}
;
if (err.code === 'ENOTEMPTY' && ++retries < 5) {
return setTimeout(function () { return retry(cb); }, 10);
}
return cb(err);
});
};
return function (cb) { return retry(cb); };
}
exports.rimraf = rimraf;
function getVersion(root) {
var version = process.env['BUILD_SOURCEVERSION'];
if (!version || !/^[0-9a-f]{40}$/i.test(version)) {
version = git.getVersion(root);
}
return version;
}
exports.getVersion = getVersion;
function rebase(count) {
return rename(function (f) {
var parts = f.dirname.split(/[\/\\]/);
f.dirname = parts.slice(count).join(path.sep);
});
}
exports.rebase = rebase;
function filter(fn) {
var result = es.through(function (data) {
if (fn(data)) {
this.emit('data', data);
}
else {
result.restore.push(data);
}
});
result.restore = es.through();
return result;
}
exports.filter = filter;

View file

@ -221,9 +221,15 @@ export function rimraf(dir:string):(cb:any)=>void {
const retry = cb => {
_rimraf(dir, { maxBusyTries: 1 }, (err:any) => {
if (!err) return cb();
if (err.code === 'ENOTEMPTY' && ++retries < 5) return setTimeout(() => retry(cb), 10);
else return cb(err);
if (!err) {
return cb();
};
if (err.code === 'ENOTEMPTY' && ++retries < 5) {
return setTimeout(() => retry(cb), 10);
}
return cb(err);
});
};

View file

@ -1,346 +1,346 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
"use strict";
var fs = require("fs");
var ts = require("typescript");
var path = require("path");
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));
}
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');
var CURRENT_PROCESSING_RULE = '';
function logErr(message) {
var rest = [];
for (var _i = 1; _i < arguments.length; _i++) {
rest[_i - 1] = arguments[_i];
}
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));
}
function moduleIdToPath(out, moduleId) {
if (/\.d\.ts/.test(moduleId)) {
return path.join(SRC, moduleId);
}
return path.join(OUT_ROOT, out, moduleId) + '.d.ts';
}
var SOURCE_FILE_MAP = {};
function getSourceFile(out, moduleId) {
if (!SOURCE_FILE_MAP[moduleId]) {
var filePath = moduleIdToPath(out, moduleId);
var fileContents = void 0;
try {
fileContents = fs.readFileSync(filePath).toString();
}
catch (err) {
logErr('CANNOT FIND FILE ' + filePath);
return null;
}
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
|| a.kind === ts.SyntaxKind.ClassDeclaration
|| a.kind === ts.SyntaxKind.TypeAliasDeclaration
|| a.kind === ts.SyntaxKind.FunctionDeclaration
|| a.kind === ts.SyntaxKind.ModuleDeclaration);
}
function visitTopLevelDeclarations(sourceFile, visitor) {
var stop = false;
var visit = function (node) {
if (stop) {
return;
}
switch (node.kind) {
case ts.SyntaxKind.InterfaceDeclaration:
case ts.SyntaxKind.EnumDeclaration:
case ts.SyntaxKind.ClassDeclaration:
case ts.SyntaxKind.VariableStatement:
case ts.SyntaxKind.TypeAliasDeclaration:
case ts.SyntaxKind.FunctionDeclaration:
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;
}
ts.forEachChild(node, visit);
};
visit(sourceFile);
}
function getAllTopLevelDeclarations(sourceFile) {
var all = [];
visitTopLevelDeclarations(sourceFile, function (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);
// }
if (triviaText.indexOf('@internal') === -1) {
all.push(node);
}
}
else {
var nodeText = getNodeText(sourceFile, node);
if (nodeText.indexOf('@internal') === -1) {
all.push(node);
}
}
return false /*continue*/;
});
return all;
}
function getTopLevelDeclaration(sourceFile, typeName) {
var result = null;
visitTopLevelDeclarations(sourceFile, function (node) {
if (isDeclaration(node)) {
if (node.name.text === typeName) {
result = node;
return true /*stop*/;
}
return false /*continue*/;
}
// node is ts.VariableStatement
if (getNodeText(sourceFile, node).indexOf(typeName) >= 0) {
result = node;
return true /*stop*/;
}
return false /*continue*/;
});
return result;
}
function getNodeText(sourceFile, node) {
return sourceFile.getFullText().substring(node.pos, node.end);
}
function getMassagedTopLevelDeclarationText(sourceFile, declaration) {
var 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) {
var interfaceDeclaration = declaration;
var members = interfaceDeclaration.members;
members.forEach(function (member) {
try {
var memberText = getNodeText(sourceFile, member);
if (memberText.indexOf('@internal') >= 0 || memberText.indexOf('private') >= 0) {
// console.log('BEFORE: ', result);
result = result.replace(memberText, '');
}
}
catch (err) {
}
});
}
result = result.replace(/export default/g, 'export');
result = result.replace(/export declare/g, 'export');
return result;
}
function format(text) {
var options = getDefaultOptions();
// Parse the source text
var 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(options), options);
// Apply the edits on the input code
return applyEdits(text, edits);
function getRuleProvider(options) {
// Share this between multiple formatters using the same options.
// This represents the bulk of the space the formatter uses.
var ruleProvider = new ts.formatting.RulesProvider();
ruleProvider.ensureUpToDate(options);
return ruleProvider;
}
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);
result = head + change.newText + tail;
}
return result;
}
function getDefaultOptions() {
return {
indentSize: 4,
tabSize: 4,
newLineCharacter: '\r\n',
convertTabsToSpaces: true,
indentStyle: ts.IndentStyle.Block,
insertSpaceAfterCommaDelimiter: true,
insertSpaceAfterSemicolonInForStatements: true,
insertSpaceBeforeAndAfterBinaryOperators: true,
insertSpaceAfterKeywordsInControlFlowStatements: true,
insertSpaceAfterFunctionKeywordForAnonymousFunctions: false,
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: true,
placeOpenBraceOnNewLineForFunctions: false,
placeOpenBraceOnNewLineForControlBlocks: false,
};
}
}
function createReplacer(data) {
data = data || '';
var rawDirectives = data.split(';');
var directives = [];
rawDirectives.forEach(function (rawDirective) {
if (rawDirective.length === 0) {
return;
}
var pieces = rawDirective.split('=>');
var findStr = pieces[0];
var 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++) {
str = str.replace(directives[i][0], directives[i][1]);
}
return str;
};
}
function generateDeclarationFile(out, recipe) {
var lines = recipe.split(/\r\n|\n|\r/);
var result = [];
lines.forEach(function (line) {
var m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
if (m1) {
CURRENT_PROCESSING_RULE = line;
var moduleId = m1[1];
var sourceFile_1 = getSourceFile(out, moduleId);
if (!sourceFile_1) {
return;
}
var replacer_1 = createReplacer(m1[2]);
var typeNames = m1[3].split(/,/);
typeNames.forEach(function (typeName) {
typeName = typeName.trim();
if (typeName.length === 0) {
return;
}
var declaration = getTopLevelDeclaration(sourceFile_1, typeName);
if (!declaration) {
logErr('Cannot find type ' + typeName);
return;
}
result.push(replacer_1(getMassagedTopLevelDeclarationText(sourceFile_1, declaration)));
});
return;
}
var m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
if (m2) {
CURRENT_PROCESSING_RULE = line;
var moduleId = m2[1];
var sourceFile_2 = getSourceFile(out, moduleId);
if (!sourceFile_2) {
return;
}
var replacer_2 = createReplacer(m2[2]);
var typeNames = m2[3].split(/,/);
var typesToExcludeMap_1 = {};
var typesToExcludeArr_1 = [];
typeNames.forEach(function (typeName) {
typeName = typeName.trim();
if (typeName.length === 0) {
return;
}
typesToExcludeMap_1[typeName] = true;
typesToExcludeArr_1.push(typeName);
});
getAllTopLevelDeclarations(sourceFile_2).forEach(function (declaration) {
if (isDeclaration(declaration)) {
if (typesToExcludeMap_1[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) {
return;
}
}
}
result.push(replacer_2(getMassagedTopLevelDeclarationText(sourceFile_2, declaration)));
});
return;
}
result.push(line);
});
var resultTxt = result.join('\n');
resultTxt = resultTxt.replace(/\bURI\b/g, 'Uri');
resultTxt = resultTxt.replace(/\bEvent</g, 'IEvent<');
resultTxt = resultTxt.replace(/\bTPromise</g, 'Promise<');
resultTxt = format(resultTxt);
resultTxt = resultTxt.replace(/\r\n/g, '\n');
return resultTxt;
}
function getFilesToWatch(out) {
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\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
if (m1) {
var moduleId = m1[1];
result.push(moduleIdToPath(out, moduleId));
return;
}
var m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
if (m2) {
var moduleId = m2[1];
result.push(moduleIdToPath(out, moduleId));
return;
}
});
return result;
}
exports.getFilesToWatch = getFilesToWatch;
function run(out) {
log('Starting monaco.d.ts generation');
SOURCE_FILE_MAP = {};
var recipe = fs.readFileSync(RECIPE_PATH).toString();
var result = generateDeclarationFile(out, recipe);
var currentContent = fs.readFileSync(DECLARATION_PATH).toString();
log('Finished monaco.d.ts generation');
return {
content: result,
filePath: DECLARATION_PATH,
isTheSame: currentContent === result
};
}
exports.run = run;
function complainErrors() {
logErr('Not running monaco.d.ts generation due to compile errors');
}
exports.complainErrors = complainErrors;
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var fs = require("fs");
var ts = require("typescript");
var path = require("path");
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));
}
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');
var CURRENT_PROCESSING_RULE = '';
function logErr(message) {
var rest = [];
for (var _i = 1; _i < arguments.length; _i++) {
rest[_i - 1] = arguments[_i];
}
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));
}
function moduleIdToPath(out, moduleId) {
if (/\.d\.ts/.test(moduleId)) {
return path.join(SRC, 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
|| a.kind === ts.SyntaxKind.ClassDeclaration
|| a.kind === ts.SyntaxKind.TypeAliasDeclaration
|| a.kind === ts.SyntaxKind.FunctionDeclaration
|| a.kind === ts.SyntaxKind.ModuleDeclaration);
}
function visitTopLevelDeclarations(sourceFile, visitor) {
var stop = false;
var visit = function (node) {
if (stop) {
return;
}
switch (node.kind) {
case ts.SyntaxKind.InterfaceDeclaration:
case ts.SyntaxKind.EnumDeclaration:
case ts.SyntaxKind.ClassDeclaration:
case ts.SyntaxKind.VariableStatement:
case ts.SyntaxKind.TypeAliasDeclaration:
case ts.SyntaxKind.FunctionDeclaration:
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;
}
ts.forEachChild(node, visit);
};
visit(sourceFile);
}
function getAllTopLevelDeclarations(sourceFile) {
var all = [];
visitTopLevelDeclarations(sourceFile, function (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);
// }
if (triviaText.indexOf('@internal') === -1) {
all.push(node);
}
}
else {
var nodeText = getNodeText(sourceFile, node);
if (nodeText.indexOf('@internal') === -1) {
all.push(node);
}
}
return false /*continue*/;
});
return all;
}
function getTopLevelDeclaration(sourceFile, typeName) {
var result = null;
visitTopLevelDeclarations(sourceFile, function (node) {
if (isDeclaration(node)) {
if (node.name.text === typeName) {
result = node;
return true /*stop*/;
}
return false /*continue*/;
}
// node is ts.VariableStatement
if (getNodeText(sourceFile, node).indexOf(typeName) >= 0) {
result = node;
return true /*stop*/;
}
return false /*continue*/;
});
return result;
}
function getNodeText(sourceFile, node) {
return sourceFile.getFullText().substring(node.pos, node.end);
}
function getMassagedTopLevelDeclarationText(sourceFile, declaration) {
var 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) {
var interfaceDeclaration = declaration;
var members = interfaceDeclaration.members;
members.forEach(function (member) {
try {
var 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);
}
}
catch (err) {
// life..
}
});
}
result = result.replace(/export default/g, 'export');
result = result.replace(/export declare/g, 'export');
return result;
}
function format(text) {
var options = getDefaultOptions();
// Parse the source text
var 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(options), options);
// Apply the edits on the input code
return applyEdits(text, edits);
function getRuleProvider(options) {
// Share this between multiple formatters using the same options.
// This represents the bulk of the space the formatter uses.
var ruleProvider = new ts.formatting.RulesProvider();
ruleProvider.ensureUpToDate(options);
return ruleProvider;
}
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);
result = head + change.newText + tail;
}
return result;
}
function getDefaultOptions() {
return {
indentSize: 4,
tabSize: 4,
newLineCharacter: '\r\n',
convertTabsToSpaces: true,
indentStyle: ts.IndentStyle.Block,
insertSpaceAfterCommaDelimiter: true,
insertSpaceAfterSemicolonInForStatements: true,
insertSpaceBeforeAndAfterBinaryOperators: true,
insertSpaceAfterKeywordsInControlFlowStatements: true,
insertSpaceAfterFunctionKeywordForAnonymousFunctions: false,
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: true,
placeOpenBraceOnNewLineForFunctions: false,
placeOpenBraceOnNewLineForControlBlocks: false,
};
}
}
function createReplacer(data) {
data = data || '';
var rawDirectives = data.split(';');
var directives = [];
rawDirectives.forEach(function (rawDirective) {
if (rawDirective.length === 0) {
return;
}
var pieces = rawDirective.split('=>');
var findStr = pieces[0];
var 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++) {
str = str.replace(directives[i][0], directives[i][1]);
}
return str;
};
}
function generateDeclarationFile(out, inputFiles, recipe) {
var lines = recipe.split(/\r\n|\n|\r/);
var result = [];
lines.forEach(function (line) {
var 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) {
return;
}
var replacer_1 = createReplacer(m1[2]);
var typeNames = m1[3].split(/,/);
typeNames.forEach(function (typeName) {
typeName = typeName.trim();
if (typeName.length === 0) {
return;
}
var declaration = getTopLevelDeclaration(sourceFile_1, typeName);
if (!declaration) {
logErr('Cannot find type ' + typeName);
return;
}
result.push(replacer_1(getMassagedTopLevelDeclarationText(sourceFile_1, declaration)));
});
return;
}
var 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) {
return;
}
var replacer_2 = createReplacer(m2[2]);
var typeNames = m2[3].split(/,/);
var typesToExcludeMap_1 = {};
var typesToExcludeArr_1 = [];
typeNames.forEach(function (typeName) {
typeName = typeName.trim();
if (typeName.length === 0) {
return;
}
typesToExcludeMap_1[typeName] = true;
typesToExcludeArr_1.push(typeName);
});
getAllTopLevelDeclarations(sourceFile_2).forEach(function (declaration) {
if (isDeclaration(declaration)) {
if (typesToExcludeMap_1[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) {
return;
}
}
}
result.push(replacer_2(getMassagedTopLevelDeclarationText(sourceFile_2, declaration)));
});
return;
}
result.push(line);
});
var resultTxt = result.join('\n');
resultTxt = resultTxt.replace(/\bURI\b/g, 'Uri');
resultTxt = resultTxt.replace(/\bEvent</g, 'IEvent<');
resultTxt = resultTxt.replace(/\bTPromise</g, 'Promise<');
resultTxt = format(resultTxt);
resultTxt = resultTxt.replace(/\r\n/g, '\n');
return resultTxt;
}
function getFilesToWatch(out) {
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\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
if (m1) {
var moduleId = m1[1];
result.push(moduleIdToPath(out, moduleId));
return;
}
var m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
if (m2) {
var moduleId = m2[1];
result.push(moduleIdToPath(out, moduleId));
return;
}
});
return result;
}
exports.getFilesToWatch = getFilesToWatch;
function run(out, inputFiles) {
log('Starting monaco.d.ts generation');
SOURCE_FILE_MAP = {};
var recipe = fs.readFileSync(RECIPE_PATH).toString();
var result = generateDeclarationFile(out, inputFiles, recipe);
var currentContent = fs.readFileSync(DECLARATION_PATH).toString();
log('Finished monaco.d.ts generation');
return {
content: result,
filePath: DECLARATION_PATH,
isTheSame: currentContent === result
};
}
exports.run = run;
function complainErrors() {
logErr('Not running monaco.d.ts generation due to compile errors');
}
exports.complainErrors = complainErrors;

View file

@ -31,18 +31,16 @@ function moduleIdToPath(out:string, moduleId:string): string {
}
let SOURCE_FILE_MAP: {[moduleId:string]:ts.SourceFile;} = {};
function getSourceFile(out:string, moduleId:string): ts.SourceFile {
function getSourceFile(out:string, inputFiles: { [file: string]: string; }, moduleId:string): ts.SourceFile {
if (!SOURCE_FILE_MAP[moduleId]) {
let filePath = moduleIdToPath(out, moduleId);
let filePath = path.normalize(moduleIdToPath(out, moduleId));
let fileContents: string;
try {
fileContents = fs.readFileSync(filePath).toString();
} catch (err) {
logErr('CANNOT FIND FILE ' + filePath);
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;
@ -262,7 +260,7 @@ function createReplacer(data:string): (str:string)=>string {
};
}
function generateDeclarationFile(out:string, recipe:string): string {
function generateDeclarationFile(out: string, inputFiles: { [file: string]: string; }, recipe:string): string {
let lines = recipe.split(/\r\n|\n|\r/);
let result = [];
@ -273,7 +271,7 @@ function generateDeclarationFile(out:string, recipe:string): string {
if (m1) {
CURRENT_PROCESSING_RULE = line;
let moduleId = m1[1];
let sourceFile = getSourceFile(out, moduleId);
let sourceFile = getSourceFile(out, inputFiles, moduleId);
if (!sourceFile) {
return;
}
@ -300,7 +298,7 @@ function generateDeclarationFile(out:string, recipe:string): string {
if (m2) {
CURRENT_PROCESSING_RULE = line;
let moduleId = m2[1];
let sourceFile = getSourceFile(out, moduleId);
let sourceFile = getSourceFile(out, inputFiles, moduleId);
if (!sourceFile) {
return;
}
@ -383,12 +381,12 @@ export interface IMonacoDeclarationResult {
isTheSame: boolean;
}
export function run(out:string): IMonacoDeclarationResult {
export function run(out: string, inputFiles: { [file: string]: string; }): IMonacoDeclarationResult {
log('Starting monaco.d.ts generation');
SOURCE_FILE_MAP = {};
let recipe = fs.readFileSync(RECIPE_PATH).toString();
let result = generateDeclarationFile(out, recipe);
let result = generateDeclarationFile(out, inputFiles, recipe);
let currentContent = fs.readFileSync(DECLARATION_PATH).toString();
log('Finished monaco.d.ts generation');

View file

@ -40,7 +40,7 @@ declare module monaco {
#include(vs/base/common/cancellation): CancellationTokenSource, CancellationToken
#include(vs/base/common/uri): URI
#include(vs/editor/common/standalone/standaloneBase): KeyCode, KeyMod
#include(vs/base/common/keyCodes): Keybinding
#include(vs/base/common/keyCodes): SimpleKeybinding
#include(vs/base/common/htmlContent): MarkedString
#include(vs/base/browser/keyboardEvent): IKeyboardEvent
#include(vs/base/browser/mouseEvent): IMouseEvent

View file

@ -1,7 +1,7 @@
{
"name": "monaco-editor-core",
"private": true,
"version": "0.8.1",
"version": "0.8.2",
"description": "A browser based code editor",
"author": "Microsoft Corporation",
"license": "MIT",

61
build/npm/update-theme.js Normal file
View file

@ -0,0 +1,61 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
var path = require('path');
var fs = require('fs');
var plist = require('fast-plist');
var mappings = {
"ansiBlack": ["terminalAnsiBlack"], "ansiRed": ["terminalAnsiRed"], "ansiGreen": ["terminalAnsiGreen"], "ansiYellow": ["terminalAnsiYellow"], "ansiBlue": ["terminalAnsiBlue"], "ansiMagenta": ["terminalAnsiMagenta"], "ansiCyan": ["terminalAnsiCyan"], "ansiWhite": ["terminalAnsiWhite"], "ansiBrightBlack": ["terminalAnsiBrightBlack"], "ansiBrightRed": ["terminalAnsiBrightRed"], "ansiBrightGreen": ["terminalAnsiBrightGreen"], "ansiBrightYellow": ["terminalAnsiBrightYellow"], "ansiBrightBlue": ["terminalAnsiBrightBlue"], "ansiBrightMagenta": ["terminalAnsiBrightMagenta"], "ansiBrightCyan": ["terminalAnsiBrightCyan"], "ansiBrightWhite": ["terminalAnsiBrightWhite"], "background": ["editorBackground"],
"hoverHighlight": ["editorHoverHighlight", "editorHoverHighlight"], "linkForeground": ["editorLinkForeground"], "selection": ["editorSelection"], "inactiveSelection": ["editorInactiveSelection"], "selectionHighlightColor": ["editorSelectionHighlightColor"], "wordHighlight": ["editorWordHighlight"], "wordHighlightStrong": ["editorWordHighlightStrong"], "findMatchHighlight": ["editorFindMatchHighlight", "referencesFindMatchHighlight"], "currentFindMatchHighlight": ["editorCurrentFindMatchHighlight"], "findRangeHighlight": ["editorFindRangeHighlight"], "referenceHighlight": ["referencesReferenceHighlight"], "lineHighlight": ["editorLineHighlight"], "rangeHighlight": ["editorRangeHighlight"], "caret": ["editorCursor"], "invisibles": ["editorInvisibles"], "guide": ["editorGuide"]
};
exports.update = function (srcName, destName) {
try {
console.log('reading ', srcName);
let result = {};
let plistContent = fs.readFileSync(srcName).toString();
let theme = plist.parse(plistContent);
let settings = theme.settings;
if (Array.isArray(settings)) {
let colorMap = {};
for (let entry of settings) {
let scope = entry.scope;
if (scope) {
let parts = scope.split(',').map(p => p.trim());
if (parts.length > 1) {
entry.scope = parts;
}
} else {
var entrySettings = entry.settings;
for (let entry in entrySettings) {
let mapping = mappings[entry];
if (mapping) {
for (let newKey of mapping) {
colorMap[newKey] = entrySettings[entry];
}
if (entry !== 'foreground' && entry !== 'background') {
delete entrySettings[entry];
}
}
}
}
}
result.name = theme.name;
result.syntaxTokens = settings;
result.colors = colorMap;
}
fs.writeFileSync(destName, JSON.stringify(result, null, '\t'));
} catch (e) {
console.log(e);
}
}
if (path.basename(process.argv[1]) === 'update-theme.js') {
exports.update(process.argv[2], process.argv[3]);
}

View file

@ -1,7 +1,8 @@
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
[{
"name": "mmcgrana/textmate-clojure",
"name": "atom/language-clojure",
"version": "0.0.0",
"license": "MIT",
"repositoryURL": "https://github.com/mmcgrana/textmate-clojure"
"repositoryURL": "https://github.com/atom/language-clojure",
"description": "The file syntaxes/clojure.tmLanguage.json was derived from the Atom package https://github.com/atom/language-clojure which was originally converted from the TextMate bundle https://github.com/mmcgrana/textmate-clojure."
}]

View file

@ -3,6 +3,9 @@
"version": "0.1.0",
"publisher": "vscode",
"engines": { "vscode": "*" },
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js atom/language-clojure grammars/clojure.cson ./syntaxes/clojure.tmLanguage.json"
},
"contributes": {
"languages": [{
"id": "clojure",
@ -13,7 +16,7 @@
"grammars": [{
"language": "clojure",
"scopeName": "source.clojure",
"path": "./syntaxes/Clojure.tmLanguage"
"path": "./syntaxes/clojure.tmLanguage.json"
}]
}
}

View file

@ -1,440 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>fileTypes</key>
<array>
<string>clj</string>
<string>cljs</string>
<string>clojure</string>
</array>
<key>foldingStartMarker</key>
<string>\(\s*$</string>
<key>foldingStopMarker</key>
<string>^\s*\)</string>
<key>keyEquivalent</key>
<string>^~C</string>
<key>name</key>
<string>Clojure</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#comment</string>
</dict>
<dict>
<key>include</key>
<string>#shebang-comment</string>
</dict>
<dict>
<key>include</key>
<string>#qouted-sexp</string>
</dict>
<dict>
<key>include</key>
<string>#sexp</string>
</dict>
<dict>
<key>include</key>
<string>#keyfn</string>
</dict>
<dict>
<key>include</key>
<string>#string</string>
</dict>
<dict>
<key>include</key>
<string>#vector</string>
</dict>
<dict>
<key>include</key>
<string>#set</string>
</dict>
<dict>
<key>include</key>
<string>#map</string>
</dict>
<dict>
<key>include</key>
<string>#regexp</string>
</dict>
<dict>
<key>include</key>
<string>#var</string>
</dict>
<dict>
<key>include</key>
<string>#constants</string>
</dict>
<dict>
<key>include</key>
<string>#symbol</string>
</dict>
<dict>
<key>include</key>
<string>#whitespace</string>
</dict>
</array>
<key>repository</key>
<dict>
<key>comment</key>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.comment.clojure</string>
</dict>
</dict>
<key>match</key>
<string>(;).*$\n?</string>
<key>name</key>
<string>comment.line.semicolon.clojure</string>
</dict>
<key>constants</key>
<dict>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>(nil)(?=(\s|\)|\]|\}))</string>
<key>name</key>
<string>constant.language.nil.clojure</string>
</dict>
<dict>
<key>match</key>
<string>(true|false)</string>
<key>name</key>
<string>constant.language.boolean.clojure</string>
</dict>
<dict>
<key>match</key>
<string>(\d+/\d+)</string>
<key>name</key>
<string>constant.numeric.ratio.clojure</string>
</dict>
<dict>
<key>match</key>
<string>(\d+r\d+)</string>
<key>name</key>
<string>constant.numeric.arbitrary-radix.clojure</string>
</dict>
<dict>
<key>match</key>
<string>(0x\d+)</string>
<key>name</key>
<string>constant.numeric.hexidecimal.clojure</string>
</dict>
<dict>
<key>match</key>
<string>(0\d+)</string>
<key>name</key>
<string>constant.numeric.octal.clojure</string>
</dict>
<dict>
<key>match</key>
<string>(\d+)</string>
<key>name</key>
<string>constant.numeric.decimal.clojure</string>
</dict>
<dict>
<key>match</key>
<string>(?&lt;=(\s|\(|\[|\{)):[a-zA-Z0-9\#\.\-\_\:\+\=\&gt;\&lt;\/\!\?\*]+(?=(\s|\)|\]|\}))</string>
<key>name</key>
<string>constant.keyword.clojure</string>
</dict>
</array>
</dict>
<key>keyfn</key>
<dict>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>(?&lt;=(\s|\(|\[|\{))(if(-[-a-z\?]*)?|when(-[-a-z]*)?|for(-[-a-z]*)?|cond|do|let(-[-a-z\?]*)?|binding|loop|recur|fn|throw[a-z\-]*|try|catch|finally|([a-z]*case))(?=(\s|\)|\]|\}))</string>
<key>name</key>
<string>storage.control.clojure</string>
</dict>
<dict>
<key>match</key>
<string>(?&lt;=(\s|\(|\[|\{))(declare-?|(in-)?ns|import|use|require|load|compile|(def[a-z\-]*))(?=(\s|\)|\]|\}))</string>
<key>name</key>
<string>keyword.control.clojure</string>
</dict>
</array>
</dict>
<key>map</key>
<dict>
<key>begin</key>
<string>(\{)</string>
<key>end</key>
<string>(\})</string>
<key>name</key>
<string>meta.map.clojure</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>$self</string>
</dict>
</array>
</dict>
<key>qouted-sexp</key>
<dict>
<key>begin</key>
<string>(['``]\()</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.section.expression.begin.clojure</string>
</dict>
</dict>
<key>end</key>
<string>(\))(\n)?</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.section.expression.end.clojure</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>meta.after-expression.clojure</string>
</dict>
</dict>
<key>name</key>
<string>meta.qouted-expression.clojure</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>$self</string>
</dict>
</array>
</dict>
<key>regexp</key>
<dict>
<key>begin</key>
<string>#\"</string>
<key>end</key>
<string>\"</string>
<key>name</key>
<string>string.regexp.clojure</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#regexp_escaped_char</string>
</dict>
</array>
</dict>
<key>regexp_escaped_char</key>
<dict>
<key>match</key>
<string>\\(\")</string>
<key>name</key>
<string>string.regexp.clojure</string>
</dict>
<key>set</key>
<dict>
<key>begin</key>
<string>(\#\{)</string>
<key>end</key>
<string>(\})</string>
<key>name</key>
<string>meta.set.clojure</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>$self</string>
</dict>
</array>
</dict>
<key>sexp</key>
<dict>
<key>begin</key>
<string>(\()</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.section.expression.begin.clojure</string>
</dict>
</dict>
<key>end</key>
<string>(\))(\n)?</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.section.expression.end.clojure</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>meta.after-expression.clojure</string>
</dict>
</dict>
<key>name</key>
<string>meta.expression.clojure</string>
<key>patterns</key>
<array>
<dict>
<key>begin</key>
<string>(?&lt;=\()(ns|def|def-|defn|defn-|defvar|defvar-|defmacro|defmacro-|deftest)\s+(.+?)(?=\s)</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>keyword.control.clojure</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>entity.global.clojure</string>
</dict>
</dict>
<key>end</key>
<string>(?=\))</string>
<key>name</key>
<string>meta.definition.global.clojure</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>$self</string>
</dict>
</array>
</dict>
<dict>
<key>include</key>
<string>$self</string>
</dict>
</array>
</dict>
<key>shebang-comment</key>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.comment.shebang.clojure</string>
</dict>
</dict>
<key>match</key>
<string>^(\#!).*$\n?</string>
<key>name</key>
<string>comment.line.semicolon.clojure</string>
</dict>
<key>string</key>
<dict>
<key>begin</key>
<string>(")</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.clojure</string>
</dict>
</dict>
<key>end</key>
<string>(")</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.clojure</string>
</dict>
</dict>
<key>name</key>
<string>string.quoted.double.clojure</string>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>\\.</string>
<key>name</key>
<string>constant.character.escape.clojure</string>
</dict>
</array>
</dict>
<key>symbol</key>
<dict>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>(\w[\w\d]+)</string>
<key>name</key>
<string>meta.symbol.clojure</string>
</dict>
</array>
</dict>
<key>var</key>
<dict>
<key>match</key>
<string>(?&lt;=(\s|\(|\[|\{)\#)'[a-zA-Z0-9\.\-\_\:\+\=\&gt;\&lt;\/\!\?\*]+(?=(\s|\)|\]|\}))</string>
<key>name</key>
<string>meta.var.clojure</string>
</dict>
<key>vector</key>
<dict>
<key>begin</key>
<string>(\[)</string>
<key>end</key>
<string>(\])</string>
<key>name</key>
<string>meta.vector.clojure</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>$self</string>
</dict>
</array>
</dict>
<key>whitespace</key>
<dict>
<key>match</key>
<string>\s+$</string>
<key>name</key>
<string>invalid.trailing-whitespace</string>
</dict>
</dict>
<key>scopeName</key>
<string>source.clojure</string>
<key>smartTypingPairs</key>
<array>
<array>
<string>"</string>
<string>"</string>
</array>
<array>
<string>(</string>
<string>)</string>
</array>
<array>
<string>{</string>
<string>}</string>
</array>
<array>
<string>[</string>
<string>]</string>
</array>
</array>
<key>uuid</key>
<string>6A87759F-F746-4E84-B788-965B46363202</string>
</dict>
</plist>

View file

@ -0,0 +1,448 @@
{
"scopeName": "source.clojure",
"fileTypes": [
"boot",
"clj",
"clj.hl",
"cljc",
"cljs",
"cljs.hl",
"cljx",
"clojure",
"edn",
"org"
],
"foldingStartMarker": "\\(\\s*$",
"foldingStopMarker": "^\\s*\\)",
"firstLineMatch": "(?x)\n# Hashbang\n^\\#!.*(?:\\s|\\/)\n boot\n(?:$|\\s)\n|\n# Modeline\n(?i:\n # Emacs\n -\\*-(?:\\s*(?=[^:;\\s]+\\s*-\\*-)|(?:.*?[;\\s]|(?<=-\\*-))mode\\s*:\\s*)\n clojure(script)?\n (?=[\\s;]|(?<![-*])-\\*-).*?-\\*-\n |\n # Vim\n (?:(?:\\s|^)vi(?:m[<=>]?\\d+|m)?|\\sex)(?=:(?=\\s*set?\\s[^\\n:]+:)|:(?!\\s*set?\\s))(?:(?:\\s|\\s*:\\s*)\\w*(?:\\s*=(?:[^\\n\\\\\\s]|\\\\.)*)?)*[\\s:](?:filetype|ft|syntax)\\s*=\n clojure\n (?=\\s|:|$)\n)",
"name": "Clojure",
"patterns": [
{
"include": "#comment"
},
{
"include": "#shebang-comment"
},
{
"include": "#quoted-sexp"
},
{
"include": "#sexp"
},
{
"include": "#keyfn"
},
{
"include": "#string"
},
{
"include": "#vector"
},
{
"include": "#set"
},
{
"include": "#map"
},
{
"include": "#regexp"
},
{
"include": "#var"
},
{
"include": "#constants"
},
{
"include": "#dynamic-variables"
},
{
"include": "#metadata"
},
{
"include": "#namespace-symbol"
},
{
"include": "#symbol"
},
{
"include": "#whitespace"
}
],
"repository": {
"comment": {
"begin": ";",
"beginCaptures": {
"0": {
"name": "punctuation.definition.comment.clojure"
}
},
"end": "$",
"name": "comment.line.semicolon.clojure"
},
"constants": {
"patterns": [
{
"match": "(nil)(?=(\\s|\\)|\\]|\\}))",
"name": "constant.language.nil.clojure"
},
{
"match": "(true|false)",
"name": "constant.language.boolean.clojure"
},
{
"match": "(-?\\d+/\\d+)",
"name": "constant.numeric.ratio.clojure"
},
{
"match": "(-?\\d+[rR][0-9a-zA-Z]+)",
"name": "constant.numeric.arbitrary-radix.clojure"
},
{
"match": "(-?0[xX][0-9a-fA-F]+)",
"name": "constant.numeric.hexadecimal.clojure"
},
{
"match": "(-?0\\d+)",
"name": "constant.numeric.octal.clojure"
},
{
"match": "(-?\\d+\\.\\d+([eE][+-]?\\d+)?M)",
"name": "constant.numeric.bigdecimal.clojure"
},
{
"match": "(-?\\d+\\.\\d+([eE][+-]?\\d+)?)",
"name": "constant.numeric.double.clojure"
},
{
"match": "(-?\\d+N)",
"name": "constant.numeric.bigint.clojure"
},
{
"match": "(-?\\d+)",
"name": "constant.numeric.long.clojure"
},
{
"include": "#keyword"
}
]
},
"keyword": {
"match": "(?<=(\\s|\\(|\\[|\\{)):[a-zA-Z0-9\\#\\.\\-\\_\\:\\+\\=\\>\\<\\/\\!\\?\\*]+(?=(\\s|\\)|\\]|\\}|\\,))",
"name": "constant.keyword.clojure"
},
"keyfn": {
"patterns": [
{
"match": "(?<=(\\s|\\(|\\[|\\{))(if(-[-a-z\\?]*)?|when(-[-a-z]*)?|for(-[-a-z]*)?|cond|do|let(-[-a-z\\?]*)?|binding|loop|recur|fn|throw[a-z\\-]*|try|catch|finally|([a-z]*case))(?=(\\s|\\)|\\]|\\}))",
"name": "storage.control.clojure"
},
{
"match": "(?<=(\\s|\\(|\\[|\\{))(declare-?|(in-)?ns|import|use|require|load|compile|(def[a-z\\-]*))(?=(\\s|\\)|\\]|\\}))",
"name": "keyword.control.clojure"
}
]
},
"dynamic-variables": {
"match": "\\*[\\w\\.\\-\\_\\:\\+\\=\\>\\<\\!\\?\\d]+\\*",
"name": "meta.symbol.dynamic.clojure"
},
"map": {
"begin": "(\\{)",
"beginCaptures": {
"1": {
"name": "punctuation.section.map.begin.clojure"
}
},
"end": "(\\}(?=[\\}\\]\\)\\s]*(?:;|$)))|(\\})",
"endCaptures": {
"1": {
"name": "punctuation.section.map.end.trailing.clojure"
},
"2": {
"name": "punctuation.section.map.end.clojure"
}
},
"name": "meta.map.clojure",
"patterns": [
{
"include": "$self"
}
]
},
"metadata": {
"patterns": [
{
"begin": "(\\^\\{)",
"beginCaptures": {
"1": {
"name": "punctuation.section.metadata.map.begin.clojure"
}
},
"end": "(\\}(?=[\\}\\]\\)\\s]*(?:;|$)))|(\\})",
"endCaptures": {
"1": {
"name": "punctuation.section.metadata.map.end.trailing.clojure"
},
"2": {
"name": "punctuation.section.metadata.map.end.clojure"
}
},
"name": "meta.metadata.map.clojure",
"patterns": [
{
"include": "$self"
}
]
},
{
"begin": "(\\^)",
"end": "(\\s)",
"name": "meta.metadata.simple.clojure",
"patterns": [
{
"include": "#keyword"
},
{
"include": "$self"
}
]
}
]
},
"quoted-sexp": {
"begin": "(['``]\\()",
"beginCaptures": {
"1": {
"name": "punctuation.section.expression.begin.clojure"
}
},
"end": "(\\))(\\n)|(\\)(?=[\\}\\]\\)\\s]*(?:;|$)))|(\\))",
"endCaptures": {
"1": {
"name": "punctuation.section.expression.end.trailing.clojure"
},
"2": {
"name": "meta.after-expression.clojure"
},
"3": {
"name": "punctuation.section.expression.end.trailing.clojure"
},
"4": {
"name": "punctuation.section.expression.end.clojure"
}
},
"name": "meta.quoted-expression.clojure",
"patterns": [
{
"include": "$self"
}
]
},
"regexp": {
"begin": "#\\\"",
"end": "\\\"",
"name": "string.regexp.clojure",
"patterns": [
{
"include": "#regexp_escaped_char"
}
]
},
"regexp_escaped_char": {
"match": "\\\\.",
"name": "constant.character.escape.clojure"
},
"set": {
"begin": "(\\#\\{)",
"beginCaptures": {
"1": {
"name": "punctuation.section.set.begin.clojure"
}
},
"end": "(\\}(?=[\\}\\]\\)\\s]*(?:;|$)))|(\\})",
"endCaptures": {
"1": {
"name": "punctuation.section.set.end.trailing.clojure"
},
"2": {
"name": "punctuation.section.set.end.clojure"
}
},
"name": "meta.set.clojure",
"patterns": [
{
"include": "$self"
}
]
},
"sexp": {
"begin": "(\\()",
"beginCaptures": {
"1": {
"name": "punctuation.section.expression.begin.clojure"
}
},
"end": "(\\))(\\n)|(\\)(?=[\\}\\]\\)\\s]*(?:;|$)))|(\\))",
"endCaptures": {
"1": {
"name": "punctuation.section.expression.end.trailing.clojure"
},
"2": {
"name": "meta.after-expression.clojure"
},
"3": {
"name": "punctuation.section.expression.end.trailing.clojure"
},
"4": {
"name": "punctuation.section.expression.end.clojure"
}
},
"name": "meta.expression.clojure",
"patterns": [
{
"begin": "(?<=\\()(ns|def|def-|defn|defn-|defvar|defvar-|defmacro|defmacro-|deftest)\\s+",
"beginCaptures": {
"1": {
"name": "keyword.control.clojure"
}
},
"end": "(?=\\))",
"name": "meta.definition.global.clojure",
"patterns": [
{
"include": "#metadata"
},
{
"include": "#dynamic-variables"
},
{
"match": "([\\w\\.\\-\\_\\:\\+\\=\\>\\<\\!\\?\\*][\\w\\.\\-\\_\\:\\+\\=\\>\\<\\!\\?\\*\\d]+)",
"name": "entity.global.clojure"
},
{
"include": "$self"
}
]
},
{
"include": "#keyfn"
},
{
"include": "#constants"
},
{
"include": "#vector"
},
{
"include": "#map"
},
{
"include": "#set"
},
{
"include": "#sexp"
},
{
"match": "(?<=\\()(.+?)(?=\\s|\\))",
"captures": {
"1": {
"name": "entity.name.function.clojure"
}
},
"patterns": [
{
"include": "$self"
}
]
},
{
"include": "$self"
}
]
},
"shebang-comment": {
"begin": "^(#!)",
"beginCaptures": {
"1": {
"name": "punctuation.definition.comment.shebang.clojure"
}
},
"end": "$",
"name": "comment.line.shebang.clojure"
},
"string": {
"begin": "(?<!\\\\)(\")",
"beginCaptures": {
"1": {
"name": "punctuation.definition.string.begin.clojure"
}
},
"end": "(\")",
"endCaptures": {
"1": {
"name": "punctuation.definition.string.end.clojure"
}
},
"name": "string.quoted.double.clojure",
"patterns": [
{
"match": "\\\\.",
"name": "constant.character.escape.clojure"
}
]
},
"namespace-symbol": {
"patterns": [
{
"match": "([\\w\\.\\-\\_\\:\\+\\=\\>\\<\\!\\?\\*][\\w\\.\\-\\_\\:\\+\\=\\>\\<\\!\\?\\*\\d]+)/",
"captures": {
"1": {
"name": "meta.symbol.namespace.clojure"
}
}
}
]
},
"symbol": {
"patterns": [
{
"match": "([\\w\\.\\-\\_\\:\\+\\=\\>\\<\\!\\?\\*][\\w\\.\\-\\_\\:\\+\\=\\>\\<\\!\\?\\*\\d]+)",
"name": "meta.symbol.clojure"
}
]
},
"var": {
"match": "(?<=(\\s|\\(|\\[|\\{)\\#)'[a-zA-Z0-9\\.\\-\\_\\:\\+\\=\\>\\<\\/\\!\\?\\*]+(?=(\\s|\\)|\\]|\\}))",
"name": "meta.var.clojure"
},
"vector": {
"begin": "(\\[)",
"beginCaptures": {
"1": {
"name": "punctuation.section.vector.begin.clojure"
}
},
"end": "(\\](?=[\\}\\]\\)\\s]*(?:;|$)))|(\\])",
"endCaptures": {
"1": {
"name": "punctuation.section.vector.end.trailing.clojure"
},
"2": {
"name": "punctuation.section.vector.end.clojure"
}
},
"name": "meta.vector.clojure",
"patterns": [
{
"include": "$self"
}
]
},
"whitespace": {
"match": "\\s+$",
"name": "invalid.trailing-whitespace"
}
},
"version": "https://github.com/atom/language-clojure/commit/9a79169ec89e25476214c42fe2d5702dfa9ebb83"
}

File diff suppressed because it is too large Load diff

View file

@ -14,6 +14,8 @@ const decoration = vscode.window.createTextEditorDecorationType({
color: '#b1b1b1'
});
let pendingLaunchJsonDecoration: NodeJS.Timer;
export function activate(context): void {
//keybindings.json command-suggestions
@ -26,7 +28,10 @@ export function activate(context): void {
context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor(editor => updateLaunchJsonDecorations(editor), null, context.subscriptions));
context.subscriptions.push(vscode.workspace.onDidChangeTextDocument(event => {
if (vscode.window.activeTextEditor && event.document === vscode.window.activeTextEditor.document) {
updateLaunchJsonDecorations(vscode.window.activeTextEditor);
if (pendingLaunchJsonDecoration) {
clearTimeout(pendingLaunchJsonDecoration);
}
pendingLaunchJsonDecoration = setTimeout(() => updateLaunchJsonDecorations(vscode.window.activeTextEditor), 1000);
}
}, null, context.subscriptions));
updateLaunchJsonDecorations(vscode.window.activeTextEditor);

View file

@ -38,8 +38,9 @@ export class SettingsDocument {
private provideWindowTitleCompletionItems(location: Location, range: vscode.Range): vscode.ProviderResult<vscode.CompletionItem[]> {
const completions: vscode.CompletionItem[] = [];
completions.push(this.newSimpleCompletionItem('${activeEditorName}', range, localize('activeEditorName', "e.g. myFile.txt")));
completions.push(this.newSimpleCompletionItem('${activeFilePath}', range, localize('activeFilePath', "e.g. /Users/Development/myProject/myFile.txt")));
completions.push(this.newSimpleCompletionItem('${activeEditorShort}', range, localize('activeEditorShort', "e.g. myFile.txt")));
completions.push(this.newSimpleCompletionItem('${activeEditorMedium}', range, localize('activeEditorMedium', "e.g. myFolder/myFile.txt")));
completions.push(this.newSimpleCompletionItem('${activeEditorLong}', range, localize('activeEditorLong', "e.g. /Users/Development/myProject/myFolder/myFile.txt")));
completions.push(this.newSimpleCompletionItem('${rootName}', range, localize('rootName', "e.g. myProject")));
completions.push(this.newSimpleCompletionItem('${rootPath}', range, localize('rootPath', "e.g. /Users/Development/myProject")));
completions.push(this.newSimpleCompletionItem('${appName}', range, localize('appName', "e.g. VS Code")));
@ -160,7 +161,7 @@ export class SettingsDocument {
// Suggestion model word matching includes quotes,
// hence exclude the starting quote from the snippet and the range
// ending quote gets replaced
if (text.startsWith('"')) {
if (text && text.startsWith('"')) {
range = new vscode.Range(new vscode.Position(range.start.line, range.start.character + 1), range.end);
snippet = snippet.substring(1);
}
@ -173,7 +174,7 @@ export class SettingsDocument {
})]);
}
if (location.path.length === 1 && location.previousNode && location.previousNode.value.startsWith('[')) {
if (location.path.length === 1 && location.previousNode && typeof location.previousNode.value === 'string' && location.previousNode.value.startsWith('[')) {
// Suggestion model word matching includes starting quote and open sqaure bracket
// Hence exclude them from the proposal range

View file

@ -15,7 +15,7 @@
},
{
"id": "cpp",
"extensions": [ ".cpp", ".cc", ".cxx", ".hpp", ".hh", ".hxx", ".h", ".mm", ".ino", ".inl" ],
"extensions": [ ".cpp", ".cc", ".cxx", ".hpp", ".hh", ".hxx", ".h", ".ino", ".inl" ],
"aliases": [ "C++", "Cpp", "cpp"],
"configuration": "./language-configuration.json"
}],

View file

@ -566,6 +566,9 @@
},
"end": "(?=\\{)",
"patterns": [
{
"include": "#comment"
},
{
"include": "#type-parameter-list"
},
@ -649,6 +652,9 @@
"begin": "(?=enum)",
"end": "(?=\\{)",
"patterns": [
{
"include": "#comment"
},
{
"match": "(enum)\\s+([_[:alpha:]][_[:alnum:]]*)",
"captures": {
@ -745,6 +751,9 @@
},
"end": "(?=\\{)",
"patterns": [
{
"include": "#comment"
},
{
"include": "#type-parameter-list"
},
@ -799,6 +808,9 @@
},
"end": "(?=\\{)",
"patterns": [
{
"include": "#comment"
},
{
"include": "#type-parameter-list"
},
@ -2809,7 +2821,7 @@
]
},
"element-access-expression": {
"begin": "(?x)\n(?:(\\?)\\s*)? # preceding null-conditional operator?\n(?:(\\.)\\s*)? # preceding dot?\n([_[:alpha:]][_[:alnum:]]*)\\s* # property name\n(?:(\\?)\\s*)? # null-conditional operator?\n(?=\\[) # open bracket of argument list",
"begin": "(?x)\n(?:(\\?)\\s*)? # preceding null-conditional operator?\n(?:(\\.)\\s*)? # preceding dot?\n(?:([_[:alpha:]][_[:alnum:]]*)\\s*)? # property name\n(?:(\\?)\\s*)? # null-conditional operator?\n(?=\\[) # open bracket of argument list",
"beginCaptures": {
"1": {
"name": "keyword.operator.null-conditional.cs"
@ -2824,7 +2836,7 @@
"name": "keyword.operator.null-conditional.cs"
}
},
"end": "(?<=\\])",
"end": "(?<=\\])(?!\\s*\\[)",
"patterns": [
{
"include": "#bracketed-argument-list"
@ -2949,7 +2961,7 @@
"name": "keyword.other.new.cs"
}
},
"end": "(?=;|\\))",
"end": "(?=\\)|;|})",
"patterns": [
{
"include": "#initializer-expression"
@ -4163,5 +4175,5 @@
}
}
},
"version": "https://github.com/dotnet/csharp-tmLanguage/commit/edf7cdf5073db593691a110efa8cdc10c34c3d1e"
"version": "https://github.com/dotnet/csharp-tmLanguage/commit/c6def572109a0c7323ea1d1ca66e5af020ab070e"
}

View file

@ -23,13 +23,18 @@ let decorationType: DecorationRenderOptions = {
}
};
export function activateColorDecorations(decoratorProvider: (uri: string) => Thenable<Range[]>, supportedLanguages: { [id: string]: boolean }): Disposable {
export function activateColorDecorations(decoratorProvider: (uri: string) => Thenable<Range[]>, supportedLanguages: { [id: string]: boolean }, isDecoratorEnabled: (languageId: string) => boolean): Disposable {
let disposables: Disposable[] = [];
let colorsDecorationType = window.createTextEditorDecorationType(decorationType);
disposables.push(colorsDecorationType);
let decoratorEnablement = {};
for (let languageId in supportedLanguages) {
decoratorEnablement[languageId] = isDecoratorEnabled(languageId);
}
let pendingUpdateRequests: { [key: string]: NodeJS.Timer; } = {};
window.onDidChangeVisibleTextEditors(editors => {
@ -40,29 +45,53 @@ export function activateColorDecorations(decoratorProvider: (uri: string) => The
workspace.onDidChangeTextDocument(event => triggerUpdateDecorations(event.document), null, disposables);
// we care about all visible editors
window.visibleTextEditors.forEach(editor => {
if (editor.document) {
triggerUpdateDecorations(editor.document);
}
});
// track open and close for document languageId changes
workspace.onDidCloseTextDocument(event => triggerUpdateDecorations(event, true));
workspace.onDidOpenTextDocument(event => triggerUpdateDecorations(event));
function triggerUpdateDecorations(document: TextDocument) {
let triggerUpdate = supportedLanguages[document.languageId];
let documentUri = document.uri;
let documentUriStr = documentUri.toString();
let timeout = pendingUpdateRequests[documentUriStr];
if (typeof timeout !== 'undefined') {
clearTimeout(timeout);
triggerUpdate = true; // force update, even if languageId is not supported (anymore)
workspace.onDidChangeConfiguration(_ => {
let hasChanges = false;
for (let languageId in supportedLanguages) {
let prev = decoratorEnablement[languageId];
let curr = isDecoratorEnabled(languageId);
if (prev !== curr) {
decoratorEnablement[languageId] = curr;
hasChanges = true;
}
}
if (hasChanges) {
updateAllVisibleEditors(true);
}
}, null, disposables);
updateAllVisibleEditors(false);
function updateAllVisibleEditors(settingsChanges: boolean) {
window.visibleTextEditors.forEach(editor => {
if (editor.document) {
triggerUpdateDecorations(editor.document, settingsChanges);
}
});
}
function triggerUpdateDecorations(document: TextDocument, settingsChanges = false) {
let triggerUpdate = supportedLanguages[document.languageId] && (decoratorEnablement[document.languageId] || settingsChanges);
if (triggerUpdate) {
let documentUriStr = document.uri.toString();
let timeout = pendingUpdateRequests[documentUriStr];
if (typeof timeout !== 'undefined') {
clearTimeout(timeout);
}
pendingUpdateRequests[documentUriStr] = setTimeout(() => {
// check if the document is in use by an active editor
for (let editor of window.visibleTextEditors) {
if (editor.document && documentUriStr === editor.document.uri.toString()) {
updateDecorationForEditor(documentUriStr, editor.document.version);
break;
if (decoratorEnablement[editor.document.languageId]) {
updateDecorationForEditor(documentUriStr, editor.document.version);
break;
} else {
editor.setDecorations(colorsDecorationType, []);
}
}
}
delete pendingUpdateRequests[documentUriStr];

View file

@ -6,7 +6,7 @@
import * as path from 'path';
import { languages, window, commands, ExtensionContext } from 'vscode';
import { languages, window, commands, workspace, ExtensionContext } from 'vscode';
import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, RequestType, Range, TextEdit } from 'vscode-languageclient';
import { activateColorDecorations } from './colorDecorators';
@ -54,7 +54,10 @@ export function activate(context: ExtensionContext) {
let colorRequestor = (uri: string) => {
return client.sendRequest(ColorSymbolRequest.type, uri).then(ranges => ranges.map(client.protocol2CodeConverter.asRange));
};
disposable = activateColorDecorations(colorRequestor, { css: true, scss: true, less: true });
let isDecoratorEnabled = (languageId: string) => {
return workspace.getConfiguration().get<boolean>(languageId + '.colorDecorators.enable');
};
disposable = activateColorDecorations(colorRequestor, { css: true, scss: true, less: true }, isDecoratorEnabled);
context.subscriptions.push(disposable);
});

View file

@ -64,6 +64,11 @@
"default": true,
"description": "%css.validate.desc%"
},
"css.colorDecorators.enable": {
"type": "boolean",
"default": true,
"description": "%css.colorDecorators.enable.desc%"
},
"css.lint.compatibleVendorPrefixes": {
"type": "string",
"enum": [
@ -271,6 +276,11 @@
"default": true,
"description": "%scss.validate.desc%"
},
"scss.colorDecorators.enable": {
"type": "boolean",
"default": true,
"description": "%scss.colorDecorators.enable.desc%"
},
"scss.lint.compatibleVendorPrefixes": {
"type": "string",
"enum": [
@ -469,6 +479,11 @@
"default": true,
"description": "%less.validate.desc%"
},
"less.colorDecorators.enable": {
"type": "boolean",
"default": true,
"description": "%less.colorDecorators.enable.desc%"
},
"less.lint.compatibleVendorPrefixes": {
"type": "string",
"enum": [

View file

@ -55,5 +55,8 @@
"scss.lint.unknownVendorSpecificProperties.desc": "Unknown vendor specific property.",
"scss.lint.vendorPrefix.desc": "When using a vendor-specific prefix also include the standard property",
"scss.lint.zeroUnits.desc": "No unit for zero needed",
"scss.validate.desc": "Enables or disables all validations"
"scss.validate.desc": "Enables or disables all validations",
"less.colorDecorators.enable.desc": "Enables or disables color decorators",
"scss.colorDecorators.enable.desc": "Enables or disables color decorators",
"css.colorDecorators.enable.desc": "Enables or disables color decorators"
}

View file

@ -35,6 +35,10 @@
{
"fileMatch": "*icon-theme.json",
"url": "vscode://schemas/icon-theme"
},
{
"fileMatch": "*color-theme.json",
"url": "vscode://schemas/color-theme"
}
]
},

View file

@ -33,7 +33,7 @@ export class PackageDocument {
// Suggestion model word matching includes quotes,
// hence exclude the starting quote from the snippet and the range
// ending quote gets replaced
if (text.startsWith('"')) {
if (text && text.startsWith('"')) {
range = new vscode.Range(new vscode.Position(range.start.line, range.start.character + 1), range.end);
snippet = snippet.substring(1);
}
@ -46,7 +46,7 @@ export class PackageDocument {
})]);
}
if (location.path.length === 3 && location.previousNode && location.previousNode.value.startsWith('[')) {
if (location.path.length === 3 && location.previousNode && typeof location.previousNode.value === 'string' && location.previousNode.value.startsWith('[')) {
// Suggestion model word matching includes starting quote and open sqaure bracket
// Hence exclude them from the proposal range

26
extensions/git/npm-shrinkwrap.json generated Normal file
View file

@ -0,0 +1,26 @@
{
"name": "git",
"version": "0.0.1",
"dependencies": {
"applicationinsights": {
"version": "0.18.0",
"from": "applicationinsights@0.18.0",
"resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-0.18.0.tgz"
},
"vscode-extension-telemetry": {
"version": "0.0.6",
"from": "vscode-extension-telemetry@>=0.0.6 <0.0.7",
"resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.6.tgz"
},
"vscode-nls": {
"version": "2.0.2",
"from": "vscode-nls@>=2.0.1 <3.0.0",
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-2.0.2.tgz"
},
"winreg": {
"version": "1.2.3",
"from": "winreg@1.2.3",
"resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.3.tgz"
}
}
}

View file

@ -7,6 +7,7 @@
"engines": {
"vscode": "^1.5.0"
},
"aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217",
"enableProposedApi": true,
"categories": [
"Other"
@ -21,6 +22,11 @@
},
"contributes": {
"commands": [
{
"command": "git.clone",
"title": "%command.clone%",
"category": "Git"
},
{
"command": "git.init",
"title": "%command.init%",
@ -206,14 +212,6 @@
"category": "Git"
}
],
"keybindings": [
{
"command": "git.commitWithInput",
"key": "ctrl+enter",
"mac": "cmd+enter",
"when": "inSCMInput"
}
],
"menus": {
"commandPalette": [
{
@ -512,12 +510,12 @@
{
"command": "git.openFile",
"group": "navigation",
"when": "isInDiffEditor"
"when": "isInDiffEditor && resourceScheme == file"
},
{
"command": "git.openChange",
"group": "navigation",
"when": "!isInDiffEditor"
"when": "!isInDiffEditor && resourceScheme == file"
}
]
},
@ -548,11 +546,6 @@
"description": "%config.autofetch%",
"default": true
},
"git.enableLongCommitWarning": {
"type": "boolean",
"description": "%config.enableLongCommitWarning%",
"default": true
},
"git.confirmSync": {
"type": "boolean",
"description": "%config.confirmSync%",
@ -583,6 +576,7 @@
}
},
"dependencies": {
"vscode-extension-telemetry": "^0.0.6",
"vscode-nls": "^2.0.1"
},
"devDependencies": {

View file

@ -1,17 +1,18 @@
{
"command.init": "Initialize Git Repository",
"command.clone": "Clone",
"command.init": "Initialize Repository",
"command.refresh": "Refresh",
"command.openChange": "Open Change",
"command.openFile": "Open File",
"command.stage": "Stage",
"command.stageAll": "Stage All",
"command.stage": "Stage File",
"command.stageAll": "Stage All Files",
"command.stageSelectedRanges": "Stage Selected Ranges",
"command.revertSelectedRanges": "Revert Selected Ranges",
"command.unstage": "Unstage",
"command.unstageAll": "Unstage All",
"command.unstage": "Unstage File",
"command.unstageAll": "Unstage All Files",
"command.unstageSelectedRanges": "Unstage Selected Ranges",
"command.clean": "Clean",
"command.cleanAll": "Clean All",
"command.clean": "Clean File",
"command.cleanAll": "Clean All Files",
"command.commit": "Commit",
"command.commitStaged": "Commit Staged",
"command.commitStagedSigned": "Commit Staged (Signed Off)",

View file

@ -0,0 +1,76 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as http from 'http';
import * as fs from 'fs';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
function fatal(err: any): void {
console.error(localize('missOrInvalid', "Missing or invalid credentials."));
console.error(err);
process.exit(1);
}
function main(argv: string[]): void {
if (argv.length !== 5) {
return fatal('Wrong number of arguments');
}
if (!process.env['VSCODE_GIT_ASKPASS_PORT']) {
return fatal('Missing port');
}
if (!process.env['VSCODE_GIT_ASKPASS_PIPE']) {
return fatal('Missing pipe');
}
if (process.env['VSCODE_GIT_COMMAND'] === 'fetch') {
return fatal('Skip fetch commands');
}
const output = process.env['VSCODE_GIT_ASKPASS_PIPE'];
const port = Number.parseInt(process.env['VSCODE_GIT_ASKPASS_PORT']);
const request = argv[2];
const host = argv[4].substring(1, argv[4].length - 2);
const opts: http.RequestOptions = {
hostname: 'localhost',
port,
path: '/',
method: 'POST'
};
const req = http.request(opts, res => {
if (res.statusCode !== 200) {
return fatal(`Bad status code: ${res.statusCode}`);
}
const chunks: string[] = [];
res.setEncoding('utf8');
res.on('data', (d: string) => chunks.push(d));
res.on('end', () => {
const raw = chunks.join('');
try {
const result = JSON.parse(raw);
fs.writeFileSync(output, result + '\n');
} catch (err) {
return fatal(`Error parsing response`);
}
setTimeout(() => process.exit(0), 0);
});
});
req.on('error', () => fatal('Error in request'));
req.write(JSON.stringify({ request, host }));
req.end();
}
main(process.argv);

5
extensions/git/src/askpass.sh Executable file
View file

@ -0,0 +1,5 @@
#!/bin/sh
VSCODE_GIT_ASKPASS_PIPE=`mktemp`
VSCODE_GIT_ASKPASS_PIPE="$VSCODE_GIT_ASKPASS_PIPE" "$VSCODE_GIT_ASKPASS_NODE" "$VSCODE_GIT_ASKPASS_MAIN" $*
cat $VSCODE_GIT_ASKPASS_PIPE
rm $VSCODE_GIT_ASKPASS_PIPE

View file

@ -0,0 +1,69 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { Disposable, window, InputBoxOptions } from 'vscode';
import * as path from 'path';
import * as http from 'http';
export class Askpass implements Disposable {
private server: http.Server;
private portPromise: Promise<number>;
constructor() {
this.server = http.createServer((req, res) => this.onRequest(req, res));
this.server.listen(0, 'localhost');
this.portPromise = new Promise(c => {
this.server.on('listening', () => c(this.server.address().port));
});
this.server.on('error', err => console.error(err));
}
private onRequest(req: http.ServerRequest, res: http.ServerResponse): void {
const chunks: string[] = [];
req.setEncoding('utf8');
req.on('data', (d: string) => chunks.push(d));
req.on('end', () => {
const {request, host} = JSON.parse(chunks.join(''));
this.prompt(host, request).then(result => {
res.writeHead(200);
res.end(JSON.stringify(result));
}, () => {
res.writeHead(500);
res.end();
});
});
}
private async prompt(host: string, request: string): Promise<string> {
const options: InputBoxOptions = {
password: /password/i.test(request),
placeHolder: request,
prompt: `Git: ${host}`,
ignoreFocusOut: true
};
return await window.showInputBox(options) || '';
}
getEnv(): Promise<any> {
return this.portPromise.then(port => ({
ELECTRON_RUN_AS_NODE: '1',
GIT_ASKPASS: path.join(__dirname, 'askpass.sh'),
VSCODE_GIT_ASKPASS_NODE: process.execPath,
VSCODE_GIT_ASKPASS_MAIN: path.join(__dirname, 'askpass-main.js'),
VSCODE_GIT_ASKPASS_PORT: String(port)
}));
}
dispose(): void {
this.server.close();
}
}

View file

@ -5,33 +5,17 @@
'use strict';
import { Uri, commands, scm, Disposable, SCMResourceGroup, SCMResource, window, workspace, QuickPickItem, OutputChannel, computeDiff, Range, WorkspaceEdit, Position } from 'vscode';
import { Uri, commands, scm, Disposable, window, workspace, QuickPickItem, OutputChannel, computeDiff, Range, WorkspaceEdit, Position } from 'vscode';
import { Ref, RefType } from './git';
import { Model, Resource, Status, CommitOptions } from './model';
import * as staging from './staging';
import * as path from 'path';
import * as os from 'os';
import TelemetryReporter from 'vscode-extension-telemetry';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
function resolveGitURI(uri: Uri): SCMResource | SCMResourceGroup | undefined {
if (uri.authority !== 'git') {
return;
}
return scm.getResourceFromURI(uri);
}
function resolveGitResource(uri: Uri): Resource | undefined {
const resource = resolveGitURI(uri);
if (!(resource instanceof Resource)) {
return;
}
return resource;
}
class CheckoutItem implements QuickPickItem {
protected get shortCommit(): string { return (this.ref.commit || '').substr(0, 8); }
@ -94,14 +78,15 @@ export class CommandCenter {
constructor(
model: Model | undefined,
private outputChannel: OutputChannel
private outputChannel: OutputChannel,
private telemetryReporter: TelemetryReporter
) {
if (model) {
this.model = model;
}
this.disposables = Commands
.map(({ commandId, method }) => commands.registerCommand(commandId, this.createCommand(method)));
.map(({ commandId, method }) => commands.registerCommand(commandId, this.createCommand(commandId, method)));
}
@command('git.refresh')
@ -184,44 +169,106 @@ export class CommandCenter {
return '';
}
/**
* Attempts to clone a git repository. Throws descriptive errors
* for usual error cases. Returns whether the user chose to open
* the resulting folder or otherwise.
*
* This only exists for the walkthrough contribution to have good
* telemetry.
*
* TODO@Christof: when all the telemetry questions are answered,
* please clean this up into a single clone method.
*/
@command('_git.clone')
async _clone(): Promise<boolean> {
const url = await window.showInputBox({
prompt: localize('repourl', "Repository URL"),
ignoreFocusOut: true
});
if (!url) {
throw new Error('no_URL');
}
const parentPath = await window.showInputBox({
prompt: localize('parent', "Parent Directory"),
value: os.homedir(),
ignoreFocusOut: true
});
if (!parentPath) {
throw new Error('no_directory');
}
const clonePromise = this.model.git.clone(url, parentPath);
window.setStatusBarMessage(localize('cloning', "Cloning git repository..."), clonePromise);
let repositoryPath: string;
try {
repositoryPath = await clonePromise;
} catch (err) {
if (/already exists and is not an empty directory/.test(err && err.stderr || '')) {
throw new Error('directory_not_empty');
}
throw err;
}
const open = localize('openrepo', "Open Repository");
const result = await window.showInformationMessage(localize('proposeopen', "Would you like to open the cloned repository?"), open);
const openFolder = result === open;
if (openFolder) {
commands.executeCommand('vscode.openFolder', Uri.file(repositoryPath));
}
return openFolder;
}
@command('git.clone')
async clone(): Promise<void> {
try {
await this._clone();
} catch (err) {
// noop
}
}
@command('git.init')
async init(): Promise<void> {
await this.model.init();
}
@command('git.openFile')
async openFile(uri: Uri): Promise<void> {
const scmResource = resolveGitResource(uri);
if (scmResource) {
return await commands.executeCommand<void>('vscode.open', scmResource.uri);
async openFile(uri?: Uri): Promise<void> {
if (uri && uri.scheme === 'file') {
return await commands.executeCommand<void>('vscode.open', uri);
}
return await commands.executeCommand<void>('vscode.open', uri.with({ scheme: 'file' }));
const resource = this.resolveSCMResource(uri);
if (!resource) {
return;
}
return await commands.executeCommand<void>('vscode.open', resource.uri);
}
@command('git.openChange')
async openChange(uri: Uri): Promise<void> {
const scmResource = resolveGitResource(uri);
async openChange(uri?: Uri): Promise<void> {
const resource = this.resolveSCMResource(uri);
if (scmResource) {
return await this.open(scmResource);
if (!resource) {
return;
}
if (uri.scheme === 'file') {
const uriString = uri.toString();
const resource = this.model.workingTreeGroup.resources.filter(r => r.uri.toString() === uriString)[0]
|| this.model.indexGroup.resources.filter(r => r.uri.toString() === uriString)[0];
if (resource) {
return await this.open(resource);
}
}
return await this.open(resource);
}
@command('git.stage')
async stage(uri: Uri): Promise<void> {
const resource = resolveGitResource(uri);
async stage(uri?: Uri): Promise<void> {
const resource = this.resolveSCMResource(uri);
if (!resource) {
return;
@ -317,8 +364,8 @@ export class CommandCenter {
}
@command('git.unstage')
async unstage(uri: Uri): Promise<void> {
const resource = resolveGitResource(uri);
async unstage(uri?: Uri): Promise<void> {
const resource = this.resolveSCMResource(uri);
if (!resource) {
return;
@ -375,8 +422,8 @@ export class CommandCenter {
}
@command('git.clean')
async clean(uri: Uri): Promise<void> {
const resource = resolveGitResource(uri);
async clean(uri?: Uri): Promise<void> {
const resource = this.resolveSCMResource(uri);
if (!resource) {
return;
@ -446,14 +493,15 @@ export class CommandCenter {
return await window.showInputBox({
placeHolder: localize('commit message', "Commit message"),
prompt: localize('provide commit message', "Please provide a commit message")
prompt: localize('provide commit message', "Please provide a commit message"),
ignoreFocusOut: true
});
};
const didCommit = await this.smartCommit(getCommitMessage, opts);
if (message && didCommit) {
scm.inputBox.value = '';
scm.inputBox.value = await this.model.getCommitTemplate();
}
}
@ -467,7 +515,7 @@ export class CommandCenter {
const didCommit = await this.smartCommit(async () => scm.inputBox.value);
if (didCommit) {
scm.inputBox.value = '';
scm.inputBox.value = await this.model.getCommitTemplate();
}
}
@ -535,7 +583,8 @@ export class CommandCenter {
async branch(): Promise<void> {
const result = await window.showInputBox({
placeHolder: localize('branch name', "Branch name"),
prompt: localize('provide branch name', "Please provide a branch name")
prompt: localize('provide branch name', "Please provide a branch name"),
ignoreFocusOut: true
});
if (!result) {
@ -661,13 +710,15 @@ export class CommandCenter {
this.outputChannel.show();
}
private createCommand(method: Function): (...args: any[]) => any {
private createCommand(id: string, method: Function): (...args: any[]) => any {
return (...args) => {
if (!this.model) {
window.showInformationMessage(localize('disabled', "Git is either disabled or not supported in this workspace"));
return;
}
this.telemetryReporter.sendTelemetryEvent('git.command', { command: id });
const result = Promise.resolve(method.apply(this, args));
return result.catch(async err => {
@ -703,6 +754,30 @@ export class CommandCenter {
};
}
private resolveSCMResource(uri?: Uri): Resource | undefined {
uri = uri || window.activeTextEditor && window.activeTextEditor.document.uri;
if (!uri) {
return;
}
if (uri.scheme === 'scm' && uri.authority === 'git') {
const resource = scm.getResourceFromURI(uri);
return resource instanceof Resource ? resource : undefined;
}
if (uri.scheme === 'git') {
uri = uri.with({ scheme: 'file' });
}
if (uri.scheme === 'file') {
const uriString = uri.toString();
return this.model.workingTreeGroup.resources.filter(r => r.uri.toString() === uriString)[0]
|| this.model.indexGroup.resources.filter(r => r.uri.toString() === uriString)[0];
}
}
dispose(): void {
this.disposables.forEach(d => d.dispose());
}

View file

@ -1,112 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { workspace, window, languages, Disposable, Uri, HoverProvider, Hover, TextEditor, Position, TextDocument, Range, TextEditorDecorationType, WorkspaceEdit } from 'vscode';
import { filterEvent } from './util';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
const scmInputUri = Uri.parse('scm:input');
function isSCMInput(uri: Uri) {
return uri.toString() === scmInputUri.toString();
}
interface Diagnostic {
range: Range;
message: string;
}
// TODO@Joao: hover disappears if editor is scrolled
export class CommitController implements HoverProvider {
private visibleTextEditorsDisposable: Disposable;
private editor: TextEditor;
private diagnostics: Diagnostic[] = [];
private decorationType: TextEditorDecorationType;
private disposables: Disposable[] = [];
get message(): string | undefined {
if (!this.editor) {
return;
}
return this.editor.document.getText();
}
set message(message: string | undefined) {
if (!this.editor || message === undefined) {
return;
}
const document = this.editor.document;
const start = document.lineAt(0).range.start;
const end = document.lineAt(document.lineCount - 1).range.end;
const range = new Range(start, end);
const edit = new WorkspaceEdit();
edit.replace(scmInputUri, range, message);
workspace.applyEdit(edit);
}
constructor() {
this.visibleTextEditorsDisposable = window.onDidChangeVisibleTextEditors(this.onVisibleTextEditors, this);
this.onVisibleTextEditors(window.visibleTextEditors);
this.decorationType = window.createTextEditorDecorationType({
isWholeLine: true,
color: 'rgb(228, 157, 43)',
dark: {
color: 'rgb(220, 211, 71)'
}
});
}
private onVisibleTextEditors(editors: TextEditor[]): void {
const [editor] = editors.filter(e => isSCMInput(e.document.uri));
if (!editor) {
return;
}
this.visibleTextEditorsDisposable.dispose();
this.editor = editor;
const onDidChange = filterEvent(workspace.onDidChangeTextDocument, e => e.document && isSCMInput(e.document.uri));
onDidChange(this.update, this, this.disposables);
workspace.onDidChangeConfiguration(this.update, this, this.disposables);
languages.registerHoverProvider({ scheme: 'scm' }, this);
}
private update(): void {
this.diagnostics = [];
const range = this.editor.document.lineAt(0).range;
const length = range.end.character - range.start.character;
if (workspace.getConfiguration('git').get<boolean>('enableLongCommitWarning') && length > 80) {
const message = localize('too long', "You should keep the first line under 50 characters.\n\nYou can use more lines for extra information.");
this.diagnostics.push({ range, message });
}
this.editor.setDecorations(this.decorationType, this.diagnostics.map(d => d.range));
}
provideHover(document: TextDocument, position: Position): Hover | undefined {
const [decoration] = this.diagnostics.filter(d => d.range.contains(position));
if (!decoration) {
return;
}
return new Hover(decoration.message, decoration.range);
}
dispose(): void {
this.disposables.forEach(d => d.dispose());
}
}

View file

@ -5,34 +5,64 @@
'use strict';
import { workspace, Uri, Disposable, Event, EventEmitter } from 'vscode';
import { debounce } from './decorators';
import { workspace, Uri, Disposable, Event, EventEmitter, window } from 'vscode';
import { debounce, throttle } from './decorators';
import { Model } from './model';
export class GitContentProvider {
interface CacheRow {
uri: Uri;
timestamp: number;
}
private disposables: Disposable[] = [];
interface Cache {
[uri: string]: CacheRow;
}
const THREE_MINUTES = 1000 * 60 * 3;
const FIVE_MINUTES = 1000 * 60 * 5;
export class GitContentProvider {
private onDidChangeEmitter = new EventEmitter<Uri>();
get onDidChange(): Event<Uri> { return this.onDidChangeEmitter.event; }
private uris: { [uri: string]: Uri } = Object.create(null) as { [uri: string]: Uri };
private cache: Cache = Object.create(null);
private disposables: Disposable[] = [];
constructor(private model: Model) {
this.disposables.push(
model.onDidChangeRepository(this.fireChangeEvents, this),
workspace.registerTextDocumentContentProvider('git', this)
model.onDidChangeRepository(this.eventuallyFireChangeEvents, this),
workspace.registerTextDocumentContentProvider('git', this),
workspace.registerTextDocumentContentProvider('git-original', this)
);
setInterval(() => this.cleanup(), FIVE_MINUTES);
}
@debounce(300)
private fireChangeEvents(): void {
Object.keys(this.uris).forEach(key => {
this.onDidChangeEmitter.fire(this.uris[key]);
});
@debounce(1100)
private eventuallyFireChangeEvents(): void {
this.fireChangeEvents();
}
@throttle
private async fireChangeEvents(): Promise<void> {
await this.model.whenIdle();
Object.keys(this.cache)
.forEach(key => this.onDidChangeEmitter.fire(this.cache[key].uri));
}
async provideTextDocumentContent(uri: Uri): Promise<string> {
const cacheKey = uri.toString();
const timestamp = new Date().getTime();
const cacheValue = { uri, timestamp };
this.cache[cacheKey] = cacheValue;
if (uri.scheme === 'git-original') {
uri = new Uri().with({ scheme: 'git', path: uri.query });
}
let ref = uri.query;
if (ref === '~') {
@ -44,14 +74,28 @@ export class GitContentProvider {
try {
const result = await this.model.show(ref, uri);
this.uris[uri.toString()] = uri;
return result;
} catch (err) {
delete this.uris[uri.toString()];
return '';
}
}
private cleanup(): void {
const now = new Date().getTime();
const cache = Object.create(null);
Object.keys(this.cache).forEach(key => {
const row = this.cache[key];
const isOpen = window.visibleTextEditors.some(e => e.document.uri.fsPath === row.uri.fsPath);
if (isOpen || now - row.timestamp < THREE_MINUTES) {
cache[row.uri.toString()] = row;
}
});
this.cache = cache;
}
dispose(): void {
this.disposables.forEach(d => d.dispose());
}

View file

@ -9,7 +9,7 @@ import * as fs from 'fs';
import * as path from 'path';
import * as os from 'os';
import * as cp from 'child_process';
import { assign, uniqBy, groupBy, denodeify, IDisposable, toDisposable, dispose } from './util';
import { assign, uniqBy, groupBy, denodeify, IDisposable, toDisposable, dispose, mkdirp } from './util';
import { EventEmitter, Event } from 'vscode';
import * as nls from 'vscode-nls';
@ -289,6 +289,20 @@ export class Git {
return new Repository(this, repository, env);
}
async init(repository: string): Promise<void> {
await this.exec(repository, ['init']);
return;
}
async clone(url: string, parentPath: string): Promise<string> {
const folderName = url.replace(/^.*\//, '').replace(/\.git$/, '') || 'repository';
const folderPath = path.join(parentPath, folderName);
await mkdirp(parentPath);
await this.exec(parentPath, ['clone', url, folderPath]);
return folderPath;
}
async getRepositoryRoot(path: string): Promise<string> {
const result = await this.exec(path, ['rev-parse', '--show-toplevel']);
return result.stdout.trim();
@ -361,6 +375,7 @@ export class Git {
}
options.env = assign({}, process.env, options.env || {}, {
VSCODE_GIT_COMMAND: args[0],
LANG: 'en_US.UTF-8'
});
@ -419,10 +434,6 @@ export class Repository {
return this.git.spawn(args, options);
}
init(): Promise<any> {
return this.run(['init']);
}
async config(scope: string, key: string, value: any, options: any): Promise<string> {
const args = ['config'];

View file

@ -5,7 +5,7 @@
'use strict';
import { ExtensionContext, workspace, window, Disposable, commands, Uri } from 'vscode';
import { ExtensionContext, workspace, window, Disposable, commands, Uri, scm } from 'vscode';
import { findGit, Git } from './git';
import { Model } from './model';
import { GitSCMProvider } from './scmProvider';
@ -14,21 +14,26 @@ import { CheckoutStatusBar, SyncStatusBar } from './statusbar';
import { GitContentProvider } from './contentProvider';
import { AutoFetcher } from './autofetch';
import { MergeDecorator } from './merge';
import { CommitController } from './commit';
import { Askpass } from './askpass';
import TelemetryReporter from 'vscode-extension-telemetry';
import * as nls from 'vscode-nls';
const localize = nls.config()();
async function init(disposables: Disposable[]): Promise<void> {
async function init(context: ExtensionContext, disposables: Disposable[]): Promise<void> {
const { name, version, aiKey } = require(context.asAbsolutePath('./package.json')) as { name: string, version: string, aiKey: string };
const telemetryReporter: TelemetryReporter = new TelemetryReporter(name, version, aiKey);
disposables.push(telemetryReporter);
const outputChannel = window.createOutputChannel('Git');
disposables.push(outputChannel);
const config = workspace.getConfiguration('git');
const enabled = config.get<boolean>('enabled') === true;
const rootPath = workspace.rootPath;
const workspaceRootPath = workspace.rootPath;
if (!rootPath || !enabled) {
const commandCenter = new CommandCenter(undefined, outputChannel);
if (!workspaceRootPath || !enabled) {
const commandCenter = new CommandCenter(undefined, outputChannel, telemetryReporter);
disposables.push(commandCenter);
return;
}
@ -36,13 +41,13 @@ async function init(disposables: Disposable[]): Promise<void> {
const pathHint = workspace.getConfiguration('git').get<string>('path');
const info = await findGit(pathHint);
const git = new Git({ gitPath: info.path, version: info.version });
const model = new Model(git, rootPath);
const askpass = new Askpass();
const model = new Model(git, workspaceRootPath, askpass);
outputChannel.appendLine(localize('using git', "Using git {0} from {1}", info.version, info.path));
git.onOutput(str => outputChannel.append(str), null, disposables);
const commitHandler = new CommitController();
const commandCenter = new CommandCenter(model, outputChannel);
const commandCenter = new CommandCenter(model, outputChannel, telemetryReporter);
const provider = new GitSCMProvider(model, commandCenter);
const contentProvider = new GitContentProvider(model);
const checkoutStatusBar = new CheckoutStatusBar(model);
@ -51,7 +56,6 @@ async function init(disposables: Disposable[]): Promise<void> {
const mergeDecorator = new MergeDecorator(model);
disposables.push(
commitHandler,
commandCenter,
provider,
contentProvider,
@ -70,6 +74,8 @@ async function init(disposables: Disposable[]): Promise<void> {
commands.executeCommand('vscode.open', Uri.parse('https://git-scm.com/'));
}
}
scm.inputBox.value = await model.getCommitTemplate();
}
export function activate(context: ExtensionContext): any {
@ -80,6 +86,6 @@ export function activate(context: ExtensionContext): any {
const disposables: Disposable[] = [];
context.subscriptions.push(new Disposable(() => Disposable.from(...disposables).dispose()));
init(disposables)
init(context, disposables)
.catch(err => console.error(err));
}

View file

@ -10,9 +10,14 @@ import { Git, Repository, Ref, Branch, Remote, PushOptions, Commit, GitErrorCode
import { anyEvent, eventToPromise, filterEvent, mapEvent, EmptyDisposable, combinedDisposable, dispose } from './util';
import { memoize, throttle, debounce } from './decorators';
import { watch } from './watch';
import { Askpass } from './askpass';
import * as path from 'path';
import * as fs from 'fs';
import * as nls from 'vscode-nls';
const timeout = (millis: number) => new Promise(c => setTimeout(c, millis));
const exists = (path: string) => new Promise(c => fs.exists(path, c));
const localize = nls.loadMessageBundle();
const iconsRootPath = path.join(path.dirname(__dirname), 'resources', 'icons');
@ -183,7 +188,40 @@ export enum Operation {
Sync = 1 << 11,
Init = 1 << 12,
Show = 1 << 13,
Stage = 1 << 13
Stage = 1 << 14,
GetCommitTemplate = 1 << 15
}
// function getOperationName(operation: Operation): string {
// switch (operation) {
// case Operation.Status: return 'Status';
// case Operation.Add: return 'Add';
// case Operation.RevertFiles: return 'RevertFiles';
// case Operation.Commit: return 'Commit';
// case Operation.Clean: return 'Clean';
// case Operation.Branch: return 'Branch';
// case Operation.Checkout: return 'Checkout';
// case Operation.Reset: return 'Reset';
// case Operation.Fetch: return 'Fetch';
// case Operation.Pull: return 'Pull';
// case Operation.Push: return 'Push';
// case Operation.Sync: return 'Sync';
// case Operation.Init: return 'Init';
// case Operation.Show: return 'Show';
// case Operation.Stage: return 'Stage';
// case Operation.GetCommitTemplate: return 'GetCommitTemplate';
// default: return 'unknown';
// }
// }
function isReadOnly(operation: Operation): boolean {
switch (operation) {
case Operation.Show:
case Operation.GetCommitTemplate:
return true;
default:
return false;
}
}
export interface Operations {
@ -247,6 +285,10 @@ export class Model implements Disposable {
return anyEvent(this.onRunOperation as Event<any>, this.onDidRunOperation as Event<any>);
}
get git(): Git {
return this._git;
}
private _mergeGroup = new MergeGroup([]);
get mergeGroup(): MergeGroup { return this._mergeGroup; }
@ -312,8 +354,9 @@ export class Model implements Disposable {
private disposables: Disposable[] = [];
constructor(
private git: Git,
private rootPath: string,
private _git: Git,
private workspaceRootPath: string,
private askpass: Askpass
) {
const fsWatcher = workspace.createFileSystemWatcher('**');
this.onWorkspaceChange = anyEvent(fsWatcher.onDidChange, fsWatcher.onDidCreate, fsWatcher.onDidDelete);
@ -322,13 +365,34 @@ export class Model implements Disposable {
this.status();
}
async whenIdle(): Promise<void> {
while (!this.operations.isIdle()) {
await eventToPromise(this.onDidRunOperation);
}
}
/**
* Returns promise which resolves when there is no `.git/index.lock` file,
* or when it has attempted way too many times. Back off mechanism.
*/
async whenUnlocked(): Promise<void> {
let millis = 100;
let retries = 0;
while (retries < 10 && await exists(path.join(this.repository.root, '.git', 'index.lock'))) {
retries += 1;
millis *= 1.4;
await timeout(millis);
}
}
@throttle
async init(): Promise<void> {
if (this.state !== State.NotAGitRepository) {
return;
}
await this.repository.init();
await this.git.init(this.workspaceRootPath);
await this.status();
}
@ -438,6 +502,9 @@ export class Model implements Disposable {
}
async show(ref: string, uri: Uri): Promise<string> {
// TODO@Joao: should we make this a general concept?
await this.whenIdle();
return await this.run(Operation.Show, async () => {
const relativePath = path.relative(this.repository.root, uri.fsPath).replace(/\\/g, '/');
const result = await this.repository.git.exec(this.repository.root, ['show', `${ref}:${relativePath}`]);
@ -453,6 +520,10 @@ export class Model implements Disposable {
});
}
async getCommitTemplate(): Promise<string> {
return await this.run(Operation.GetCommitTemplate, async () => this.repository.getCommitTemplate());
}
private async run<T>(operation: Operation, runOperation: () => Promise<T> = () => Promise.resolve<any>(null)): Promise<T> {
return window.withScmProgress(async () => {
this._operations = this._operations.start(operation);
@ -460,12 +531,22 @@ export class Model implements Disposable {
try {
await this.assertIdleState();
await this.whenUnlocked();
const result = await runOperation();
await this.update();
if (!isReadOnly(operation)) {
await this.update();
}
return result;
} catch (err) {
if (err.gitErrorCode === GitErrorCodes.NotAGitRepository) {
this.repositoryDisposable.dispose();
const disposables: Disposable[] = [];
this.onWorkspaceChange(this.onFSChange, this, disposables);
this.repositoryDisposable = combinedDisposable(disposables);
this.state = State.NotAGitRepository;
}
@ -490,8 +571,9 @@ export class Model implements Disposable {
this.repositoryDisposable.dispose();
const disposables: Disposable[] = [];
const repositoryRoot = await this.git.getRepositoryRoot(this.rootPath);
this.repository = this.git.open(repositoryRoot);
const repositoryRoot = await this.git.getRepositoryRoot(this.workspaceRootPath);
const askpassEnv = await this.askpass.getEnv();
this.repository = this.git.open(repositoryRoot, askpassEnv);
const dotGitPath = path.join(repositoryRoot, '.git');
const { event: onRawGitChange, disposable: watcher } = watch(dotGitPath);
@ -600,13 +682,7 @@ export class Model implements Disposable {
private async updateWhenIdleAndWait(): Promise<void> {
await this.whenIdle();
await this.status();
await new Promise(c => setTimeout(c, 5000));
}
private async whenIdle(): Promise<void> {
while (!this.operations.isIdle()) {
await eventToPromise(this.onDidRunOperation);
}
await timeout(5000);
}
dispose(): void {

View file

@ -49,6 +49,10 @@ export class GitSCMProvider implements SCMProvider {
return this.commandCenter.open(resource);
}
acceptChanges(): ProviderResult<void> {
return this.commandCenter.commitWithInput();
}
drag(resource: Resource, resourceGroup: ResourceGroup): void {
console.log('drag', resource, resourceGroup);
}
@ -58,7 +62,9 @@ export class GitSCMProvider implements SCMProvider {
return;
}
return uri.with({ scheme: 'git' });
// As a mitigation for extensions like ESLint showing warnings and errors
// for git URIs, let's change the file extension of these uris to .git.
return new Uri().with({ scheme: 'git-original', query: uri.path, path: uri.path + '.git' });
}
dispose(): void {

View file

@ -6,6 +6,8 @@
'use strict';
import { Event } from 'vscode';
import { dirname } from 'path';
import * as fs from 'fs';
export function log(...args: any[]): void {
console.log.apply(console, ['git:', ...args]);
@ -39,7 +41,15 @@ export function filterEvent<T>(event: Event<T>, filter: (e: T) => boolean): Even
}
export function anyEvent<T>(...events: Event<T>[]): Event<T> {
return (listener, thisArgs = null, disposables?) => combinedDisposable(events.map(event => event(i => listener.call(thisArgs, i), disposables)));
return (listener, thisArgs = null, disposables?) => {
const result = combinedDisposable(events.map(event => event(i => listener.call(thisArgs, i))));
if (disposables) {
disposables.push(result);
}
return result;
};
}
export function done<T>(promise: Promise<T>): Promise<void> {
@ -96,3 +106,45 @@ export function groupBy<T>(arr: T[], fn: (el: T) => string): { [key: string]: T[
export function denodeify<R>(fn: Function): (...args) => Promise<R> {
return (...args) => new Promise((c, e) => fn(...args, (err, r) => err ? e(err) : c(r)));
}
export function nfcall<R>(fn: Function, ...args): Promise<R> {
return new Promise((c, e) => fn(...args, (err, r) => err ? e(err) : c(r)));
}
export async function mkdirp(path: string, mode?: number): Promise<boolean> {
const mkdir = async () => {
try {
await nfcall(fs.mkdir, path, mode);
} catch (err) {
if (err.code === 'EEXIST') {
const stat = await nfcall<fs.Stats>(fs.stat, path);
if (stat.isDirectory) {
return;
}
throw new Error(`'${path}' exists and is not a directory.`);
}
throw err;
}
};
// is root?
if (path === dirname(path)) {
return true;
}
try {
await mkdir();
} catch (err) {
if (err.code !== 'ENOENT') {
throw err;
}
await mkdirp(dirname(path), mode);
await mkdir();
}
return true;
}

View file

@ -17,6 +17,11 @@
"language": "go",
"scopeName": "source.go",
"path": "./syntaxes/go.json"
}]
}],
"configurationDefaults": {
"[go]": {
"editor.insertSpaces": false
}
}
}
}

View file

@ -8,6 +8,7 @@
"id": "groovy",
"aliases": ["Groovy", "groovy"],
"extensions": [".groovy", ".gvy", ".gradle"],
"filenames": [ "Jenkinsfile" ],
"firstLine": "^#!.*\\bgroovy\\b",
"configuration": "./language-configuration.json"
}],

View file

@ -0,0 +1,8 @@
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
[{
"name": "shaders-tmLanguage",
"version": "0.1.0",
"license": "MIT",
"repositoryURL": "https://github.com/tgjones/shaders-tmLanguage"
}]

View file

@ -0,0 +1,23 @@
{
"comments": {
"lineComment": "//",
"blockComment": [ "/*", "*/" ]
},
"brackets": [
["{", "}"],
["[", "]"],
["(", ")"]
],
"autoClosingPairs": [
["{", "}"],
["[", "]"],
["(", ")"],
["\"", "\""]
],
"surroundingPairs": [
["{", "}"],
["[", "]"],
["(", ")"],
["\"", "\""]
]
}

View file

@ -0,0 +1,22 @@
{
"name": "hlsl",
"version": "0.1.0",
"publisher": "vscode",
"engines": { "vscode": "*" },
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js tgjones/shaders-tmLanguage grammars/hlsl.json ./syntaxes/hlsl.json"
},
"contributes": {
"languages": [{
"id": "hlsl",
"extensions": [".hlsl",".hlsli",".fx",".fxh",".vsh",".psh",".cginc",".compute"],
"aliases": ["HLSL", "hlsl"],
"configuration": "./language-configuration.json"
}],
"grammars": [{
"language": "hlsl",
"path": "./syntaxes/hlsl.json",
"scopeName":"source.hlsl"
}]
}
}

View file

@ -0,0 +1,218 @@
{
"scopeName": "source.hlsl",
"name": "HLSL",
"fileTypes": [
"hlsl",
"hlsli",
"fx",
"fxh",
"vsh",
"psh",
"cginc",
"compute"
],
"patterns": [
{
"name": "comment.line.block.hlsl",
"begin": "/\\*",
"end": "\\*/"
},
{
"name": "comment.line.double-slash.hlsl",
"begin": "//",
"end": "$"
},
{
"name": "constant.numeric.hlsl",
"match": "\\b([0-9]+\\.?[0-9]*)\\b"
},
{
"name": "constant.numeric.hlsl",
"match": "\\b(\\.[0-9]+)\\b"
},
{
"name": "constant.numeric.hex.hlsl",
"match": "\\b(0x[0-9A-F]+)\\b"
},
{
"name": "constant.language.hlsl",
"match": "\\b(false|true)\\b"
},
{
"name": "keyword.preprocessor.hlsl",
"match": "^\\s*#\\s*(define|elif|else|endif|ifdef|ifndef|if|undef|include|line|error|pragma)"
},
{
"name": "keyword.control.hlsl",
"match": "\\b(break|case|continue|default|discard|do|else|for|if|return|switch|while)\\b"
},
{
"name": "keyword.control.fx.hlsl",
"match": "\\b(compile)\\b"
},
{
"name": "keyword.typealias.hlsl",
"match": "\\b(typedef)\\b"
},
{
"name": "storage.type.basic.hlsl",
"match": "\\b(bool([1-4](x[1-4])?)?|double([1-4](x[1-4])?)?|dword|float([1-4](x[1-4])?)?|half([1-4](x[1-4])?)?|int([1-4](x[1-4])?)?|matrix|min10float([1-4](x[1-4])?)?|min12int([1-4](x[1-4])?)?|min16float([1-4](x[1-4])?)?|min16int([1-4](x[1-4])?)?|min16uint([1-4](x[1-4])?)?|unsigned|uint([1-4](x[1-4])?)?|vector|void)\\b"
},
{
"name": "support.function.hlsl",
"match": "\\b([a-zA-Z_][a-zA-Z0-9_]*)(?=[\\s]*\\()"
},
{
"name": "support.variable.semantic.hlsl",
"match": "(?<=\\:\\s|\\:)(?i:BINORMAL[0-9]*|BLENDINDICES[0-9]*|BLENDWEIGHT[0-9]*|COLOR[0-9]*|NORMAL[0-9]*|POSITIONT|POSITION|PSIZE[0-9]*|TANGENT[0-9]*|TEXCOORD[0-9]*|FOG|TESSFACTOR[0-9]*|VFACE|VPOS|DEPTH[0-9]*)\\b"
},
{
"name": "support.variable.semantic.sm4.hlsl",
"match": "(?<=\\:\\s|\\:)(?i:SV_ClipDistance[0-9]*|SV_CullDistance[0-9]*|SV_Coverage|SV_Depth|SV_DepthGreaterEqual[0-9]*|SV_DepthLessEqual[0-9]*|SV_InstanceID|SV_IsFrontFace|SV_Position|SV_RenderTargetArrayIndex|SV_SampleIndex|SV_StencilRef|SV_Target[0-7]?|SV_VertexID|SV_ViewportArrayIndex)\\b"
},
{
"name": "support.variable.semantic.sm5.hlsl",
"match": "(?<=\\:\\s|\\:)(?i:SV_DispatchThreadID|SV_DomainLocation|SV_GroupID|SV_GroupIndex|SV_GroupThreadID|SV_GSInstanceID|SV_InsideTessFactor|SV_OutputControlPointID|SV_TessFactor)\\b"
},
{
"name": "support.variable.semantic.sm5_1.hlsl",
"match": "(?<=\\:\\s|\\:)(?i:SV_InnerCoverage|SV_StencilRef)\\b"
},
{
"name": "storage.modifier.hlsl",
"match": "\\b(column_major|const|export|extern|globallycoherent|groupshared|inline|inout|in|out|precise|row_major|shared|static|uniform|volatile)\\b"
},
{
"name": "storage.modifier.float.hlsl",
"match": "\\b(snorm|unorm)\\b"
},
{
"name": "storage.modifier.postfix.hlsl",
"match": "\\b(packoffset|register)\\b"
},
{
"name": "storage.modifier.interpolation.hlsl",
"match": "\\b(centroid|linear|nointerpolation|noperspective|sample)\\b"
},
{
"name": "storage.modifier.geometryshader.hlsl",
"match": "\\b(lineadj|line|point|triangle|triangleadj)\\b"
},
{
"name": "support.type.other.hlsl",
"match": "\\b(string)\\b"
},
{
"name": "support.type.object.hlsl",
"match": "\\b(AppendStructuredBuffer|Buffer|ByteAddressBuffer|ConstantBuffer|ConsumeStructuredBuffer|InputPatch|OutputPatch)\\b"
},
{
"name": "support.type.object.rasterizerordered.hlsl",
"match": "\\b(RasterizerOrderedBuffer|RasterizerOrderedByteAddressBuffer|RasterizerOrderedStructuredBuffer|RasterizerOrderedTexture1D|RasterizerOrderedTexture1DArray|RasterizerOrderedTexture2D|RasterizerOrderedTexture2DArray|RasterizerOrderedTexture3D)\\b"
},
{
"name": "support.type.object.rw.hlsl",
"match": "\\b(RWBuffer|RWByteAddressBuffer|RWStructuredBuffer|RWTexture1D|RWTexture1DArray|RWTexture2D|RWTexture2DArray|RWTexture3D)\\b"
},
{
"name": "support.type.object.geometryshader.hlsl",
"match": "\\b(LineStream|PointStream|TriangleStream)\\b"
},
{
"name": "support.type.sampler.legacy.hlsl",
"match": "\\b(sampler|sampler1D|sampler2D|sampler3D|samplerCUBE|sampler_state)\\b"
},
{
"name": "support.type.sampler.hlsl",
"match": "\\b(SamplerState|SamplerComparisonState)\\b"
},
{
"name": "support.type.texture.legacy.hlsl",
"match": "\\b(texture2D|textureCUBE)\\b"
},
{
"name": "support.type.texture.hlsl",
"match": "\\b(Texture1D|Texture1DArray|Texture2D|Texture2DArray|Texture2DMS|Texture2DMSArray|Texture3D|TextureCube|TextureCubeArray)\\b"
},
{
"name": "storage.type.structured.hlsl",
"match": "\\b(cbuffer|class|interface|namespace|struct|tbuffer)\\b"
},
{
"name": "support.constant.property-value.fx.hlsl",
"match": "\\b(FALSE|TRUE|NULL)\\b"
},
{
"name": "support.type.fx.hlsl",
"match": "\\b(BlendState|DepthStencilState|RasterizerState)\\b"
},
{
"name": "storage.type.fx.technique.hlsl",
"match": "\\b(technique|Technique|technique10|technique11|pass)\\b"
},
{
"name": "meta.object-literal.key.fx.blendstate.hlsl",
"match": "\\b(AlphaToCoverageEnable|BlendEnable|SrcBlend|DestBlend|BlendOp|SrcBlendAlpha|DestBlendAlpha|BlendOpAlpha|RenderTargetWriteMask)\\b"
},
{
"name": "meta.object-literal.key.fx.depthstencilstate.hlsl",
"match": "\\b(DepthEnable|DepthWriteMask|DepthFunc|StencilEnable|StencilReadMask|StencilWriteMask|FrontFaceStencilFail|FrontFaceStencilZFail|FrontFaceStencilPass|FrontFaceStencilFunc|BackFaceStencilFail|BackFaceStencilZFail|BackFaceStencilPass|BackFaceStencilFunc)\\b"
},
{
"name": "meta.object-literal.key.fx.rasterizerstate.hlsl",
"match": "\\b(FillMode|CullMode|FrontCounterClockwise|DepthBias|DepthBiasClamp|SlopeScaleDepthBias|ZClipEnable|ScissorEnable|MultiSampleEnable|AntiAliasedLineEnable)\\b"
},
{
"name": "meta.object-literal.key.fx.samplerstate.hlsl",
"match": "\\b(Filter|AddressU|AddressV|AddressW|MipLODBias|MaxAnisotropy|ComparisonFunc|BorderColor|MinLOD|MaxLOD)\\b"
},
{
"name": "support.constant.property-value.fx.blend.hlsl",
"match": "\\b(?i:ZERO|ONE|SRC_COLOR|INV_SRC_COLOR|SRC_ALPHA|INV_SRC_ALPHA|DEST_ALPHA|INV_DEST_ALPHA|DEST_COLOR|INV_DEST_COLOR|SRC_ALPHA_SAT|BLEND_FACTOR|INV_BLEND_FACTOR|SRC1_COLOR|INV_SRC1_COLOR|SRC1_ALPHA|INV_SRC1_ALPHA)\\b"
},
{
"name": "support.constant.property-value.fx.blendop.hlsl",
"match": "\\b(?i:ADD|SUBTRACT|REV_SUBTRACT|MIN|MAX)\\b"
},
{
"name": "support.constant.property-value.fx.depthwritemask.hlsl",
"match": "\\b(?i:ALL)\\b"
},
{
"name": "support.constant.property-value.fx.comparisonfunc.hlsl",
"match": "\\b(?i:NEVER|LESS|EQUAL|LESS_EQUAL|GREATER|NOT_EQUAL|GREATER_EQUAL|ALWAYS)\\b"
},
{
"name": "support.constant.property-value.fx.stencilop.hlsl",
"match": "\\b(?i:KEEP|REPLACE|INCR_SAT|DECR_SAT|INVERT|INCR|DECR)\\b"
},
{
"name": "support.constant.property-value.fx.fillmode.hlsl",
"match": "\\b(?i:WIREFRAME|SOLID)\\b"
},
{
"name": "support.constant.property-value.fx.cullmode.hlsl",
"match": "\\b(?i:NONE|FRONT|BACK)\\b"
},
{
"name": "support.constant.property-value.fx.filter.hlsl",
"match": "\\b(?i:MIN_MAG_MIP_POINT|MIN_MAG_POINT_MIP_LINEAR|MIN_POINT_MAG_LINEAR_MIP_POINT|MIN_POINT_MAG_MIP_LINEAR|MIN_LINEAR_MAG_MIP_POINT|MIN_LINEAR_MAG_POINT_MIP_LINEAR|MIN_MAG_LINEAR_MIP_POINT|MIN_MAG_MIP_LINEAR|ANISOTROPIC|COMPARISON_MIN_MAG_MIP_POINT|COMPARISON_MIN_MAG_POINT_MIP_LINEAR|COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT|COMPARISON_MIN_POINT_MAG_MIP_LINEAR|COMPARISON_MIN_LINEAR_MAG_MIP_POINT|COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR|COMPARISON_MIN_MAG_LINEAR_MIP_POINT|COMPARISON_MIN_MAG_MIP_LINEAR|COMPARISON_ANISOTROPIC|TEXT_1BIT)\\b"
},
{
"name": "support.constant.property-value.fx.textureaddressmode.hlsl",
"match": "\\b(?i:WRAP|MIRROR|CLAMP|BORDER|MIRROR_ONCE)\\b"
},
{
"name": "string.quoted.double.hlsl",
"begin": "\"",
"end": "\"",
"patterns": [
{
"name": "constant.character.escape.hlsl",
"match": "\\\\."
}
]
}
],
"version": "https://github.com/tgjones/shaders-tmLanguage/commit/cd1ef40f549f9ce2b9e6b73498688de114a85382"
}

View file

@ -0,0 +1,13 @@
struct VS_OUTPUT
{
float4 Position : SV_Position;
};
VS_OUTPUT main(in float4 vPosition : POSITION)
{
VS_OUTPUT Output;
Output.Position = vPosition;
return Output;
}

View file

@ -0,0 +1,277 @@
[
{
"c": "struct",
"t": "source.hlsl storage.type.structured.hlsl",
"r": {
"dark_plus": "storage.type: #569CD6",
"light_plus": "storage.type: #0000FF",
"dark_vs": "storage.type: #569CD6",
"light_vs": "storage.type: #0000FF",
"hc_black": "storage.type: #569CD6"
}
},
{
"c": " VS_OUTPUT",
"t": "source.hlsl",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "{",
"t": "source.hlsl",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": " ",
"t": "source.hlsl",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "float4",
"t": "source.hlsl storage.type.basic.hlsl",
"r": {
"dark_plus": "storage.type: #569CD6",
"light_plus": "storage.type: #0000FF",
"dark_vs": "storage.type: #569CD6",
"light_vs": "storage.type: #0000FF",
"hc_black": "storage.type: #569CD6"
}
},
{
"c": " Position : ",
"t": "source.hlsl",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "SV_Position",
"t": "source.hlsl support.variable.semantic.sm4.hlsl",
"r": {
"dark_plus": "support.variable: #9CDCFE",
"light_plus": "support.variable: #001080",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": ";",
"t": "source.hlsl",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "};",
"t": "source.hlsl",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "VS_OUTPUT ",
"t": "source.hlsl",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "main",
"t": "source.hlsl support.function.hlsl",
"r": {
"dark_plus": "support.function: #DCDCAA",
"light_plus": "support.function: #795E26",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "(",
"t": "source.hlsl",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "in",
"t": "source.hlsl storage.modifier.hlsl",
"r": {
"dark_plus": "storage.modifier: #569CD6",
"light_plus": "storage.modifier: #0000FF",
"dark_vs": "storage.modifier: #569CD6",
"light_vs": "storage.modifier: #0000FF",
"hc_black": "storage.modifier: #569CD6"
}
},
{
"c": " ",
"t": "source.hlsl",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "float4",
"t": "source.hlsl storage.type.basic.hlsl",
"r": {
"dark_plus": "storage.type: #569CD6",
"light_plus": "storage.type: #0000FF",
"dark_vs": "storage.type: #569CD6",
"light_vs": "storage.type: #0000FF",
"hc_black": "storage.type: #569CD6"
}
},
{
"c": " vPosition : ",
"t": "source.hlsl",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "POSITION",
"t": "source.hlsl support.variable.semantic.hlsl",
"r": {
"dark_plus": "support.variable: #9CDCFE",
"light_plus": "support.variable: #001080",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": ")",
"t": "source.hlsl",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "{",
"t": "source.hlsl",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": " VS_OUTPUT Output;",
"t": "source.hlsl",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": " Output.Position = vPosition;",
"t": "source.hlsl",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": " ",
"t": "source.hlsl",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "return",
"t": "source.hlsl keyword.control.hlsl",
"r": {
"dark_plus": "keyword.control: #C586C0",
"light_plus": "keyword.control: #AF00DB",
"dark_vs": "keyword.control: #569CD6",
"light_vs": "keyword.control: #0000FF",
"hc_black": "keyword.control: #569CD6"
}
},
{
"c": " Output;",
"t": "source.hlsl",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "}",
"t": "source.hlsl",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
}
]

View file

@ -23,13 +23,18 @@ let decorationType: DecorationRenderOptions = {
}
};
export function activateColorDecorations(decoratorProvider: (uri: string) => Thenable<Range[]>, supportedLanguages: { [id: string]: boolean }): Disposable {
export function activateColorDecorations(decoratorProvider: (uri: string) => Thenable<Range[]>, supportedLanguages: { [id: string]: boolean }, isDecoratorEnabled: (languageId: string) => boolean): Disposable {
let disposables: Disposable[] = [];
let colorsDecorationType = window.createTextEditorDecorationType(decorationType);
disposables.push(colorsDecorationType);
let decoratorEnablement = {};
for (let languageId in supportedLanguages) {
decoratorEnablement[languageId] = isDecoratorEnabled(languageId);
}
let pendingUpdateRequests: { [key: string]: NodeJS.Timer; } = {};
window.onDidChangeVisibleTextEditors(editors => {
@ -40,29 +45,53 @@ export function activateColorDecorations(decoratorProvider: (uri: string) => The
workspace.onDidChangeTextDocument(event => triggerUpdateDecorations(event.document), null, disposables);
// we care about all visible editors
window.visibleTextEditors.forEach(editor => {
if (editor.document) {
triggerUpdateDecorations(editor.document);
}
});
// track open and close for document languageId changes
workspace.onDidCloseTextDocument(event => triggerUpdateDecorations(event, true));
workspace.onDidOpenTextDocument(event => triggerUpdateDecorations(event));
function triggerUpdateDecorations(document: TextDocument) {
let triggerUpdate = supportedLanguages[document.languageId];
let documentUri = document.uri;
let documentUriStr = documentUri.toString();
let timeout = pendingUpdateRequests[documentUriStr];
if (typeof timeout !== 'undefined') {
clearTimeout(timeout);
triggerUpdate = true; // force update, even if languageId is not supported (anymore)
workspace.onDidChangeConfiguration(_ => {
let hasChanges = false;
for (let languageId in supportedLanguages) {
let prev = decoratorEnablement[languageId];
let curr = isDecoratorEnabled(languageId);
if (prev !== curr) {
decoratorEnablement[languageId] = curr;
hasChanges = true;
}
}
if (hasChanges) {
updateAllVisibleEditors(true);
}
}, null, disposables);
updateAllVisibleEditors(false);
function updateAllVisibleEditors(settingsChanges: boolean) {
window.visibleTextEditors.forEach(editor => {
if (editor.document) {
triggerUpdateDecorations(editor.document, settingsChanges);
}
});
}
function triggerUpdateDecorations(document: TextDocument, settingsChanges = false) {
let triggerUpdate = supportedLanguages[document.languageId] && (decoratorEnablement[document.languageId] || settingsChanges);
if (triggerUpdate) {
let documentUriStr = document.uri.toString();
let timeout = pendingUpdateRequests[documentUriStr];
if (typeof timeout !== 'undefined') {
clearTimeout(timeout);
}
pendingUpdateRequests[documentUriStr] = setTimeout(() => {
// check if the document is in use by an active editor
for (let editor of window.visibleTextEditors) {
if (editor.document && documentUriStr === editor.document.uri.toString()) {
updateDecorationForEditor(documentUriStr, editor.document.version);
break;
if (decoratorEnablement[editor.document.languageId]) {
updateDecorationForEditor(documentUriStr, editor.document.version);
break;
} else {
editor.setDecorations(colorsDecorationType, []);
}
}
}
delete pendingUpdateRequests[documentUriStr];

View file

@ -6,7 +6,7 @@
import * as path from 'path';
import { languages, ExtensionContext, IndentAction } from 'vscode';
import { languages, workspace, ExtensionContext, IndentAction } from 'vscode';
import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, Range, RequestType } from 'vscode-languageclient';
import { EMPTY_ELEMENTS } from './htmlEmptyTagsShared';
import { activateColorDecorations } from './colorDecorators';
@ -29,6 +29,7 @@ export function activate(context: ExtensionContext) {
let packageInfo = getPackageInfo(context);
let telemetryReporter: TelemetryReporter = packageInfo && new TelemetryReporter(packageInfo.name, packageInfo.version, packageInfo.aiKey);
context.subscriptions.push(telemetryReporter);
// The server is implemented in node
let serverModule = context.asAbsolutePath(path.join('server', 'out', 'htmlServerMain.js'));
@ -64,7 +65,10 @@ export function activate(context: ExtensionContext) {
let colorRequestor = (uri: string) => {
return client.sendRequest(ColorSymbolRequest.type, uri).then(ranges => ranges.map(client.protocol2CodeConverter.asRange));
};
let disposable = activateColorDecorations(colorRequestor, { html: true, handlebars: true, razor: true });
let isDecoratorEnabled = (languageId: string) => {
return workspace.getConfiguration().get<boolean>('css.colorDecorators.enable');
};
let disposable = activateColorDecorations(colorRequestor, { html: true, handlebars: true, razor: true }, isDecoratorEnabled);
context.subscriptions.push(disposable);
client.onTelemetry(e => {
if (telemetryReporter) {

View file

@ -1,6 +0,0 @@
declare module 'vscode-extension-telemetry' {
export default class TelemetryReporter {
constructor(extensionId: string, extensionVersion: string, key: string);
sendTelemetryEvent(eventName: string, properties?: { [key: string]: string }, measures?: { [key: string]: number }): void;
}
}

View file

@ -3,14 +3,14 @@
"version": "0.1.0",
"dependencies": {
"applicationinsights": {
"version": "0.15.6",
"from": "applicationinsights@0.15.6",
"resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-0.15.6.tgz"
"version": "0.18.0",
"from": "applicationinsights@0.18.0",
"resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-0.18.0.tgz"
},
"vscode-extension-telemetry": {
"version": "0.0.5",
"from": "vscode-extension-telemetry@>=0.0.5 <0.0.6",
"resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.5.tgz"
"version": "0.0.6",
"from": "vscode-extension-telemetry@>=0.0.6 <0.0.7",
"resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.6.tgz"
},
"vscode-jsonrpc": {
"version": "3.1.0-alpha.1",
@ -33,9 +33,9 @@
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-2.0.2.tgz"
},
"winreg": {
"version": "0.0.13",
"from": "winreg@0.0.13",
"resolved": "https://registry.npmjs.org/winreg/-/winreg-0.0.13.tgz"
"version": "1.2.3",
"from": "winreg@1.2.3",
"resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.3.tgz"
}
}
}

View file

@ -33,8 +33,7 @@
".asp",
".aspx",
".jshtm",
".volt",
".vue"
".volt"
],
"aliases": [
"HTML",
@ -190,7 +189,7 @@
}
},
"dependencies": {
"vscode-extension-telemetry": "0.0.5",
"vscode-extension-telemetry": "^0.0.6",
"vscode-languageclient": "^3.1.0-alpha.1",
"vscode-languageserver-types": "^3.0.3",
"vscode-nls": "^2.0.2"

View file

@ -8,9 +8,9 @@
"resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-2.0.0.tgz"
},
"vscode-html-languageservice": {
"version": "2.0.0",
"version": "2.0.2-next.2",
"from": "vscode-html-languageservice@next",
"resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-2.0.0.tgz"
"resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-2.0.2-next.2.tgz"
},
"vscode-jsonrpc": {
"version": "3.1.0-alpha.1",

View file

@ -9,7 +9,7 @@
},
"dependencies": {
"vscode-css-languageservice": "^2.0.0",
"vscode-html-languageservice": "^2.0.0",
"vscode-html-languageservice": "^2.0.2-next.2",
"vscode-languageserver": "^3.1.0-alpha.1",
"vscode-nls": "^2.0.2",
"vscode-uri": "^1.0.0"

View file

@ -32,6 +32,9 @@ export function getHTMLMode(htmlLanguageService: HTMLLanguageService): LanguageM
findDocumentLinks(document: TextDocument, documentContext: DocumentContext) {
return htmlLanguageService.findDocumentLinks(document, documentContext);
},
findDocumentSymbols(document: TextDocument) {
return htmlLanguageService.findDocumentSymbols(document, htmlDocuments.get(document));
},
format(document: TextDocument, range: Range, formatParams: FormattingOptions) {
let formatSettings = settings && settings.format;
if (!formatSettings) {

View file

@ -152,12 +152,12 @@
}
},
"end": "(</)((?i:style))(>)(?:\\s*\\n)?",
"contentName": "source.css.embedded.html",
"patterns": [
{
"include": "#tag-stuff"
},
{
"contentName": "source.css.embedded.html",
"begin": "(>)",
"beginCaptures": {
"1": {
@ -192,12 +192,12 @@
"name": "punctuation.definition.tag.html"
}
},
"contentName": "source.js.embedded.html",
"patterns": [
{
"include": "#tag-stuff"
},
{
"contentName": "source.js.embedded.html",
"begin": "(?<!</(?:script|SCRIPT))(>)",
"captures": {
"1": {

View file

@ -23,7 +23,7 @@
},
{
"c": " ",
"t": "text.html.basic source.js.embedded.html",
"t": "text.html.basic",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@ -34,7 +34,7 @@
},
{
"c": "type",
"t": "text.html.basic source.js.embedded.html entity.other.attribute-name.html",
"t": "text.html.basic entity.other.attribute-name.html",
"r": {
"dark_plus": "entity.other.attribute-name: #9CDCFE",
"light_plus": "entity.other.attribute-name: #FF0000",
@ -45,7 +45,7 @@
},
{
"c": "=",
"t": "text.html.basic source.js.embedded.html",
"t": "text.html.basic",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@ -56,7 +56,7 @@
},
{
"c": "\"",
"t": "text.html.basic source.js.embedded.html string.quoted.double.html punctuation.definition.string.begin.html",
"t": "text.html.basic string.quoted.double.html punctuation.definition.string.begin.html",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string.quoted.double.html: #0000FF",
@ -67,7 +67,7 @@
},
{
"c": "text/javascript",
"t": "text.html.basic source.js.embedded.html string.quoted.double.html",
"t": "text.html.basic string.quoted.double.html",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string.quoted.double.html: #0000FF",
@ -78,7 +78,7 @@
},
{
"c": "\"",
"t": "text.html.basic source.js.embedded.html string.quoted.double.html punctuation.definition.string.end.html",
"t": "text.html.basic string.quoted.double.html punctuation.definition.string.end.html",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string.quoted.double.html: #0000FF",
@ -89,7 +89,7 @@
},
{
"c": ">",
"t": "text.html.basic source.js.embedded.html punctuation.definition.tag.html",
"t": "text.html.basic punctuation.definition.tag.html",
"r": {
"dark_plus": "punctuation.definition.tag: #808080",
"light_plus": "punctuation.definition.tag: #800000",
@ -210,7 +210,7 @@
},
{
"c": "</",
"t": "text.html.basic source.js.embedded.html punctuation.definition.tag.html",
"t": "text.html.basic punctuation.definition.tag.html",
"r": {
"dark_plus": "punctuation.definition.tag: #808080",
"light_plus": "punctuation.definition.tag: #800000",
@ -221,7 +221,7 @@
},
{
"c": "script",
"t": "text.html.basic source.js.embedded.html entity.name.tag.script.html",
"t": "text.html.basic entity.name.tag.script.html",
"r": {
"dark_plus": "entity.name.tag: #569CD6",
"light_plus": "entity.name.tag: #800000",
@ -265,7 +265,7 @@
},
{
"c": ">",
"t": "text.html.basic source.js.embedded.html punctuation.definition.tag.html",
"t": "text.html.basic punctuation.definition.tag.html",
"r": {
"dark_plus": "punctuation.definition.tag: #808080",
"light_plus": "punctuation.definition.tag: #800000",
@ -386,7 +386,7 @@
},
{
"c": "</",
"t": "text.html.basic source.js.embedded.html punctuation.definition.tag.html",
"t": "text.html.basic punctuation.definition.tag.html",
"r": {
"dark_plus": "punctuation.definition.tag: #808080",
"light_plus": "punctuation.definition.tag: #800000",
@ -397,7 +397,7 @@
},
{
"c": "script",
"t": "text.html.basic source.js.embedded.html entity.name.tag.script.html",
"t": "text.html.basic entity.name.tag.script.html",
"r": {
"dark_plus": "entity.name.tag: #569CD6",
"light_plus": "entity.name.tag: #800000",

View file

@ -474,7 +474,7 @@
},
{
"c": " ",
"t": "text.html.basic source.css.embedded.html",
"t": "text.html.basic",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@ -485,7 +485,7 @@
},
{
"c": "type",
"t": "text.html.basic source.css.embedded.html entity.other.attribute-name.html",
"t": "text.html.basic entity.other.attribute-name.html",
"r": {
"dark_plus": "entity.other.attribute-name: #9CDCFE",
"light_plus": "entity.other.attribute-name: #FF0000",
@ -496,7 +496,7 @@
},
{
"c": "=",
"t": "text.html.basic source.css.embedded.html",
"t": "text.html.basic",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@ -507,7 +507,7 @@
},
{
"c": "\"",
"t": "text.html.basic source.css.embedded.html string.quoted.double.html punctuation.definition.string.begin.html",
"t": "text.html.basic string.quoted.double.html punctuation.definition.string.begin.html",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string.quoted.double.html: #0000FF",
@ -518,7 +518,7 @@
},
{
"c": "text/css",
"t": "text.html.basic source.css.embedded.html string.quoted.double.html",
"t": "text.html.basic string.quoted.double.html",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string.quoted.double.html: #0000FF",
@ -529,7 +529,7 @@
},
{
"c": "\"",
"t": "text.html.basic source.css.embedded.html string.quoted.double.html punctuation.definition.string.end.html",
"t": "text.html.basic string.quoted.double.html punctuation.definition.string.end.html",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string.quoted.double.html: #0000FF",
@ -540,7 +540,7 @@
},
{
"c": ">",
"t": "text.html.basic source.css.embedded.html punctuation.definition.tag.html",
"t": "text.html.basic punctuation.definition.tag.html",
"r": {
"dark_plus": "punctuation.definition.tag: #808080",
"light_plus": "punctuation.definition.tag: #800000",
@ -1112,7 +1112,7 @@
},
{
"c": " ",
"t": "text.html.basic source.js.embedded.html",
"t": "text.html.basic",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@ -1123,7 +1123,7 @@
},
{
"c": "src",
"t": "text.html.basic source.js.embedded.html entity.other.attribute-name.html",
"t": "text.html.basic entity.other.attribute-name.html",
"r": {
"dark_plus": "entity.other.attribute-name: #9CDCFE",
"light_plus": "entity.other.attribute-name: #FF0000",
@ -1134,7 +1134,7 @@
},
{
"c": "=",
"t": "text.html.basic source.js.embedded.html",
"t": "text.html.basic",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@ -1145,7 +1145,7 @@
},
{
"c": "\"",
"t": "text.html.basic source.js.embedded.html string.quoted.double.html punctuation.definition.string.begin.html",
"t": "text.html.basic string.quoted.double.html punctuation.definition.string.begin.html",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string.quoted.double.html: #0000FF",
@ -1156,7 +1156,7 @@
},
{
"c": "/out/vs/loader.js",
"t": "text.html.basic source.js.embedded.html string.quoted.double.html",
"t": "text.html.basic string.quoted.double.html",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string.quoted.double.html: #0000FF",
@ -1167,7 +1167,7 @@
},
{
"c": "\"",
"t": "text.html.basic source.js.embedded.html string.quoted.double.html punctuation.definition.string.end.html",
"t": "text.html.basic string.quoted.double.html punctuation.definition.string.end.html",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string.quoted.double.html: #0000FF",
@ -1178,7 +1178,7 @@
},
{
"c": "></",
"t": "text.html.basic source.js.embedded.html punctuation.definition.tag.html",
"t": "text.html.basic punctuation.definition.tag.html",
"r": {
"dark_plus": "punctuation.definition.tag: #808080",
"light_plus": "punctuation.definition.tag: #800000",
@ -1189,7 +1189,7 @@
},
{
"c": "script",
"t": "text.html.basic source.js.embedded.html entity.name.tag.script.html",
"t": "text.html.basic entity.name.tag.script.html",
"r": {
"dark_plus": "entity.name.tag: #569CD6",
"light_plus": "entity.name.tag: #800000",
@ -1244,7 +1244,7 @@
},
{
"c": " ",
"t": "text.html.basic source.js.embedded.html",
"t": "text.html.basic",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@ -1255,7 +1255,7 @@
},
{
"c": "src",
"t": "text.html.basic source.js.embedded.html entity.other.attribute-name.html",
"t": "text.html.basic entity.other.attribute-name.html",
"r": {
"dark_plus": "entity.other.attribute-name: #9CDCFE",
"light_plus": "entity.other.attribute-name: #FF0000",
@ -1266,7 +1266,7 @@
},
{
"c": "=",
"t": "text.html.basic source.js.embedded.html",
"t": "text.html.basic",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@ -1277,7 +1277,7 @@
},
{
"c": "\"",
"t": "text.html.basic source.js.embedded.html string.quoted.double.html punctuation.definition.string.begin.html",
"t": "text.html.basic string.quoted.double.html punctuation.definition.string.begin.html",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string.quoted.double.html: #0000FF",
@ -1288,7 +1288,7 @@
},
{
"c": "https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.js",
"t": "text.html.basic source.js.embedded.html string.quoted.double.html",
"t": "text.html.basic string.quoted.double.html",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string.quoted.double.html: #0000FF",
@ -1299,7 +1299,7 @@
},
{
"c": "\"",
"t": "text.html.basic source.js.embedded.html string.quoted.double.html punctuation.definition.string.end.html",
"t": "text.html.basic string.quoted.double.html punctuation.definition.string.end.html",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string.quoted.double.html: #0000FF",
@ -1310,7 +1310,7 @@
},
{
"c": "></",
"t": "text.html.basic source.js.embedded.html punctuation.definition.tag.html",
"t": "text.html.basic punctuation.definition.tag.html",
"r": {
"dark_plus": "punctuation.definition.tag: #808080",
"light_plus": "punctuation.definition.tag: #800000",
@ -1321,7 +1321,7 @@
},
{
"c": "script",
"t": "text.html.basic source.js.embedded.html entity.name.tag.script.html",
"t": "text.html.basic entity.name.tag.script.html",
"r": {
"dark_plus": "entity.name.tag: #569CD6",
"light_plus": "entity.name.tag: #800000",
@ -1376,7 +1376,7 @@
},
{
"c": ">",
"t": "text.html.basic source.js.embedded.html punctuation.definition.tag.html",
"t": "text.html.basic punctuation.definition.tag.html",
"r": {
"dark_plus": "punctuation.definition.tag: #808080",
"light_plus": "punctuation.definition.tag: #800000",
@ -2157,7 +2157,7 @@
},
{
"c": "</",
"t": "text.html.basic source.js.embedded.html punctuation.definition.tag.html",
"t": "text.html.basic punctuation.definition.tag.html",
"r": {
"dark_plus": "punctuation.definition.tag: #808080",
"light_plus": "punctuation.definition.tag: #800000",
@ -2168,7 +2168,7 @@
},
{
"c": "script",
"t": "text.html.basic source.js.embedded.html entity.name.tag.script.html",
"t": "text.html.basic entity.name.tag.script.html",
"r": {
"dark_plus": "entity.name.tag: #569CD6",
"light_plus": "entity.name.tag: #800000",

View file

@ -13,7 +13,8 @@
["[", "]"],
["(", ")"],
["\"", "\""],
["'", "'"]
["'", "'"],
{ "open": "/**", "close": " */", "notIn": ["string"] }
],
"surroundingPairs": [
["{", "}"],
@ -23,4 +24,4 @@
["'", "'"],
["<", ">"]
]
}
}

View file

@ -35,6 +35,7 @@ export function activate(context: ExtensionContext) {
let packageInfo = getPackageInfo(context);
let telemetryReporter: TelemetryReporter = packageInfo && new TelemetryReporter(packageInfo.name, packageInfo.version, packageInfo.aiKey);
context.subscriptions.push(telemetryReporter);
// The server is implemented in node
let serverModule = context.asAbsolutePath(path.join('server', 'out', 'jsonServerMain.js'));
@ -99,7 +100,7 @@ function getSchemaAssociation(context: ExtensionContext): ISchemaAssociations {
let jsonValidation = packageJSON.contributes.jsonValidation;
if (Array.isArray(jsonValidation)) {
jsonValidation.forEach(jv => {
let {fileMatch, url} = jv;
let { fileMatch, url } = jv;
if (fileMatch && url) {
if (url[0] === '.' && url[1] === '/') {
url = Uri.file(path.join(extension.extensionPath, url)).toString();

View file

@ -1,6 +0,0 @@
declare module 'vscode-extension-telemetry' {
export default class TelemetryReporter {
constructor(extensionId: string, extensionVersion: string, key: string);
sendTelemetryEvent(eventName: string, properties?: { [key: string]: string }, measures?: { [key: string]: number }): void;
}
}

View file

@ -3,14 +3,14 @@
"version": "0.1.0",
"dependencies": {
"applicationinsights": {
"version": "0.15.6",
"from": "applicationinsights@0.15.6",
"resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-0.15.6.tgz"
"version": "0.18.0",
"from": "applicationinsights@0.18.0",
"resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-0.18.0.tgz"
},
"vscode-extension-telemetry": {
"version": "0.0.5",
"from": "vscode-extension-telemetry@>=0.0.5 <0.0.6",
"resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.5.tgz"
"version": "0.0.6",
"from": "vscode-extension-telemetry@>=0.0.6 <0.0.7",
"resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.6.tgz"
},
"vscode-jsonrpc": {
"version": "3.1.0-alpha.1",
@ -33,9 +33,9 @@
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-2.0.2.tgz"
},
"winreg": {
"version": "0.0.13",
"from": "winreg@0.0.13",
"resolved": "https://registry.npmjs.org/winreg/-/winreg-0.0.13.tgz"
"version": "1.2.3",
"from": "winreg@1.2.3",
"resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.3.tgz"
}
}
}

View file

@ -112,7 +112,7 @@
}
},
"dependencies": {
"vscode-extension-telemetry": "^0.0.5",
"vscode-extension-telemetry": "^0.0.6",
"vscode-languageclient": "^3.1.0-alpha.1",
"vscode-nls": "^2.0.2"
},

View file

@ -28,9 +28,9 @@
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-0.3.6.tgz"
},
"jsonc-parser": {
"version": "0.3.1",
"from": "jsonc-parser@0.3.1",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-0.3.1.tgz"
"version": "0.4.0",
"from": "jsonc-parser@0.4.0",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-0.4.0.tgz"
},
"ms": {
"version": "0.7.2",
@ -43,9 +43,9 @@
"resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.0.tgz"
},
"vscode-json-languageservice": {
"version": "2.0.0",
"version": "2.0.4",
"from": "vscode-json-languageservice@next",
"resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-2.0.0.tgz"
"resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-2.0.4.tgz"
},
"vscode-jsonrpc": {
"version": "3.1.0-alpha.1",

View file

@ -8,9 +8,9 @@
"node": "*"
},
"dependencies": {
"jsonc-parser": "^0.3.1",
"jsonc-parser": "^0.4.0",
"request-light": "^0.2.0",
"vscode-json-languageservice": "^2.0.0",
"vscode-json-languageservice": "^2.0.4",
"vscode-languageserver": "^3.1.0-alpha.1",
"vscode-nls": "^2.0.2"
},

View file

@ -19,6 +19,11 @@
"language": "makefile",
"scopeName": "source.makefile",
"path": "./syntaxes/Makefile.json"
}]
}],
"configurationDefaults": {
"[makefile]": {
"editor.insertSpaces": false
}
}
}
}

View file

@ -0,0 +1,32 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
(function () {
const settings = JSON.parse(document.getElementById('vscode-markdown-preview-data').getAttribute('data-settings'));
const strings = JSON.parse(document.getElementById('vscode-markdown-preview-data').getAttribute('data-strings'));
let didShow = false;
document.addEventListener('securitypolicyviolation', () => {
if (didShow) {
return;
}
didShow = true;
const args = [settings.previewUri];
const notification = document.createElement('a');
notification.innerText = strings.cspAlertMessageText;
notification.setAttribute('id', 'code-csp-warning');
notification.setAttribute('title', strings.cspAlertMessageTitle);
notification.setAttribute('role', 'button');
notification.setAttribute('aria-label', strings.cspAlertMessageLabel);
notification.setAttribute('href', `command:markdown.showPreviewSecuritySelector?${encodeURIComponent(JSON.stringify(args))}`);
document.body.appendChild(notification);
});
}());

View file

@ -59,6 +59,7 @@
*/
function getLineElementsAtPageOffset(offset) {
const lines = document.getElementsByClassName('code-line');
const position = offset - window.scrollY;
let previous = null;
for (const element of lines) {
const line = +element.getAttribute('data-line');
@ -67,13 +68,14 @@
}
const bounds = element.getBoundingClientRect();
const entry = { element, line };
if (offset >= window.scrollY + bounds.top && offset <= window.scrollY + bounds.top + bounds.height) {
// add progress through element
entry.line += (offset - (window.scrollY + bounds.top)) / (bounds.height);
return { previous: entry };
} else if (offset < window.scrollY + bounds.top) {
if (position < bounds.top) {
if (previous && previous.fractional < 1) {
previous.line += previous.fractional;
return { previous };
}
return { previous, next: entry };
}
entry.fractional = (position - bounds.top) / (bounds.height);
previous = entry;
}
return { previous };
@ -87,9 +89,9 @@
* Attempt to reveal the element for a source line in the editor.
*/
function scrollToRevealSourceLine(line) {
const {previous, next} = getElementsForSourceLine(line);
const { previous, next } = getElementsForSourceLine(line);
marker.update(previous && previous.element);
if (previous && window.initialData.scrollPreviewWithEditorSelection) {
if (previous && settings.scrollPreviewWithEditorSelection) {
let scrollTo = 0;
if (next) {
// Between two elements. Go to percentage offset between them.
@ -104,7 +106,7 @@
}
function getEditorLineNumberForPageOffset(offset) {
const {previous, next} = getLineElementsAtPageOffset(offset);
const { previous, next } = getLineElementsAtPageOffset(offset);
if (previous) {
if (next) {
const betweenProgress = (offset - window.scrollY - previous.element.getBoundingClientRect().top) / (next.element.getBoundingClientRect().top - previous.element.getBoundingClientRect().top);
@ -141,10 +143,11 @@
var scrollDisabled = true;
var marker = new ActiveLineMarker();
const settings = JSON.parse(document.getElementById('vscode-markdown-preview-data').getAttribute('data-settings'));
window.onload = () => {
if (window.initialData.scrollPreviewWithEditorSelection) {
const initialLine = +window.initialData.line;
if (settings.scrollPreviewWithEditorSelection) {
const initialLine = +settings.line;
if (!isNaN(initialLine)) {
setTimeout(() => {
scrollDisabled = true;
@ -172,7 +175,7 @@
})(), false);
document.addEventListener('dblclick', event => {
if (!window.initialData.doubleClickToSwitchToEditor) {
if (!settings.doubleClickToSwitchToEditor) {
return;
}
@ -186,7 +189,7 @@
const offset = event.pageY;
const line = getEditorLineNumberForPageOffset(offset);
if (!isNaN(line)) {
const args = [window.initialData.source, line];
const args = [settings.source, line];
window.parent.postMessage({
command: "did-click-link",
data: `command:_markdown.didClick?${encodeURIComponent(JSON.stringify(args))}`
@ -194,14 +197,14 @@
}
});
if (window.initialData.scrollEditorWithPreview) {
if (settings.scrollEditorWithPreview) {
window.addEventListener('scroll', throttle(() => {
if (scrollDisabled) {
scrollDisabled = false;
} else {
const line = getEditorLineNumberForPageOffset(window.scrollY);
if (!isNaN(line)) {
const args = [window.initialData.source, line];
const args = [settings.source, line];
window.parent.postMessage({
command: "did-click-link",
data: `command:_markdown.revealLine?${encodeURIComponent(JSON.stringify(args))}`

View file

@ -11,6 +11,28 @@ body {
word-wrap: break-word;
}
#code-csp-warning {
position: fixed;
top: 0;
right: 0;
color: white;
margin: 16px;
text-align: center;
font-size: 12px;
font-family: sans-serif;
background-color:#444444;
cursor: pointer;
padding: 6px;
box-shadow: 1px 1px 1px rgba(0,0,0,.25);
}
#code-csp-warning:hover {
text-decoration: none;
background-color:#007acc;
box-shadow: 2px 2px 2px rgba(0,0,0,.25);
}
body.scrollBeyondLastLine {
margin-bottom: calc(100vh - 22px);
}

View file

@ -3,9 +3,9 @@
"version": "0.2.0",
"dependencies": {
"applicationinsights": {
"version": "0.15.6",
"from": "applicationinsights@0.15.6",
"resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-0.15.6.tgz"
"version": "0.18.0",
"from": "applicationinsights@0.18.0",
"resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-0.18.0.tgz"
},
"argparse": {
"version": "1.0.9",
@ -58,14 +58,19 @@
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.3.tgz"
},
"vscode-extension-telemetry": {
"version": "0.0.5",
"from": "vscode-extension-telemetry@>=0.0.5 <0.0.6",
"resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.5.tgz"
"version": "0.0.6",
"from": "vscode-extension-telemetry@>=0.0.6 <0.0.7",
"resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.6.tgz"
},
"vscode-nls": {
"version": "2.0.2",
"from": "vscode-nls@latest",
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-2.0.2.tgz"
},
"winreg": {
"version": "0.0.13",
"from": "winreg@0.0.13",
"resolved": "https://registry.npmjs.org/winreg/-/winreg-0.0.13.tgz"
"version": "1.2.3",
"from": "winreg@1.2.3",
"resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.3.tgz"
}
}
}

View file

@ -69,6 +69,11 @@
"light": "./media/ViewSource.svg",
"dark": "./media/ViewSource_inverse.svg"
}
},
{
"command": "markdown.showPreviewSecuritySelector",
"title": "%markdown.showPreviewSecuritySelector.title%",
"category": "Markdown"
}
],
"menus": {
@ -83,6 +88,10 @@
"when": "resourceScheme == markdown",
"command": "markdown.showSource",
"group": "navigation"
},
{
"when": "resourceScheme == markdown",
"command": "markdown.showPreviewSecuritySelector"
}
],
"explorer/context": [
@ -168,18 +177,28 @@
"description": "%markdown.preview.doubleClickToSwitchToEditor.desc%"
}
}
},
"configurationDefaults": {
"[markdown]": {
"editor.wordWrap": "on",
"editor.quickSuggestions": false
}
}
},
"scripts": {
"vscode:prepublish": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../build/gulpfile.extensions.js compile-extension:markdown ./tsconfig.json"
"vscode:prepublish": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../build/gulpfile.extensions.js compile-extension:markdown ./tsconfig.json",
"update-grammar": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ./syntaxes/gulpfile.js"
},
"dependencies": {
"highlight.js": "^9.3.0",
"markdown-it": "^8.2.2",
"markdown-it-named-headers": "0.0.4",
"vscode-extension-telemetry": "^0.0.5"
"vscode-extension-telemetry": "^0.0.6",
"vscode-nls": "^2.0.2"
},
"devDependencies": {
"@types/node": "^7.0.4"
"@types/node": "^7.0.4",
"gulp-rename": "^1.2.2",
"gulp-replace": "^0.5.4"
}
}

View file

@ -10,5 +10,6 @@
"markdown.previewFrontMatter.dec": "Sets how YAML front matter should be rendered in the markdown preview. 'hide' removes the front matter. Otherwise, the front matter is treated as markdown content.",
"markdown.previewSide.title" : "Open Preview to the Side",
"markdown.showSource.title" : "Show Source",
"markdown.styles.dec": "A list of URLs or local paths to CSS style sheets to use from the markdown preview. Relative paths are interpreted relative to the folder open in the explorer. If there is no open folder, they are interpreted relative to the location of the markdown file. All '\\' need to be written as '\\\\'."
"markdown.styles.dec": "A list of URLs or local paths to CSS style sheets to use from the markdown preview. Relative paths are interpreted relative to the folder open in the explorer. If there is no open folder, they are interpreted relative to the location of the markdown file. All '\\' need to be written as '\\\\'.",
"markdown.showPreviewSecuritySelector.title": "Change Markdown Preview Security Settings"
}

View file

@ -10,7 +10,7 @@ import * as path from 'path';
export default class MarkdownDocumentLinkProvider implements vscode.DocumentLinkProvider {
private _linkPattern = /(\[[^\]]*\]\(\s*?)(\S+?)(\s+[^\)]*)?\)/g;
private _linkPattern = /(\[[^\]]*\]\(\s*?)(\S+?)(\s+[^\)]+)?\)/g;
constructor() { }

View file

@ -11,9 +11,14 @@ import TelemetryReporter from 'vscode-extension-telemetry';
import { MarkdownEngine } from './markdownEngine';
import DocumentLinkProvider from './documentLinkProvider';
import MDDocumentSymbolProvider from './documentSymbolProvider';
import { MDDocumentContentProvider, getMarkdownUri, isMarkdownFile } from './previewContentProvider';
import { MDDocumentContentProvider, getMarkdownUri, isMarkdownFile, ContentSecurityPolicyArbiter } from './previewContentProvider';
import { TableOfContentsProvider } from './tableOfContentsProvider';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
interface IPackageInfo {
name: string;
version: string;
@ -25,15 +30,50 @@ interface OpenDocumentLinkArgs {
fragment: string;
}
enum PreviewSecuritySelection {
None,
DisableEnhancedSecurityForWorkspace,
EnableEnhancedSecurityForWorkspace
}
interface PreviewSecurityPickItem extends vscode.QuickPickItem {
id: PreviewSecuritySelection;
}
class ExtensionContentSecurityProlicyArbiter implements ContentSecurityPolicyArbiter {
private readonly key = 'trusted_preview_workspace:';
constructor(
private globalState: vscode.Memento
) { }
public isEnhancedSecurityDisableForWorkspace(): boolean {
return this.globalState.get<boolean>(this.key + vscode.workspace.rootPath, false);
}
public addTrustedWorkspace(rootPath: string): Thenable<void> {
return this.globalState.update(this.key + rootPath, true);
}
public removeTrustedWorkspace(rootPath: string): Thenable<void> {
return this.globalState.update(this.key + rootPath, false);
}
}
var telemetryReporter: TelemetryReporter | null;
export function activate(context: vscode.ExtensionContext) {
const packageInfo = getPackageInfo();
telemetryReporter = packageInfo && new TelemetryReporter(packageInfo.name, packageInfo.version, packageInfo.aiKey);
if (telemetryReporter) {
context.subscriptions.push(telemetryReporter);
}
const cspArbiter = new ExtensionContentSecurityProlicyArbiter(context.globalState);
const engine = new MarkdownEngine();
const contentProvider = new MDDocumentContentProvider(engine, context);
const contentProvider = new MDDocumentContentProvider(engine, context, cspArbiter);
const contentProviderRegistration = vscode.workspace.registerTextDocumentContentProvider('markdown', contentProvider);
const symbolsProvider = new MDDocumentSymbolProvider(engine);
@ -61,7 +101,7 @@ export function activate(context: vscode.ExtensionContext) {
});
}));
context.subscriptions.push(vscode.commands.registerCommand('_markdown.didClick', (uri, line) => {
context.subscriptions.push(vscode.commands.registerCommand('_markdown.didClick', (uri: string, line) => {
const sourceUri = vscode.Uri.parse(decodeURIComponent(uri));
return vscode.workspace.openTextDocument(sourceUri)
.then(document => vscode.window.showTextDocument(document))
@ -97,6 +137,68 @@ export function activate(context: vscode.ExtensionContext) {
}
}));
context.subscriptions.push(vscode.commands.registerCommand('markdown.showPreviewSecuritySelector', (resource: string | undefined) => {
const workspacePath = vscode.workspace.rootPath || resource;
if (!workspacePath) {
return;
}
let sourceUri: vscode.Uri | null = null;
if (resource) {
sourceUri = vscode.Uri.parse(decodeURIComponent(resource));
}
if (!sourceUri && vscode.window.activeTextEditor) {
const activeDocument = vscode.window.activeTextEditor.document;
if (activeDocument.uri.scheme === 'markdown') {
sourceUri = activeDocument.uri;
} else {
sourceUri = getMarkdownUri(activeDocument.uri);
}
}
vscode.window.showQuickPick<PreviewSecurityPickItem>(
[
{
id: PreviewSecuritySelection.EnableEnhancedSecurityForWorkspace,
label: localize(
'preview.showPreviewSecuritySelector.disallowScriptsForWorkspaceTitle',
'Disable script execution in markdown previews for this workspace'),
description: '',
detail: cspArbiter.isEnhancedSecurityDisableForWorkspace()
? ''
: localize('preview.showPreviewSecuritySelector.currentSelection', 'Current setting')
}, {
id: PreviewSecuritySelection.DisableEnhancedSecurityForWorkspace,
label: localize(
'preview.showPreviewSecuritySelector.allowScriptsForWorkspaceTitle',
'Enable script execution in markdown previews for this workspace'),
description: '',
detail: cspArbiter.isEnhancedSecurityDisableForWorkspace()
? localize('preview.showPreviewSecuritySelector.currentSelection', 'Current setting')
: ''
},
], {
placeHolder: localize('preview.showPreviewSecuritySelector.title', 'Change security settings for the Markdown preview'),
}).then(selection => {
if (!workspacePath) {
return false;
}
switch (selection && selection.id) {
case PreviewSecuritySelection.DisableEnhancedSecurityForWorkspace:
return cspArbiter.addTrustedWorkspace(workspacePath).then(() => true);
case PreviewSecuritySelection.EnableEnhancedSecurityForWorkspace:
return cspArbiter.removeTrustedWorkspace(workspacePath).then(() => true);
}
return false;
}).then(shouldUpdate => {
if (shouldUpdate && sourceUri) {
contentProvider.update(sourceUri);
}
});
}));
context.subscriptions.push(vscode.workspace.onDidSaveTextDocument(document => {
if (isMarkdownFile(document)) {
const uri = getMarkdownUri(document.uri);

View file

@ -97,7 +97,7 @@ export class MarkdownEngine {
const original = md.renderer.rules[ruleName];
md.renderer.rules[ruleName] = (tokens: any, idx: number, options: any, env: any, self: any) => {
const token = tokens[idx];
if ((token.level === 0 || token.type === 'list_item_open' && token.level === 1) && token.map && token.map.length) {
if (token.map && token.map.length) {
token.attrSet('data-line', this.firstLine + token.map[0]);
token.attrJoin('class', 'code-line');
}

View file

@ -9,6 +9,13 @@ import * as vscode from 'vscode';
import * as path from 'path';
import { MarkdownEngine } from './markdownEngine';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
export interface ContentSecurityPolicyArbiter {
isEnhancedSecurityDisableForWorkspace(): boolean;
}
export function isMarkdownFile(document: vscode.TextDocument) {
return document.languageId === 'markdown'
&& document.uri.scheme !== 'markdown'; // prevent processing of own documents
@ -24,7 +31,8 @@ export class MDDocumentContentProvider implements vscode.TextDocumentContentProv
constructor(
private engine: MarkdownEngine,
private context: vscode.ExtensionContext
private context: vscode.ExtensionContext,
private cspArbiter: ContentSecurityPolicyArbiter
) { }
private getMediaPath(mediaFile: string): string {
@ -60,7 +68,7 @@ export class MDDocumentContentProvider implements vscode.TextDocumentContentProv
return vscode.Uri.file(path.join(path.dirname(resource.fsPath), href)).toString();
}
private computeCustomStyleSheetIncludes(uri: vscode.Uri): string {
private computeCustomStyleSheetIncludes(uri: vscode.Uri, _nonce: string): string {
const styles = vscode.workspace.getConfiguration('markdown')['styles'];
if (styles && Array.isArray(styles) && styles.length > 0) {
return styles.map((style) => {
@ -70,13 +78,13 @@ export class MDDocumentContentProvider implements vscode.TextDocumentContentProv
return '';
}
private getSettingsOverrideStyles(): string {
private getSettingsOverrideStyles(nonce: string): string {
const previewSettings = vscode.workspace.getConfiguration('markdown')['preview'];
if (!previewSettings) {
return '';
}
const { fontFamily, fontSize, lineHeight } = previewSettings;
return `<style>
return `<style nonce="${nonce}">
body {
${fontFamily ? `font-family: ${fontFamily};` : ''}
${+fontSize > 0 ? `font-size: ${fontSize}px;` : ''}
@ -100,29 +108,46 @@ export class MDDocumentContentProvider implements vscode.TextDocumentContentProv
initialLine = editor.selection.active.line;
}
const initialData = {
previewUri: encodeURIComponent(uri.toString(true)),
source: encodeURIComponent(sourceUri.toString(true)),
line: initialLine,
scrollPreviewWithEditorSelection: !!markdownConfig.get('preview.scrollPreviewWithEditorSelection', true),
scrollEditorWithPreview: !!markdownConfig.get('preview.scrollEditorWithPreview', true),
doubleClickToSwitchToEditor: !!markdownConfig.get('preview.doubleClickToSwitchToEditor', true),
};
const previewStrings = {
cspAlertMessageText: localize('preview.securityMessage.text', 'Scripts have been disabled in this document'),
cspAlertMessageTitle: localize('preview.securityMessage.title', 'Scripts are disabled in the markdown preview. Change the Markdown preview secuirty setting to enable scripts'),
cspAlertMessageLabel: localize('preview.securityMessage.label', 'Scripts Disabled Security Warning')
};
// Content Security Policy
const nonce = new Date().getTime() + '' + new Date().getMilliseconds();
let csp = `<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src 'self' http: https: data:; media-src 'self' http: https: data:; child-src 'none'; script-src 'nonce-${nonce}'; style-src 'self' 'unsafe-inline' http: https: data:;">`;
if (this.cspArbiter.isEnhancedSecurityDisableForWorkspace()) {
csp = '';
}
const body = this.engine.render(sourceUri, previewFrontMatter === 'hide', document.getText());
return `<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
${csp}
<meta id="vscode-markdown-preview-data" data-settings="${JSON.stringify(initialData).replace(/"/g, '&quot;')}" data-strings="${JSON.stringify(previewStrings).replace(/"/g, '&quot;')}">
<script src="${this.getMediaPath('csp.js')}" nonce="${nonce}"></script>
<link rel="stylesheet" type="text/css" href="${this.getMediaPath('markdown.css')}">
<link rel="stylesheet" type="text/css" href="${this.getMediaPath('tomorrow.css')}">
${this.getSettingsOverrideStyles()}
${this.computeCustomStyleSheetIncludes(uri)}
${this.getSettingsOverrideStyles(nonce)}
${this.computeCustomStyleSheetIncludes(uri, nonce)}
<base href="${document.uri.toString(true)}">
<script>
window.initialData = {
source: "${encodeURIComponent(sourceUri.toString(true))}",
line: ${initialLine},
scrollPreviewWithEditorSelection: ${!!markdownConfig.get('preview.scrollPreviewWithEditorSelection', true)},
scrollEditorWithPreview: ${!!markdownConfig.get('preview.scrollEditorWithPreview', true)},
doubleClickToSwitchToEditor: ${!!markdownConfig.get('preview.doubleClickToSwitchToEditor', true)},
};
</script>
</head>
<body class="${scrollBeyondLastLine ? 'scrollBeyondLastLine' : ''} ${wordWrap ? 'wordWrap' : ''} ${!!markdownConfig.get('preview.markEditorSelection') ? 'showEditorSelection' : ''}">
${body}
<script src="${this.getMediaPath('main.js')}"></script>
<div class="code-line" data-line="${document.lineCount}"></div>
<script src="${this.getMediaPath('main.js')}" nonce="${nonce}"></script>
</body>
</html>`;
});

View file

@ -1,6 +0,0 @@
declare module 'vscode-extension-telemetry' {
export default class TelemetryReporter {
constructor(extensionId: string, extensionVersion: string, key: string);
sendTelemetryEvent(eventName: string, properties?: { [key: string]: string }, measures?: { [key: string]: number }): void;
}
}

View file

@ -0,0 +1,147 @@
var gulp = require('gulp');
var replace = require('gulp-replace');
var rename = require('gulp-rename');
const languages = [
{ name: 'css', identifiers: ['css', 'css.erb'], source: 'source.css' },
{ name: 'basic', identifiers: ['html', 'htm', 'shtml', 'xhtml', 'inc', 'tmpl', 'tpl'], source: 'text.html.basic' },
{ name: 'ini', identifiers: ['ini', 'conf'], source: 'source.ini' },
{ name: 'java', identifiers: ['java', 'bsh'], source: 'source.java' },
{ name: 'lua', identifiers: ['lua'], source: 'source.lua' },
{ name: 'makefile', identifiers: ['Makefile', 'makefile', 'GNUmakefile', 'OCamlMakefile'], source: 'source.makefile' },
{ name: 'perl', identifiers: ['perl', 'pl', 'pm', 'pod', 't', 'PL', 'psgi', 'vcl'], source: 'source.perl' },
{ name: 'r', identifiers: ['R', 'r', 's', 'S', 'Rprofile'], source: 'source.r' },
{ name: 'ruby', identifiers: ['ruby', 'rb', 'rbx', 'rjs', 'Rakefile', 'rake', 'cgi', 'fcgi', 'gemspec', 'irbrc', 'Capfile', 'ru', 'prawn', 'Cheffile', 'Gemfile', 'Guardfile', 'Hobofile', 'Vagrantfile', 'Appraisals', 'Rantfile', 'Berksfile', 'Berksfile.lock', 'Thorfile', 'Puppetfile'], source: 'source.ruby' },
// Left to its own devices, the PHP grammar will match HTML as a combination of operators
// and constants. Therefore, HTML must take precedence over PHP in order to get proper
// syntax highlighting.
{ name: 'php', identifiers: ['php', 'php3', 'php4', 'php5', 'phpt', 'phtml', 'aw', 'ctp'], source: ['text.html.basic', 'text.html.php#language'] },
{ name: 'sql', identifiers: ['sql', 'ddl', 'dml'], source: 'source.sql' },
{ name: 'vs_net', identifiers: ['vb'], source: 'source.asp.vb.net' },
{ name: 'xml', identifiers: ['xml', 'xsd', 'tld', 'jsp', 'pt', 'cpt', 'dtml', 'rss', 'opml'], source: 'text.xml' },
{ name: 'xsl', identifiers: ['xsl', 'xslt'], source: 'text.xml.xsl' },
{ name: 'yaml', identifiers: ['yaml', 'yml'], source: 'source.yaml' },
{ name: 'dosbatch', identifiers: ['bat', 'batch'], source: 'source.dosbatch' },
{ name: 'clojure', identifiers: ['clj', 'cljs', 'clojure'], source: 'source.clojure' },
{ name: 'coffee', identifiers: ['coffee', 'Cakefile', 'coffee.erb'], source: 'source.coffee' },
{ name: 'c', identifiers: ['c', 'h'], source: 'source.c' },
{ name: 'cpp', identifiers: ['cpp', 'c\\+\\+', 'cxx'], source: 'source.cpp' },
{ name: 'diff', identifiers: ['patch', 'diff', 'rej'], source: 'source.diff' },
{ name: 'dockerfile', identifiers: ['dockerfile', 'Dockerfile'], source: 'source.dockerfile' },
{ name: 'git_commit', identifiers: ['COMMIT_EDITMSG', 'MERGE_MSG'], source: 'text.git-commit' },
{ name: 'git_rebase', identifiers: ['git-rebase-todo'], source: 'text.git-rebase' },
{ name: 'go', identifiers: ['go', 'golang'], source: 'source.go' },
{ name: 'groovy', identifiers: ['groovy', 'gvy'], source: 'source.groovy' },
{ name: 'jade', identifiers: ['jade'], source: 'text.jade' },
{ name: 'js', identifiers: ['js', 'jsx', 'javascript'], source: 'source.js' },
{ name: 'js_regexp', identifiers: ['regexp'], source: 'source.js.regexp' },
{ name: 'json', identifiers: ['json', 'sublime-settings', 'sublime-menu', 'sublime-keymap', 'sublime-mousemap', 'sublime-theme', 'sublime-build', 'sublime-project', 'sublime-completions'], source: 'source.json' },
{ name: 'less', identifiers: ['less'], source: 'source.css.less' },
{ name: 'objc', identifiers: ['objectivec', 'objective-c', 'mm', 'objc', 'obj-c', 'm', 'h'], source: 'source.objc' },
{ name: 'perl6', identifiers: ['perl6', 'p6', 'pl6', 'pm6', 'nqp'], source: 'source.perl.6' },
{ name: 'powershell', identifiers: ['powershell', 'ps1', 'psm1', 'psd1'], source: 'source.powershell' },
{ name: 'python', identifiers: ['python', 'py', 'py3', 'rpy', 'pyw', 'cpy', 'SConstruct', 'Sconstruct', 'sconstruct', 'SConscript', 'gyp', 'gypi'], source: 'source.python' },
{ name: 'regexp_python', identifiers: ['re'], source: 'source.regexp.python' },
{ name: 'rust', identifiers: ['rust', 'rs'], source: 'source.rust' },
{ name: 'scala', identifiers: ['scala', 'sbt'], source: 'source.scala' },
{ name: 'shell', identifiers: ['shell', 'sh', 'bash', 'zsh', 'bashrc', 'bash_profile', 'bash_login', 'profile', 'bash_logout', '.textmate_init'], source: 'source.shell' },
{ name: 'ts', identifiers: ['typescript', 'ts'], source: 'source.ts' },
{ name: 'tsx', identifiers: ['tsx'], source: 'source.tsx' },
{ name: 'csharp', identifiers: ['cs', 'csharp', 'c#'], source: 'source.cs' },
{ name: 'fsharp', identifiers: ['fs', 'fsharp', 'f#'], source: 'source.fsharp' },
];
const fencedCodeBlockDefinition = (name, identifiers, sourceScope) => {
if (!Array.isArray(sourceScope)) {
sourceScope = [sourceScope];
}
const scopes = sourceScope.map(scope =>
`<dict>
<key>include</key>
<string>${scope}</string>
</dict>`).join('\n');
return `<key>fenced_code_block_${name}</key>
<dict>
<key>begin</key>
<string>(^|\\G)(\\s*)([\`~]{3,})\\s*((${identifiers.join('|')})(\\s+[^\`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$</string>
<key>beginCaptures</key>
<dict>
<key>3</key>
<dict>
<key>name</key>
<string>punctuation.definition.markdown</string>
</dict>
<key>5</key>
<dict>
<key>name</key>
<string>fenced_code.block.language</string>
</dict>
<key>6</key>
<dict>
<key>name</key>
<string>fenced_code.block.language.attributes</string>
</dict>
</dict>
<key>endCaptures</key>
<dict>
<key>3</key>
<dict>
<key>name</key>
<string>punctuation.definition.markdown</string>
</dict>
</dict>
<key>patterns</key>
<array>
<dict>
<key>begin</key>
<string>(^|\\G)(\\s*)(.*)</string>
<key>while</key>
<string>(^|\\G)(?!\\s*([\`~]{3,})\\s*$)</string>
<key>patterns</key>
<array>
${indent(4, scopes)}
</array>
</dict>
</array>
</dict>`;
};
const indent = (count, text) => {
const indent = new Array(count + 1).join('\t');
return text.replace(/^/gm, indent);
};
const fencedCodeBlockInclude = (name) =>
`<dict>
<key>include</key>
<string>#fenced_code_block_${name}</string>
</dict>`;
const fencedCodeBlockDefinitions = () =>
languages
.map(language => fencedCodeBlockDefinition(language.name, language.identifiers, language.source))
.join('\n');
const fencedCodeBlockIncludes = () =>
languages
.map(language => fencedCodeBlockInclude(language.name))
.join('\n');
gulp.task('default', function () {
gulp.src(['markdown.tmLanguage.base'])
.pipe(replace('{{languageIncludes}}', indent(4, fencedCodeBlockIncludes())))
.pipe(replace('{{languageDefinitions}}', indent(4, fencedCodeBlockDefinitions())))
.pipe(rename('markdown.tmLanguage'))
.pipe(gulp.dest('.'));
});

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