vararg.add(rawargs[i+1])
end
# FIXME: its it to late to determine the vararg type, this should have been done during a previous analysis
- var elttype = m.msignature.parameter_mtypes[vararg_rank]
+ var elttype = m.msignature.mparameters[vararg_rank].mtype
elttype = self.resolve_for(elttype, recv)
args.add(self.array_instance(vararg, elttype))
assert args.length == m.msignature.arity + 1 # because of self
for i in [0..m.msignature.arity[ do
- var t = m.msignature.parameter_mtypes[i]
+ var t = m.msignature.mparameters[i].mtype
if i == vararg_rank then
t = args[i+1].mtype
end
comment.append("(self: {recv}")
arguments.add(selfvar)
for i in [0..self.msignature.arity[ do
- var mtype = self.msignature.parameter_mtypes[i]
+ var mtype = self.msignature.mparameters[i].mtype
if i == self.msignature.vararg_rank then
mtype = v.get_class("Array").get_mtype([mtype])
end
class MSignature
super MType
- # The names of each parameter (in order)
- var parameter_names: Array[String]
-
- # The types of each parameter (in order)
- var parameter_mtypes: Array[MType]
+ # The each parameter (in order)
+ var mparameters: Array[MParameter]
# The return type (null for a procedure)
var return_mtype: nullable MType
- init(parameter_names: Array[String], parameter_mtypes: Array[MType], return_mtype: nullable MType, vararg_rank: Int)
+ # REQUIRE: 1 <= mparameters.count p -> p.is_vararg
+ init(mparameters: Array[MParameter], return_mtype: nullable MType)
do
- self.parameter_names = parameter_names
- self.parameter_mtypes = parameter_mtypes
+ var vararg_rank = -1
+ for i in [0..mparameters.length[ do
+ var parameter = mparameters[i]
+ if parameter.is_vararg then
+ assert vararg_rank == -1
+ vararg_rank = i
+ end
+ end
+ self.mparameters = mparameters
self.return_mtype = return_mtype
self.vararg_rank = vararg_rank
end
var vararg_rank: Int
# The number or parameters
- fun arity: Int do return parameter_mtypes.length
+ fun arity: Int do return mparameters.length
redef fun to_s
do
var b = new Buffer
- if not parameter_names.is_empty then
+ if not mparameters.is_empty then
b.append("(")
- for i in [0..parameter_names.length[ do
+ for i in [0..mparameters.length[ do
+ var mparameter = mparameters[i]
if i > 0 then b.append(", ")
- b.append(parameter_names[i])
+ b.append(mparameter.name)
b.append(": ")
- b.append(parameter_mtypes[i].to_s)
- if i == self.vararg_rank then
+ b.append(mparameter.mtype.to_s)
+ if mparameter.is_vararg then
b.append("...")
end
end
redef fun resolve_for(mtype: MType, anchor: MClassType, mmodule: MModule, cleanup_virtual: Bool): MSignature
do
- var params = new Array[MType]
- for t in self.parameter_mtypes do
- params.add(t.resolve_for(mtype, anchor, mmodule, cleanup_virtual))
+ var params = new Array[MParameter]
+ for p in self.mparameters do
+ params.add(p.resolve_for(mtype, anchor, mmodule, cleanup_virtual))
end
var ret = self.return_mtype
if ret != null then
ret = ret.resolve_for(mtype, anchor, mmodule, cleanup_virtual)
end
- var res = new MSignature(self.parameter_names, params, ret, self.vararg_rank)
+ var res = new MSignature(params, ret)
+ return res
+ end
+end
+
+# A parameter in a signature
+class MParameter
+ # The name of the parameter
+ var name: String
+
+ # The static type of the parameter
+ var mtype: MType
+
+ # Is the parameter a vararg?
+ var is_vararg: Bool
+
+ fun resolve_for(mtype: MType, anchor: MClassType, mmodule: MModule, cleanup_virtual: Bool): MParameter
+ do
+ if not self.mtype.need_anchor then return self
+ var newtype = self.mtype.resolve_for(mtype, anchor, mmodule, cleanup_virtual)
+ var res = new MParameter(self.name, newtype, self.is_vararg)
return res
end
end
nclassdef.super_inits = combine
var mprop = new MMethod(mclassdef, "init", mclassdef.mclass.visibility)
var mpropdef = new MMethodDef(mclassdef, mprop, nclassdef.location)
- var param_names = new Array[String]
- var param_types = new Array[MType]
- var msignature = new MSignature(param_names, param_types, null, -1)
+ var mparameters = new Array[MParameter]
+ var msignature = new MSignature(mparameters, null)
mpropdef.msignature = msignature
mprop.is_init = true
nclassdef.mfree_init = mpropdef
end
# Collect undefined attributes
- var param_names = new Array[String]
- var param_types = new Array[MType]
+ var mparameters = new Array[MParameter]
for npropdef in nclassdef.n_propdefs do
if npropdef isa AAttrPropdef and npropdef.n_expr == null then
- param_names.add(npropdef.mpropdef.mproperty.name.substring_from(1))
+ var paramname = npropdef.mpropdef.mproperty.name.substring_from(1)
var ret_type = npropdef.mpropdef.static_mtype
if ret_type == null then return
- param_types.add(ret_type)
+ var mparameter = new MParameter(paramname, ret_type, false)
+ mparameters.add(mparameter)
end
end
var mprop = new MMethod(mclassdef, "init", mclassdef.mclass.visibility)
var mpropdef = new MMethodDef(mclassdef, mprop, nclassdef.location)
- var msignature = new MSignature(param_names, param_types, null, -1)
+ var msignature = new MSignature(mparameters, null)
mpropdef.msignature = msignature
mprop.is_init = true
nclassdef.mfree_init = mpropdef
self.ret_type = modelbuilder.resolve_mtype(nclassdef, ntype)
if self.ret_type == null then return false # Skip errir
end
+
self.is_visited = true
return true
end
# Inherit the signature
if msignature != null and param_names.length != param_types.length and param_names.length == msignature.arity and param_types.length == 0 then
# Parameters are untyped, thus inherit them
- param_types = msignature.parameter_mtypes
+ param_types = new Array[MType]
+ for mparameter in msignature.mparameters do
+ param_types.add(mparameter.mtype)
+ end
vararg_rank = msignature.vararg_rank
end
if msignature != null and ret_type == null then
return
end
- msignature = new MSignature(param_names, param_types, ret_type, vararg_rank)
+ var mparameters = new Array[MParameter]
+ for i in [0..param_names.length[ do
+ var mparameter = new MParameter(param_names[i], param_types[i], i == vararg_rank)
+ mparameters.add(mparameter)
+ end
+ msignature = new MSignature(mparameters, ret_type)
mpropdef.msignature = msignature
end
if mysignature.arity > 0 then
# Check parameters types
for i in [0..mysignature.arity[ do
- var myt = mysignature.parameter_mtypes[i]
- var prt = msignature.parameter_mtypes[i]
+ var myt = mysignature.mparameters[i].mtype
+ var prt = msignature.mparameters[i].mtype
if not myt.is_subtype(mmodule, nclassdef.mclassdef.bound_mtype, prt) and
not prt.is_subtype(mmodule, nclassdef.mclassdef.bound_mtype, myt) then
- modelbuilder.error(nsig.n_params[i], "Redef Error: Wrong type for parameter `{mysignature.parameter_names[i]}'. found {myt}, expected {prt}.")
+ modelbuilder.error(nsig.n_params[i], "Redef Error: Wrong type for parameter `{mysignature.mparameters[i].name}'. found {myt}, expected {prt}.")
end
end
end
var mreadpropdef = self.mreadpropdef
if mreadpropdef != null then
- var msignature = new MSignature(new Array[String], new Array[MType], mtype, -1)
+ var msignature = new MSignature(new Array[MParameter], mtype)
mreadpropdef.msignature = msignature
end
else
name = n_id2.text
end
- var msignature = new MSignature([name], [mtype], null, -1)
+ var mparameter = new MParameter(name, mtype, false)
+ var msignature = new MSignature([mparameter], null)
mwritepropdef.msignature = msignature
end
end
vararg.add(rawargs[i+1])
end
# FIXME: its it to late to determine the vararg type, this should have been done during a previous analysis
- var elttype = mpropdef.msignature.parameter_mtypes[vararg_rank].anchor_to(self.mainmodule, args.first.mtype.as(MClassType))
+ var elttype = mpropdef.msignature.mparameters[vararg_rank].mtype.anchor_to(self.mainmodule, args.first.mtype.as(MClassType))
args.add(self.array_instance(vararg, elttype))
for i in [vararg_lastrank+1..rawargs.length-1[ do
var vararg_rank = mr.mmethoddef.msignature.vararg_rank
if vararg_rank > -1 then
- var elttype = mr.mmethoddef.msignature.parameter_mtypes[vararg_rank]
+ var elttype = mr.mmethoddef.msignature.mparameters[vararg_rank].mtype
elttype = elttype.anchor_to(self.mainmodule, mr.receiver)
var vararg = self.mainmodule.get_primitive_class("Array").get_mtype([elttype])
self.add_type(vararg)
if i > vararg_rank then
j = i + vararg_decl
end
- var paramtype = msignature.parameter_mtypes[i]
+ var paramtype = msignature.mparameters[i].mtype
self.visit_expr_subtype(args[j], paramtype)
end
if vararg_rank >= 0 then
var varargs = new Array[AExpr]
- var paramtype = msignature.parameter_mtypes[vararg_rank]
+ var paramtype = msignature.mparameters[vararg_rank].mtype
for j in [vararg_rank..vararg_rank+vararg_decl] do
varargs.add(args[j])
self.visit_expr_subtype(args[j], paramtype)
var mmethoddef = self.mpropdef.as(not null)
for i in [0..mmethoddef.msignature.arity[ do
- var mtype = mmethoddef.msignature.parameter_mtypes[i]
+ var mtype = mmethoddef.msignature.mparameters[i].mtype
if mmethoddef.msignature.vararg_rank == i then
var arrayclass = v.get_mclass(self.n_signature.n_params[i], "Array")
if arrayclass == null then return # Skip error
var rettype = msignature.return_mtype
assert msignature.arity == 1 and rettype != null
- var value_type = v.visit_expr_subtype(self.n_value, msignature.parameter_mtypes.first)
+ var value_type = v.visit_expr_subtype(self.n_value, msignature.mparameters.first.mtype)
if value_type == null then return null # Skip error
v.check_subtype(self, rettype, writetype)
if wmsignature == null then abort # Forward error
wmsignature = v.resolve_signature_for(wmsignature, recvtype, for_self)
- var wtype = self.resolve_reassignment(v, readtype, wmsignature.parameter_mtypes.last)
+ var wtype = self.resolve_reassignment(v, readtype, wmsignature.mparameters.last.mtype)
if wtype == null then return
args.add(self.n_value)