Module: Solargraph::YardMap::Directives::VisibilityDirective

Defined in:
lib/solargraph/yard_map/directives/visibility_directive.rb

Constant Summary collapse

VALID_VISIBILITIES =
%i[public protected private].freeze

Class Method Summary collapse

Class Method Details

.closure_at(pins, position) ⇒ Pin::Closure

Parameters:

Returns:



64
65
66
# File 'lib/solargraph/yard_map/directives/visibility_directive.rb', line 64

def closure_at pins, position
  pins.select { |pin| pin.is_a?(Pin::Closure) and pin.location&.range&.contain?(position) }.last
end

.no_empty_lines?(code, line1, line2) ⇒ Boolean

@sg-ignore return type could not be inferred

Parameters:

  • code (String)
  • line1 (Integer)
  • line2 (Integer)

Returns:

  • (Boolean)


56
57
58
59
# File 'lib/solargraph/yard_map/directives/visibility_directive.rb', line 56

def no_empty_lines? code, line1, line2
  # @sg-ignore unresolved call none? on the array.
  code.lines[line1..line2].none? { |line| line.strip.empty? }
end

.process_directive(source, pins, source_position, comment_position, directive) ⇒ Array<Solargraph::Pin::Base>

Parameters:

Returns:



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/solargraph/yard_map/directives/visibility_directive.rb', line 17

def process_directive source, pins, source_position, comment_position, directive
  kind = directive.tag.text&.to_sym

  # @sg-ignore include? only expects Symbol, but receives Symbol or nil
  return [] unless VALID_VISIBILITIES.include?(kind.to_sym)

  name = directive.tag.name
  closure = closure_at(pins, source_position) || pins.first
  closure = closure_at(pins, comment_position) if closure.location&.range&.start&.line&.< comment_position.line # rubocop:disable Style/SafeNavigationChainLength
  if closure.is_a?(Pin::Method) && no_empty_lines?(source.code, comment_position.line, source_position.line)
    # @todo Smelly instance variable access
    closure.instance_variable_set(:@visibility, kind)
  else
    namespace = closure_at(pins, source_position)
    matches = pins.select do |pin|
      if pin.is_a?(Pin::Method) &&
         pin.name == name &&
         pin.namespace == namespace &&
         pin.context.scope == namespace.is_a?(Pin::Singleton)
        :class
      else
        :instance
      end
    end

    matches.each do |pin|
      # @todo Smelly instance variable access
      pin.instance_variable_set(:@visibility, kind)
    end
  end

  []
end