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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +9 -0
  3. data/.vscode/settings.json +6 -2
  4. data/README.md +69 -0
  5. data/lib/generators/rbs_activesupport/install_generator.rb +2 -0
  6. data/lib/rbs_activesupport/ast.rb +4 -2
  7. data/lib/rbs_activesupport/attribute_accessor.rb +22 -9
  8. data/lib/rbs_activesupport/class_attribute.rb +21 -8
  9. data/lib/rbs_activesupport/declaration_builder.rb +41 -21
  10. data/lib/rbs_activesupport/delegate.rb +11 -6
  11. data/lib/rbs_activesupport/generator.rb +18 -8
  12. data/lib/rbs_activesupport/include.rb +14 -8
  13. data/lib/rbs_activesupport/method_searcher.rb +8 -4
  14. data/lib/rbs_activesupport/parser/comment_parser.rb +38 -0
  15. data/lib/rbs_activesupport/parser.rb +37 -8
  16. data/lib/rbs_activesupport/rake_task.rb +21 -12
  17. data/lib/rbs_activesupport/version.rb +1 -1
  18. data/lib/rbs_activesupport.rb +1 -0
  19. data/rbs_collection.lock.yaml +24 -20
  20. data/rbs_collection.yaml +2 -4
  21. data/sig/generators/rbs_activesupport/install_generator.rbs +7 -0
  22. data/sig/rbs_activesupport/ast.rbs +8 -2
  23. data/sig/rbs_activesupport/attribute_accessor.rbs +14 -0
  24. data/sig/rbs_activesupport/class_attribute.rbs +13 -0
  25. data/sig/rbs_activesupport/declaration_builder.rbs +32 -4
  26. data/sig/rbs_activesupport/delegate.rbs +11 -0
  27. data/sig/rbs_activesupport/generator.rbs +14 -0
  28. data/sig/rbs_activesupport/include.rbs +14 -0
  29. data/sig/rbs_activesupport/method_searcher.rbs +8 -1
  30. data/sig/rbs_activesupport/parser/comment_parser.rbs +16 -0
  31. data/sig/rbs_activesupport/parser.rbs +28 -1
  32. data/sig/rbs_activesupport/rake_task.rbs +10 -0
  33. data/sig/rbs_activesupport/version.rbs +5 -0
  34. data/sig/rbs_activesupport.rbs +4 -2
  35. metadata +7 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 15aaf2bfe1439cdfd04de74b02a684b4dd81be4a076378f8746b6f65fef6eae2
4
- data.tar.gz: b8f442d762f030c4f7eec6f36de7be7ff90f027968b056e1d996c1da47c7ad0e
3
+ metadata.gz: 2e77fa40a7a5219ebb44f4f61f46e6191d57fdbb484ee21bf56482e1e39f15be
4
+ data.tar.gz: e357c7dcb7a169e1fb4134bb3f86fdfe7651a79ce705de666c0d131defc632e0
5
5
  SHA512:
6
- metadata.gz: 60d85781b44efb807e298c2dc5c261fd135553ba36d08460a99cfc67688616da7171d472fd4d1744c06700ad6caf006433fc70d612ae9c38cde932990e85bdc8
7
- data.tar.gz: 8ee761e2ce8f2ee1b4e18a90501ee6250ac618351e937abcef5a3cb2e9141e3f128f046d7329ca3174d8f88c6297f9ad832e6fc42ff8f83522c6aedd41b53f17
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
 
@@ -1,6 +1,10 @@
1
1
  {
2
2
  "rbs-helper.signature-directory": "sig/",
3
3
  "cSpell.words": [
4
- "Cyclomatic"
5
- ]
4
+ "cattr",
5
+ "Cyclomatic",
6
+ "mattr"
7
+ ],
8
+ "rbs-helper.rbs-inline-on-save": true,
9
+ "rbs-helper.rbs-inline-options": "--opt-out --output=sig/"
6
10
  }
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
- def eval_args(node)
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
- def eval_args_with_options(node)
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, :options
5
+ attr_reader :name #: Symbol
6
+ attr_reader :options #: Hash[untyped, untyped]
6
7
 
7
- def initialize(name, options)
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 singleton_reader?
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, :options
5
+ attr_reader :name #: Symbol
6
+ attr_reader :options #: Hash[untyped, untyped]
6
7
 
7
- def initialize(name, options)
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 instance_accessor?
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
- def initialize(method_searcher)
11
+ # @rbs method_searcher: MethodSearcher
12
+ def initialize(method_searcher) #: void
10
13
  @method_searcher = method_searcher
11
14
  end
12
15
 
13
- def build(namespace, method_calls)
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
- def build_method_calls(namespace, method_calls)
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
- def build_attribute_accessor(method_call)
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
- def build_class_attribute(method_call)
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
- def build_delegate(namespace, method_call)
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
- def build_include(namespace, method_call)
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
- def render(decl)
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
- def render_attribute_accessor(decl)
103
+ # @rbs decl: AttributeAccessor
104
+ def render_attribute_accessor(decl) #: String
88
105
  methods = []
89
- methods << "def self.#{decl.name}: () -> untyped" if decl.singleton_reader?
90
- methods << "def self.#{decl.name}=: (untyped) -> untyped" if decl.singleton_writer?
91
- methods << "def #{decl.name}: () -> untyped" if decl.instance_reader?
92
- methods << "def #{decl.name}=: (untyped) -> untyped" if decl.instance_writer?
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
- def render_class_attribute(decl)
113
+ # @rbs decl: ClassAttribute
114
+ def render_class_attribute(decl) #: String
97
115
  methods = []
98
- methods << "def self.#{decl.name}: () -> untyped"
99
- methods << "def self.#{decl.name}=: (untyped) -> untyped"
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}: () -> untyped" if decl.instance_reader?
102
- methods << "def #{decl.name}=: (untyped) -> untyped" if decl.instance_writer?
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
- def render_delegate(decl)
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
- def render_include(decl)
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, :method, :options
5
+ attr_reader :namespace #: RBS::Namespace
6
+ attr_reader :method #: Symbol
7
+ attr_reader :options #: Hash[Symbol, untyped]
6
8
 
7
- def initialize(namespace, method, options)
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
- def self.generate(pathname, rbs_builder)
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
- attr_reader :pathname, :declaration_builder
11
+ include AST
10
12
 
11
- def initialize(pathname, rbs_builder)
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
- def format(rbs)
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
- def header(namespace)
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
- def footer(namespace)
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, :module_path, :options
7
+ attr_reader :context #: RBS::Namespace
8
+ attr_reader :module_path #: Array[Symbol?]
9
+ attr_reader :options #: Hash[Symbol, untyped]
8
10
 
9
- def initialize(context, module_path, options)
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
- def module_name
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
- def initialize(rbs_builder)
9
+ # @rbs rbs_builder: RBS::DefinitionBuilder
10
+ def initialize(rbs_builder) #: void
10
11
  @rbs_builder = rbs_builder
11
12
  end
12
13
 
13
- def method_types_for(delegate)
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
- def lookup_method_types(type_name, method)
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