From 8ee377f55f23512dea7bd7a24bf188461d30fed7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Christophe=20Beaupr=C3=A9?= Date: Fri, 2 Jun 2017 11:04:43 -0400 Subject: [PATCH] modelbuilder_base: Refactor the signature of `resolve_mtype*` MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Only `modelize_mclass` require support for partial context. Furthermore, in a future PR, it may need to resolve types just before modeling the class definition (in a place where the `MClass` is available and must be used). Signed-off-by: Jean-Christophe Beaupré --- src/metrics/static_types_metrics.nit | 4 +- src/modelbuilder_base.nit | 91 ++++++++++++++++++++++++++++------ src/modelize/modelize_class.nit | 18 +++++-- src/modelize/modelize_property.nit | 26 +++++----- src/nitni/nitni_callbacks.nit | 15 +++--- src/semantize/typing.nit | 2 +- 6 files changed, 111 insertions(+), 45 deletions(-) diff --git a/src/metrics/static_types_metrics.nit b/src/metrics/static_types_metrics.nit index b94ca13..5276632 100644 --- a/src/metrics/static_types_metrics.nit +++ b/src/metrics/static_types_metrics.nit @@ -54,8 +54,8 @@ private class ATypeCounterVisitor if n isa AAnnotation then return if n isa AType then - var mclassdef = self.nclassdef.mclassdef - var mtype = modelbuilder.resolve_mtype(mclassdef.mmodule, mclassdef, n) + var mclassdef = self.nclassdef.mclassdef.as(not null) + var mtype = modelbuilder.resolve_mtype(mclassdef, n) if mtype != null then self.typecount.inc(mtype) end diff --git a/src/modelbuilder_base.nit b/src/modelbuilder_base.nit index 1d7b074..0db4b4b 100644 --- a/src/modelbuilder_base.nit +++ b/src/modelbuilder_base.nit @@ -260,18 +260,50 @@ class ModelBuilder end # Return the static type associated to the node `ntype`. - # `mmodule` and `mclassdef` is the context where the call is made (used to understand formal types) + # + # `mclassdef` is the context where the call is made (used to understand + # formal types). # In case of problem, an error is displayed on `ntype` and null is returned. - # FIXME: the name "resolve_mtype" is awful - fun resolve_mtype_unchecked(mmodule: MModule, mclassdef: nullable MClassDef, ntype: AType, with_virtual: Bool): nullable MType + # + # Same as `resolve_mtype_unchecked3`, but get the context (module, class and + # anchor) from `mclassdef`. + # + # SEE: `resolve_mtype` + # SEE: `resolve_mtype3_unchecked` + # + # FIXME: Find a better name for this method. + fun resolve_mtype_unchecked(mclassdef: MClassDef, ntype: AType, with_virtual: Bool): nullable MType + do + return resolve_mtype3_unchecked( + mclassdef.mmodule, + mclassdef.mclass, + mclassdef.bound_mtype, + ntype, + with_virtual + ) + end + + # Return the static type associated to the node `ntype`. + # + # `mmodule`, `mclass` and `anchor` compose the context where the call is + # made (used to understand formal types). + # In case of problem, an error is displayed on `ntype` and null is returned. + # + # Note: The “3” is for 3 contextual parameters. + # + # SEE: `resolve_mtype` + # SEE: `resolve_mtype_unchecked` + # + # FIXME: Find a better name for this method. + fun resolve_mtype3_unchecked(mmodule: MModule, mclass: nullable MClass, anchor: nullable MClassType, ntype: AType, with_virtual: Bool): nullable MType do var qid = ntype.n_qid var name = qid.n_id.text var res: MType # Check virtual type - if mclassdef != null and with_virtual then - var prop = try_get_mproperty_by_name(ntype, mclassdef, name).as(nullable MVirtualTypeProp) + if anchor != null and with_virtual then + var prop = try_get_mproperty_by_name2(ntype, mmodule, anchor, name).as(nullable MVirtualTypeProp) if prop != null then if not ntype.n_types.is_empty then error(ntype, "Type Error: formal type `{name}` cannot have formal parameters.") @@ -284,8 +316,8 @@ class ModelBuilder end # Check parameter type - if mclassdef != null then - for p in mclassdef.mclass.mparameters do + if mclass != null then + for p in mclass.mparameters do if p.name != name then continue if not ntype.n_types.is_empty then @@ -321,7 +353,7 @@ class ModelBuilder else var mtypes = new Array[MType] for nt in ntype.n_types do - var mt = resolve_mtype_unchecked(mmodule, mclassdef, nt, with_virtual) + var mt = resolve_mtype3_unchecked(mmodule, mclass, anchor, nt, with_virtual) if mt == null then return null # Forward error mtypes.add(mt) end @@ -415,13 +447,44 @@ class ModelBuilder private var bad_class_names = new MultiHashMap[MModule, String] # Return the static type associated to the node `ntype`. - # `mmodule` and `mclassdef` is the context where the call is made (used to understand formal types) + # + # `mclassdef` is the context where the call is made (used to understand + # formal types). # In case of problem, an error is displayed on `ntype` and null is returned. - # FIXME: the name "resolve_mtype" is awful - fun resolve_mtype(mmodule: MModule, mclassdef: nullable MClassDef, ntype: AType): nullable MType + # + # Same as `resolve_mtype3`, but get the context (module, class and ) from + # `mclassdef`. + # + # SEE: `resolve_mtype3` + # SEE: `resolve_mtype_unchecked` + # + # FIXME: Find a better name for this method. + fun resolve_mtype(mclassdef: MClassDef, ntype: AType): nullable MType + do + return resolve_mtype3( + mclassdef.mmodule, + mclassdef.mclass, + mclassdef.bound_mtype, + ntype + ) + end + + # Return the static type associated to the node `ntype`. + # + # `mmodule`, `mclass` and `anchor` compose the context where the call is + # made (used to understand formal types). + # In case of problem, an error is displayed on `ntype` and null is returned. + # + # Note: The “3” is for 3 contextual parameters. + # + # SEE: `resolve_mtype` + # SEE: `resolve_mtype_unchecked` + # + # FIXME: Find a better name for this method. + fun resolve_mtype3(mmodule: MModule, mclass: nullable MClass, anchor: nullable MClassType, ntype: AType): nullable MType do var mtype = ntype.mtype - if mtype == null then mtype = resolve_mtype_unchecked(mmodule, mclassdef, ntype, true) + if mtype == null then mtype = resolve_mtype3_unchecked(mmodule, mclass, anchor, ntype, true) if mtype == null then return null # Forward error if ntype.checked_mtype then return mtype @@ -432,10 +495,8 @@ class ModelBuilder if intro == null then return null # skip error var bound = intro.bound_mtype.arguments[i] var nt = ntype.n_types[i] - var mt = resolve_mtype(mmodule, mclassdef, nt) + var mt = resolve_mtype3(mmodule, mclass, anchor, nt) if mt == null then return null # forward error - var anchor - if mclassdef != null then anchor = mclassdef.bound_mtype else anchor = null if not check_subtype(nt, mmodule, anchor, mt, bound) then error(nt, "Type Error: expected `{bound}`, got `{mt}`.") return null diff --git a/src/modelize/modelize_class.nit b/src/modelize/modelize_class.nit index 23ab906..3be6804 100644 --- a/src/modelize/modelize_class.nit +++ b/src/modelize/modelize_class.nit @@ -179,7 +179,7 @@ redef class ModelBuilder end var nfdt = nfd.n_type if nfdt != null then - var bound = resolve_mtype_unchecked(mmodule, null, nfdt, false) + var bound = resolve_mtype3_unchecked(mmodule, null, null, nfdt, false) if bound == null then return # Forward error if bound.need_anchor then # No F-bounds! @@ -256,7 +256,7 @@ redef class ModelBuilder for nsc in nclassdef.n_superclasses do specobject = false var ntype = nsc.n_type - var mtype = resolve_mtype_unchecked(mmodule, mclassdef, ntype, false) + var mtype = resolve_mtype_unchecked(mclassdef, ntype, false) if mtype == null then continue # Skip because of error if not mtype isa MClassType then error(ntype, "Error: supertypes cannot be a formal type.") @@ -364,11 +364,21 @@ redef class ModelBuilder for nclassdef in nmodule.n_classdefs do if nclassdef isa AStdClassdef then var mclassdef = nclassdef.mclassdef + var mclass + var anchor + if mclassdef == null then + mclass = null + anchor = null + else + mclass = mclassdef.mclass + anchor = mclassdef.bound_mtype + end + # check bound of formal parameter for nfd in nclassdef.n_formaldefs do var nfdt = nfd.n_type if nfdt != null and nfdt.mtype != null then - var bound = resolve_mtype(mmodule, mclassdef, nfdt) + var bound = resolve_mtype3(mmodule, mclass, anchor, nfdt) if bound == null then return # Forward error end end @@ -376,7 +386,7 @@ redef class ModelBuilder for nsc in nclassdef.n_superclasses do var ntype = nsc.n_type if ntype.mtype != null then - var mtype = resolve_mtype(mmodule, mclassdef, ntype) + var mtype = resolve_mtype3(mmodule, mclass, anchor, ntype) if mtype == null then return # Forward error end end diff --git a/src/modelize/modelize_property.nit b/src/modelize/modelize_property.nit index 44d551d..a7f75ff 100644 --- a/src/modelize/modelize_property.nit +++ b/src/modelize/modelize_property.nit @@ -671,14 +671,13 @@ redef class ASignature # Visit and fill information about a signature private fun visit_signature(modelbuilder: ModelBuilder, mclassdef: MClassDef): Bool do - var mmodule = mclassdef.mmodule var param_names = self.param_names var param_types = self.param_types for np in self.n_params do param_names.add(np.n_id.text) var ntype = np.n_type if ntype != null then - var mtype = modelbuilder.resolve_mtype_unchecked(mmodule, mclassdef, ntype, true) + var mtype = modelbuilder.resolve_mtype_unchecked(mclassdef, ntype, true) if mtype == null then return false # Skip error for i in [0..param_names.length-param_types.length[ do param_types.add(mtype) @@ -695,7 +694,7 @@ redef class ASignature end var ntype = self.n_type if ntype != null then - self.ret_type = modelbuilder.resolve_mtype_unchecked(mmodule, mclassdef, ntype, true) + self.ret_type = modelbuilder.resolve_mtype_unchecked(mclassdef, ntype, true) if self.ret_type == null then return false # Skip error end @@ -709,14 +708,14 @@ redef class ASignature for np in self.n_params do var ntype = np.n_type if ntype != null then - if modelbuilder.resolve_mtype(mclassdef.mmodule, mclassdef, ntype) == null then + if modelbuilder.resolve_mtype(mclassdef, ntype) == null then res = false end end end var ntype = self.n_type if ntype != null then - if modelbuilder.resolve_mtype(mclassdef.mmodule, mclassdef, ntype) == null then + if modelbuilder.resolve_mtype(mclassdef, ntype) == null then res = false end end @@ -1348,7 +1347,7 @@ redef class AAttrPropdef var ntype = self.n_type if ntype != null then - mtype = modelbuilder.resolve_mtype_unchecked(mmodule, mclassdef, ntype, true) + mtype = modelbuilder.resolve_mtype_unchecked(mclassdef, ntype, true) if mtype == null then return end @@ -1369,9 +1368,9 @@ redef class AAttrPropdef if mtype == null then if nexpr != null then if nexpr isa ANewExpr then - mtype = modelbuilder.resolve_mtype_unchecked(mmodule, mclassdef, nexpr.n_type, true) + mtype = modelbuilder.resolve_mtype_unchecked(mclassdef, nexpr.n_type, true) else if nexpr isa AAsCastExpr then - mtype = modelbuilder.resolve_mtype_unchecked(mmodule, mclassdef, nexpr.n_type, true) + mtype = modelbuilder.resolve_mtype_unchecked(mclassdef, nexpr.n_type, true) else if nexpr isa AIntegerExpr then var cla: nullable MClass = null if nexpr.value isa Int then @@ -1432,7 +1431,7 @@ redef class AAttrPropdef end else if ntype != null and inherited_type == mtype then if nexpr isa ANewExpr then - var xmtype = modelbuilder.resolve_mtype_unchecked(mmodule, mclassdef, nexpr.n_type, true) + var xmtype = modelbuilder.resolve_mtype_unchecked(mclassdef, nexpr.n_type, true) if xmtype == mtype then modelbuilder.advice(ntype, "useless-type", "Warning: useless type definition") end @@ -1488,11 +1487,11 @@ redef class AAttrPropdef # Check types if ntype != null then - if modelbuilder.resolve_mtype(mmodule, mclassdef, ntype) == null then return + if modelbuilder.resolve_mtype(mclassdef, ntype) == null then return end var nexpr = n_expr if nexpr isa ANewExpr then - if modelbuilder.resolve_mtype(mmodule, mclassdef, nexpr.n_type) == null then return + if modelbuilder.resolve_mtype(mclassdef, nexpr.n_type) == null then return end # Lookup for signature in the precursor @@ -1645,11 +1644,10 @@ redef class ATypePropdef var mpropdef = self.mpropdef if mpropdef == null then return # Error thus skipped var mclassdef = mpropdef.mclassdef - var mmodule = mclassdef.mmodule var mtype: nullable MType = null var ntype = self.n_type - mtype = modelbuilder.resolve_mtype_unchecked(mmodule, mclassdef, ntype, true) + mtype = modelbuilder.resolve_mtype_unchecked(mclassdef, ntype, true) if mtype == null then return mpropdef.bound = mtype @@ -1671,7 +1669,7 @@ redef class ATypePropdef var anchor = mclassdef.bound_mtype var ntype = self.n_type - if modelbuilder.resolve_mtype(mmodule, mclassdef, ntype) == null then + if modelbuilder.resolve_mtype(mclassdef, ntype) == null then mpropdef.bound = null return end diff --git a/src/nitni/nitni_callbacks.nit b/src/nitni/nitni_callbacks.nit index 823f624..6d05196 100644 --- a/src/nitni/nitni_callbacks.nit +++ b/src/nitni/nitni_callbacks.nit @@ -304,7 +304,7 @@ redef class AFullPropExternCall var mmodule = npropdef.mpropdef.mclassdef.mmodule var mclassdef = npropdef.mpropdef.mclassdef var mclass_type = mclassdef.bound_mtype - var mtype = toolcontext.modelbuilder.resolve_mtype(mmodule, mclassdef, n_type) + var mtype = toolcontext.modelbuilder.resolve_mtype(mclassdef, n_type) if mtype == null then return @@ -337,7 +337,7 @@ redef class AInitPropExternCall do var mmodule = npropdef.mpropdef.mclassdef.mmodule var mclassdef = npropdef.mpropdef.mclassdef - var mtype = toolcontext.modelbuilder.resolve_mtype(mmodule, mclassdef, n_type) + var mtype = toolcontext.modelbuilder.resolve_mtype(mclassdef, n_type) if mtype == null then return if not mtype isa MClassType then @@ -398,9 +398,8 @@ redef class ACastAsExternCall redef fun verify_and_collect(npropdef, callback_set, toolcontext) do var mclassdef = npropdef.mpropdef.mclassdef - var mmodule = mclassdef.mmodule - toolcontext.modelbuilder.resolve_mtype_unchecked(mmodule, mclassdef, n_from_type, true) - toolcontext.modelbuilder.resolve_mtype_unchecked(mmodule, mclassdef, n_to_type, true) + toolcontext.modelbuilder.resolve_mtype_unchecked(mclassdef, n_from_type, true) + toolcontext.modelbuilder.resolve_mtype_unchecked(mclassdef, n_to_type, true) super end end @@ -412,8 +411,7 @@ redef class AAsNullableExternCall redef fun verify_and_collect(npropdef, callback_set, toolcontext) do var mclassdef = npropdef.mpropdef.mclassdef - var mmodule = mclassdef.mmodule - toolcontext.modelbuilder.resolve_mtype_unchecked(mmodule, mclassdef, n_type, true) + toolcontext.modelbuilder.resolve_mtype_unchecked(mclassdef, n_type, true) super end end @@ -429,8 +427,7 @@ redef class AAsNotNullableExternCall redef fun verify_and_collect(npropdef, callback_set, toolcontext) do var mclassdef = npropdef.mpropdef.mclassdef - var mmodule = mclassdef.mmodule - toolcontext.modelbuilder.resolve_mtype_unchecked(mmodule, mclassdef, n_type, true) + toolcontext.modelbuilder.resolve_mtype_unchecked(mclassdef, n_type, true) super end end diff --git a/src/semantize/typing.nit b/src/semantize/typing.nit index 37a1494..8890ba9 100644 --- a/src/semantize/typing.nit +++ b/src/semantize/typing.nit @@ -275,7 +275,7 @@ private class TypeVisitor fun resolve_mtype(node: AType): nullable MType do - return self.modelbuilder.resolve_mtype(mmodule, mclassdef, node) + return self.modelbuilder.resolve_mtype(mclassdef, node) end fun try_get_mclass(node: ANode, name: String): nullable MClass -- 1.7.9.5