Class: Kapusta::LSP::ScopeWalker

Inherits:
Object
  • Object
show all
Defined in:
lib/kapusta/lsp/scope_walker.rb

Defined Under Namespace

Classes: Binding, Reference, Scope

Constant Summary collapse

SKIPPED_HEADS =
%w[macros quasi-sym quasi-list
quasi-list-tail quasi-vec quasi-vec-tail quasi-hash quasi-gensym].freeze
DISPATCHERS =
{
  'let' => :walk_let,
  'local' => :walk_local_var,
  'var' => :walk_local_var,
  'global' => :walk_global,
  'set' => :walk_set,
  'fn' => :walk_fn,
  'lambda' => :walk_fn,
  'λ' => :walk_fn,
  'for' => :walk_for,
  'each' => :walk_each_like,
  'collect' => :walk_each_like,
  'icollect' => :walk_each_like,
  'fcollect' => :walk_for_like,
  'accumulate' => :walk_accumulate,
  'faccumulate' => :walk_faccumulate,
  'case' => :walk_case_match,
  'match' => :walk_case_match,
  'try' => :walk_try,
  'module' => :walk_module_class,
  'class' => :walk_module_class,
  'hashfn' => :walk_hashfn,
  'macro' => :walk_macro_def,
  'import-macros' => :walk_import_macros,
  'ivar' => :walk_sigil_form,
  'cvar' => :walk_sigil_form,
  'gvar' => :walk_sigil_form
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeScopeWalker

Returns a new instance of ScopeWalker.



59
60
61
62
63
64
65
66
67
# File 'lib/kapusta/lsp/scope_walker.rb', line 59

def initialize
  @bindings = []
  @references = []
  @scope_seq = 0
  @root_scope = make_scope(nil, :file)
  @gvar_scope = make_scope(nil, :gvars)
  @in_module_or_class = 0
  @sigil_scope_stack = [make_sigil_scopes]
end

Instance Attribute Details

#bindingsObject (readonly)

Returns the value of attribute bindings.



51
52
53
# File 'lib/kapusta/lsp/scope_walker.rb', line 51

def bindings
  @bindings
end

#referencesObject (readonly)

Returns the value of attribute references.



51
52
53
# File 'lib/kapusta/lsp/scope_walker.rb', line 51

def references
  @references
end

#root_scopeObject (readonly)

Returns the value of attribute root_scope.



51
52
53
# File 'lib/kapusta/lsp/scope_walker.rb', line 51

def root_scope
  @root_scope
end

Class Method Details

.analyze(forms) ⇒ Object



53
54
55
56
57
# File 'lib/kapusta/lsp/scope_walker.rb', line 53

def self.analyze(forms)
  walker = new
  walker.walk_top(forms)
  walker
end

Instance Method Details

#binding_at(line, column) ⇒ Object



83
84
85
86
87
88
# File 'lib/kapusta/lsp/scope_walker.rb', line 83

def binding_at(line, column)
  @bindings.each do |b|
    return b if b.line == line && column >= b.column && column <= b.end_column
  end
  nil
end

#reference_at(line, column) ⇒ Object



90
91
92
93
94
95
# File 'lib/kapusta/lsp/scope_walker.rb', line 90

def reference_at(line, column)
  @references.each do |r|
    return r if r.line == line && column >= r.column && column <= r.end_column
  end
  nil
end

#sym_at(line, column) ⇒ Object



97
98
99
# File 'lib/kapusta/lsp/scope_walker.rb', line 97

def sym_at(line, column)
  binding_at(line, column) || reference_at(line, column)
end

#walk_top(forms) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/kapusta/lsp/scope_walker.rb', line 69

def walk_top(forms)
  i = 0
  while i < forms.length
    form = forms[i]
    if bodyless_header?(form)
      walk_bodyless_header(form, forms[(i + 1)..] || [], @root_scope)
      break
    end

    walk_form(form, @root_scope)
    i += 1
  end
end