Class: ReplTypeCompletor::Result

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

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_candidatesObject



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
# 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) | type.constants
  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
  in [:gvar, name, scope]
    scope.global_variables
  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.sort
    end
    if key_type == Symbol
      keys = Symbol.all_symbols if keys.empty? && name.size >= 1
      filter_symbol_candidates(keys, name, limit: 100)
    else
      keys.select { _1.start_with?(name) }.sort
    end
  in [:call, name, type, self_call]
    (self_call ? type.all_methods : type.methods).map(&:to_s) - HIDDEN_METHODS
  in [:lvar_or_method, name, scope]
    scope.self_type.all_methods.map(&:to_s) | scope.local_variables | 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) ⇒ Object



100
101
102
103
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
# File 'lib/repl_type_completor/result.rb', line 100

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