Class: TypeProf::Core::GlobalEnv

Inherits:
Object
  • Object
show all
Defined in:
lib/typeprof/core/env.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeGlobalEnv



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
# File 'lib/typeprof/core/env.rb', line 3

def initialize
  @type_table = {}

  @static_eval_queue = []

  @run_queue = []
  @run_queue_set = Set[]

  @pending_diagnostic_paths = Set[]

  @mod_object = ModuleEntity.new([])
  @mod_object.inner_modules[:Object] = @mod_object

  @mod_basic_object = resolve_cpath([:BasicObject])
  @mod_class = resolve_cpath([:Class])
  @mod_module = resolve_cpath([:Module])

  @gvars = {}
  @mod_ary = resolve_cpath([:Array])
  @mod_hash = resolve_cpath([:Hash])
  @mod_range = resolve_cpath([:Range])
  @mod_str = resolve_cpath([:String])

  @cls_type = Type::Instance.new(self, @mod_class, [])
  @mod_type = Type::Instance.new(self, @mod_module, [])
  @obj_type = Type::Instance.new(self, resolve_cpath([:Object]), [])
  @nil_type = Type::Instance.new(self, resolve_cpath([:NilClass]), [])
  @true_type = Type::Instance.new(self, resolve_cpath([:TrueClass]), [])
  @false_type = Type::Instance.new(self, resolve_cpath([:FalseClass]), [])
  @str_type = Type::Instance.new(self, resolve_cpath([:String]), [])
  @int_type = Type::Instance.new(self, resolve_cpath([:Integer]), [])
  @float_type = Type::Instance.new(self, resolve_cpath([:Float]), [])
  @rational_type = Type::Instance.new(self, resolve_cpath([:Rational]), [])
  @complex_type = Type::Instance.new(self, resolve_cpath([:Complex]), [])
  @proc_type = Type::Instance.new(self, resolve_cpath([:Proc]), [])
  @symbol_type = Type::Instance.new(self, resolve_cpath([:Symbol]), [])
  @set_type = Type::Instance.new(self, resolve_cpath([:Set]), [])
  @regexp_type = Type::Instance.new(self, resolve_cpath([:Regexp]), [])

  @run_count = 0
end

Instance Attribute Details

#cls_typeObject (readonly)

Returns the value of attribute cls_type.



48
49
50
# File 'lib/typeprof/core/env.rb', line 48

def cls_type
  @cls_type
end

#complex_typeObject (readonly)

Returns the value of attribute complex_type.



50
51
52
# File 'lib/typeprof/core/env.rb', line 50

def complex_type
  @complex_type
end

#false_typeObject (readonly)

Returns the value of attribute false_type.



49
50
51
# File 'lib/typeprof/core/env.rb', line 49

def false_type
  @false_type
end

#float_typeObject (readonly)

Returns the value of attribute float_type.



50
51
52
# File 'lib/typeprof/core/env.rb', line 50

def float_type
  @float_type
end

#int_typeObject (readonly)

Returns the value of attribute int_type.



50
51
52
# File 'lib/typeprof/core/env.rb', line 50

def int_type
  @int_type
end

#mod_aryObject (readonly)

Returns the value of attribute mod_ary.



47
48
49
# File 'lib/typeprof/core/env.rb', line 47

def mod_ary
  @mod_ary
end

#mod_classObject (readonly)

Returns the value of attribute mod_class.



47
48
49
# File 'lib/typeprof/core/env.rb', line 47

def mod_class
  @mod_class
end

#mod_hashObject (readonly)

Returns the value of attribute mod_hash.



47
48
49
# File 'lib/typeprof/core/env.rb', line 47

def mod_hash
  @mod_hash
end

#mod_objectObject (readonly)

Returns the value of attribute mod_object.



47
48
49
# File 'lib/typeprof/core/env.rb', line 47

def mod_object
  @mod_object
end

#mod_rangeObject (readonly)

Returns the value of attribute mod_range.



47
48
49
# File 'lib/typeprof/core/env.rb', line 47

def mod_range
  @mod_range
end

#mod_strObject (readonly)

Returns the value of attribute mod_str.



47
48
49
# File 'lib/typeprof/core/env.rb', line 47

def mod_str
  @mod_str
end

#mod_typeObject (readonly)

Returns the value of attribute mod_type.



48
49
50
# File 'lib/typeprof/core/env.rb', line 48

def mod_type
  @mod_type
end

#nil_typeObject (readonly)

Returns the value of attribute nil_type.



49
50
51
# File 'lib/typeprof/core/env.rb', line 49

def nil_type
  @nil_type
end

#obj_typeObject (readonly)

Returns the value of attribute obj_type.



49
50
51
# File 'lib/typeprof/core/env.rb', line 49

def obj_type
  @obj_type
end

#proc_typeObject (readonly)

Returns the value of attribute proc_type.



51
52
53
# File 'lib/typeprof/core/env.rb', line 51

def proc_type
  @proc_type
end

#rational_typeObject (readonly)

Returns the value of attribute rational_type.



50
51
52
# File 'lib/typeprof/core/env.rb', line 50

def rational_type
  @rational_type
end

#regexp_typeObject (readonly)

Returns the value of attribute regexp_type.



51
52
53
# File 'lib/typeprof/core/env.rb', line 51

def regexp_type
  @regexp_type
end

#run_countObject

Returns the value of attribute run_count.



65
66
67
# File 'lib/typeprof/core/env.rb', line 65

def run_count
  @run_count
end

#set_typeObject (readonly)

Returns the value of attribute set_type.



51
52
53
# File 'lib/typeprof/core/env.rb', line 51

def set_type
  @set_type
end

#str_typeObject (readonly)

Returns the value of attribute str_type.



49
50
51
# File 'lib/typeprof/core/env.rb', line 49

def str_type
  @str_type
end

#symbol_typeObject (readonly)

Returns the value of attribute symbol_type.



51
52
53
# File 'lib/typeprof/core/env.rb', line 51

def symbol_type
  @symbol_type
end

#true_typeObject (readonly)

Returns the value of attribute true_type.



49
50
51
# File 'lib/typeprof/core/env.rb', line 49

def true_type
  @true_type
end

#type_tableObject (readonly)

Returns the value of attribute type_table.



45
46
47
# File 'lib/typeprof/core/env.rb', line 45

def type_table
  @type_table
end

Instance Method Details

#add_diagnostic_path(path) ⇒ Object



197
198
199
# File 'lib/typeprof/core/env.rb', line 197

def add_diagnostic_path(path)
  @pending_diagnostic_paths << path unless @pending_diagnostic_paths.include?(path)
end

#add_run(obj) ⇒ Object



168
169
170
171
172
173
# File 'lib/typeprof/core/env.rb', line 168

def add_run(obj)
  unless @run_queue_set.include?(obj)
    @run_queue << obj
    @run_queue_set << obj
  end
end

#add_static_eval_queue(change_type, arg) ⇒ Object



141
142
143
# File 'lib/typeprof/core/env.rb', line 141

def add_static_eval_queue(change_type, arg)
  @static_eval_queue << [change_type, arg]
end

#define_allObject



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/typeprof/core/env.rb', line 145

def define_all
  until @static_eval_queue.empty?
    change_type, arg = @static_eval_queue.shift
    case change_type
    when :inner_modules_changed
      arg[0].on_inner_modules_changed(self, arg[1])
    when :static_read_changed
      case arg
      when BaseStaticRead
        arg.on_scope_updated(self)
      when ScopedStaticRead
        arg.on_cbase_updated(self)
      else
        raise
      end
    when :parent_modules_changed
      arg.on_parent_modules_changed(self)
    else
      raise change_type.to_s
    end
  end
end

#each_direct_superclass(mod, singleton) ⇒ Object



67
68
69
70
71
72
# File 'lib/typeprof/core/env.rb', line 67

def each_direct_superclass(mod, singleton)
  while mod
    yield mod, singleton
    singleton, mod = get_superclass(singleton, mod)
  end
end

#each_included_module(mod, &blk) ⇒ Object



87
88
89
90
91
92
# File 'lib/typeprof/core/env.rb', line 87

def each_included_module(mod, &blk)
  mod.included_modules.each do |_inc_decl, inc_mod|
    yield inc_mod, false
    each_included_module(inc_mod, &blk)
  end
end

#each_superclass(mod, singleton, &blk) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/typeprof/core/env.rb', line 74

def each_superclass(mod, singleton, &blk)
  while mod
    # TODO: prepended modules
    yield mod, singleton
    if singleton
      # TODO: extended modules
    else
      each_included_module(mod, &blk)
    end
    singleton, mod = get_superclass(singleton, mod)
  end
end

#gen_ary_type(elem_vtx) ⇒ Object



53
54
55
# File 'lib/typeprof/core/env.rb', line 53

def gen_ary_type(elem_vtx)
  Type::Instance.new(self, @mod_ary, [elem_vtx])
end

#gen_hash_type(key_vtx, val_vtx) ⇒ Object



57
58
59
# File 'lib/typeprof/core/env.rb', line 57

def gen_hash_type(key_vtx, val_vtx)
  Type::Instance.new(self, @mod_hash, [key_vtx, val_vtx])
end

#gen_range_type(elem_vtx) ⇒ Object



61
62
63
# File 'lib/typeprof/core/env.rb', line 61

def gen_range_type(elem_vtx)
  Type::Instance.new(self, @mod_range, [elem_vtx])
end

#get_instance_type(mod, type_args, changes, base_ty_env, base_ty) ⇒ Object



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/typeprof/core/env.rb', line 113

def get_instance_type(mod, type_args, changes, base_ty_env, base_ty)
  ty_env = base_ty_env.dup
  if base_ty.is_a?(Type::Instance)
    base_ty.mod.type_params.zip(base_ty.args) do |param, arg|
      ty_env[param] = arg || Source.new
    end
  elsif base_ty.is_a?(Type::Singleton)
    base_ty.mod.type_params&.each do |param|
      ty_env[param] = Source.new
    end
  end
  args = mod.type_params.zip(type_args).map do |param, arg|
    arg && changes ? arg.covariant_vertex(self, changes, ty_env) : Source.new
  end
  Type::Instance.new(self, mod, args)
end

#get_superclass(singleton, mod) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/typeprof/core/env.rb', line 94

def get_superclass(singleton, mod)
  super_mod = mod.superclass
  if super_mod
    return [singleton, super_mod]
  else
    if mod == @mod_basic_object
      if singleton
        return [false, @mod_class]
      else
        return nil
      end
    elsif mod == @mod_module && !singleton
      return nil
    else
      return [false, @mod_module]
    end
  end
end

#get_superclass_type(ty, changes, base_ty_env) ⇒ Object



130
131
132
133
134
135
136
137
138
139
# File 'lib/typeprof/core/env.rb', line 130

def get_superclass_type(ty, changes, base_ty_env)
  singleton, super_mod = get_superclass(ty.is_a?(Type::Singleton), ty.mod)
  return unless super_mod

  if singleton
    Type::Singleton.new(self, super_mod)
  else
    get_instance_type(super_mod, ty.mod.superclass_type_args || [], changes, base_ty_env, ty)
  end
end

#get_vertexes(vtxs) ⇒ Object

just for validation



202
203
204
205
206
207
# File 'lib/typeprof/core/env.rb', line 202

def get_vertexes(vtxs)
  @mod_object.get_vertexes(vtxs)
  @gvars.each_value do |gvar_entity|
    vtxs << gvar_entity.vtx
  end
end

#load_core_rbs(raw_decls) ⇒ Object



254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/typeprof/core/env.rb', line 254

def load_core_rbs(raw_decls)
  lenv = LocalEnv.new(nil, CRef::Toplevel, {}, [])
  decls = raw_decls.map do |raw_decl|
    AST.create_rbs_decl(raw_decl, lenv)
  end.compact

  decls += AST.parse_rbs("typeprof-rbs-shim.rbs", "    class Exception\n      include _Exception\n    end\n    class String\n      include _ToS\n      include _ToStr\n    end\n    class Array[Elem]\n      include _ToAry[Elem]\n      include _Each[Elem]\n    end\n    class Hash[K, V]\n      include _Each[[K, V]]\n    end\n  RBS\n\n  # Loading frequently used modules first will reduces constant resolution\n  # which makes loading faster :-)\n  critical_modules = [\n    decls.find {|decl| decl.cpath == [:Object] },\n    decls.find {|decl| decl.cpath == [:Module] },\n    decls.find {|decl| decl.cpath == [:Numeric] },\n    decls.find {|decl| decl.cpath == [:Integer] },\n    decls.find {|decl| decl.cpath == [:String] },\n    decls.find {|decl| decl.cpath == [:Array] },\n    decls.find {|decl| decl.cpath == [:Hash] },\n    decls.find {|decl| decl.cpath == [:Enumerator] },\n  ]\n  decls = critical_modules + (decls - critical_modules)\n\n  decls.each {|decl| decl.define(self) }\n  define_all\n  decls.each {|decl| decl.install(self) }\n  run_all\nend\n")

#process_diagnostic_pathsObject



188
189
190
191
192
193
194
195
# File 'lib/typeprof/core/env.rb', line 188

def process_diagnostic_paths
  processed_paths = []
  @pending_diagnostic_paths.each do |path|
    processed = yield path
    processed_paths << path if processed
  end
  processed_paths.each {|path| @pending_diagnostic_paths.delete(path) }
end

#resolve_const(cpath) ⇒ Object

constants



222
223
224
225
# File 'lib/typeprof/core/env.rb', line 222

def resolve_const(cpath)
  mod = resolve_cpath(cpath[0..-2])
  mod.get_const(cpath[-1])
end

#resolve_cpath(cpath) ⇒ Object

classes and modules



211
212
213
214
215
216
217
218
# File 'lib/typeprof/core/env.rb', line 211

def resolve_cpath(cpath)
  mod = @mod_object
  raise unless cpath # annotation
  cpath.each do |cname|
    mod = mod.inner_modules[cname] ||= ModuleEntity.new(mod.cpath + [cname], mod)
  end
  mod
end

#resolve_cvar(cpath, name) ⇒ Object



242
243
244
245
246
# File 'lib/typeprof/core/env.rb', line 242

def resolve_cvar(cpath, name)
  # TODO: include はあとで考える
  mod = resolve_cpath(cpath)
  mod.get_cvar(name)
end

#resolve_gvar(name) ⇒ Object



232
233
234
# File 'lib/typeprof/core/env.rb', line 232

def resolve_gvar(name)
  @gvars[name] ||= ValueEntity.new
end

#resolve_ivar(cpath, singleton, name) ⇒ Object



236
237
238
239
240
# File 'lib/typeprof/core/env.rb', line 236

def resolve_ivar(cpath, singleton, name)
  # TODO: include はあとで考える
  mod = resolve_cpath(cpath)
  mod.get_ivar(singleton, name)
end

#resolve_method(cpath, singleton, mid) ⇒ Object



227
228
229
230
# File 'lib/typeprof/core/env.rb', line 227

def resolve_method(cpath, singleton, mid)
  mod = resolve_cpath(cpath)
  mod.get_method(singleton, mid)
end

#resolve_type_alias(cpath, name) ⇒ Object



248
249
250
251
252
# File 'lib/typeprof/core/env.rb', line 248

def resolve_type_alias(cpath, name)
  # TODO: include はあとで考える
  mod = resolve_cpath(cpath)
  mod.get_type_alias(name)
end

#run_allObject



175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/typeprof/core/env.rb', line 175

def run_all
  run_count = 0
  until @run_queue.empty?
    obj = @run_queue.shift
    @run_queue_set.delete(obj)
    unless obj.destroyed
      run_count += 1
      obj.run(self)
    end
  end
  @run_count += run_count
end