prism 0.23.0 → 0.25.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/BSDmakefile +58 -0
- data/CHANGELOG.md +65 -1
- data/Makefile +5 -2
- data/README.md +45 -6
- data/config.yml +499 -4
- data/docs/build_system.md +31 -0
- data/docs/configuration.md +2 -0
- data/docs/cruby_compilation.md +1 -1
- data/docs/parser_translation.md +14 -9
- data/docs/releasing.md +3 -3
- data/docs/ripper_translation.md +50 -0
- data/docs/ruby_api.md +1 -0
- data/docs/serialization.md +26 -5
- data/ext/prism/api_node.c +2342 -1801
- data/ext/prism/api_pack.c +9 -0
- data/ext/prism/extconf.rb +27 -11
- data/ext/prism/extension.c +313 -66
- data/ext/prism/extension.h +5 -4
- data/include/prism/ast.h +213 -64
- data/include/prism/defines.h +106 -2
- data/include/prism/diagnostic.h +134 -71
- data/include/prism/encoding.h +22 -4
- data/include/prism/node.h +93 -0
- data/include/prism/options.h +82 -7
- data/include/prism/pack.h +11 -0
- data/include/prism/parser.h +198 -53
- data/include/prism/prettyprint.h +8 -0
- data/include/prism/static_literals.h +118 -0
- data/include/prism/util/pm_buffer.h +65 -2
- data/include/prism/util/pm_constant_pool.h +18 -1
- data/include/prism/util/pm_integer.h +119 -0
- data/include/prism/util/pm_list.h +1 -1
- data/include/prism/util/pm_newline_list.h +12 -3
- data/include/prism/util/pm_string.h +26 -2
- data/include/prism/version.h +2 -2
- data/include/prism.h +59 -1
- data/lib/prism/compiler.rb +8 -1
- data/lib/prism/debug.rb +46 -3
- data/lib/prism/desugar_compiler.rb +225 -80
- data/lib/prism/dispatcher.rb +29 -0
- data/lib/prism/dot_visitor.rb +87 -16
- data/lib/prism/dsl.rb +315 -300
- data/lib/prism/ffi.rb +165 -84
- data/lib/prism/lex_compat.rb +17 -15
- data/lib/prism/mutation_compiler.rb +11 -0
- data/lib/prism/node.rb +4857 -3750
- data/lib/prism/node_ext.rb +77 -29
- data/lib/prism/pack.rb +4 -0
- data/lib/prism/parse_result/comments.rb +34 -17
- data/lib/prism/parse_result/newlines.rb +3 -1
- data/lib/prism/parse_result.rb +88 -34
- data/lib/prism/pattern.rb +16 -4
- data/lib/prism/polyfill/string.rb +12 -0
- data/lib/prism/serialize.rb +960 -327
- data/lib/prism/translation/parser/compiler.rb +152 -50
- data/lib/prism/translation/parser/lexer.rb +103 -22
- data/lib/prism/translation/parser/rubocop.rb +47 -11
- data/lib/prism/translation/parser.rb +134 -10
- data/lib/prism/translation/parser33.rb +12 -0
- data/lib/prism/translation/parser34.rb +12 -0
- data/lib/prism/translation/ripper/sexp.rb +125 -0
- data/lib/prism/translation/ripper/shim.rb +5 -0
- data/lib/prism/translation/ripper.rb +3248 -379
- data/lib/prism/translation/ruby_parser.rb +35 -18
- data/lib/prism/translation.rb +3 -1
- data/lib/prism/visitor.rb +10 -0
- data/lib/prism.rb +8 -2
- data/prism.gemspec +35 -4
- data/rbi/prism/compiler.rbi +14 -0
- data/rbi/prism/desugar_compiler.rbi +5 -0
- data/rbi/prism/mutation_compiler.rbi +5 -0
- data/rbi/prism/node.rbi +8221 -0
- data/rbi/prism/node_ext.rbi +102 -0
- data/rbi/prism/parse_result.rbi +304 -0
- data/rbi/prism/translation/parser/compiler.rbi +13 -0
- data/rbi/prism/translation/ripper/ripper_compiler.rbi +5 -0
- data/rbi/prism/translation/ripper.rbi +25 -0
- data/rbi/prism/translation/ruby_parser.rbi +11 -0
- data/rbi/prism/visitor.rbi +470 -0
- data/rbi/prism.rbi +39 -7749
- data/sig/prism/compiler.rbs +9 -0
- data/sig/prism/dispatcher.rbs +16 -0
- data/sig/prism/dot_visitor.rbs +6 -0
- data/sig/prism/dsl.rbs +462 -0
- data/sig/prism/mutation_compiler.rbs +158 -0
- data/sig/prism/node.rbs +3529 -0
- data/sig/prism/node_ext.rbs +78 -0
- data/sig/prism/pack.rbs +43 -0
- data/sig/prism/parse_result.rbs +127 -0
- data/sig/prism/pattern.rbs +13 -0
- data/sig/prism/serialize.rbs +7 -0
- data/sig/prism/visitor.rbs +168 -0
- data/sig/prism.rbs +188 -4767
- data/src/diagnostic.c +575 -230
- data/src/encoding.c +211 -108
- data/src/node.c +7526 -447
- data/src/options.c +36 -12
- data/src/pack.c +33 -17
- data/src/prettyprint.c +1297 -1388
- data/src/prism.c +3665 -1121
- data/src/regexp.c +17 -2
- data/src/serialize.c +47 -28
- data/src/static_literals.c +552 -0
- data/src/token_type.c +1 -0
- data/src/util/pm_buffer.c +147 -20
- data/src/util/pm_char.c +4 -4
- data/src/util/pm_constant_pool.c +35 -11
- data/src/util/pm_integer.c +629 -0
- data/src/util/pm_list.c +1 -1
- data/src/util/pm_newline_list.c +20 -8
- data/src/util/pm_string.c +134 -5
- data/src/util/pm_string_list.c +2 -2
- metadata +37 -6
- data/docs/ripper.md +0 -36
- data/rbi/prism_static.rbi +0 -207
- data/sig/prism_static.rbs +0 -201
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 15343c4f2d796d38ab23791193ad8e7caad9c1f53632fc6a6de0b1f842a09202
|
4
|
+
data.tar.gz: 0ef3cf6a5ed5853439e2854c4142e3f00e2a56b8e77e15c8b77bb759572745ff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6d6e43bb22ed673caed7fb74e59f027a7781bfa55ff9b9d4fc386a547c615288e9d83b0e35482fa5cb8989365a6cf65b69d9d7b5e98bc42bf1603f557c80f859
|
7
|
+
data.tar.gz: 174c82145e87749e11e7bdbf99185f8383e51321556158b4a2379c315eee86c1c5de36ab843ef3e2ac153224c6a251bd40fdf613d928aded37b31cc05995d65e
|
data/BSDmakefile
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# GNU makefile proxy script for BSD make
|
2
|
+
#
|
3
|
+
# Written and maintained by Mahmoud Al-Qudsi <mqudsi@neosmart.net>
|
4
|
+
# Copyright NeoSmart Technologies <https://neosmart.net/> 2014-2019
|
5
|
+
# Obtain updates from <https://github.com/neosmart/gmake-proxy>
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions are met:
|
9
|
+
#
|
10
|
+
# 1. Redistributions of source code must retain the above copyright notice, this
|
11
|
+
# list of conditions and the following disclaimer.
|
12
|
+
#
|
13
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
14
|
+
# this list of conditions and the following disclaimer in the documentation
|
15
|
+
# and/or other materials provided with the distribution.
|
16
|
+
#
|
17
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
18
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
19
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
21
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
22
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
23
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
24
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
25
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
26
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27
|
+
|
28
|
+
JARG =
|
29
|
+
GMAKE = "gmake"
|
30
|
+
# When gmake is called from another make instance, -w is automatically added
|
31
|
+
# which causes extraneous messages about directory changes to be emitted.
|
32
|
+
# Running with --no-print-directory silences these messages.
|
33
|
+
GARGS = "--no-print-directory"
|
34
|
+
|
35
|
+
.if "$(.MAKE.JOBS)" != ""
|
36
|
+
JARG = -j$(.MAKE.JOBS)
|
37
|
+
.endif
|
38
|
+
|
39
|
+
# bmake prefers out-of-source builds and tries to cd into ./obj (among others)
|
40
|
+
# where possible. GNU Make doesn't, so override that value.
|
41
|
+
.OBJDIR: ./
|
42
|
+
|
43
|
+
# The GNU convention is to use the lowercased `prefix` variable/macro to
|
44
|
+
# specify the installation directory. Humor them.
|
45
|
+
GPREFIX = ""
|
46
|
+
.if defined(PREFIX) && ! defined(prefix)
|
47
|
+
GPREFIX = 'prefix = "$(PREFIX)"'
|
48
|
+
.endif
|
49
|
+
|
50
|
+
.BEGIN: .SILENT
|
51
|
+
which $(GMAKE) || printf "Error: GNU Make is required!\n\n" 1>&2 && false
|
52
|
+
|
53
|
+
.PHONY: FRC
|
54
|
+
$(.TARGETS): FRC
|
55
|
+
$(GMAKE) $(GPREFIX) $(GARGS) $(.TARGETS:S,.DONE,,) $(JARG)
|
56
|
+
|
57
|
+
.DONE .DEFAULT: .SILENT
|
58
|
+
$(GMAKE) $(GPREFIX) $(GARGS) $(.TARGETS:S,.DONE,,) $(JARG)
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,68 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## [0.25.0] - 2024-04-05
|
10
|
+
|
11
|
+
### Added
|
12
|
+
|
13
|
+
- `Prism::Translation::Ripper` is now able to mirror all of the Ripper APIs.
|
14
|
+
- `Prism::Location#leading_comments` and `Prism::Location#trailing_comments` is added.
|
15
|
+
- `Prism::Comment#slice` is added.
|
16
|
+
- Warn for writing literal values in conditional predicates.
|
17
|
+
- Check for `_POSIX_MAPPED_FILES` before using `mmap`.
|
18
|
+
- `Prism::ItParametersNode` is added, to support `-> { it }`.
|
19
|
+
- Parse integer and float literal values onto the tree.
|
20
|
+
- Warn on duplicated hash keys and duplicated when clauses.
|
21
|
+
- Ship much improved `RBI` and `RBS` types.
|
22
|
+
- Support for the `-p`, `-n`, `-a`, and `-l` command line switches.
|
23
|
+
- Warn on integer literals in flip-flops.
|
24
|
+
- Support BSD make.
|
25
|
+
- Add `Prism::WhenNode#then_keyword_loc`.
|
26
|
+
- Support custom allocation functions through the `PRISM_XALLOCATOR` define.
|
27
|
+
- Warn for certain keywrods at the end of the line.
|
28
|
+
- Provide `pm_visit_node`, a C visitor API.
|
29
|
+
- `Prism::parse_stream` is added, which works for any Ruby `IO` object.
|
30
|
+
- Provide flags for regular expression literals for their derived encoding.
|
31
|
+
- Provide flags for whether or not an interpolated string literal is frozen.
|
32
|
+
- Add `Prism::StringNode.mutable?` for when a string is explicitly mutable, to support delineating chilled strings.
|
33
|
+
- Warn for incorrect character literal syntax.
|
34
|
+
- Warn for chained comparison operators.
|
35
|
+
- Warn for `**` interpreted as an argument prefix.
|
36
|
+
- Warn for `&` interpreted as an argument prefix.
|
37
|
+
- `Prism::ShareableConstantNode` added to support ractors.
|
38
|
+
- Warn for frozen string literals found after tokens.
|
39
|
+
- Support `PRISM_BUILD_MINIMAL` to provide only the minimal necessary functionality to reduce the binary size.
|
40
|
+
- Handle CLRF inside heredocs, strings, and regular expressions.
|
41
|
+
- Mark inner strings in interpolated strings as frozen.
|
42
|
+
- Support the `-x` command line switch.
|
43
|
+
- Error messages now much more closely mirror CRuby.
|
44
|
+
- Provide syntax errors for invalid block exits (`break`, `next`, `retry`, and `yield`).
|
45
|
+
- Warn on unused local variables.
|
46
|
+
- Do not syntax error on default parameter values that only write to the parameter.
|
47
|
+
|
48
|
+
### Changed
|
49
|
+
|
50
|
+
- Many improvements to the compatibility with the `whitequark/parser` translation.
|
51
|
+
- Accept newlines before pattern terminators `)` or `]`.
|
52
|
+
- `Prism::Node#start_offset` and `Prism::Node#end_offset` are now much more efficient.
|
53
|
+
- Read files using `fread` instead of `mmap` when we're going to keep around the source through the Ruby API.
|
54
|
+
- Fix `Sexp#line_max` setting in the `seattlerb/ruby_parser` translation layer.
|
55
|
+
- Allow spaces before the encoding comment.
|
56
|
+
|
57
|
+
## [0.24.0] - 2024-02-15
|
58
|
+
|
59
|
+
### Added
|
60
|
+
|
61
|
+
- More support for `Prism::Translation::Ripper` is added.
|
62
|
+
- Support multiple versions for `Prism::Translation::Parser`.
|
63
|
+
- Improved memory usage in the FFI backend.
|
64
|
+
- Very large speed and memory improvements for creating the Ruby AST.
|
65
|
+
|
66
|
+
### Changed
|
67
|
+
|
68
|
+
- Fix location for empty symbol in hash key.
|
69
|
+
- Fix parsing a rescue modifier on the value of an assignment when the LHS is a method call with arguments and no parentheses.
|
70
|
+
|
9
71
|
## [0.23.0] - 2024-02-14
|
10
72
|
|
11
73
|
### Added
|
@@ -378,7 +440,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
|
|
378
440
|
|
379
441
|
- 🎉 Initial release! 🎉
|
380
442
|
|
381
|
-
[unreleased]: https://github.com/ruby/prism/compare/v0.
|
443
|
+
[unreleased]: https://github.com/ruby/prism/compare/v0.25.0...HEAD
|
444
|
+
[0.25.0]: https://github.com/ruby/prism/compare/v0.24.0...v0.25.0
|
445
|
+
[0.24.0]: https://github.com/ruby/prism/compare/v0.23.0...v0.24.0
|
382
446
|
[0.23.0]: https://github.com/ruby/prism/compare/v0.22.0...v0.23.0
|
383
447
|
[0.22.0]: https://github.com/ruby/prism/compare/v0.21.0...v0.22.0
|
384
448
|
[0.21.0]: https://github.com/ruby/prism/compare/v0.20.0...v0.21.0
|
data/Makefile
CHANGED
@@ -10,8 +10,8 @@ FUZZ_OUTPUT_DIR = $(shell pwd)/fuzz/output
|
|
10
10
|
|
11
11
|
SOEXT := $(shell ruby -e 'puts RbConfig::CONFIG["SOEXT"]')
|
12
12
|
|
13
|
-
CPPFLAGS := -Iinclude
|
14
|
-
CFLAGS := -g -O2 -std=c99 -Wall -Werror -Wextra -Wpedantic -Wundef -Wconversion -Wno-missing-braces -fPIC -fvisibility=hidden
|
13
|
+
CPPFLAGS := -Iinclude $(CPPFLAGS)
|
14
|
+
CFLAGS := -g -O2 -std=c99 -Wall -Werror -Wextra -Wpedantic -Wundef -Wconversion -Wno-missing-braces -fPIC -fvisibility=hidden $(CFLAGS)
|
15
15
|
CC := cc
|
16
16
|
WASI_SDK_PATH := /opt/wasi-sdk
|
17
17
|
|
@@ -94,6 +94,9 @@ all-no-debug: DEBUG_FLAGS := -DNDEBUG=1
|
|
94
94
|
all-no-debug: OPTFLAGS := -O3
|
95
95
|
all-no-debug: all
|
96
96
|
|
97
|
+
minimal: CFLAGS := $(CFLAGS) -DPRISM_BUILD_MINIMAL
|
98
|
+
minimal: all
|
99
|
+
|
97
100
|
run: Makefile $(STATIC_OBJECTS) $(HEADERS) test.c
|
98
101
|
$(ECHO) "compiling test.c"
|
99
102
|
$(Q) $(CC) $(CPPFLAGS) $(CFLAGS) $(STATIC_OBJECTS) test.c
|
data/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
<img alt="Prism Ruby parser" height="256px" src="https://github.com/ruby/prism/blob/main/doc/images/prism.png?raw=true">
|
4
4
|
</div>
|
5
5
|
|
6
|
-
This is a parser for the Ruby programming language. It is designed to be portable, error tolerant, and maintainable. It is written in C99 and has no dependencies.
|
6
|
+
This is a parser for the Ruby programming language. It is designed to be portable, error tolerant, and maintainable. It is written in C99 and has no dependencies.
|
7
7
|
|
8
8
|
## Overview
|
9
9
|
|
@@ -15,27 +15,33 @@ The repository contains the infrastructure for both a shared library (libprism)
|
|
15
15
|
├── Rakefile configuration to compile the native extension and run the Ruby tests
|
16
16
|
├── bin
|
17
17
|
│ ├── lex runs the lexer on a file or string, prints the tokens, and compares to ripper
|
18
|
-
│
|
18
|
+
│ ├── parse runs the parse on a file or string and prints the AST
|
19
|
+
│ └── prism a CLI for development and debugging
|
19
20
|
├── config.yml specification for tokens and nodes in the tree
|
20
|
-
├──
|
21
|
+
├── doc documentation website
|
22
|
+
├── docs markdown documentation about the project
|
21
23
|
├── ext
|
22
24
|
│ └── prism
|
23
25
|
│ ├── extconf.rb configuration to generate the Makefile for the native extension
|
24
26
|
│ └── extension.c the native extension that interacts with libprism
|
25
27
|
├── fuzz files related to fuzz testing
|
28
|
+
├── gemfiles gemfiles used by different Ruby versions in CI
|
26
29
|
├── include
|
27
30
|
│ ├── prism header files for the shared library
|
28
31
|
│ └── prism.h main header file for the shared library
|
29
32
|
├── java Java bindings for the shared library
|
33
|
+
├── java-wasm Java WASM bindings for the shared library
|
34
|
+
├── javascript JavaScript WASM bindings for the shared library
|
30
35
|
├── lib
|
31
36
|
│ ├── prism Ruby library files
|
32
37
|
│ └── prism.rb main entrypoint for the Ruby library
|
33
38
|
├── rakelib various Rake tasks for the project
|
39
|
+
├── rbi RBI type signatures for the Ruby library
|
34
40
|
├── rust
|
35
41
|
│ ├── ruby-prism Rustified crate for the shared library
|
36
42
|
│ └── ruby-prism-sys FFI binding for Rust
|
43
|
+
├── sig RBS type signatures for the Ruby library
|
37
44
|
├── src
|
38
|
-
│ ├── enc various encoding files
|
39
45
|
│ ├── util various utility files
|
40
46
|
│ └── prism.c main entrypoint for the shared library
|
41
47
|
├── templates contains ERB templates generated by templates/template.rb
|
@@ -51,7 +57,7 @@ The repository contains the infrastructure for both a shared library (libprism)
|
|
51
57
|
To compile the shared library, you will need:
|
52
58
|
|
53
59
|
* C99 compiler
|
54
|
-
* make
|
60
|
+
* GNU make
|
55
61
|
* Ruby 2.7.0 or later
|
56
62
|
|
57
63
|
Once you have these dependencies, run:
|
@@ -91,8 +97,41 @@ See the [CONTRIBUTING.md](CONTRIBUTING.md) file for more information. We additio
|
|
91
97
|
* [Parser translation](docs/parser_translation.md)
|
92
98
|
* [Parsing rules](docs/parsing_rules.md)
|
93
99
|
* [Releasing](docs/releasing.md)
|
94
|
-
* [Ripper](docs/
|
100
|
+
* [Ripper translation](docs/ripper_translation.md)
|
95
101
|
* [Ruby API](docs/ruby_api.md)
|
96
102
|
* [RubyParser translation](docs/ruby_parser_translation.md)
|
97
103
|
* [Serialization](docs/serialization.md)
|
98
104
|
* [Testing](docs/testing.md)
|
105
|
+
|
106
|
+
## Examples
|
107
|
+
|
108
|
+
Prism has been integrated into the majority of Ruby runtimes, many libraries, and some applications. Below is a list of some of the projects that use Prism:
|
109
|
+
|
110
|
+
### Runtimes
|
111
|
+
|
112
|
+
* [CRuby](https://github.com/ruby/ruby/pull/7964) (via C)
|
113
|
+
* [Garnet](https://github.com/camertron/garnet-js) (via WASM)
|
114
|
+
* [JRuby](https://github.com/jruby/jruby/pull/8103) (via Java)
|
115
|
+
* [Natalie](https://github.com/natalie-lang/natalie/pull/1213) (via C++ and Ruby)
|
116
|
+
* [Opal](https://github.com/opal/opal/pull/2642) (via Ruby and WASM)
|
117
|
+
* [TruffleRuby](https://github.com/oracle/truffleruby/issues/3117) (via Java)
|
118
|
+
|
119
|
+
### Libraries
|
120
|
+
|
121
|
+
* [dispersion](https://github.com/joeldrapper/dispersion)
|
122
|
+
* [packwerk](https://github.com/Shopify/packwerk/pull/388) (via parser translator)
|
123
|
+
* [rbi](https://github.com/Shopify/rbi)
|
124
|
+
* [rails](https://github.com/rails/rails)
|
125
|
+
* [parsing renders](https://github.com/rails/rails/pull/49438)
|
126
|
+
* [parsing rdoc](https://github.com/rails/rails/pull/50870)
|
127
|
+
* [parsing tests](https://github.com/rails/rails/pull/51006)
|
128
|
+
* [repl_type_completor](https://github.com/ruby/repl_type_completor)
|
129
|
+
* [rubocop](https://docs.rubocop.org/rubocop/configuration.html#setting-the-parser-engine) (via parser translator)
|
130
|
+
* [ruby-lsp](https://github.com/Shopify/ruby-lsp)
|
131
|
+
* [smart_todo](https://github.com/Shopify/smart_todo/pull/69)
|
132
|
+
* [sorbet-eraser](https://github.com/kddnewton/sorbet-eraser/pull/25)
|
133
|
+
* [synvert](https://github.com/xinminlabs/synvert-core-ruby)
|
134
|
+
|
135
|
+
### Applications
|
136
|
+
|
137
|
+
* [gem.sh](https://github.com/marcoroth/gem.sh/pull/96)
|