rbs_activesupport 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +9 -0
- data/.vscode/settings.json +6 -2
- data/README.md +69 -0
- data/lib/generators/rbs_activesupport/install_generator.rb +2 -0
- data/lib/rbs_activesupport/ast.rb +4 -2
- data/lib/rbs_activesupport/attribute_accessor.rb +22 -9
- data/lib/rbs_activesupport/class_attribute.rb +21 -8
- data/lib/rbs_activesupport/declaration_builder.rb +41 -21
- data/lib/rbs_activesupport/delegate.rb +11 -6
- data/lib/rbs_activesupport/generator.rb +18 -8
- data/lib/rbs_activesupport/include.rb +14 -8
- data/lib/rbs_activesupport/method_searcher.rb +8 -4
- data/lib/rbs_activesupport/parser/comment_parser.rb +38 -0
- data/lib/rbs_activesupport/parser.rb +37 -8
- data/lib/rbs_activesupport/rake_task.rb +21 -12
- data/lib/rbs_activesupport/version.rb +1 -1
- data/lib/rbs_activesupport.rb +1 -0
- data/rbs_collection.lock.yaml +24 -20
- data/rbs_collection.yaml +2 -4
- data/sig/generators/rbs_activesupport/install_generator.rbs +7 -0
- data/sig/rbs_activesupport/ast.rbs +8 -2
- data/sig/rbs_activesupport/attribute_accessor.rbs +14 -0
- data/sig/rbs_activesupport/class_attribute.rbs +13 -0
- data/sig/rbs_activesupport/declaration_builder.rbs +32 -4
- data/sig/rbs_activesupport/delegate.rbs +11 -0
- data/sig/rbs_activesupport/generator.rbs +14 -0
- data/sig/rbs_activesupport/include.rbs +14 -0
- data/sig/rbs_activesupport/method_searcher.rbs +8 -1
- data/sig/rbs_activesupport/parser/comment_parser.rbs +16 -0
- data/sig/rbs_activesupport/parser.rbs +28 -1
- data/sig/rbs_activesupport/rake_task.rbs +10 -0
- data/sig/rbs_activesupport/version.rbs +5 -0
- data/sig/rbs_activesupport.rbs +4 -2
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e77fa40a7a5219ebb44f4f61f46e6191d57fdbb484ee21bf56482e1e39f15be
|
4
|
+
data.tar.gz: e357c7dcb7a169e1fb4134bb3f86fdfe7651a79ce705de666c0d131defc632e0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fc3430776bd189fa7af3ba83d205328adb8222cc26061fa3f3069e0ad0ea9ffa6140a9f2d6dcfa19720eec0970b2f9f16d16ef11d8c0e1de72d749d0c8572298
|
7
|
+
data.tar.gz: 3a9f7bc7e633726b9928db97d93937c3b753b6bfbe2a796b161cb11dc8acd66360a654d274bd7cfa9d91209bc062bc6b348e9470125ebd5ac4ca2f47bfa95b79
|
data/.rubocop.yml
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
AllCops:
|
2
2
|
TargetRubyVersion: 2.7
|
3
3
|
|
4
|
+
Layout/LeadingCommentSpace:
|
5
|
+
Enabled: false
|
6
|
+
|
4
7
|
Metrics/AbcSize:
|
5
8
|
Max: 25
|
6
9
|
Exclude:
|
@@ -22,6 +25,12 @@ Metrics/MethodLength:
|
|
22
25
|
Exclude:
|
23
26
|
- "lib/rbs_activesupport/ast.rb"
|
24
27
|
|
28
|
+
Style/AccessorGrouping:
|
29
|
+
Enabled: false
|
30
|
+
|
31
|
+
Style/CommentedKeyword:
|
32
|
+
Enabled: false
|
33
|
+
|
25
34
|
Style/Documentation:
|
26
35
|
Enabled: false
|
27
36
|
|
data/.vscode/settings.json
CHANGED
data/README.md
CHANGED
@@ -14,6 +14,13 @@ After the installation, please run rake task generator:
|
|
14
14
|
|
15
15
|
bundle exec rails g rbs_activesupport:install
|
16
16
|
|
17
|
+
And then, please modify `lib/tasks/rbs_activesupport.rake` to fit your application.
|
18
|
+
For example, set it up like this if you're using Rails configuration:
|
19
|
+
|
20
|
+
RbsActivesupport::RakeTask.new do |task|
|
21
|
+
task.target_directories = [Rails.root / "app", Rails.root / "lib"]
|
22
|
+
end
|
23
|
+
|
17
24
|
## Usage
|
18
25
|
|
19
26
|
Run `rbs:activesupport:setup` task:
|
@@ -22,6 +29,68 @@ Run `rbs:activesupport:setup` task:
|
|
22
29
|
|
23
30
|
Then rbs_activesupport will scan your source code and generate RBS file into `sig/activesupport` directory.
|
24
31
|
|
32
|
+
rbs_activesupport will generate types for the following code:
|
33
|
+
|
34
|
+
* auto-extend on including ActiveSupport::Concern module
|
35
|
+
* delegate
|
36
|
+
* class_attribute, cattr_* and mattr_*
|
37
|
+
|
38
|
+
|
39
|
+
### auto-extend on including ActiveSupport::Concern module
|
40
|
+
|
41
|
+
The concern modules using `ActiveSupport::Concern` can provide the sub module named
|
42
|
+
`ClassMethods`. It is useful to define class methods to the including class.
|
43
|
+
|
44
|
+
Extending the `ClassMethods` on including the concern module goes automatically and
|
45
|
+
silently. So developers who uses the concern modules don't know the concern modules
|
46
|
+
automatically call "extend" in the background.
|
47
|
+
|
48
|
+
On the other hand, in the Type World, Steep and RBS does not support auto-extending.
|
49
|
+
Therefore we need to define the "extend" call manually.
|
50
|
+
|
51
|
+
For example, we need to write the "extend" call like the following:
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
# user.rbs
|
55
|
+
class User
|
56
|
+
include ActiveModel::Attribute
|
57
|
+
extend ActiveModel::Attribute::ClassMethods
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
61
|
+
rbs_activesupport detects the including concern modules and generates the "extend"
|
62
|
+
call automatically if the concern modules have `ClassMethods` module.
|
63
|
+
|
64
|
+
### delegate
|
65
|
+
|
66
|
+
ActiveSupport provides `delegate` method to delegate the method calls to the other
|
67
|
+
objects. It's very useful and powerful.
|
68
|
+
|
69
|
+
But RBS generators like `rbs prototype rb` and `rbs-inline` does not support it.
|
70
|
+
As a result, the delegation methods are missing in the RBS files.
|
71
|
+
|
72
|
+
rbs_activesupport detects the `delegate` method call and generates the types for
|
73
|
+
them automatically.
|
74
|
+
|
75
|
+
### class_attribute, cattr_* and mattr_*
|
76
|
+
|
77
|
+
ActiveSupport provides some methods to define class attributes and accessors:
|
78
|
+
|
79
|
+
* `class_attribute`
|
80
|
+
* `cattr_accessor`, `cattr_reader`, `cattr_writer`
|
81
|
+
* `mattr_accessor`, `mattr_reader`, `mattr_writer`
|
82
|
+
|
83
|
+
rbs_activesupport detects the calls of these methods and generates the types
|
84
|
+
for them.
|
85
|
+
|
86
|
+
Additionally, rbs_activesupport also supports the type annotation comment like RBS::Inline.
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
class User
|
90
|
+
class_attribute :name #: String
|
91
|
+
end
|
92
|
+
```
|
93
|
+
|
25
94
|
## Development
|
26
95
|
|
27
96
|
After checking out the repo, run `bin/setup` to install dependencies. You can also
|
@@ -12,6 +12,8 @@ module RbsActivesupport
|
|
12
12
|
require 'rbs_activesupport/rake_task'
|
13
13
|
|
14
14
|
RbsActivesupport::RakeTask.new do |task|
|
15
|
+
# The target directories
|
16
|
+
# task.target_directories = [Rails.root / "app"]
|
15
17
|
end
|
16
18
|
rescue LoadError
|
17
19
|
# failed to load rbs_activesupport. Skip to load rbs_activesupport tasks.
|
@@ -2,13 +2,15 @@
|
|
2
2
|
|
3
3
|
module RbsActivesupport
|
4
4
|
module AST
|
5
|
-
|
5
|
+
# @rbs node: Array[untyped]
|
6
|
+
def eval_args(node) #: Array[Array[Symbol?]]
|
6
7
|
# @type var args: Array[Array[Symbol?]]
|
7
8
|
*args, _ = eval_node(node)
|
8
9
|
args
|
9
10
|
end
|
10
11
|
|
11
|
-
|
12
|
+
# @rbs node: Array[untyped]
|
13
|
+
def eval_args_with_options(node) #: [Array[Symbol], Hash[Symbol, untyped]]
|
12
14
|
# @type var methods: Array[Symbol]
|
13
15
|
# @type var options: Hash[Symbol, untyped]
|
14
16
|
*args, _ = eval_node(node)
|
@@ -2,38 +2,51 @@
|
|
2
2
|
|
3
3
|
module RbsActivesupport
|
4
4
|
class AttributeAccessor
|
5
|
-
attr_reader :name
|
5
|
+
attr_reader :name #: Symbol
|
6
|
+
attr_reader :options #: Hash[untyped, untyped]
|
6
7
|
|
7
|
-
|
8
|
+
# @rbs name: Symbol
|
9
|
+
# @rbs options: Hash[untyped, untyped]
|
10
|
+
def initialize(name, options) #: void
|
8
11
|
@name = name
|
9
12
|
@options = options
|
10
13
|
end
|
11
14
|
|
12
|
-
def
|
15
|
+
def type #: String
|
16
|
+
# @type var trailng_comment: String?
|
17
|
+
trailing_comment = options[:trailing_comment]
|
18
|
+
if trailing_comment&.start_with?("#:")
|
19
|
+
trailing_comment[2..].strip
|
20
|
+
else
|
21
|
+
"untyped"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def singleton_reader? #: bool
|
13
26
|
options.fetch(:singleton_reader, true)
|
14
27
|
end
|
15
28
|
|
16
|
-
def singleton_writer?
|
29
|
+
def singleton_writer? #: bool
|
17
30
|
options.fetch(:singleton_writer, true)
|
18
31
|
end
|
19
32
|
|
20
|
-
def instance_accessor?
|
33
|
+
def instance_accessor? #: bool
|
21
34
|
options.fetch(:instance_accessor, true)
|
22
35
|
end
|
23
36
|
|
24
|
-
def instance_reader?
|
37
|
+
def instance_reader? #: bool
|
25
38
|
options.fetch(:instance_reader, instance_accessor?)
|
26
39
|
end
|
27
40
|
|
28
|
-
def instance_writer?
|
41
|
+
def instance_writer? #: bool
|
29
42
|
options.fetch(:instance_writer, instance_accessor?)
|
30
43
|
end
|
31
44
|
|
32
|
-
def public?
|
45
|
+
def public? #: bool
|
33
46
|
!private?
|
34
47
|
end
|
35
48
|
|
36
|
-
def private?
|
49
|
+
def private? #: bool
|
37
50
|
options.fetch(:private, false)
|
38
51
|
end
|
39
52
|
end
|
@@ -2,34 +2,47 @@
|
|
2
2
|
|
3
3
|
module RbsActivesupport
|
4
4
|
class ClassAttribute
|
5
|
-
attr_reader :name
|
5
|
+
attr_reader :name #: Symbol
|
6
|
+
attr_reader :options #: Hash[untyped, untyped]
|
6
7
|
|
7
|
-
|
8
|
+
# @rbs name: Symbol
|
9
|
+
# @rbs options: Hash[untyped, untyped]
|
10
|
+
def initialize(name, options) #: void
|
8
11
|
@name = name
|
9
12
|
@options = options
|
10
13
|
end
|
11
14
|
|
12
|
-
def
|
15
|
+
def type #: String
|
16
|
+
# @type var trailng_comment: String?
|
17
|
+
trailing_comment = options[:trailing_comment]
|
18
|
+
if trailing_comment&.start_with?("#:")
|
19
|
+
trailing_comment[2..].strip
|
20
|
+
else
|
21
|
+
"untyped"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def instance_accessor? #: bool
|
13
26
|
options.fetch(:instance_accessor, true)
|
14
27
|
end
|
15
28
|
|
16
|
-
def instance_reader?
|
29
|
+
def instance_reader? #: bool
|
17
30
|
options.fetch(:instance_reader, instance_accessor?)
|
18
31
|
end
|
19
32
|
|
20
|
-
def instance_writer?
|
33
|
+
def instance_writer? #: bool
|
21
34
|
options.fetch(:instance_writer, instance_accessor?)
|
22
35
|
end
|
23
36
|
|
24
|
-
def instance_predicate?
|
37
|
+
def instance_predicate? #: bool
|
25
38
|
options.fetch(:instance_predicate, true)
|
26
39
|
end
|
27
40
|
|
28
|
-
def public?
|
41
|
+
def public? #: bool
|
29
42
|
!private?
|
30
43
|
end
|
31
44
|
|
32
|
-
def private?
|
45
|
+
def private? #: bool
|
33
46
|
options.fetch(:private, false)
|
34
47
|
end
|
35
48
|
end
|
@@ -2,15 +2,20 @@
|
|
2
2
|
|
3
3
|
module RbsActivesupport
|
4
4
|
class DeclarationBuilder
|
5
|
+
# @rbs! type t = AttributeAccessor | ClassAttribute | Delegate | Include
|
6
|
+
|
5
7
|
include AST
|
6
8
|
|
7
|
-
attr_reader :method_searcher
|
9
|
+
attr_reader :method_searcher #: MethodSearcher
|
8
10
|
|
9
|
-
|
11
|
+
# @rbs method_searcher: MethodSearcher
|
12
|
+
def initialize(method_searcher) #: void
|
10
13
|
@method_searcher = method_searcher
|
11
14
|
end
|
12
15
|
|
13
|
-
|
16
|
+
# @rbs namespace: RBS::Namespace
|
17
|
+
# @rbs method_calls: Array[Parser::MethodCall]
|
18
|
+
def build(namespace, method_calls) #: [Array[String], Array[String]]
|
14
19
|
public_decls, private_decls = build_method_calls(namespace, method_calls).partition(&:public?)
|
15
20
|
[public_decls.map(&method(:render)).compact, # steep:ignore BlockTypeMismatch
|
16
21
|
private_decls.map(&method(:render)).compact] # steep:ignore BlockTypeMismatch
|
@@ -18,7 +23,9 @@ module RbsActivesupport
|
|
18
23
|
|
19
24
|
private
|
20
25
|
|
21
|
-
|
26
|
+
# @rbs namespace: RBS::Namespace
|
27
|
+
# @rbs method_calls: Array[Parser::MethodCall]
|
28
|
+
def build_method_calls(namespace, method_calls) #: Array[t]
|
22
29
|
method_calls.flat_map do |method_call|
|
23
30
|
case method_call.name
|
24
31
|
when :class_attribute
|
@@ -36,27 +43,33 @@ module RbsActivesupport
|
|
36
43
|
end.compact
|
37
44
|
end
|
38
45
|
|
39
|
-
|
46
|
+
# @rbs method_call: Parser::MethodCall
|
47
|
+
def build_attribute_accessor(method_call) #: Array[AttributeAccessor]
|
40
48
|
methods, options = eval_args_with_options(method_call.args)
|
41
49
|
options[:singleton_reader] = false if %i[cattr_writer mattr_writer].include?(method_call.name)
|
42
50
|
options[:singleton_writer] = false if %i[cattr_reader mattr_reader].include?(method_call.name)
|
43
51
|
options[:instance_reader] = false if %i[cattr_writer mattr_writer].include?(method_call.name)
|
44
52
|
options[:instance_writer] = false if %i[cattr_reader mattr_reader].include?(method_call.name)
|
45
53
|
options[:private] = true if method_call.private?
|
54
|
+
options[:trailing_comment] = method_call.trailing_comment
|
46
55
|
methods.map do |method|
|
47
56
|
AttributeAccessor.new(method, options)
|
48
57
|
end
|
49
58
|
end
|
50
59
|
|
51
|
-
|
60
|
+
# @rbs method_call: Parser::MethodCall
|
61
|
+
def build_class_attribute(method_call) #: Array[ClassAttribute]
|
52
62
|
methods, options = eval_args_with_options(method_call.args)
|
53
63
|
options[:private] = true if method_call.private?
|
64
|
+
options[:trailing_comment] = method_call.trailing_comment
|
54
65
|
methods.map do |method|
|
55
66
|
ClassAttribute.new(method, options)
|
56
67
|
end
|
57
68
|
end
|
58
69
|
|
59
|
-
|
70
|
+
# @rbs namespace: RBS::Namespace
|
71
|
+
# @rbs method_call: Parser::MethodCall
|
72
|
+
def build_delegate(namespace, method_call) #: Array[Delegate]
|
60
73
|
methods, options = eval_args_with_options(method_call.args)
|
61
74
|
options[:private] = true if method_call.private?
|
62
75
|
methods.map do |method|
|
@@ -64,14 +77,17 @@ module RbsActivesupport
|
|
64
77
|
end
|
65
78
|
end
|
66
79
|
|
67
|
-
|
80
|
+
# @rbs namespace: RBS::Namespace
|
81
|
+
# @rbs method_call: Parser::MethodCall
|
82
|
+
def build_include(namespace, method_call) #: Array[Include]
|
68
83
|
module_paths = eval_args(method_call.args)
|
69
84
|
module_paths.map do |module_path|
|
70
85
|
Include.new(namespace, module_path, { private: method_call.private? })
|
71
86
|
end
|
72
87
|
end
|
73
88
|
|
74
|
-
|
89
|
+
# @rbs decl: t
|
90
|
+
def render(decl) #: String?
|
75
91
|
case decl
|
76
92
|
when AttributeAccessor
|
77
93
|
render_attribute_accessor(decl)
|
@@ -84,33 +100,37 @@ module RbsActivesupport
|
|
84
100
|
end
|
85
101
|
end
|
86
102
|
|
87
|
-
|
103
|
+
# @rbs decl: AttributeAccessor
|
104
|
+
def render_attribute_accessor(decl) #: String
|
88
105
|
methods = []
|
89
|
-
methods << "def self.#{decl.name}: () ->
|
90
|
-
methods << "def self.#{decl.name}=: (
|
91
|
-
methods << "def #{decl.name}: () ->
|
92
|
-
methods << "def #{decl.name}=: (
|
106
|
+
methods << "def self.#{decl.name}: () -> (#{decl.type})" if decl.singleton_reader?
|
107
|
+
methods << "def self.#{decl.name}=: (#{decl.type}) -> (#{decl.type})" if decl.singleton_writer?
|
108
|
+
methods << "def #{decl.name}: () -> (#{decl.type})" if decl.instance_reader?
|
109
|
+
methods << "def #{decl.name}=: (#{decl.type}) -> (#{decl.type})" if decl.instance_writer?
|
93
110
|
methods.join("\n")
|
94
111
|
end
|
95
112
|
|
96
|
-
|
113
|
+
# @rbs decl: ClassAttribute
|
114
|
+
def render_class_attribute(decl) #: String
|
97
115
|
methods = []
|
98
|
-
methods << "def self.#{decl.name}: () ->
|
99
|
-
methods << "def self.#{decl.name}=: (
|
116
|
+
methods << "def self.#{decl.name}: () -> (#{decl.type})"
|
117
|
+
methods << "def self.#{decl.name}=: (#{decl.type}) -> (#{decl.type})"
|
100
118
|
methods << "def self.#{decl.name}?: () -> bool" if decl.instance_predicate?
|
101
|
-
methods << "def #{decl.name}: () ->
|
102
|
-
methods << "def #{decl.name}=: (
|
119
|
+
methods << "def #{decl.name}: () -> (#{decl.type})" if decl.instance_reader?
|
120
|
+
methods << "def #{decl.name}=: (#{decl.type}) -> (#{decl.type})" if decl.instance_writer?
|
103
121
|
methods << "def #{decl.name}?: () -> bool" if decl.instance_predicate? && decl.instance_reader?
|
104
122
|
methods.join("\n")
|
105
123
|
end
|
106
124
|
|
107
|
-
|
125
|
+
# @rbs decl: Delegate
|
126
|
+
def render_delegate(decl) #: String
|
108
127
|
method_types = method_searcher.method_types_for(decl)
|
109
128
|
|
110
129
|
"def #{decl.method_name}: #{method_types.join(" | ")}"
|
111
130
|
end
|
112
131
|
|
113
|
-
|
132
|
+
# @rbs decl: Include
|
133
|
+
def render_include(decl) #: String?
|
114
134
|
return unless decl.concern? && decl.classmethods?
|
115
135
|
|
116
136
|
<<~RBS
|
@@ -2,19 +2,24 @@
|
|
2
2
|
|
3
3
|
module RbsActivesupport
|
4
4
|
class Delegate
|
5
|
-
attr_reader :namespace
|
5
|
+
attr_reader :namespace #: RBS::Namespace
|
6
|
+
attr_reader :method #: Symbol
|
7
|
+
attr_reader :options #: Hash[Symbol, untyped]
|
6
8
|
|
7
|
-
|
9
|
+
# @rbs namespace: RBS::Namespace
|
10
|
+
# @rbs method: Symbol
|
11
|
+
# @rbs options: Hash[Symbol, untyped]
|
12
|
+
def initialize(namespace, method, options) #: void
|
8
13
|
@namespace = namespace
|
9
14
|
@method = method
|
10
15
|
@options = options
|
11
16
|
end
|
12
17
|
|
13
|
-
def to
|
18
|
+
def to #: Symbol
|
14
19
|
options[:to]
|
15
20
|
end
|
16
21
|
|
17
|
-
def method_name
|
22
|
+
def method_name #: Symbol
|
18
23
|
case options[:prefix]
|
19
24
|
when true
|
20
25
|
:"#{to}_#{method}"
|
@@ -25,11 +30,11 @@ module RbsActivesupport
|
|
25
30
|
end
|
26
31
|
end
|
27
32
|
|
28
|
-
def public?
|
33
|
+
def public? #: bool
|
29
34
|
!private?
|
30
35
|
end
|
31
36
|
|
32
|
-
def private?
|
37
|
+
def private? #: bool
|
33
38
|
options.fetch(:private, false)
|
34
39
|
end
|
35
40
|
end
|
@@ -2,20 +2,27 @@
|
|
2
2
|
|
3
3
|
module RbsActivesupport
|
4
4
|
class Generator
|
5
|
-
|
5
|
+
# @rbs pathname: Pathname
|
6
|
+
# @rbs rbs_builder: RBS::DefinitionBuilder
|
7
|
+
def self.generate(pathname, rbs_builder) #: String?
|
6
8
|
new(pathname, rbs_builder).generate
|
7
9
|
end
|
8
10
|
|
9
|
-
|
11
|
+
include AST
|
10
12
|
|
11
|
-
|
13
|
+
attr_reader :pathname #: Pathname
|
14
|
+
attr_reader :declaration_builder #: DeclarationBuilder
|
15
|
+
|
16
|
+
# @rbs pathname: Pathname
|
17
|
+
# @rbs rbs_builder: RBS::DefinitionBuilder
|
18
|
+
def initialize(pathname, rbs_builder) #: void
|
12
19
|
@pathname = pathname
|
13
20
|
|
14
21
|
method_searcher = MethodSearcher.new(rbs_builder)
|
15
22
|
@declaration_builder = DeclarationBuilder.new(method_searcher)
|
16
23
|
end
|
17
24
|
|
18
|
-
def generate
|
25
|
+
def generate #: String?
|
19
26
|
declarations = parse_source_code
|
20
27
|
return if declarations.empty?
|
21
28
|
|
@@ -42,20 +49,22 @@ module RbsActivesupport
|
|
42
49
|
|
43
50
|
private
|
44
51
|
|
45
|
-
|
52
|
+
# @rbs rbs: String
|
53
|
+
def format(rbs) #: String
|
46
54
|
parsed = RBS::Parser.parse_signature(rbs)
|
47
55
|
StringIO.new.tap do |out|
|
48
56
|
RBS::Writer.new(out: out).write(parsed[1] + parsed[2])
|
49
57
|
end.string
|
50
58
|
end
|
51
59
|
|
52
|
-
def parse_source_code
|
60
|
+
def parse_source_code #: Hash[RBS::Namespace, Array[Parser::MethodCall]]
|
53
61
|
parser = Parser.new
|
54
62
|
parser.parse(pathname.read)
|
55
63
|
parser.method_calls
|
56
64
|
end
|
57
65
|
|
58
|
-
|
66
|
+
# @rbs namespace: RBS::Namespace
|
67
|
+
def header(namespace) #: String
|
59
68
|
context = +""
|
60
69
|
namespace.path.map do |mod_name|
|
61
70
|
context += "::#{mod_name}"
|
@@ -75,7 +84,8 @@ module RbsActivesupport
|
|
75
84
|
end.join("\n")
|
76
85
|
end
|
77
86
|
|
78
|
-
|
87
|
+
# @rbs namespace: RBS::Namespace
|
88
|
+
def footer(namespace) #: String
|
79
89
|
"end\n" * namespace.path.size
|
80
90
|
end
|
81
91
|
end
|
@@ -4,15 +4,20 @@ require "active_support/concern"
|
|
4
4
|
|
5
5
|
module RbsActivesupport
|
6
6
|
class Include
|
7
|
-
attr_reader :context
|
7
|
+
attr_reader :context #: RBS::Namespace
|
8
|
+
attr_reader :module_path #: Array[Symbol?]
|
9
|
+
attr_reader :options #: Hash[Symbol, untyped]
|
8
10
|
|
9
|
-
|
11
|
+
# @rbs context: RBS::Namespace
|
12
|
+
# @rbs module_path: Array[Symbol?]
|
13
|
+
# @rbs options: Hash[Symbol, untyped]
|
14
|
+
def initialize(context, module_path, options) #: void
|
10
15
|
@context = context
|
11
16
|
@module_path = module_path
|
12
17
|
@options = options
|
13
18
|
end
|
14
19
|
|
15
|
-
def argument
|
20
|
+
def argument #: RBS::Namespace
|
16
21
|
if module_path.first.nil?
|
17
22
|
RBS::Namespace.new(path: module_path[1...], absolute: true) # steep:ignore ArgumentTypeMismatch
|
18
23
|
else
|
@@ -20,7 +25,8 @@ module RbsActivesupport
|
|
20
25
|
end
|
21
26
|
end
|
22
27
|
|
23
|
-
|
28
|
+
# @rbs %a{pure}
|
29
|
+
def module_name #: RBS::Namespace?
|
24
30
|
namespace = @context
|
25
31
|
|
26
32
|
loop do
|
@@ -33,7 +39,7 @@ module RbsActivesupport
|
|
33
39
|
end
|
34
40
|
end
|
35
41
|
|
36
|
-
def concern?
|
42
|
+
def concern? #: bool
|
37
43
|
return false unless module_name
|
38
44
|
|
39
45
|
modname = module_name.to_s.delete_suffix("::")
|
@@ -43,18 +49,18 @@ module RbsActivesupport
|
|
43
49
|
mod&.singleton_class&.include?(ActiveSupport::Concern)
|
44
50
|
end
|
45
51
|
|
46
|
-
def classmethods?
|
52
|
+
def classmethods? #: bool
|
47
53
|
return false unless module_name
|
48
54
|
|
49
55
|
modname = module_name.append(:ClassMethods).to_s.delete_suffix("::")
|
50
56
|
Object.const_defined?(modname)
|
51
57
|
end
|
52
58
|
|
53
|
-
def public?
|
59
|
+
def public? #: bool
|
54
60
|
!private?
|
55
61
|
end
|
56
62
|
|
57
|
-
def private?
|
63
|
+
def private? #: bool
|
58
64
|
options.fetch(:private, false)
|
59
65
|
end
|
60
66
|
end
|
@@ -4,13 +4,15 @@ require "rbs"
|
|
4
4
|
|
5
5
|
module RbsActivesupport
|
6
6
|
class MethodSearcher
|
7
|
-
attr_reader :rbs_builder
|
7
|
+
attr_reader :rbs_builder #: RBS::DefinitionBuilder
|
8
8
|
|
9
|
-
|
9
|
+
# @rbs rbs_builder: RBS::DefinitionBuilder
|
10
|
+
def initialize(rbs_builder) #: void
|
10
11
|
@rbs_builder = rbs_builder
|
11
12
|
end
|
12
13
|
|
13
|
-
|
14
|
+
# @rbs delegate: Delegate
|
15
|
+
def method_types_for(delegate) #: Array[String]
|
14
16
|
delegate_to = lookup_method_types(delegate.namespace.to_type_name, delegate.to)
|
15
17
|
return ["() -> untyped"] if delegate_to.any? { |t| t.type.return_type.is_a?(RBS::Types::Bases::Any) }
|
16
18
|
|
@@ -25,7 +27,9 @@ module RbsActivesupport
|
|
25
27
|
|
26
28
|
private
|
27
29
|
|
28
|
-
|
30
|
+
# @rbs type_name: RBS::TypeName
|
31
|
+
# @rbs method: Symbol
|
32
|
+
def lookup_method_types(type_name, method) #: Array[RBS::MethodType]
|
29
33
|
instance = rbs_builder.build_instance(type_name)
|
30
34
|
method_def = instance.methods[method]
|
31
35
|
return [] unless method_def
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RbsActivesupport
|
4
|
+
class Parser
|
5
|
+
class CommentParser
|
6
|
+
attr_reader :line_comments #: Hash[Integer, String]
|
7
|
+
attr_reader :trailing_comments #: Hash[Integer, String]
|
8
|
+
|
9
|
+
def initialize #: void
|
10
|
+
@line_comments = {}
|
11
|
+
@trailing_comments = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
# @rbs string: String
|
15
|
+
def parse(string) #: self
|
16
|
+
# @type var code_lines: Hash[Integer, bool]
|
17
|
+
code_lines = {}
|
18
|
+
Ripper.lex(string).each do |(line, _), type, token, _|
|
19
|
+
case type
|
20
|
+
when :on_sp, :on_ignored_nl
|
21
|
+
# ignore
|
22
|
+
when :on_comment
|
23
|
+
if code_lines[line]
|
24
|
+
trailing_comments[line] = token.chomp
|
25
|
+
else
|
26
|
+
line_comments[line] = token.chomp
|
27
|
+
end
|
28
|
+
:here
|
29
|
+
else
|
30
|
+
code_lines[line] = true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
self
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|