Class: ReplTypeCompletor::RootScope

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

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(binding, self_object, local_variables) ⇒ RootScope

Returns a new instance of RootScope.



10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/repl_type_completor/scope.rb', line 10

def initialize(binding, self_object, local_variables)
  @binding = binding
  @self_object = self_object
  @cache = {}
  modules = [*binding.eval('::Module.nesting'), Object]
  @module_nesting = modules.map { [_1, []] }
  binding_local_variables = binding.local_variables
  uninitialized_locals = local_variables - binding_local_variables
  uninitialized_locals.each { @cache[_1] = Types::NIL }
  @local_variables = (local_variables | binding_local_variables).map(&:to_s).to_set
  @global_variables = Kernel.global_variables.map(&:to_s).to_set
  @owned_constants_cache = {}
end

Instance Attribute Details

#module_nestingObject (readonly)

Returns the value of attribute module_nesting.



8
9
10
# File 'lib/repl_type_completor/scope.rb', line 8

def module_nesting
  @module_nesting
end

#self_objectObject (readonly)

Returns the value of attribute self_object.



8
9
10
# File 'lib/repl_type_completor/scope.rb', line 8

def self_object
  @self_object
end

Class Method Details

.type_by_name(name) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/repl_type_completor/scope.rb', line 84

def self.type_by_name(name)
  if name.start_with? '@@'
    # "@@cvar" or "@@cvar::[module_id]::[module_path]"
    :cvar
  elsif name.start_with? '@'
    :ivar
  elsif name.start_with? '$'
    :gvar
  elsif name.start_with? '%'
    :internal
  elsif name[0].downcase != name[0] || name[0].match?(/\d/)
    # "ConstName" or "[module_id]::[const_path]"
    :const
  else
    :lvar
  end
end

Instance Method Details

#[](name) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/repl_type_completor/scope.rb', line 56

def [](name)
  @cache[name] ||= (
    value = case RootScope.type_by_name name
    when :ivar
      begin
        Methods::OBJECT_INSTANCE_VARIABLE_GET_METHOD.bind_call(@self_object, name)
      rescue NameError
      end
    when :lvar
      begin
        @binding.local_variable_get(name)
      rescue NameError
      end
    when :gvar
      @binding.eval name if @global_variables.include? name
    end
    Types.type_from_object(value)
  )
end

#get_const(nesting, path, _key = nil) ⇒ Object



35
36
37
38
39
40
41
42
43
# File 'lib/repl_type_completor/scope.rb', line 35

def get_const(nesting, path, _key = nil)
  return unless nesting

  result = path.reduce nesting do |mod, name|
    return nil unless mod.is_a?(Module) && module_own_constant?(mod, name)
    mod.const_get name
  end
  Types.type_from_object result
end

#get_cvar(nesting, path, name, _key = nil) ⇒ Object



45
46
47
48
49
50
51
52
53
54
# File 'lib/repl_type_completor/scope.rb', line 45

def get_cvar(nesting, path, name, _key = nil)
  return Types::NIL unless nesting

  result = path.reduce nesting do |mod, n|
    return Types::NIL unless mod.is_a?(Module) && module_own_constant?(mod, n)
    mod.const_get n
  end
  value = result.class_variable_get name if result.is_a?(Module) && name.size >= 3 && result.class_variable_defined?(name)
  Types.type_from_object value
end

#global_variablesObject



82
# File 'lib/repl_type_completor/scope.rb', line 82

def global_variables() = @global_variables.to_a

#levelObject



24
# File 'lib/repl_type_completor/scope.rb', line 24

def level() = 0

#level_of(_name, _var_type) ⇒ Object



26
# File 'lib/repl_type_completor/scope.rb', line 26

def level_of(_name, _var_type) = 0

#local_variablesObject



80
# File 'lib/repl_type_completor/scope.rb', line 80

def local_variables() = @local_variables.to_a

#module_own_constant?(mod, name) ⇒ Boolean

Returns:

  • (Boolean)


30
31
32
33
# File 'lib/repl_type_completor/scope.rb', line 30

def module_own_constant?(mod, name)
  set = (@owned_constants_cache[mod] ||= Set.new(mod.constants.map(&:to_s)))
  set.include? name
end

#mutable?Boolean

Returns:

  • (Boolean)


28
# File 'lib/repl_type_completor/scope.rb', line 28

def mutable?() = false

#self_typeObject



76
77
78
# File 'lib/repl_type_completor/scope.rb', line 76

def self_type
  Types.type_from_object @self_object
end