typeprof 0.21.11 → 0.30.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +15 -31
- data/bin/typeprof +5 -0
- data/doc/doc.ja.md +134 -0
- data/doc/doc.md +136 -0
- data/lib/typeprof/cli/cli.rb +178 -0
- data/lib/typeprof/cli.rb +3 -133
- data/lib/typeprof/code_range.rb +112 -0
- data/lib/typeprof/core/ast/base.rb +263 -0
- data/lib/typeprof/core/ast/call.rb +259 -0
- data/lib/typeprof/core/ast/const.rb +126 -0
- data/lib/typeprof/core/ast/control.rb +433 -0
- data/lib/typeprof/core/ast/meta.rb +150 -0
- data/lib/typeprof/core/ast/method.rb +339 -0
- data/lib/typeprof/core/ast/misc.rb +263 -0
- data/lib/typeprof/core/ast/module.rb +123 -0
- data/lib/typeprof/core/ast/pattern.rb +140 -0
- data/lib/typeprof/core/ast/sig_decl.rb +471 -0
- data/lib/typeprof/core/ast/sig_type.rb +663 -0
- data/lib/typeprof/core/ast/value.rb +319 -0
- data/lib/typeprof/core/ast/variable.rb +315 -0
- data/lib/typeprof/core/ast.rb +472 -0
- data/lib/typeprof/core/builtin.rb +146 -0
- data/lib/typeprof/core/env/method.rb +137 -0
- data/lib/typeprof/core/env/method_entity.rb +55 -0
- data/lib/typeprof/core/env/module_entity.rb +408 -0
- data/lib/typeprof/core/env/static_read.rb +155 -0
- data/lib/typeprof/core/env/type_alias_entity.rb +27 -0
- data/lib/typeprof/core/env/value_entity.rb +32 -0
- data/lib/typeprof/core/env.rb +366 -0
- data/lib/typeprof/core/graph/box.rb +998 -0
- data/lib/typeprof/core/graph/change_set.rb +224 -0
- data/lib/typeprof/core/graph/filter.rb +155 -0
- data/lib/typeprof/core/graph/vertex.rb +225 -0
- data/lib/typeprof/core/service.rb +514 -0
- data/lib/typeprof/core/type.rb +352 -0
- data/lib/typeprof/core/util.rb +81 -0
- data/lib/typeprof/core.rb +31 -0
- data/lib/typeprof/diagnostic.rb +35 -0
- data/lib/typeprof/lsp/messages.rb +415 -0
- data/lib/typeprof/lsp/server.rb +203 -0
- data/lib/typeprof/lsp/text.rb +69 -0
- data/lib/typeprof/lsp/util.rb +51 -0
- data/lib/typeprof/lsp.rb +4 -907
- data/lib/typeprof/version.rb +1 -1
- data/lib/typeprof.rb +4 -18
- data/typeprof.gemspec +5 -7
- metadata +47 -33
- data/.github/dependabot.yml +0 -6
- data/.github/workflows/main.yml +0 -39
- data/.gitignore +0 -9
- data/Gemfile +0 -17
- data/Gemfile.lock +0 -41
- data/Rakefile +0 -10
- data/exe/typeprof +0 -10
- data/lib/typeprof/analyzer.rb +0 -2598
- data/lib/typeprof/arguments.rb +0 -414
- data/lib/typeprof/block.rb +0 -176
- data/lib/typeprof/builtin.rb +0 -893
- data/lib/typeprof/code-range.rb +0 -177
- data/lib/typeprof/config.rb +0 -158
- data/lib/typeprof/container-type.rb +0 -912
- data/lib/typeprof/export.rb +0 -589
- data/lib/typeprof/import.rb +0 -852
- data/lib/typeprof/insns-def.rb +0 -65
- data/lib/typeprof/iseq.rb +0 -864
- data/lib/typeprof/method.rb +0 -355
- data/lib/typeprof/type.rb +0 -1140
- data/lib/typeprof/utils.rb +0 -212
- data/tools/coverage.rb +0 -14
- data/tools/setup-insns-def.rb +0 -30
- data/typeprof-lsp +0 -3
@@ -0,0 +1,137 @@
|
|
1
|
+
module TypeProf::Core
|
2
|
+
class FormalArguments
|
3
|
+
def initialize(req_positionals, opt_positionals, rest_positionals, post_positionals, req_keywords, opt_keywords, rest_keywords, block)
|
4
|
+
@req_positionals = req_positionals
|
5
|
+
@opt_positionals = opt_positionals
|
6
|
+
@rest_positionals = rest_positionals
|
7
|
+
@post_positionals = post_positionals
|
8
|
+
@req_keywords = req_keywords
|
9
|
+
@opt_keywords = opt_keywords
|
10
|
+
@rest_keywords = rest_keywords
|
11
|
+
@block = block
|
12
|
+
end
|
13
|
+
|
14
|
+
Empty = FormalArguments.new([], [], nil, [], [], [], nil, nil)
|
15
|
+
|
16
|
+
attr_reader :req_positionals
|
17
|
+
attr_reader :opt_positionals
|
18
|
+
attr_reader :rest_positionals
|
19
|
+
attr_reader :post_positionals
|
20
|
+
attr_reader :req_keywords
|
21
|
+
attr_reader :opt_keywords
|
22
|
+
attr_reader :rest_keywords
|
23
|
+
attr_reader :block
|
24
|
+
end
|
25
|
+
|
26
|
+
class ActualArguments
|
27
|
+
def initialize(positionals, splat_flags, keywords, block)
|
28
|
+
@positionals = positionals
|
29
|
+
@splat_flags = splat_flags
|
30
|
+
@keywords = keywords
|
31
|
+
@block = block
|
32
|
+
end
|
33
|
+
|
34
|
+
attr_reader :positionals, :splat_flags, :keywords, :block
|
35
|
+
|
36
|
+
def new_vertexes(genv, node)
|
37
|
+
positionals = @positionals.map {|arg| arg.new_vertex(genv, node) }
|
38
|
+
splat_flags = @splat_flags
|
39
|
+
keywords = @keywords ? @keywords.new_vertex(genv, node) : nil
|
40
|
+
block = @block ? @block.new_vertex(genv, node) : nil
|
41
|
+
ActualArguments.new(positionals, splat_flags, keywords, block)
|
42
|
+
end
|
43
|
+
|
44
|
+
def get_rest_args(genv, start_rest, end_rest)
|
45
|
+
vtxs = []
|
46
|
+
|
47
|
+
start_rest.upto(end_rest - 1) do |i|
|
48
|
+
a_arg = @positionals[i]
|
49
|
+
if @splat_flags[i]
|
50
|
+
a_arg.each_type do |ty|
|
51
|
+
ty = ty.base_type(genv)
|
52
|
+
if ty.is_a?(Type::Instance) && ty.mod == genv.mod_ary && ty.args[0]
|
53
|
+
vtxs << ty.args[0].new_vertex(genv, self)
|
54
|
+
else
|
55
|
+
"???"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
else
|
59
|
+
vtxs << a_arg
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
vtxs.uniq
|
64
|
+
end
|
65
|
+
|
66
|
+
def get_keyword_arg(genv, changes, name)
|
67
|
+
vtx = Vertex.new(self)
|
68
|
+
@keywords.each_type do |ty|
|
69
|
+
case ty
|
70
|
+
when Type::Hash
|
71
|
+
changes.add_edge(genv, ty.get_value(name), vtx)
|
72
|
+
when Type::Instance
|
73
|
+
if ty.mod == genv.mod_hash
|
74
|
+
changes.add_edge(genv, ty.args[1], vtx)
|
75
|
+
end
|
76
|
+
else
|
77
|
+
# what to do?
|
78
|
+
end
|
79
|
+
end
|
80
|
+
vtx
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class Block
|
85
|
+
def initialize(node, f_ary_arg, f_args, next_boxes)
|
86
|
+
@node = node
|
87
|
+
@f_ary_arg = f_ary_arg
|
88
|
+
@f_args = f_args
|
89
|
+
@next_boxes = next_boxes
|
90
|
+
end
|
91
|
+
|
92
|
+
attr_reader :node, :f_args, :ret
|
93
|
+
|
94
|
+
def accept_args(genv, changes, caller_positionals, caller_ret, ret_check)
|
95
|
+
if caller_positionals.size == 1 && @f_args.size >= 2
|
96
|
+
# TODO: support splat "do |a, *b, c|"
|
97
|
+
changes.add_edge(genv, caller_positionals[0].new_vertex(genv, @node), @f_ary_arg)
|
98
|
+
else
|
99
|
+
caller_positionals.zip(@f_args) do |a_arg, f_arg|
|
100
|
+
changes.add_edge(genv, a_arg, f_arg) if f_arg
|
101
|
+
end
|
102
|
+
end
|
103
|
+
if ret_check
|
104
|
+
@next_boxes.each do |box|
|
105
|
+
changes.add_edge(genv, caller_ret, box.f_ret)
|
106
|
+
end
|
107
|
+
else
|
108
|
+
@next_boxes.each do |box|
|
109
|
+
changes.add_edge(genv, box.a_ret, caller_ret)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
class RecordBlock
|
116
|
+
def initialize(node)
|
117
|
+
@node = node
|
118
|
+
@used = false
|
119
|
+
@f_args = []
|
120
|
+
@ret = Vertex.new(node)
|
121
|
+
end
|
122
|
+
|
123
|
+
def get_f_arg(i)
|
124
|
+
@f_args[i] ||= Vertex.new(@node)
|
125
|
+
end
|
126
|
+
|
127
|
+
attr_reader :node, :f_args, :ret, :used
|
128
|
+
|
129
|
+
def accept_args(genv, changes, caller_positionals, caller_ret, ret_check)
|
130
|
+
@used = true
|
131
|
+
caller_positionals.each_with_index do |a_arg, i|
|
132
|
+
changes.add_edge(genv, a_arg.new_vertex(genv, @node), get_f_arg(i))
|
133
|
+
end
|
134
|
+
changes.add_edge(genv, caller_ret, @ret)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module TypeProf::Core
|
2
|
+
class MethodEntity
|
3
|
+
def initialize
|
4
|
+
@builtin = nil
|
5
|
+
@decls = Set[]
|
6
|
+
@defs = Set[]
|
7
|
+
@aliases = {}
|
8
|
+
@method_call_boxes = Set[]
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :decls, :defs, :aliases, :method_call_boxes
|
12
|
+
attr_accessor :builtin
|
13
|
+
|
14
|
+
def add_decl(decl)
|
15
|
+
@decls << decl
|
16
|
+
end
|
17
|
+
|
18
|
+
def remove_decl(decl)
|
19
|
+
@decls.delete(decl) || raise
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_def(mdef)
|
23
|
+
@defs << mdef
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def remove_def(mdef)
|
28
|
+
@defs.delete(mdef) || raise
|
29
|
+
end
|
30
|
+
|
31
|
+
def add_alias(node, old_mid)
|
32
|
+
@aliases[node] = old_mid
|
33
|
+
end
|
34
|
+
|
35
|
+
def remove_alias(node)
|
36
|
+
@aliases.delete(node) || raise
|
37
|
+
end
|
38
|
+
|
39
|
+
def exist?
|
40
|
+
@builtin || !@decls.empty? || !@defs.empty?
|
41
|
+
end
|
42
|
+
|
43
|
+
def add_run_all_mdefs(genv)
|
44
|
+
@defs.each do |mdef|
|
45
|
+
genv.add_run(mdef)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def add_run_all_method_call_boxes(genv)
|
50
|
+
@method_call_boxes.each do |box|
|
51
|
+
genv.add_run(box)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,408 @@
|
|
1
|
+
module TypeProf::Core
|
2
|
+
class ModuleEntity
|
3
|
+
def initialize(cpath, outer_module = self)
|
4
|
+
@cpath = cpath
|
5
|
+
|
6
|
+
@module_decls = Set[]
|
7
|
+
@module_defs = Set[]
|
8
|
+
@include_decls = Set[]
|
9
|
+
@include_defs = Set[]
|
10
|
+
|
11
|
+
@inner_modules = {}
|
12
|
+
@outer_module = outer_module
|
13
|
+
|
14
|
+
# parent modules (superclass and all modules that I include)
|
15
|
+
@superclass = nil
|
16
|
+
@self_types = {}
|
17
|
+
@included_modules = {}
|
18
|
+
@basic_object = @cpath == [:BasicObject]
|
19
|
+
|
20
|
+
# child modules (subclasses and all modules that include me)
|
21
|
+
@child_modules = {}
|
22
|
+
|
23
|
+
# class Foo[X, Y, Z] < Bar[A, B, C]
|
24
|
+
@superclass_type_args = nil # A, B, C
|
25
|
+
@type_params = [] # X, Y, Z
|
26
|
+
|
27
|
+
@consts = {}
|
28
|
+
@methods = { true => {}, false => {} }
|
29
|
+
@ivars = { true => {}, false => {} }
|
30
|
+
@cvars = {}
|
31
|
+
@type_aliases = {}
|
32
|
+
|
33
|
+
@static_reads = {}
|
34
|
+
@subclass_checks = Set[]
|
35
|
+
@ivar_reads = Set[] # should be handled in @ivars ??
|
36
|
+
@cvar_reads = Set[]
|
37
|
+
end
|
38
|
+
|
39
|
+
attr_reader :cpath
|
40
|
+
attr_reader :module_decls
|
41
|
+
attr_reader :module_defs
|
42
|
+
|
43
|
+
attr_reader :inner_modules
|
44
|
+
attr_reader :outer_module
|
45
|
+
|
46
|
+
attr_reader :superclass
|
47
|
+
attr_reader :self_types
|
48
|
+
attr_reader :included_modules
|
49
|
+
attr_reader :child_modules
|
50
|
+
|
51
|
+
attr_reader :superclass_type_args
|
52
|
+
attr_reader :type_params
|
53
|
+
|
54
|
+
attr_reader :consts
|
55
|
+
attr_reader :methods
|
56
|
+
attr_reader :ivars
|
57
|
+
attr_reader :cvars
|
58
|
+
attr_reader :type_aliases
|
59
|
+
|
60
|
+
attr_reader :static_reads
|
61
|
+
attr_reader :subclass_checks
|
62
|
+
attr_reader :ivar_reads
|
63
|
+
attr_reader :cvar_reads
|
64
|
+
|
65
|
+
def module?
|
66
|
+
!@superclass && !@basic_object
|
67
|
+
end
|
68
|
+
|
69
|
+
def interface?
|
70
|
+
@cpath.last && @cpath.last.start_with?("_")
|
71
|
+
end
|
72
|
+
|
73
|
+
def get_cname
|
74
|
+
@cpath.empty? ? :Object : @cpath.last
|
75
|
+
end
|
76
|
+
|
77
|
+
def exist?
|
78
|
+
!@module_decls.empty? || !@module_defs.empty?
|
79
|
+
end
|
80
|
+
|
81
|
+
def on_inner_modules_changed(genv, changed_cname)
|
82
|
+
@child_modules.each_key do |child_mod|
|
83
|
+
child_mod.on_inner_modules_changed(genv, changed_cname)
|
84
|
+
end
|
85
|
+
if @static_reads[changed_cname]
|
86
|
+
@static_reads[changed_cname].each do |static_read|
|
87
|
+
genv.add_static_eval_queue(:static_read_changed, static_read)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def on_module_added(genv)
|
93
|
+
return if @cpath.empty?
|
94
|
+
unless exist?
|
95
|
+
genv.add_static_eval_queue(:inner_modules_changed, [@outer_module, get_cname])
|
96
|
+
end
|
97
|
+
genv.add_static_eval_queue(:parent_modules_changed, self)
|
98
|
+
end
|
99
|
+
|
100
|
+
def on_module_removed(genv)
|
101
|
+
return if @cpath.empty?
|
102
|
+
genv.add_static_eval_queue(:parent_modules_changed, self)
|
103
|
+
unless exist?
|
104
|
+
genv.add_static_eval_queue(:inner_modules_changed, [@outer_module, get_cname])
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def add_module_decl(genv, decl)
|
109
|
+
on_module_added(genv)
|
110
|
+
|
111
|
+
@module_decls << decl
|
112
|
+
|
113
|
+
if @type_params
|
114
|
+
update_type_params if @type_params != decl.params
|
115
|
+
else
|
116
|
+
@type_params = decl.params
|
117
|
+
end
|
118
|
+
|
119
|
+
if decl.is_a?(AST::SigClassNode) && !@superclass_type_args
|
120
|
+
@superclass_type_args = decl.superclass_args
|
121
|
+
end
|
122
|
+
|
123
|
+
ce = @outer_module.get_const(get_cname)
|
124
|
+
ce.add_decl(decl)
|
125
|
+
ce
|
126
|
+
end
|
127
|
+
|
128
|
+
def remove_module_decl(genv, decl)
|
129
|
+
@outer_module.get_const(get_cname).remove_decl(decl)
|
130
|
+
@module_decls.delete(decl) || raise
|
131
|
+
|
132
|
+
update_type_params if @type_params == decl.params
|
133
|
+
if decl.is_a?(AST::SigClassNode) && @superclass_type_args == decl.superclass_args
|
134
|
+
@superclass_type_args = nil
|
135
|
+
@module_decls.each do |decl|
|
136
|
+
if decl.superclass_args
|
137
|
+
@superclass_type_args = decl.superclass_args
|
138
|
+
break
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
on_module_removed(genv)
|
144
|
+
end
|
145
|
+
|
146
|
+
def update_type_params
|
147
|
+
@type_params = nil
|
148
|
+
@module_decls.each do |decl|
|
149
|
+
params = decl.params
|
150
|
+
next unless params
|
151
|
+
if @type_params
|
152
|
+
@type_params = params if (@type_params <=> params) > 0
|
153
|
+
else
|
154
|
+
@type_params = params
|
155
|
+
end
|
156
|
+
end
|
157
|
+
@type_params ||= []
|
158
|
+
# TODO: report an error if there are multiple inconsistent declarations
|
159
|
+
end
|
160
|
+
|
161
|
+
def add_module_def(genv, node)
|
162
|
+
on_module_added(genv)
|
163
|
+
@module_defs << node
|
164
|
+
ce = @outer_module.get_const(get_cname)
|
165
|
+
ce.add_def(node)
|
166
|
+
ce
|
167
|
+
end
|
168
|
+
|
169
|
+
def remove_module_def(genv, node)
|
170
|
+
@outer_module.get_const(get_cname).remove_def(node)
|
171
|
+
@module_defs.delete(node) || raise
|
172
|
+
on_module_removed(genv)
|
173
|
+
end
|
174
|
+
|
175
|
+
def add_include_decl(genv, node)
|
176
|
+
@include_decls << node
|
177
|
+
genv.add_static_eval_queue(:parent_modules_changed, self)
|
178
|
+
end
|
179
|
+
|
180
|
+
def remove_include_decl(genv, node)
|
181
|
+
@include_decls.delete(node) || raise
|
182
|
+
genv.add_static_eval_queue(:parent_modules_changed, self)
|
183
|
+
end
|
184
|
+
|
185
|
+
def add_include_def(genv, node)
|
186
|
+
@include_defs << node
|
187
|
+
genv.add_static_eval_queue(:parent_modules_changed, self)
|
188
|
+
end
|
189
|
+
|
190
|
+
def remove_include_def(genv, node)
|
191
|
+
@include_defs.delete(node) || raise
|
192
|
+
genv.add_static_eval_queue(:parent_modules_changed, self)
|
193
|
+
end
|
194
|
+
|
195
|
+
def update_parent(genv, origin, old_parent, new_parent_cpath)
|
196
|
+
new_parent = new_parent_cpath ? genv.resolve_cpath(new_parent_cpath) : nil
|
197
|
+
if old_parent != new_parent
|
198
|
+
# check circular inheritance
|
199
|
+
mod = new_parent
|
200
|
+
while mod
|
201
|
+
if mod == self
|
202
|
+
# TODO: report an "circular inheritance" error
|
203
|
+
new_parent = nil
|
204
|
+
break
|
205
|
+
end
|
206
|
+
mod = mod.superclass
|
207
|
+
end
|
208
|
+
|
209
|
+
if old_parent != new_parent
|
210
|
+
if old_parent
|
211
|
+
set = old_parent.child_modules[self]
|
212
|
+
set.delete(origin)
|
213
|
+
old_parent.child_modules.delete(self) if set.empty?
|
214
|
+
end
|
215
|
+
if new_parent
|
216
|
+
set = new_parent.child_modules[self] ||= Set[]
|
217
|
+
set << origin
|
218
|
+
end
|
219
|
+
return [new_parent, true]
|
220
|
+
end
|
221
|
+
end
|
222
|
+
return [new_parent, false]
|
223
|
+
end
|
224
|
+
|
225
|
+
def find_superclass_const_read
|
226
|
+
return nil if @basic_object
|
227
|
+
|
228
|
+
if @module_decls.empty?
|
229
|
+
@module_defs.each do |mdef|
|
230
|
+
case mdef
|
231
|
+
when AST::ClassNode
|
232
|
+
if mdef.superclass_cpath
|
233
|
+
const_read = mdef.superclass_cpath.static_ret
|
234
|
+
return const_read ? const_read.cpath : []
|
235
|
+
end
|
236
|
+
when AST::SingletonClassNode
|
237
|
+
next
|
238
|
+
when AST::ModuleNode
|
239
|
+
return nil
|
240
|
+
else
|
241
|
+
raise
|
242
|
+
end
|
243
|
+
end
|
244
|
+
else
|
245
|
+
@module_decls.each do |mdecl|
|
246
|
+
case mdecl
|
247
|
+
when AST::SigClassNode
|
248
|
+
if mdecl.superclass_cpath
|
249
|
+
const_read = mdecl.static_ret[:superclass_cpath].last
|
250
|
+
return const_read ? const_read.cpath : []
|
251
|
+
end
|
252
|
+
when AST::SigModuleNode, AST::SigInterfaceNode
|
253
|
+
return nil
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
return []
|
259
|
+
end
|
260
|
+
|
261
|
+
def on_parent_modules_changed(genv)
|
262
|
+
any_updated = false
|
263
|
+
|
264
|
+
unless @basic_object
|
265
|
+
new_superclass_cpath = find_superclass_const_read
|
266
|
+
|
267
|
+
new_superclass, updated = update_parent(genv, :superclass, @superclass, new_superclass_cpath)
|
268
|
+
if updated
|
269
|
+
@superclass = new_superclass
|
270
|
+
any_updated = true
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
@module_decls.each do |mdecl|
|
275
|
+
case mdecl
|
276
|
+
when AST::SigModuleNode
|
277
|
+
mdecl.static_ret[:self_types].each_with_index do |const_reads, i|
|
278
|
+
key = [mdecl, i]
|
279
|
+
new_parent_cpath = const_reads.last.cpath
|
280
|
+
new_self_type, updated = update_parent(genv, key, @self_types[key], new_parent_cpath)
|
281
|
+
if updated
|
282
|
+
if new_self_type
|
283
|
+
@self_types[key] = new_self_type
|
284
|
+
else
|
285
|
+
@self_types.delete(key) || raise
|
286
|
+
end
|
287
|
+
any_updated = true
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
@self_types.delete_if do |(origin_mdecl, origin_idx), old_mod|
|
293
|
+
if @module_decls.include?(origin_mdecl)
|
294
|
+
false
|
295
|
+
else
|
296
|
+
_new_self_type, updated = update_parent(genv, [origin_mdecl, origin_idx], old_mod, nil)
|
297
|
+
any_updated ||= updated
|
298
|
+
true
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
@include_decls.each do |idecl|
|
303
|
+
new_parent_cpath = idecl.static_ret.last.cpath
|
304
|
+
new_parent, updated = update_parent(genv, idecl, @included_modules[idecl], new_parent_cpath)
|
305
|
+
if updated
|
306
|
+
if new_parent
|
307
|
+
@included_modules[idecl] = new_parent
|
308
|
+
else
|
309
|
+
@included_modules.delete(idecl) || raise
|
310
|
+
end
|
311
|
+
any_updated = true
|
312
|
+
end
|
313
|
+
end
|
314
|
+
@include_defs.each do |idef|
|
315
|
+
new_parent_cpath = idef.static_ret ? idef.static_ret.cpath : nil
|
316
|
+
new_parent, updated = update_parent(genv, idef, @included_modules[idef], new_parent_cpath)
|
317
|
+
if updated
|
318
|
+
if new_parent
|
319
|
+
@included_modules[idef] = new_parent
|
320
|
+
else
|
321
|
+
@included_modules.delete(idef) || raise
|
322
|
+
end
|
323
|
+
any_updated = true
|
324
|
+
end
|
325
|
+
end
|
326
|
+
@included_modules.delete_if do |origin, old_mod|
|
327
|
+
if @include_decls.include?(origin) || @include_defs.include?(origin)
|
328
|
+
false
|
329
|
+
else
|
330
|
+
_new_parent, updated = update_parent(genv, origin, old_mod, nil)
|
331
|
+
any_updated ||= updated
|
332
|
+
true
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
if any_updated
|
337
|
+
@subclass_checks.each do |mcall_box|
|
338
|
+
genv.add_run(mcall_box)
|
339
|
+
end
|
340
|
+
on_ancestors_updated(genv, nil)
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
def on_ancestors_updated(genv, base_mod)
|
345
|
+
@child_modules.each_key {|child_mod| child_mod.on_ancestors_updated(genv, base_mod || self) }
|
346
|
+
@static_reads.each_value do |static_reads|
|
347
|
+
static_reads.each do |static_read|
|
348
|
+
genv.add_static_eval_queue(:static_read_changed, static_read)
|
349
|
+
end
|
350
|
+
end
|
351
|
+
@methods.each do |_, methods|
|
352
|
+
methods.each_value do |me|
|
353
|
+
me.method_call_boxes.each do |box|
|
354
|
+
genv.add_run(box)
|
355
|
+
end
|
356
|
+
end
|
357
|
+
end
|
358
|
+
@ivar_reads.each {|ivar_read| genv.add_run(ivar_read) }
|
359
|
+
@cvar_reads.each {|cvar_read| genv.add_run(cvar_read) }
|
360
|
+
end
|
361
|
+
|
362
|
+
def each_descendant(base_mod = nil, &blk)
|
363
|
+
return if base_mod == self
|
364
|
+
yield self
|
365
|
+
@child_modules.each_key do |child_mod|
|
366
|
+
child_mod.each_descendant(base_mod || self, &blk)
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
def get_const(cname)
|
371
|
+
@consts[cname] ||= ValueEntity.new
|
372
|
+
end
|
373
|
+
|
374
|
+
def get_method(singleton, mid)
|
375
|
+
@methods[singleton][mid] ||= MethodEntity.new
|
376
|
+
end
|
377
|
+
|
378
|
+
def get_ivar(singleton, name)
|
379
|
+
@ivars[singleton][name] ||= ValueEntity.new
|
380
|
+
end
|
381
|
+
|
382
|
+
def get_cvar(name)
|
383
|
+
@cvars[name] ||= ValueEntity.new
|
384
|
+
end
|
385
|
+
|
386
|
+
def get_type_alias(name)
|
387
|
+
@type_aliases[name] ||= TypeAliasEntity.new
|
388
|
+
end
|
389
|
+
|
390
|
+
def get_vertexes(vtxs)
|
391
|
+
@inner_modules.each_value do |mod|
|
392
|
+
next if self.equal?(mod) # for Object
|
393
|
+
mod.get_vertexes(vtxs)
|
394
|
+
end
|
395
|
+
@consts.each_value do |cdef|
|
396
|
+
vtxs << cdef.vtx
|
397
|
+
end
|
398
|
+
end
|
399
|
+
|
400
|
+
def show_cpath
|
401
|
+
@cpath.empty? ? "Object" : @cpath.join("::" )
|
402
|
+
end
|
403
|
+
|
404
|
+
def pretty_print(q)
|
405
|
+
q.text "#<ModuleEntity[::#{ @cpath.empty? ? "Object" : @cpath.join("::") }]>"
|
406
|
+
end
|
407
|
+
end
|
408
|
+
end
|