summaryrefslogtreecommitdiff
path: root/lib/syntax_suggest/lex_value.rb
blob: 008cc105b5398c2545804cb7f80353974c17cc5a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# frozen_string_literal: true

module SyntaxSuggest
  # Value object for accessing lex values
  #
  # This lex:
  #
  #   [1, 0], :on_ident, "describe", CMDARG
  #
  # Would translate into:
  #
  #  lex.line # => 1
  #  lex.type # => :on_indent
  #  lex.token # => "describe"
  class LexValue
    attr_reader :line, :type, :token, :state

    def initialize(line, type, token, state, last_lex = nil)
      @line = line
      @type = type
      @token = token
      @state = state

      set_kw_end(last_lex)
    end

    private def set_kw_end(last_lex)
      @is_end = false
      @is_kw = false
      return if type != :on_kw
      #
      return if last_lex && last_lex.fname? # https://github.com/ruby/ruby/commit/776759e300e4659bb7468e2b97c8c2d4359a2953

      case token
      when "if", "unless", "while", "until"
        # Only count if/unless when it's not a "trailing" if/unless
        # https://github.com/ruby/ruby/blob/06b44f819eb7b5ede1ff69cecb25682b56a1d60c/lib/irb/ruby-lex.rb#L374-L375
        @is_kw = true unless expr_label?
      when "def", "case", "for", "begin", "class", "module", "do"
        @is_kw = true
      when "end"
        @is_end = true
      end
    end

    def fname?
      state.allbits?(Ripper::EXPR_FNAME)
    end

    def ignore_newline?
      type == :on_ignored_nl
    end

    def is_end?
      @is_end
    end

    def is_kw?
      @is_kw
    end

    def expr_beg?
      state.anybits?(Ripper::EXPR_BEG)
    end

    def expr_label?
      state.allbits?(Ripper::EXPR_LABEL)
    end
  end
end