lib/solargraph/pin/local_variable.rb
# frozen_string_literal: true module Solargraph module Pin class LocalVariable < BaseVariable # @return [Range] attr_reader :presence # @param assignment [AST::Node, nil] # @param presence [Range, nil] # @param splat [Hash] def initialize assignment: nil, presence: nil, **splat super(**splat) @assignment = assignment @presence = presence end # @param pin [self] def try_merge! pin return false unless super @presence = pin.presence true end # @param other_closure [Pin::Closure] # @param other_loc [Location] def visible_at?(other_closure, other_loc) location.filename == other_loc.filename && presence.include?(other_loc.range.start) && match_named_closure(other_closure, closure) end # @return [String] def to_rbs (name || '(anon)') + ' ' + (return_type&.to_rbs || 'untyped') end private # @param tag1 [String] # @param tag2 [String] # @return [Boolean] def match_tags tag1, tag2 # @todo This is an unfortunate hack made necessary by a discrepancy in # how tags indicate the root namespace. The long-term solution is to # standardize it, whether it's `Class<>`, an empty string, or # something else. tag1 == tag2 || (['', 'Class<>'].include?(tag1) && ['', 'Class<>'].include?(tag2)) end # @param needle [Pin::Base] # @param haystack [Pin::Base] # @return [Boolean] def match_named_closure needle, haystack return true if needle == haystack || haystack.is_a?(Pin::Block) cursor = haystack until cursor.nil? return true if needle.path == cursor.path return false if cursor.path && !cursor.path.empty? cursor = cursor.closure end false end end end end