module rapid_type_analysis
import semantize
+private import explain_assert_api
import csv # for live_types_to_csv
private import ordered_tree # for live_methods_to_tree
# live_methods to determine new methoddefs to visit
var live_types = new HashSet[MClassType]
- # The pool of undesolved live types
+ # The pool of unresolved live types
# They are globally resolved at the end of the analaysis
var live_open_types = new HashSet[MClassType]
add_cast(paramtype)
end
+ if mmethoddef.is_abstract then continue
+
var npropdef = modelbuilder.mpropdef2node(mmethoddef)
if npropdef isa AClassdef then
if not ot.can_resolve_for(t, t, mainmodule) then continue
var rt = ot.anchor_to(mainmodule, t)
if live_types.has(rt) then continue
+ if not rt.is_legal_in(mainmodule) then continue
if not check_depth(rt) then continue
#print "{ot}/{t} -> {rt}"
live_types.add(rt)
- todo_types.add(rt)
+ # unshift means a deep-first visit.
+ # So that the `check_depth` limit is reached sooner.
+ todo_types.unshift(rt)
end
end
#print "MType {live_types.length}: {live_types.join(", ")}"
for t in live_types do
if not ot.can_resolve_for(t, t, mainmodule) then continue
var rt = ot.anchor_to(mainmodule, t)
+ if not rt.is_legal_in(mainmodule) then continue
live_cast_types.add(rt)
#print " {ot}/{t} -> {rt}"
end
redef class AStringFormExpr
redef fun accept_rapid_type_visitor(v)
do
- var native = v.analysis.mainmodule.native_string_type
+ var native = v.analysis.mainmodule.c_string_type
v.add_type(native)
- var prop = v.get_method(native, "to_s_full")
+ var prop = v.get_method(native, "to_s_unsafe")
v.add_monomorphic_send(native, prop)
v.add_callsite(to_re)
v.add_callsite(ignore_case)
end
end
+redef class AAssertExpr
+ redef fun accept_rapid_type_visitor(v)
+ do
+ if can_explain_assert(v.analysis.modelbuilder) then
+ var str = explain_assert_str
+ if str != null then str.accept_rapid_type_visitor(v)
+ end
+ end
+
+ # Does `modelbuilder` know the classes to build a superstring to explain a failed assert?
+ private fun can_explain_assert(modelbuilder: ModelBuilder): Bool
+ do
+ var nas = modelbuilder.model.get_mclasses_by_name("NativeArray")
+ if nas == null then return false
+
+ nas = modelbuilder.model.get_mclasses_by_name("Array")
+ if nas == null or nas.is_empty then return false
+
+ nas = modelbuilder.model.get_mclasses_by_name("String")
+ if nas == null or nas.is_empty then return false
+
+ return true
+ end
+end
+
redef class ASendExpr
redef fun accept_rapid_type_visitor(v)
do