X-Git-Url: http://nitlanguage.org diff --git a/src/rapid_type_analysis.nit b/src/rapid_type_analysis.nit index bcdb6db..5b8d41b 100644 --- a/src/rapid_type_analysis.nit +++ b/src/rapid_type_analysis.nit @@ -14,7 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. - # Rapid type analysis on the AST # # Rapid type analysis is an analyse that aproximates the set of live classes @@ -24,8 +23,9 @@ module rapid_type_analysis import semantize +private import explain_assert_api -private import csv # for live_types_to_csv +import csv # for live_types_to_csv private import ordered_tree # for live_methods_to_tree private import more_collections @@ -62,7 +62,7 @@ class RapidTypeAnalysis # 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] @@ -132,7 +132,7 @@ class RapidTypeAnalysis var types = typeset.to_a (new CachedAlphaComparator).sort(types) var res = new CsvDocument - res.format = new CsvFormat('"', ';', "\n") + res.separator = ';' res.header = ["Type", "Resolution", "Liveness", "Cast-liveness"] for t in types do var reso @@ -255,14 +255,18 @@ class RapidTypeAnalysis add_cast(paramtype) end + if mmethoddef.is_abstract then continue + var npropdef = modelbuilder.mpropdef2node(mmethoddef) if npropdef isa AClassdef then - # It is an init for a class - assert mmethoddef == npropdef.mfree_init - - if mmethoddef.mproperty.is_root_init and not mmethoddef.is_intro then - self.add_super_send(v.receiver, mmethoddef) + if mmethoddef.mproperty.is_root_init then + if not mmethoddef.is_intro then + self.add_super_send(v.receiver, mmethoddef) + end + else + npropdef.debug "cannot RTA {mmethoddef}" + abort end continue else if mmethoddef.constant_value != null then @@ -309,10 +313,13 @@ class RapidTypeAnalysis 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(", ")}" @@ -323,6 +330,7 @@ class RapidTypeAnalysis 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 @@ -579,10 +587,15 @@ 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) + v.add_callsite(newline) + v.add_callsite(extended) + v.add_callsite(to_bytes_with_copy) end end @@ -655,6 +668,31 @@ redef class AAsCastExpr 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 @@ -662,6 +700,13 @@ redef class ASendExpr end end +redef class ACallrefExpr + redef fun accept_rapid_type_visitor(v) + do + super + v.add_type(mtype.as(MClassType)) + end +end redef class ASendReassignFormExpr redef fun accept_rapid_type_visitor(v) @@ -699,7 +744,7 @@ redef class ASuperExpr end end -redef class AForExpr +redef class AForGroup redef fun accept_rapid_type_visitor(v) do v.add_callsite(self.method_iterator)