Class: RubyLanguageServer::SEXPProcessor
- Inherits:
-
Object
- Object
- RubyLanguageServer::SEXPProcessor
- Includes:
- RubyLanguageServer::ScopeParserCommands::RailsCommands, RubyLanguageServer::ScopeParserCommands::RakeCommands, RubyLanguageServer::ScopeParserCommands::RspecCommands, RubyLanguageServer::ScopeParserCommands::RubyCommands
- Defined in:
- lib/ruby_language_server/scope_parser.rb
Overview
This class is responsible for processing the generated sexp from the ScopeParser below. It builds scopes that amount to heirarchical arrays with information about what classes, methods, variables, etc - are in each scope.
Instance Attribute Summary collapse
-
#current_scope ⇒ Object
readonly
Returns the value of attribute current_scope.
-
#lines ⇒ Object
readonly
Returns the value of attribute lines.
-
#sexp ⇒ Object
readonly
Returns the value of attribute sexp.
Instance Method Summary collapse
- #assign_subclass(scope, sexp) ⇒ Object
-
#initialize(sexp, lines = 1, shallow = false) ⇒ SEXPProcessor
constructor
A new instance of SEXPProcessor.
- #on_assign(args, rest) ⇒ Object
- #on_block_var(args, rest) ⇒ Object
- #on_bodystmt(args, _rest) ⇒ Object
- #on_class(args, rest) ⇒ Object
-
#on_command(args, rest) ⇒ Object
The on_command function idea is stolen from RipperTags github.com/tmm1/ripper-tags/blob/master/lib/ripper-tags/parser.rb.
- #on_def(args, rest) ⇒ Object
-
#on_defs(args, rest) ⇒ Object
def self.something(par)…
- #on_do_block(args, rest) ⇒ Object
-
#on_ident(name, line, column) ⇒ Object
ident is something that gets processed at parameters to a function or block.
-
#on_method_add_arg(call, args) ⇒ Object
The on_method_add_arg function is downright stolen from RipperTags github.com/tmm1/ripper-tags/blob/master/lib/ripper-tags/parser.rb.
- #on_method_add_block(args, rest) ⇒ Object
-
#on_mlhs(args, rest) ⇒ Object
Multiple left hand side (foo, bar) = somethingg…
- #on_module(args, rest) ⇒ Object
- #on_params(args, rest) ⇒ Object
- #on_program(args, _rest) ⇒ Object
- #on_sclass(_args, rest) ⇒ Object
- #on_var_field(args, rest) ⇒ Object
-
#on_var_ref(_args, _rest) ⇒ Object
Used only to describe subclasses? – nope.
-
#on_vcall(_args, rest) ⇒ Object
foo = bar – bar is in the vcall.
- #process(sexp) ⇒ Object
- #root_scope ⇒ Object
Methods included from RubyLanguageServer::ScopeParserCommands::RubyCommands
#on_attr_accessor_command, #on_attr_command, #on_attr_reader_command, #on_attr_writer_command
Methods included from RubyLanguageServer::ScopeParserCommands::RailsCommands
Methods included from RubyLanguageServer::ScopeParserCommands::RspecCommands
#on_context_command, #on_describe_command, #on_it_command
Methods included from RubyLanguageServer::ScopeParserCommands::RakeCommands
#on_namespace_command, #on_task_command
Constructor Details
#initialize(sexp, lines = 1, shallow = false) ⇒ SEXPProcessor
Returns a new instance of SEXPProcessor.
20 21 22 23 24 25 |
# File 'lib/ruby_language_server/scope_parser.rb', line 20 def initialize(sexp, lines = 1, shallow = false) @sexp = sexp @lines = lines @shallow = shallow @root_scope = nil end |
Instance Attribute Details
#current_scope ⇒ Object (readonly)
Returns the value of attribute current_scope.
18 19 20 |
# File 'lib/ruby_language_server/scope_parser.rb', line 18 def current_scope @current_scope end |
#lines ⇒ Object (readonly)
Returns the value of attribute lines.
18 19 20 |
# File 'lib/ruby_language_server/scope_parser.rb', line 18 def lines @lines end |
#sexp ⇒ Object (readonly)
Returns the value of attribute sexp.
18 19 20 |
# File 'lib/ruby_language_server/scope_parser.rb', line 18 def sexp @sexp end |
Instance Method Details
#assign_subclass(scope, sexp) ⇒ Object
103 104 105 106 107 108 |
# File 'lib/ruby_language_server/scope_parser.rb', line 103 def assign_subclass(scope, sexp) return unless !sexp[0].nil? && sexp[0][0] == :var_ref (_, (_, name)) = sexp[0] scope.set_superclass_name(name) end |
#on_assign(args, rest) ⇒ Object
142 143 144 145 |
# File 'lib/ruby_language_server/scope_parser.rb', line 142 def on_assign(args, rest) process(args) process(rest) end |
#on_block_var(args, rest) ⇒ Object
130 131 132 133 |
# File 'lib/ruby_language_server/scope_parser.rb', line 130 def on_block_var(args, rest) process(args) process(rest) end |
#on_bodystmt(args, _rest) ⇒ Object
89 90 91 |
# File 'lib/ruby_language_server/scope_parser.rb', line 89 def on_bodystmt(args, _rest) process(args) end |
#on_class(args, rest) ⇒ Object
98 99 100 101 |
# File 'lib/ruby_language_server/scope_parser.rb', line 98 def on_class(args, rest) scope = add_scope(args.last, rest, ScopeData::Scope::TYPE_CLASS) assign_subclass(scope, rest) end |
#on_command(args, rest) ⇒ Object
The on_command function idea is stolen from RipperTags github.com/tmm1/ripper-tags/blob/master/lib/ripper-tags/parser.rb
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/ruby_language_server/scope_parser.rb', line 175 def on_command(args, rest) # [:@ident, "public", [6, 8]] (_, name, (line, _column)) = args method_name = "on_#{name}_command" if respond_to? method_name return send(method_name, line, args, rest) else RubyLanguageServer.logger.debug("We don't have a #{method_name} with #{args}") end case name when 'public', 'private', 'protected' # FIXME: access control... process(rest) when 'delegate' # on_delegate(*args[0][1..-1]) when 'def_delegator', 'def_instance_delegator' # on_def_delegator(*args[0][1..-1]) when 'def_delegators', 'def_instance_delegators' # on_def_delegators(*args[0][1..-1]) end end |
#on_def(args, rest) ⇒ Object
147 148 149 |
# File 'lib/ruby_language_server/scope_parser.rb', line 147 def on_def(args, rest) add_scope(args, rest, ScopeData::Scope::TYPE_METHOD) end |
#on_defs(args, rest) ⇒ Object
def self.something(par)…
- :var_ref, [:@kw, “self”, [28, 14]]], [[:@period, “.”, [28, 18]], [:@ident, “something”, [28, 19]], [:paren, [:params, [[:@ident, “par”, [28, 23]]], nil, nil, nil, nil, nil, nil]], [:bodystmt, [[:assign, [:var_field, [:@ident, “pax”, [29, 12]]], [:var_ref, [:@ident, “par”, [29, 18]]]]], nil, nil, nil]
153 154 155 |
# File 'lib/ruby_language_server/scope_parser.rb', line 153 def on_defs(args, rest) on_def(rest[1], rest[2..]) if args[1][1] == 'self' && rest[0][1] == '.' end |
#on_do_block(args, rest) ⇒ Object
122 123 124 125 126 127 128 |
# File 'lib/ruby_language_server/scope_parser.rb', line 122 def on_do_block(args, rest) ((_, ((_, (_, (_, _name, (line, column))))))) = args push_scope(ScopeData::Scope::TYPE_BLOCK, 'block', line, column, false) process(args) process(rest) pop_scope end |
#on_ident(name, line, column) ⇒ Object
ident is something that gets processed at parameters to a function or block
165 166 167 |
# File 'lib/ruby_language_server/scope_parser.rb', line 165 def on_ident(name, ((line, column))) add_variable(name, line, column) end |
#on_method_add_arg(call, args) ⇒ Object
The on_method_add_arg function is downright stolen from RipperTags github.com/tmm1/ripper-tags/blob/master/lib/ripper-tags/parser.rb
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/ruby_language_server/scope_parser.rb', line 200 def on_method_add_arg(call, args) call_name = call && call[0] first_arg = args && args[0] == :args && args[1] if call_name == :call && first_arg if args.length == 2 # augment call if a single argument was used call = call.dup call[3] = args[1] end call elsif call_name == :fcall && first_arg name, line = call[1] case name when 'alias_method' # this is an fcall [:alias, args[1][0], args[2][0], line] if args[1] && args[2] when 'define_method' # this is an fcall [:def, args[1][0], line] when 'public_class_method', 'private_class_method', 'private', 'public', 'protected' access = name.sub('_class_method', '') if args[1][1] == 'self' klass = 'self' method_name = args[1][2] else klass = nil method_name = args[1][1] end [:def_with_access, klass, method_name, access, line] end end end |
#on_method_add_block(args, rest) ⇒ Object
110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/ruby_language_server/scope_parser.rb', line 110 def on_method_add_block(args, rest) scope = @current_scope process(args) process(rest) # add_scope(args, rest, ScopeData::Scope::TYPE_BLOCK) unless @current_scope == scope scope.bottom_line = [scope&.bottom_line, @current_scope.bottom_line].compact.max scope.save! pop_scope end end |
#on_mlhs(args, rest) ⇒ Object
Multiple left hand side (foo, bar) = somethingg…
159 160 161 162 |
# File 'lib/ruby_language_server/scope_parser.rb', line 159 def on_mlhs(args, rest) process(args) process(rest) end |
#on_module(args, rest) ⇒ Object
93 94 95 96 |
# File 'lib/ruby_language_server/scope_parser.rb', line 93 def on_module(args, rest) scope = add_scope(args.last, rest, ScopeData::Scope::TYPE_MODULE) assign_subclass(scope, rest) end |
#on_params(args, rest) ⇒ Object
169 170 171 172 |
# File 'lib/ruby_language_server/scope_parser.rb', line 169 def on_params(args, rest) process(args) process(rest) end |
#on_program(args, _rest) ⇒ Object
73 74 75 |
# File 'lib/ruby_language_server/scope_parser.rb', line 73 def on_program(args, _rest) process(args) end |
#on_sclass(_args, rest) ⇒ Object
63 64 65 |
# File 'lib/ruby_language_server/scope_parser.rb', line 63 def on_sclass(_args, rest) process(rest) end |
#on_var_field(args, rest) ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/ruby_language_server/scope_parser.rb', line 77 def on_var_field(args, rest) (_, name, (line, column)) = args return if name.nil? if name.start_with?('@') add_ivar(name, line, column) else add_variable(name, line, column) end process(rest) end |
#on_var_ref(_args, _rest) ⇒ Object
Used only to describe subclasses? – nope
136 137 138 139 140 |
# File 'lib/ruby_language_server/scope_parser.rb', line 136 def on_var_ref(_args, _rest) # [:@const, "Bar", [13, 20]] # (_, name) = args # @current_scope.set_superclass_name(name) end |
#on_vcall(_args, rest) ⇒ Object
foo = bar – bar is in the vcall. Pretty sure we don’t want to remember this.
68 69 70 71 |
# File 'lib/ruby_language_server/scope_parser.rb', line 68 def on_vcall(_args, rest) # Seriously - discard args. Maybe process rest? process(rest) end |
#process(sexp) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/ruby_language_server/scope_parser.rb', line 36 def process(sexp) return if sexp.nil? root, args, *rest = sexp # RubyLanguageServer.logger.error("Doing #{[root, args, rest]}") case root when Array sexp.each { |child| process(child) } when Symbol root = root.to_s.gsub(/^@+/, '') method_name = "on_#{root}" if respond_to? method_name send(method_name, args, rest) else RubyLanguageServer.logger.debug("We don't have a #{method_name} with #{args}") process(args) end when String # We really don't do anything with it! RubyLanguageServer.logger.debug("We don't do Strings like #{root} with #{args}") when NilClass, FalseClass process(args) else RubyLanguageServer.logger.warn("We don't respond to the likes of #{root} of class #{root.class}") end end |
#root_scope ⇒ Object
27 28 29 30 31 32 33 34 |
# File 'lib/ruby_language_server/scope_parser.rb', line 27 def root_scope return @root_scope unless @root_scope.nil? @root_scope = ScopeData::Scope.where(path: nil, class_type: ScopeData::Scope::TYPE_ROOT).first_or_create! @current_scope = @root_scope process(@sexp) @root_scope end |