Class: ReplTypeCompletor::Result

Inherits:
Object
  • Object
show all
Defined in:
lib/repl_type_completor/result.rb,
sig/repl_type_completor.rbs

Constant Summary collapse

OPERATOR_METHODS =
%w[! != !~ % & * ** + +@ - -@ / < << <= <=> == === =~ > >= >> [] []= ^ ` | ~]
HIDDEN_METHODS =
[
  # defined by RBS, should be hidden
  'Namespace', 'TypeName',
  # operator methods does not need to be completed
  *OPERATOR_METHODS
]
RESERVED_WORDS =
%w[
  __ENCODING__ __LINE__ __FILE__
  BEGIN END
  alias and
  begin break
  case class
  def defined? do
  else elsif end ensure
  false for
  if in
  module
  next nil not
  or
  redo rescue retry return
  self super
  then true
  undef unless until
  when while
  yield
]

Instance Method Summary collapse

Constructor Details

#initialize(analyze_result, binding, source_file) ⇒ Result

Returns a new instance of Result.



35
36
37
38
39
# File 'lib/repl_type_completor/result.rb', line 35

def initialize(analyze_result, binding, source_file)
  @analyze_result = analyze_result
  @binding = binding
  @source_file = source_file
end

Instance Method Details

#completion_candidatesArray[String]

Returns:

  • (Array[String])


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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/repl_type_completor/result.rb', line 41

def completion_candidates
  verbose, $VERBOSE = $VERBOSE, nil
  candidates = case @analyze_result
  in [:require, name]
    RequirePaths.require_completions(name)
  in [:require_relative, name]
    RequirePaths.require_relative_completions(name, @source_file)
  in [:call_or_const, name, type, self_call]
    ((self_call ? type.all_methods : type.methods).map(&:to_s) - HIDDEN_METHODS).sort | type.constants.sort
  in [:const, name, type, scope]
    if type
      scope_constants = type.types.flat_map do |t|
        scope.table_module_constants(t.module_or_class) if t.is_a?(Types::SingletonType)
      end
      (scope_constants.compact | type.constants.map(&:to_s)).sort
    else
      scope.constants.sort | RESERVED_WORDS
    end
  in [:ivar, name, scope]
    ivars = scope.instance_variables.sort
    name == '@' ? ivars + scope.class_variables.sort : ivars
  in [:cvar, name, scope]
    scope.class_variables.sort
  in [:gvar, name, scope]
    scope.global_variables.sort
  in [:symbol, name]
    filter_symbol_candidates(Symbol.all_symbols, name, limit: 100)
  in [:aref, key_type, name, receiver_type]
    key_type = key_type == :string ? String : Symbol
    keys = receiver_type.types.grep(Types::InstanceType).select do |t|
      Hash == t.klass
    end.flat_map do |t|
      t.instances.flat_map(&:keys).grep(key_type).uniq
    end
    if key_type == Symbol
      keys = Symbol.all_symbols if keys.empty? && name.size >= 1
      filter_symbol_candidates(keys, name, limit: 100)
    else
      keys.sort
    end
  in [:call, name, type, self_call]
    methods = (self_call ? type.all_methods : type.methods).map(&:to_s) - HIDDEN_METHODS
    # Alphabetical order, but internal methods (leading underscore) last.
    # `_1[0] == '_'` because `start_with?('_')` raises EncodingError if the
    # method name's encoding is incompatible with US-ASCII.
    methods.sort_by { [_1[0] == '_' ? 1 : 0, _1] }
  in [:lvar_or_method, name, scope]
    scope.local_variables.sort | scope.self_type.all_methods.map(&:to_s).sort | RESERVED_WORDS
  else
    []
  end

  candidates.filter_map do
    _1[name.size..] if _1.start_with?(name)
  rescue EncodingError
  end
rescue Exception => e
  ReplTypeCompletor.handle_exception(e)
  []
ensure
  $VERBOSE = verbose
end

#doc_namespace(matched) ⇒ String?

Parameters:

  • (String)

Returns:

  • (String, nil)


104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/repl_type_completor/result.rb', line 104

def doc_namespace(matched)
  verbose, $VERBOSE = $VERBOSE, nil
  case @analyze_result
  in [:call_or_const, prefix, type, _self_call]
    call_or_const_doc type, prefix + matched
  in [:const, prefix, type, scope]
    if type
      call_or_const_doc type, prefix + matched
    else
      value_doc scope[prefix + matched]
    end
  in [:gvar, prefix, scope]
    value_doc scope[prefix + matched]
  in [:ivar, prefix, scope]
    value_doc scope[prefix + matched]
  in [:cvar, prefix, scope]
    value_doc scope[prefix + matched]
  in [:call, prefix, type, _self_call]
    method_doc type, prefix + matched
  in [:lvar_or_method, prefix, scope]
    if scope.local_variables.include?(prefix + matched)
      value_doc scope[prefix + matched]
    else
      method_doc scope.self_type, prefix + matched
    end
  else
  end
rescue Exception => e
  ReplTypeCompletor.handle_exception(e)
  nil
ensure
  $VERBOSE = verbose
end