sorbet-cfg 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.rspec +1 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +43 -0
- data/LICENSE.txt +21 -0
- data/README.md +39 -0
- data/Rakefile +2 -0
- data/lib/sorbet-cfg/loader.rb +132 -0
- data/lib/sorbet-cfg/raw_parser.rb +37 -0
- data/lib/sorbet-cfg/tree/cfg.rb +97 -0
- data/lib/sorbet-cfg/tree/loc.rb +20 -0
- data/lib/sorbet-cfg/tree/type.rb +52 -0
- data/lib/sorbet-cfg/utilities.rb +28 -0
- data/lib/sorbet-cfg.rb +13 -0
- data/sorbet/config +2 -0
- data/sorbet/rbi/gems/rake.rbi +643 -0
- data/sorbet/rbi/hidden-definitions/errors.txt +1670 -0
- data/sorbet/rbi/hidden-definitions/hidden.rbi +2732 -0
- data/sorbet/rbi/sorbet-typed/lib/bundler/all/bundler.rbi +8684 -0
- data/sorbet/rbi/sorbet-typed/lib/ruby/all/gem.rbi +4222 -0
- data/sorbet/rbi/sorbet-typed/lib/ruby/all/open3.rbi +111 -0
- data/sorbet/rbi/sorbet-typed/lib/ruby/all/resolv.rbi +543 -0
- data/sorbet-cfg.gemspec +31 -0
- metadata +111 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 48c8482457e5a75f4cc1ecffb77c1fbeb9c84b7d6ca875321ebcea98d4ef93d1
|
4
|
+
data.tar.gz: 56a087dffb2f6007debd11e60b03492344a866ce1b9af55d2a8f1da4164cda16
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 199335bf741fe283f281fda0c79d6299b82207f0098814c32321883e721fed2df24926108c62568049380d4fb2635627d1b6eaacc2383d591a25ec8867f3a827
|
7
|
+
data.tar.gz: 44eeff0c0185f951cbea1133e9aba24c839c81294a82223a5160fb5974a92d05ae6b706831134c68dad1dd0110cc71682130c9a45417882ed9081b4354e2009a
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
sorbet-cfg (0.1.0)
|
5
|
+
sorbet
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
diff-lcs (1.3)
|
11
|
+
parslet (1.8.2)
|
12
|
+
rake (10.5.0)
|
13
|
+
rspec (3.9.0)
|
14
|
+
rspec-core (~> 3.9.0)
|
15
|
+
rspec-expectations (~> 3.9.0)
|
16
|
+
rspec-mocks (~> 3.9.0)
|
17
|
+
rspec-core (3.9.0)
|
18
|
+
rspec-support (~> 3.9.0)
|
19
|
+
rspec-expectations (3.9.0)
|
20
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
21
|
+
rspec-support (~> 3.9.0)
|
22
|
+
rspec-mocks (3.9.0)
|
23
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
24
|
+
rspec-support (~> 3.9.0)
|
25
|
+
rspec-support (3.9.0)
|
26
|
+
sorbet (0.4.4997)
|
27
|
+
sorbet-static (= 0.4.4997)
|
28
|
+
sorbet-runtime (0.4.5005)
|
29
|
+
sorbet-static (0.4.4997-universal-darwin-14)
|
30
|
+
|
31
|
+
PLATFORMS
|
32
|
+
ruby
|
33
|
+
|
34
|
+
DEPENDENCIES
|
35
|
+
bundler (~> 2.0)
|
36
|
+
parslet (~> 1.8)
|
37
|
+
rake (~> 10.0)
|
38
|
+
rspec (~> 3.9)
|
39
|
+
sorbet-cfg!
|
40
|
+
sorbet-runtime (~> 0.4.5005)
|
41
|
+
|
42
|
+
BUNDLED WITH
|
43
|
+
2.0.2
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2019 Aaron Christiansen
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# Sorbet::Cfg
|
2
|
+
|
3
|
+
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/sorbet/cfg`. To experiment with that code, run `bin/console` for an interactive prompt.
|
4
|
+
|
5
|
+
TODO: Delete this and the text above, and describe your gem
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'sorbet-cfg'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install sorbet-cfg
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
TODO: Write usage instructions here
|
26
|
+
|
27
|
+
## Development
|
28
|
+
|
29
|
+
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
30
|
+
|
31
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
32
|
+
|
33
|
+
## Contributing
|
34
|
+
|
35
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/AaronC81/sorbet-cfg.
|
36
|
+
|
37
|
+
## License
|
38
|
+
|
39
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
# typed: true
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
require 'open3'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
module SorbetCFG
|
8
|
+
module Loader
|
9
|
+
extend T::Sig
|
10
|
+
|
11
|
+
sig { returns(T::Hash[T.any(Module, Class), T::Hash[String, Tree::CFG]]) }
|
12
|
+
def self.index
|
13
|
+
@index ||= {}
|
14
|
+
end
|
15
|
+
|
16
|
+
sig { params(a: Integer, b: Integer).returns(Integer) }
|
17
|
+
def self.foo(a, b)
|
18
|
+
a + b
|
19
|
+
end
|
20
|
+
|
21
|
+
sig { params(path: String).returns(T.nilable(String)) }
|
22
|
+
##
|
23
|
+
# Given an ABSOLUTE path to somewhere within a Sorbet-enabled Ruby project,
|
24
|
+
# finds the root of the project by looking for a Gemfile or .bundle, as well
|
25
|
+
# as a sorbet directory.
|
26
|
+
def self.project_root(path)
|
27
|
+
# TODO: Sorbet is currently Unix-only, so this code is too
|
28
|
+
|
29
|
+
raise 'path does not appear to be absolute' unless path.start_with?('/')
|
30
|
+
|
31
|
+
possible_paths = []
|
32
|
+
Pathname.new(path).each_filename do |part|
|
33
|
+
possible_paths << (possible_paths.empty? \
|
34
|
+
? "/#{part}"
|
35
|
+
: File.join(possible_paths.last, part))
|
36
|
+
end
|
37
|
+
|
38
|
+
possible_paths.reverse.each do |possible_path|
|
39
|
+
has_bundler = File.exist?(File.join(possible_path, 'Gemfile')) ||
|
40
|
+
File.exist?(File.join(possible_path, '.bundle'))
|
41
|
+
|
42
|
+
has_sorbet = File.exist?(File.join(possible_path, 'sorbet'))
|
43
|
+
|
44
|
+
return possible_path if has_bundler && has_sorbet
|
45
|
+
end
|
46
|
+
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
|
50
|
+
sig { params(target: T.any(Module, Class)).returns(String) }
|
51
|
+
##
|
52
|
+
# Given a module or class, returns the contents of an RBI file which, when
|
53
|
+
# loaded, makes that module or class extend T::CFGExport so that Sorbet's
|
54
|
+
# "-p cfg-json" option will print JSON for its CFG.
|
55
|
+
def self.generate_cfg_export_rbi(target)
|
56
|
+
result_lines = []
|
57
|
+
|
58
|
+
# Start from the top
|
59
|
+
current_object = T.let(Kernel, T.untyped)
|
60
|
+
|
61
|
+
total_nesting = 0
|
62
|
+
target.to_s.split('::').each.with_index do |part_name, i|
|
63
|
+
current_object = current_object.const_get(part_name)
|
64
|
+
|
65
|
+
if current_object.is_a?(Class)
|
66
|
+
kind = "class"
|
67
|
+
elsif current_object.is_a?(Module)
|
68
|
+
kind = "module"
|
69
|
+
else
|
70
|
+
raise "#{current_object} is neither a class nor a module"
|
71
|
+
end
|
72
|
+
|
73
|
+
result_lines << "#{' ' * i}#{kind} #{part_name}"
|
74
|
+
total_nesting = i
|
75
|
+
end
|
76
|
+
|
77
|
+
result_lines << "#{' ' * (total_nesting + 1)}extend T::CFGExport"
|
78
|
+
|
79
|
+
(total_nesting + 1).times do |i|
|
80
|
+
this_level = total_nesting - i
|
81
|
+
result_lines << "#{' ' * this_level}end"
|
82
|
+
end
|
83
|
+
|
84
|
+
result_lines.join("\n") + "\n"
|
85
|
+
end
|
86
|
+
|
87
|
+
sig { params(obj: Module).void }
|
88
|
+
def self.index_module(obj)
|
89
|
+
rbi_contents = generate_cfg_export_rbi(obj)
|
90
|
+
rbi_path = '/tmp/sorbet-cfg-export.rbi'
|
91
|
+
File.write(rbi_path, rbi_contents)
|
92
|
+
|
93
|
+
result = T.let(nil, T.nilable(Tree::MultiCFG))
|
94
|
+
|
95
|
+
all_methods = obj.methods + obj.instance_methods
|
96
|
+
raise "can\'t get the source location of #{obj} because it contains no methods" if all_methods.empty?
|
97
|
+
|
98
|
+
# Just pick the first one, it's easiest
|
99
|
+
# TODO: might be best to pick all unique, though?
|
100
|
+
target = obj.method(T.must(all_methods[0]))
|
101
|
+
project = project_root(Utilities.true_source_location(target)[0])
|
102
|
+
|
103
|
+
raise 'unable to locate project root' unless project
|
104
|
+
|
105
|
+
Open3.popen3('srb', 'tc', rbi_path, '-p', 'cfg-json', chdir: project) do |i, o, e, t|
|
106
|
+
json_docs = o.read
|
107
|
+
|
108
|
+
# TODO: VERY BAD
|
109
|
+
# Just all of this is terrible
|
110
|
+
# There's a stub element at the end because trailing commas aren't valid JSON
|
111
|
+
cursed_json_doc = "[#{json_docs.gsub(/^\}/, '},')} null]"
|
112
|
+
parsed_json = JSON.parse(cursed_json_doc)[0...-1]
|
113
|
+
result = Tree::MultiCFG.new(cfg: parsed_json.map { |x| Tree::CFG.from_hash(x) })
|
114
|
+
end
|
115
|
+
|
116
|
+
raise "indexing failed for #{obj}" unless result
|
117
|
+
index[obj] = {}
|
118
|
+
result.cfg.each do |cfg|
|
119
|
+
if cfg.definition_full_name.include?('.')
|
120
|
+
prefix_char = '.'
|
121
|
+
elsif cfg.definition_full_name.include?('#')
|
122
|
+
prefix_char = '#'
|
123
|
+
else
|
124
|
+
raise "unable to determine type of #{cfg}"
|
125
|
+
end
|
126
|
+
|
127
|
+
def_name = "#{prefix_char}#{cfg.definition_full_name.split(prefix_char).last}"
|
128
|
+
T.must(index[obj])[def_name] = cfg
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# typed: ignore
|
2
|
+
require 'parslet'
|
3
|
+
|
4
|
+
module SorbetCFG
|
5
|
+
class RawParser < Parslet::Parser
|
6
|
+
# As far as I can tell, it's OK to just shotgun most operators, but < and >
|
7
|
+
# need special care because they delimit #sorbet_name
|
8
|
+
# There's probably some absolutely horrendous stuff that this accepts, but
|
9
|
+
# if that sort of stuff occurs in a CFG, we have bigger problems
|
10
|
+
rule(:name) { match('[A-Za-z_0-9=\-|&.!~?]').repeat(1) |
|
11
|
+
(str('<') >> name >> str('>') | # Matches <=> too!
|
12
|
+
str('>') | str('<') | str('<=') | str('>=')) }
|
13
|
+
|
14
|
+
rule(:space) { match('\s').repeat(1) }
|
15
|
+
rule(:space?) { space.maybe }
|
16
|
+
|
17
|
+
rule(:langle) { space? >> match('<') >> space? }
|
18
|
+
rule(:rangle) { space? >> match('>') >> space? }
|
19
|
+
|
20
|
+
rule(:lbrace) { space? >> match('{') >> space? }
|
21
|
+
rule(:rbrace) { space? >> match('}') >> space? }
|
22
|
+
|
23
|
+
rule(:sorbet_name) { langle >>
|
24
|
+
match('[A-Z]').repeat(1).as(:kind) >>
|
25
|
+
space? >>
|
26
|
+
name.as(:value) >>
|
27
|
+
rangle }
|
28
|
+
|
29
|
+
rule(:local_var) { sorbet_name.as(:name) >>
|
30
|
+
str('$') >>
|
31
|
+
match('[0-9]').repeat(1).as(:unique) >>
|
32
|
+
space? }
|
33
|
+
|
34
|
+
rule(:node) { identifier.as(:type) >> lbrace >> rbrace }
|
35
|
+
root(:node)
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# typed: true
|
2
|
+
require_relative 'loc'
|
3
|
+
require_relative 'type'
|
4
|
+
|
5
|
+
module SorbetCFG
|
6
|
+
module Tree
|
7
|
+
module Instruction; end
|
8
|
+
|
9
|
+
class LocalVariable < T::Struct
|
10
|
+
prop :unique_name, String
|
11
|
+
prop :type, Type
|
12
|
+
end
|
13
|
+
|
14
|
+
class Block < T::Struct
|
15
|
+
class BlockExit < T::Struct
|
16
|
+
prop :cond, T.nilable(LocalVariable)
|
17
|
+
prop :then_block, Integer
|
18
|
+
prop :else_block, Integer
|
19
|
+
prop :location, Loc
|
20
|
+
end
|
21
|
+
|
22
|
+
prop :id, T.nilable(Integer)
|
23
|
+
prop :bindings, T::Array[Binding], factory: ->{ [] }
|
24
|
+
prop :block_exit, BlockExit
|
25
|
+
end
|
26
|
+
|
27
|
+
class UnknownInstruction < T::Struct
|
28
|
+
extend Instruction
|
29
|
+
end
|
30
|
+
|
31
|
+
class IdentInstruction < T::Struct
|
32
|
+
extend Instruction
|
33
|
+
prop :ident, LocalVariable
|
34
|
+
end
|
35
|
+
|
36
|
+
class AliasInstruction < T::Struct
|
37
|
+
extend Instruction
|
38
|
+
prop :alias_full_name, String
|
39
|
+
end
|
40
|
+
|
41
|
+
class SendInstruction < T::Struct
|
42
|
+
extend Instruction
|
43
|
+
prop :receiver, LocalVariable
|
44
|
+
prop :method_name, String
|
45
|
+
prop :arguments, T::Array[LocalVariable]
|
46
|
+
prop :block, Block
|
47
|
+
end
|
48
|
+
|
49
|
+
class ReturnInstruction < T::Struct
|
50
|
+
extend Instruction
|
51
|
+
prop :return, LocalVariable
|
52
|
+
end
|
53
|
+
|
54
|
+
class LiteralInstruction < T::Struct
|
55
|
+
extend Instruction
|
56
|
+
prop :literal, Type
|
57
|
+
end
|
58
|
+
|
59
|
+
class UnanalyzableType < T::Struct
|
60
|
+
extend Instruction
|
61
|
+
end
|
62
|
+
|
63
|
+
class LoadArgType < T::Struct
|
64
|
+
extend Instruction
|
65
|
+
prop :load_arg_name, String
|
66
|
+
end
|
67
|
+
|
68
|
+
class CastInstruction < T::Struct
|
69
|
+
extend Instruction
|
70
|
+
prop :value, LocalVariable
|
71
|
+
prop :type, Type
|
72
|
+
end
|
73
|
+
|
74
|
+
class Binding < T::Struct
|
75
|
+
prop :bind, LocalVariable
|
76
|
+
prop :value, Instruction
|
77
|
+
prop :location, Loc
|
78
|
+
end
|
79
|
+
|
80
|
+
class CFG < T::Struct
|
81
|
+
class Argument < T::Struct
|
82
|
+
prop :name, String
|
83
|
+
prop :type, T.nilable(Type)
|
84
|
+
end
|
85
|
+
|
86
|
+
prop :definition_full_name, String
|
87
|
+
prop :location, Loc
|
88
|
+
prop :return_type, T.nilable(Type)
|
89
|
+
prop :arguments, T::Array[Argument]
|
90
|
+
prop :blocks, T::Array[Block]
|
91
|
+
end
|
92
|
+
|
93
|
+
class MultiCFG < T::Struct
|
94
|
+
prop :cfg, T::Array[CFG]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# typed: true
|
2
|
+
|
3
|
+
module SorbetCFG
|
4
|
+
module Tree
|
5
|
+
class Loc < T::Struct
|
6
|
+
class Position < T::Struct
|
7
|
+
class LC < T::Struct
|
8
|
+
prop :line, T.nilable(Integer)
|
9
|
+
prop :column, T.nilable(Integer)
|
10
|
+
end
|
11
|
+
|
12
|
+
prop :start, LC
|
13
|
+
prop :end, LC
|
14
|
+
end
|
15
|
+
|
16
|
+
prop :path, String
|
17
|
+
prop :position, Position
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# typed: true
|
2
|
+
|
3
|
+
module SorbetCFG
|
4
|
+
module Tree
|
5
|
+
module Type; end
|
6
|
+
|
7
|
+
class UnknownType < T::Struct
|
8
|
+
extend Type
|
9
|
+
end
|
10
|
+
|
11
|
+
class ClassType < T::Struct
|
12
|
+
extend Type
|
13
|
+
prop :class_full_name, String
|
14
|
+
end
|
15
|
+
|
16
|
+
class CompositeType < T::Struct
|
17
|
+
class Operator < T::Enum
|
18
|
+
enums do
|
19
|
+
OR = new
|
20
|
+
AND = new
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
extend Type
|
25
|
+
prop :left, Type
|
26
|
+
prop :right, Type
|
27
|
+
prop :operator, Operator
|
28
|
+
end
|
29
|
+
|
30
|
+
class AppliedType < T::Struct
|
31
|
+
extend Type
|
32
|
+
prop :symbol_full_name, String
|
33
|
+
prop :type_args, T::Array[Type]
|
34
|
+
end
|
35
|
+
|
36
|
+
class ShapeType < T::Struct
|
37
|
+
extend Type
|
38
|
+
prop :keys, T::Array[Type]
|
39
|
+
prop :values, T::Array[Type]
|
40
|
+
end
|
41
|
+
|
42
|
+
class LiteralType < T::Struct
|
43
|
+
extend Type
|
44
|
+
prop :value, T.any(Integer, String, Symbol, T::Boolean, Float)
|
45
|
+
end
|
46
|
+
|
47
|
+
class TupleType < T::Struct
|
48
|
+
extend Type
|
49
|
+
prop :elems, T::Array[Type]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# typed: true
|
2
|
+
|
3
|
+
module SorbetCFG
|
4
|
+
module Utilities
|
5
|
+
extend T::Sig
|
6
|
+
|
7
|
+
sig { params(meth: Method).returns([String, Integer]) }
|
8
|
+
def self.true_source_location(meth)
|
9
|
+
loc = meth.source_location
|
10
|
+
|
11
|
+
file_path, line = loc
|
12
|
+
return loc unless file_path && File.exists?(file_path)
|
13
|
+
|
14
|
+
first_source_line = IO.readlines(file_path)[line - 1]
|
15
|
+
|
16
|
+
# This is how Sorbet replaces methods.
|
17
|
+
# If Sorbet undergoes drastic refactorings, this may need to be updated!
|
18
|
+
initial_sorbet_line = "T::Private::ClassUtils.replace_method(mod, method_name) do |*args, &blk|"
|
19
|
+
replaced_sorbet_line = "mod.send(:define_method, method_sig.method_name) do |*args, &blk|"
|
20
|
+
|
21
|
+
if [initial_sorbet_line, replaced_sorbet_line].include?(T.must(first_source_line).strip)
|
22
|
+
T::Private::Methods.signature_for_method(meth).method.source_location
|
23
|
+
else
|
24
|
+
loc
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/sorbet-cfg.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# typed: true
|
2
|
+
|
3
|
+
require 'sorbet-runtime'
|
4
|
+
|
5
|
+
require_relative 'sorbet-cfg/utilities'
|
6
|
+
|
7
|
+
require_relative 'sorbet-cfg/tree/loc'
|
8
|
+
require_relative 'sorbet-cfg/tree/type'
|
9
|
+
require_relative 'sorbet-cfg/tree/cfg'
|
10
|
+
|
11
|
+
require_relative 'sorbet-cfg/raw_parser'
|
12
|
+
|
13
|
+
require_relative 'sorbet-cfg/loader'
|
data/sorbet/config
ADDED