X-Git-Url: http://nitlanguage.org diff --git a/src/modelize/modelize_class.nit b/src/modelize/modelize_class.nit index 5fd0381..8164668 100644 --- a/src/modelize/modelize_class.nit +++ b/src/modelize/modelize_class.nit @@ -46,8 +46,11 @@ redef class ModelBuilder var mvisibility: nullable MVisibility var arity = 0 var names = new Array[String] + var mclass if nclassdef isa AStdClassdef then - name = nclassdef.n_id.text + var qid = nclassdef.n_qid + assert qid != null + name = qid.n_id.text nkind = nclassdef.n_classkind mkind = nkind.mkind nvisibility = nclassdef.n_visibility @@ -74,6 +77,12 @@ redef class ModelBuilder end names.add(ptname) end + mclass = try_get_mclass_by_qid(qid, mmodule) + if mclass == null and (qid.n_qualified != null or nclassdef.n_kwredef != null) then + class_not_found(qid, mmodule) + nclassdef.is_broken = true + return + end else if nclassdef isa ATopClassdef and nclassdef.n_propdefs.first.as(AMethPropdef).n_methid.collect_text == "sys" then # Special case to keep `sys` in object. @@ -84,26 +93,22 @@ redef class ModelBuilder mkind = interface_kind nvisibility = null mvisibility = public_visibility + mclass = try_get_mclass_by_name(nclassdef, mmodule, name) else name = "Sys" nkind = null mkind = concrete_kind nvisibility = null mvisibility = public_visibility + mclass = try_get_mclass_by_name(nclassdef, mmodule, name) end - var mclass = try_get_mclass_by_name(nclassdef, mmodule, name) if mclass == null then - if nclassdef isa AStdClassdef and nclassdef.n_kwredef != null then - error(nclassdef, "Redef Error: no imported class `{name}` to refine.") - return - end - - # Check for conflicting class full-names in the project + # Check for conflicting class full-names in the package if mmodule.mgroup != null and mvisibility >= protected_visibility then var mclasses = model.get_mclasses_by_name(name) if mclasses != null then for other in mclasses do - if other.intro_mmodule.mgroup != null and other.intro_mmodule.mgroup.mproject == mmodule.mgroup.mproject then + if other.intro_mmodule.mgroup != null and other.intro_mmodule.mgroup.mpackage == mmodule.mgroup.mpackage then # Skip classes that are buggy if other.try_intro == null then continue warning(nclassdef, "full-name-conflict", "Error: a class named `{other.full_name}` is already defined in module `{other.intro_mmodule}` at {other.intro.location}.") @@ -112,16 +117,19 @@ redef class ModelBuilder end end - mclass = new MClass(mmodule, name, names, mkind, mvisibility) + mclass = new MClass(mmodule, name, nclassdef.location, names, mkind, mvisibility) #print "new class {mclass}" else if nclassdef isa AStdClassdef and nmodule.mclass2nclassdef.has_key(mclass) then error(nclassdef, "Error: a class `{name}` is already defined at line {nmodule.mclass2nclassdef[mclass].location.line_start}.") + mclass.is_broken = true return else if nclassdef isa AStdClassdef and nclassdef.n_kwredef == null then error(nclassdef, "Redef Error: `{name}` is an imported class. Add the `redef` keyword to refine it.") + mclass.is_broken = true return else if arity != 0 and mclass.arity != arity then error(nclassdef, "Redef Error: expected {mclass.arity} formal parameter(s) for {mclass.signature_to_s}; got {arity}.") + mclass.is_broken = true return else if nkind != null and mkind != concrete_kind and mclass.kind != mkind then error(nkind, "Redef Error: refinement changed the kind from `{mclass.kind}` to `{mkind}`.") @@ -220,7 +228,7 @@ redef class ModelBuilder if mclassdef.is_intro then self.toolcontext.info("{mclassdef} introduces new {mclass.kind} {mclass.full_name}", 3) else - self.toolcontext.info("{mclassdef} refine {mclass.kind} {mclass.full_name}", 3) + self.toolcontext.info("{mclassdef} refines {mclass.kind} {mclass.full_name}", 3) end end @@ -266,10 +274,19 @@ redef class ModelBuilder if mclassdef.is_intro and objectclass != null then if mclass.kind == extern_kind and mclass.name != "Pointer" then # it is an extern class, but not a Pointer + if pointerclass == null then + error(nclassdef, "Error: `Pointer` must be defined first.") + return + end if specpointer then supertypes.add pointerclass.mclass_type - else if specobject and mclass.name != "Object" then - # it is a standard class without super class (but is not Object) - supertypes.add objectclass.mclass_type + else if specobject then + if mclass.name != "Object" then + # it is a standard class without super class (but is not Object) + supertypes.add objectclass.mclass_type + else if mclass.kind != interface_kind then + error(nclassdef, "Error: `Object` must be an {interface_kind}.") + return + end end end @@ -295,10 +312,8 @@ redef class ModelBuilder end # Build the classes of the module `nmodule`. - # REQUIRE: classes of imported modules are already build. (let `phase` do the job) private fun build_classes(nmodule: AModule) do - var errcount = toolcontext.error_count # Force building recursively if nmodule.build_classes_is_done then return nmodule.build_classes_is_done = true @@ -309,8 +324,6 @@ redef class ModelBuilder if nimp != null then build_classes(nimp) end - if errcount != toolcontext.error_count then return - # Create all classes # process AStdClassdef before so that non-AStdClassdef classes can be attached to existing ones, if any for nclassdef in nmodule.n_classdefs do @@ -322,8 +335,6 @@ redef class ModelBuilder self.build_a_mclass(nmodule, nclassdef) end - if errcount != toolcontext.error_count then return - # Create all classdefs for nclassdef in nmodule.n_classdefs do if not nclassdef isa AStdClassdef then continue @@ -334,29 +345,21 @@ redef class ModelBuilder self.build_a_mclassdef(nmodule, nclassdef) end - if errcount != toolcontext.error_count then return - # Create inheritance on all classdefs for nclassdef in nmodule.n_classdefs do self.collect_a_mclassdef_inheritance(nmodule, nclassdef) end - if errcount != toolcontext.error_count then return - # Create the mclassdef hierarchy for mclassdef in mmodule.mclassdefs do mclassdef.add_in_hierarchy end - if errcount != toolcontext.error_count then return - # Check inheritance for nclassdef in nmodule.n_classdefs do self.check_supertypes(nmodule, nclassdef) end - if errcount != toolcontext.error_count then return - # Check unchecked ntypes for nclassdef in nmodule.n_classdefs do if nclassdef isa AStdClassdef then @@ -380,8 +383,6 @@ redef class ModelBuilder end end - if errcount != toolcontext.error_count then return - # Check clash of ancestors for nclassdef in nmodule.n_classdefs do var mclassdef = nclassdef.mclassdef @@ -402,13 +403,11 @@ redef class ModelBuilder end end - if errcount != toolcontext.error_count then return - # TODO: Check that the super-class is not intrusive # Check that the superclasses are not already known (by transitivity) for nclassdef in nmodule.n_classdefs do - if not nclassdef isa AStdClassdef then continue + if not nclassdef isa AStdClassdef or nclassdef.is_broken then continue var mclassdef = nclassdef.mclassdef if mclassdef == null then continue