Class: RbsActivesupport::DeclarationBuilder
- Inherits:
-
Object
- Object
- RbsActivesupport::DeclarationBuilder
- Includes:
- AST
- Defined in:
- lib/rbs_activesupport/declaration_builder.rb,
sig/rbs_activesupport/declaration_builder.rbs
Instance Attribute Summary collapse
-
#method_searcher ⇒ MethodSearcher
readonly
: MethodSearcher.
-
#processed_modules ⇒ Array[RBS::Namespace]
readonly
: Array.
-
#resolver ⇒ RBS::Resolver::TypeNameResolver
readonly
: RBS::Resolver::TypeNameResolver.
Instance Method Summary collapse
- #build(namespace, method_calls, context = nil) ⇒ [ Array[String], Array[String] ]
- #build_attribute_accessor(method_call) ⇒ Array[AttributeAccessor]
- #build_class_attribute(method_call) ⇒ Array[ClassAttribute]
- #build_delegate(namespace, method_call) ⇒ Array[Delegate]
- #build_include(namespace, method_call, context, implicit:) ⇒ Array[t]
- #build_method_calls(namespace, method_calls, context, options = {}) ⇒ Array[t]
- #context_from(type_name) ⇒ RBS::Resolver::context
-
#initialize(resolver, method_searcher) ⇒ DeclarationBuilder
constructor
A new instance of DeclarationBuilder.
- #render(namespace, decl) ⇒ String
- #render_attribute_accessor(namespace, decl) ⇒ String
- #render_class_attribute(namespace, decl) ⇒ String
- #render_delegate(decl) ⇒ String
- #render_include(decl) ⇒ String
- #resolve_type(namespace, type) ⇒ String
Methods included from AST
#eval_args_with_options, #eval_include_args, #eval_node
Constructor Details
#initialize(resolver, method_searcher) ⇒ DeclarationBuilder
Returns a new instance of DeclarationBuilder.
15 16 17 18 19 |
# File 'lib/rbs_activesupport/declaration_builder.rb', line 15 def initialize(resolver, method_searcher) #: void @resolver = resolver @method_searcher = method_searcher @processed_modules = [] end |
Instance Attribute Details
#method_searcher ⇒ MethodSearcher (readonly)
: MethodSearcher
10 11 12 |
# File 'lib/rbs_activesupport/declaration_builder.rb', line 10 def method_searcher @method_searcher end |
#processed_modules ⇒ Array[RBS::Namespace] (readonly)
: Array
11 12 13 |
# File 'lib/rbs_activesupport/declaration_builder.rb', line 11 def processed_modules @processed_modules end |
#resolver ⇒ RBS::Resolver::TypeNameResolver (readonly)
: RBS::Resolver::TypeNameResolver
9 10 11 |
# File 'lib/rbs_activesupport/declaration_builder.rb', line 9 def resolver @resolver end |
Instance Method Details
#build(namespace, method_calls, context = nil) ⇒ [ Array[String], Array[String] ]
24 25 26 27 28 29 |
# File 'lib/rbs_activesupport/declaration_builder.rb', line 24 def build(namespace, method_calls, context = nil) #: [Array[String], Array[String]] built = build_method_calls(namespace, method_calls, context) public_decls, private_decls = built.partition(&:public?) [public_decls.map { |decl| render(namespace, decl) }, private_decls.map { |decl| render(namespace, decl) }] end |
#build_attribute_accessor(method_call) ⇒ Array[AttributeAccessor]
58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/rbs_activesupport/declaration_builder.rb', line 58 def build_attribute_accessor(method_call) #: Array[AttributeAccessor] methods, = (method_call.args) [:singleton_reader] = false if i[cattr_writer mattr_writer].include?(method_call.name) [:singleton_writer] = false if i[cattr_reader mattr_reader].include?(method_call.name) [:instance_reader] = false if i[cattr_writer mattr_writer].include?(method_call.name) [:instance_writer] = false if i[cattr_reader mattr_reader].include?(method_call.name) [:private] = true if method_call.private? [:included] = method_call.included [:trailing_comment] = method_call.trailing_comment methods.map do |method| AttributeAccessor.new(method, ) end end |
#build_class_attribute(method_call) ⇒ Array[ClassAttribute]
73 74 75 76 77 78 79 80 81 |
# File 'lib/rbs_activesupport/declaration_builder.rb', line 73 def build_class_attribute(method_call) #: Array[ClassAttribute] methods, = (method_call.args) [:private] = true if method_call.private? [:included] = method_call.included [:trailing_comment] = method_call.trailing_comment methods.map do |method| ClassAttribute.new(method, ) end end |
#build_delegate(namespace, method_call) ⇒ Array[Delegate]
85 86 87 88 89 90 91 |
# File 'lib/rbs_activesupport/declaration_builder.rb', line 85 def build_delegate(namespace, method_call) #: Array[Delegate] methods, = (method_call.args) [:private] = true if method_call.private? methods.map do |method| Delegate.new(namespace, method, ) end end |
#build_include(namespace, method_call, context, implicit:) ⇒ Array[t]
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/rbs_activesupport/declaration_builder.rb', line 97 def build_include(namespace, method_call, context, implicit:) #: Array[t] # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity module_paths = eval_include_args(method_call.args) module_paths.delete_if do |module_path| unless module_path.is_a?(RBS::Namespace) puts "ERROR: #{namespace}:#{method_call.name}: Failed to recognize an included module: #{module_path}" true end end module_paths.filter_map do |module_path| include = Include.new(context || namespace, module_path, { private: method_call.private?, implicit: }) if include.module_name next if processed_modules.include?(include.module_name) processed_modules << include.module_name end calls = [] #: Array[t] calls << include if include.implicit? || (include.concern? && include.classmethods?) calls.concat(build_method_calls(namespace, include.nested_includes, include.module_name)) calls.concat(build_method_calls(namespace, include.method_calls_in_included_block, include.module_name, { implicit_include: true })) calls end.flatten end |
#build_method_calls(namespace, method_calls, context, options = {}) ⇒ Array[t]
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/rbs_activesupport/declaration_builder.rb', line 37 def build_method_calls(namespace, method_calls, context, = {}) #: Array[t] method_calls.flat_map do |method_call| case method_call.name when :class_attribute build_class_attribute(method_call) when :delegate build_delegate(namespace, method_call) when :cattr_accessor, :mattr_accessor, :cattr_reader, :mattr_reader, :cattr_writer, :mattr_writer build_attribute_accessor(method_call) when :include # implicit include is an "include" internally (e.g. include call in the included block) implicit = .fetch(:implicit_include, false) build_include(namespace, method_call, context, implicit:) end rescue StandardError => e puts "ERROR: #{namespace}:#{method_call.name}: Failed to build method calls: #{e}" nil end.compact end |
#context_from(type_name) ⇒ RBS::Resolver::context
200 201 202 203 204 205 206 207 |
# File 'lib/rbs_activesupport/declaration_builder.rb', line 200 def context_from(type_name) #: RBS::Resolver::context if type_name.namespace == RBS::Namespace.root [nil, type_name] else parent = context_from(type_name.namespace.to_type_name) [parent, type_name] end end |
#render(namespace, decl) ⇒ String
125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/rbs_activesupport/declaration_builder.rb', line 125 def render(namespace, decl) #: String case decl when AttributeAccessor render_attribute_accessor(namespace, decl) when ClassAttribute render_class_attribute(namespace, decl) when Delegate render_delegate(decl) when Include render_include(decl) end end |
#render_attribute_accessor(namespace, decl) ⇒ String
140 141 142 143 144 145 146 147 148 |
# File 'lib/rbs_activesupport/declaration_builder.rb', line 140 def render_attribute_accessor(namespace, decl) #: String type = resolve_type(namespace, decl.type) methods = [] methods << "def self.#{decl.name}: () -> (#{type})" if decl.singleton_reader? methods << "def self.#{decl.name}=: (#{type}) -> (#{type})" if decl.singleton_writer? methods << "def #{decl.name}: () -> (#{type})" if decl.instance_reader? methods << "def #{decl.name}=: (#{type}) -> (#{type})" if decl.instance_writer? methods.join("\n") end |
#render_class_attribute(namespace, decl) ⇒ String
152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/rbs_activesupport/declaration_builder.rb', line 152 def render_class_attribute(namespace, decl) #: String type = resolve_type(namespace, decl.type) methods = [] methods << "def self.#{decl.name}: () -> (#{type})" methods << "def self.#{decl.name}=: (#{type}) -> (#{type})" methods << "def self.#{decl.name}?: () -> bool" if decl.instance_predicate? methods << "def #{decl.name}: () -> (#{type})" if decl.instance_reader? methods << "def #{decl.name}=: (#{type}) -> (#{type})" if decl.instance_writer? methods << "def #{decl.name}?: () -> bool" if decl.instance_predicate? && decl.instance_reader? methods.join("\n") end |
#render_delegate(decl) ⇒ String
165 166 167 168 169 |
# File 'lib/rbs_activesupport/declaration_builder.rb', line 165 def render_delegate(decl) #: String method_types = method_searcher.method_types_for(decl) "def #{decl.method_name}: #{method_types.join(" | ")}" end |
#render_include(decl) ⇒ String
172 173 174 175 176 177 178 |
# File 'lib/rbs_activesupport/declaration_builder.rb', line 172 def render_include(decl) #: String module_name = decl.module_name || decl.module_path mods = [] mods << "include #{module_name.to_s.delete_suffix("::")}" if decl.implicit? mods << "extend #{module_name}ClassMethods" if decl.concern? && decl.classmethods? mods.join("\n") end |
#resolve_type(namespace, type) ⇒ String
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/rbs_activesupport/declaration_builder.rb', line 182 def resolve_type(namespace, type) #: String context = context_from(namespace.to_type_name) typ = RBS::Parser.parse_type(type) if typ typ.map_type_name do |type_name| resolver.resolve(type_name, context:) || type_name.absolute! rescue StandardError # Resolver failed to resolve the type name because of a lack of type database # (might not have been generated yet). It will be resolved in the next execution. type_name.absolute! end.to_s else type end end |