Class: KatakataIrb::BaseScope

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

Direct Known Subclasses

Scope

Constant Summary collapse

BREAK_RESULT =
'%break'
NEXT_RESULT =
'%next'
RETURN_RESULT =
'%return'
PATTERNMATCH_BREAK =
'%match'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(binding, self_object, local_variables) ⇒ BaseScope

Returns a new instance of BaseScope.



15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/katakata_irb/scope.rb', line 15

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] = KatakataIrb::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.



13
14
15
# File 'lib/katakata_irb/scope.rb', line 13

def module_nesting
  @module_nesting
end

#self_objectObject (readonly)

Returns the value of attribute self_object.



13
14
15
# File 'lib/katakata_irb/scope.rb', line 13

def self_object
  @self_object
end

Class Method Details

.type_by_name(name) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/katakata_irb/scope.rb', line 91

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

.type_of(fallback: KatakataIrb::Types::OBJECT) ⇒ Object



83
84
85
86
87
88
89
# File 'lib/katakata_irb/scope.rb', line 83

def self.type_of(fallback: KatakataIrb::Types::OBJECT)
  begin
    KatakataIrb::Types.type_from_object yield
  rescue
    fallback
  end
end

Instance Method Details

#[](name) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/katakata_irb/scope.rb', line 61

def [](name)
  @cache[name] ||= (
    fallback = KatakataIrb::Types::NIL
    case BaseScope.type_by_name name
    when :ivar
      BaseScope.type_of(fallback: fallback) { @self_object.instance_variable_get name }
    when :lvar
      BaseScope.type_of(fallback: fallback) { @binding.local_variable_get(name) }
    when :gvar
      BaseScope.type_of(fallback: fallback) { @binding.eval name if @global_variables.include? name }
    end
  )
end

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



40
41
42
43
44
45
46
47
48
# File 'lib/katakata_irb/scope.rb', line 40

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
  KatakataIrb::Types.type_from_object result
end

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



50
51
52
53
54
55
56
57
58
59
# File 'lib/katakata_irb/scope.rb', line 50

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

  result = path.reduce nesting do |mod, n|
    return KatakataIrb::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



81
# File 'lib/katakata_irb/scope.rb', line 81

def global_variables() = @global_variables.to_a

#levelObject



29
# File 'lib/katakata_irb/scope.rb', line 29

def level() = 0

#level_of(_name, _var_type) ⇒ Object



31
# File 'lib/katakata_irb/scope.rb', line 31

def level_of(_name, _var_type) = 0

#local_variablesObject



79
# File 'lib/katakata_irb/scope.rb', line 79

def local_variables() = @local_variables.to_a

#module_own_constant?(mod, name) ⇒ Boolean

Returns:

  • (Boolean)


35
36
37
38
# File 'lib/katakata_irb/scope.rb', line 35

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)


33
# File 'lib/katakata_irb/scope.rb', line 33

def mutable?() = false

#self_typeObject



75
76
77
# File 'lib/katakata_irb/scope.rb', line 75

def self_type
  KatakataIrb::Types.type_from_object @self_object
end