nitc :: MMethodDef
nitc :: MMethodDef :: _class_call
nitc :: MMethodDef :: _constant_value
An optional constant value returned in functions.nitc :: MMethodDef :: _initializers
List of initialisers to call in root-initsnitc :: MMethodDef :: _is_abstract
Is the method definition abstract?nitc :: MMethodDef :: _is_calling_init
Does the method take the responsibility to callinit
?
nitc :: MMethodDef :: _is_old_style_init
Does the method is a old_style_init?nitc :: MMethodDef :: _line_number
nitc :: MMethodDef :: _msignature
The signature attached to the property definitionnitc :: MMethodDef :: _total_self_call
nitc :: MMethodDef :: callref_thunk
The C thunk function associated to a mmethoddef. Receives only nullablenitc :: MMethodDef :: check_contract_facet
Verification of the contract facetnitc :: MMethodDef :: check_same_contract
Is the contract already defined in the contextnitc :: MMethodDef :: class_call
nitc :: MMethodDef :: class_call=
nitc :: MMethodDef :: compile_foreign_code_entry
Compile the standardized entry point as part of the foreign lib APInitc :: MMethodDef :: compile_inside_to_c
Inline the body in another visitornitc :: MMethodDef :: compile_inside_to_java
Compile the body of this functionnitc :: MMethodDef :: compile_parameter_check
Generate type checks in the C code to check covariant parametersnitc :: MMethodDef :: compile_to_java
Generate a Java RTMethod forself
nitc :: MMethodDef :: constant_value
An optional constant value returned in functions.nitc :: MMethodDef :: constant_value=
An optional constant value returned in functions.nitc :: MMethodDef :: construct_contract
Entry point to build contract (define the contract facet and define the contract method verification)nitc :: MMethodDef :: create_contract_facet
Method to create a contract facet of the methodnitc :: MMethodDef :: defaultinit
nitc :: MMethodDef :: foreign_lib_entry_cname
Name of the entry point to the implementation function in the foreign libnitc :: MMethodDef :: initializers
List of initialisers to call in root-initsnitc :: MMethodDef :: initializers=
List of initialisers to call in root-initsnitc :: MMethodDef :: is_abstract=
Is the method definition abstract?nitc :: MMethodDef :: is_calling_init
Does the method take the responsibility to callinit
?
nitc :: MMethodDef :: is_calling_init=
Does the method take the responsibility to callinit
?
nitc :: MMethodDef :: is_old_style_init
Does the method is a old_style_init?nitc :: MMethodDef :: is_old_style_init=
Does the method is a old_style_init?nitc :: MMethodDef :: line_number
nitc :: MMethodDef :: line_number=
nitc :: MMethodDef :: msignature
The signature attached to the property definitionnitc :: MMethodDef :: msignature=
The signature attached to the property definitionnitc :: MMethodDef :: no_intro_contract
Create a contract on the introduction classdef of the property.nitc :: MMethodDef :: recv_differ_from_intro
Returns true if the current method definition differ fromnitc :: MMethodDef :: separate_runtime_function
The C function associated to a mmethoddefnitc :: MMethodDef :: total_self_call
nitc :: MMethodDef :: total_self_call=
nitc :: MMethodDef :: virtual_runtime_function
The C function associated to a mmethoddef, that can be stored into a VFT of a classnitc $ MMethodDef :: SELF
Type of this instance, automatically specialized in every classnitc :: json_model $ MMethodDef :: core_serialize_to
Actual serialization ofself
to serializer
nitc :: astbuilder $ MMethodDef :: create_ast_representation
Build a ANode fromself
nitc :: term_model $ MMethodDef :: cs_signature
Returnsself
signature formatted for console.
nitc :: html_model $ MMethodDef :: html_signature
Returns the MEntity signature decorated with HTMLnitc :: uml_module $ MMethodDef :: tpl_module
Builds a dot UML package diagram entity fromself
nitc :: vim_autocomplete $ MMethodDef :: write_location
Location (file and line when available) of related declarationsnitc :: vim_autocomplete $ MMethodDef :: write_signature_to_stream
nitc :: AnnotatedMEntity :: _annotations
Names of the annotations found onself
declaration
nitc :: MMethodDef :: _class_call
nitc :: MEntity :: _const_color
nitc :: MMethodDef :: _constant_value
An optional constant value returned in functions.nitc :: MEntity :: _css_classes
CSS classes used to decorateself
nitc :: MEntity :: _deprecation
Is the entity deprecated?nitc :: MPropDef :: _full_name
The full-name of mpropdefs combine the information about theclassdef
and the mproperty
.
nitc :: MPropDef :: _has_contract
flag to indicate is theMPropDef
has a contract
nitc :: MPropDef :: _has_supercall
Does the MPropDef contains a call to super or a call of a super-constructor?nitc :: MEntity :: _html_full_name
The MEntityfull_name
escaped for HTML
nitc :: MMethodDef :: _initializers
List of initialisers to call in root-initsnitc :: MMethodDef :: _is_abstract
Is the method definition abstract?nitc :: MPropDef :: _is_after_all
nitc :: MPropDef :: _is_after_all
Does self have theafter_all
annotation?
nitc :: MPropDef :: _is_before
nitc :: MPropDef :: _is_before_all
Does self have thebefore_all
annotation?
nitc :: MPropDef :: _is_before_all
nitc :: MEntity :: _is_broken
The indication that the entity did not pass some semantic verifications.nitc :: MMethodDef :: _is_calling_init
Does the method take the responsibility to callinit
?
nitc :: MMethodDef :: _is_old_style_init
Does the method is a old_style_init?nitc :: MMethodDef :: _line_number
nitc :: MPropDef :: _mclassdef
The class definition where the property definition isnitc :: MMethodDef :: _msignature
The signature attached to the property definitionnitc :: MMethodDef :: _total_self_call
serialization :: Serializable :: accept_inspect_serializer_core
serialization :: Serializable :: accept_json_serializer
Refinable service to customize the serialization of this class to JSONserialization :: Serializable :: accept_msgpack_attribute_counter
Hook to customize the behavior of theAttributeCounter
serialization :: Serializable :: accept_msgpack_serializer
Hook to customize the serialization of this class to MessagePacknitc :: MEntity :: add_doc_to_infobox
Append an entry for the doc in the given infoboxserialization :: Serializable :: add_to_bundle
Called by[]=
to dynamically choose the appropriate method according
nitc :: AnnotatedMEntity :: annotations
Names of the annotations found onself
declaration
nitc :: AnnotatedMEntity :: annotations=
Names of the annotations found onself
declaration
nitc :: MMethodDef :: callref_thunk
The C thunk function associated to a mmethoddef. Receives only nullablenitc :: MMethodDef :: check_contract_facet
Verification of the contract facetnitc :: MMethodDef :: check_same_contract
Is the contract already defined in the contextnitc :: MMethodDef :: class_call
nitc :: MMethodDef :: class_call=
core :: Object :: class_factory
Implementation used byget_class
to create the specific class.
nitc :: MEntity :: collect_ancestors
Collectself
ancestors (direct and indirect)
nitc :: MEntity :: collect_children
Collectself
children (direct descendants)
nitc :: MEntity :: collect_descendants
Collectself
descendants (direct and direct)
nitc :: MEntity :: collect_linearization
Collectself
linearization anchored on mainmodule
nitc :: MEntity :: collect_metrics
nitc :: MEntity :: collect_modifiers
Collect modifier keywords likeredef
, private
etc
nitc :: MEntity :: collect_parents
Collectself
parents (direct ancestors)
nitc :: MMethodDef :: compile_foreign_code_entry
Compile the standardized entry point as part of the foreign lib APInitc :: MMethodDef :: compile_inside_to_c
Inline the body in another visitornitc :: MMethodDef :: compile_inside_to_java
Compile the body of this functionnitc :: MMethodDef :: compile_parameter_check
Generate type checks in the C code to check covariant parametersnitc :: MMethodDef :: compile_to_java
Generate a Java RTMethod forself
nitc :: MEntity :: const_color
nitc :: MEntity :: const_color=
nitc :: MMethodDef :: constant_value
An optional constant value returned in functions.nitc :: MMethodDef :: constant_value=
An optional constant value returned in functions.nitc :: MMethodDef :: construct_contract
Entry point to build contract (define the contract facet and define the contract method verification)nitc :: MEntity :: core_serialize_base
serialization :: Serializable :: core_serialize_to
Actual serialization ofself
to serializer
nitc :: MEntity :: create_ast_representation
Build a ANode fromself
nitc :: MMethodDef :: create_contract_facet
Method to create a contract facet of the methodnitc :: MEntity :: cs_comment
Returns the comment of this MEntity formatted for console.nitc :: MEntity :: cs_declaration
Returns the complete MEntity declaration (modifiers + name + signature).nitc :: MEntity :: cs_full_name
Returnsself.full_name
formatted for console
nitc :: MEntity :: cs_list_item
Returnsself
as a list element that can be displayed in console.
nitc :: MEntity :: cs_location
Source code location of this MEntity formatted for consolenitc :: MEntity :: cs_short_comment
Returns the comment of this MEntity formatted for console.nitc :: MEntity :: cs_signature
Returnsself
signature formatted for console.
nitc :: MEntity :: cs_source_code
Source code associated to this MEntity.nitc :: MEntity :: css_classes=
CSS classes used to decorateself
nitc :: TableCallable :: defaultinit
core :: Object :: defaultinit
nitc :: MMethodDef :: defaultinit
nitc :: MEntity :: defaultinit
nitc :: MPropDef :: defaultinit
nitc :: AnnotatedMEntity :: defaultinit
nitc :: HInfoBoxable :: defaultinit
nitc :: MEntity :: deprecation=
Is the entity deprecated?nitc :: MEntity :: field_separator
nitc :: MMethodDef :: foreign_lib_entry_cname
Name of the entry point to the implementation function in the foreign libserialization :: Serializable :: from_deserializer
Create an instance of this class from thedeserializer
nitc :: MPropDef :: full_name=
The full-name of mpropdefs combine the information about theclassdef
and the mproperty
.
nitc :: AnnotatedMEntity :: has_annotation
Doesself
contains annotation
in its declaration?
nitc :: MPropDef :: has_contract
flag to indicate is theMPropDef
has a contract
nitc :: MPropDef :: has_contract=
flag to indicate is theMPropDef
has a contract
nitc :: MPropDef :: has_supercall
Does the MPropDef contains a call to super or a call of a super-constructor?nitc :: MPropDef :: has_supercall=
Does the MPropDef contains a call to super or a call of a super-constructor?nitc :: MEntity :: hierarchy_poset
Build a poset representingself
in it's own hierarchy
nitc :: MEntity :: html_declaration
Returns the complete MEntity declaration decorated with HTMLnitc :: MEntity :: html_full_name=
The MEntityfull_name
escaped for HTML
nitc :: MEntity :: html_name=
The MEntity name escaped for HTMLnitc :: MEntity :: html_namespace
Returnsfull_name
decorated with HTML links
nitc :: MEntity :: html_signature
Returns the MEntity signature decorated with HTMLnitc :: HInfoBoxable :: infobox
An new infobox documenting the entitynitc :: MMethodDef :: initializers
List of initialisers to call in root-initsnitc :: MMethodDef :: initializers=
List of initialisers to call in root-initsnitc :: MMethodDef :: is_abstract=
Is the method definition abstract?nitc :: MPropDef :: is_after_all=
Does self have theafter_all
annotation?
nitc :: MPropDef :: is_before=
Does self have thebefore
annotation?
nitc :: MPropDef :: is_before_all=
Does self have thebefore_all
annotation?
nitc :: MEntity :: is_broken=
The indication that the entity did not pass some semantic verifications.nitc :: MMethodDef :: is_calling_init
Does the method take the responsibility to callinit
?
nitc :: MMethodDef :: is_calling_init=
Does the method take the responsibility to callinit
?
nitc :: MEntity :: is_fictive=
Isself
created for internal purpose?
nitc :: MMethodDef :: is_old_style_init
Does the method is a old_style_init?nitc :: MMethodDef :: is_old_style_init=
Does the method is a old_style_init?core :: Object :: is_same_instance
Return true ifself
and other
are the same instance (i.e. same identity).
core :: Object :: is_same_serialized
Isself
the same as other
in a serialization context?
core :: Object :: is_same_type
Return true ifself
and other
have the same dynamic type.
nitc :: MEntity :: json_namespace
Returnself.full_name
as an object that can be serialized to json.
nitc :: MMethodDef :: line_number
nitc :: MMethodDef :: line_number=
nitc :: MEntity :: line_separator
nitc :: MEntity :: linkto_text
Link to theself
with a specific text.
nitc :: MPropDef :: lookup_next_definition
Return the next definition in linearization ofmtype
.
nitc :: MPropDef :: mclassdef=
The class definition where the property definition isnitc :: MEntity :: mdoc_or_fallback
The documentation associated to the entity or their main nested entity.nitc :: MPropDef :: mproperty=
The associated global propertyserialization :: Serializable :: msgpack_extra_array_items
Hook to request a larger than usual metadata arraynitc :: MMethodDef :: msignature
The signature attached to the property definitionnitc :: MMethodDef :: msignature=
The signature attached to the property definitioncore :: Object :: native_class_name
The class name of the object in CString format.nitc :: MMethodDef :: no_intro_contract
Create a contract on the introduction classdef of the property.core :: Object :: output_class_name
Display class name on stdout (debug only).mentity
nitc :: MEntity :: ratings_by_dimension
Get the ratings of adimension
nitc :: MMethodDef :: recv_differ_from_intro
Returns true if the current method definition differ fromnitc :: MMethodDef :: separate_runtime_function
The C function associated to a mmethoddefserialization :: Serializable :: serialize_msgpack
Serializeself
to MessagePack bytes
serialization :: Serializable :: serialize_to
Serializeself
to serializer
serialization :: Serializable :: serialize_to_json
Serializeself
to JSON
serialization :: Serializable :: serialize_to_or_delay
Accept references or force direct serialization (usingserialize_to
)
nitc :: MEntity :: source_url
Render a HTML link for the MEntity locationserialization :: Serializable :: to_pretty_json
Serializeself
to plain pretty JSON
nitc :: MMethodDef :: total_self_call
nitc :: MMethodDef :: total_self_call=
nitc :: MEntity :: tpl_module
Builds a dot UML package diagram entity fromself
nitc :: MMethodDef :: virtual_runtime_function
The C function associated to a mmethoddef, that can be stored into a VFT of a classv.enter_visit
on all nested entities.
nitc :: MEntity :: write_extra_doc
Extra auto documentation to append to thestream
nitc :: MEntity :: write_location
Location (file and line when available) of related declarationsSerializer::serialize
table_send
# A local definition of a method
class MMethodDef
super MPropDef
redef type MPROPERTY: MMethod
redef type MPROPDEF: MMethodDef
# The signature attached to the property definition
var msignature: nullable MSignature = null is writable
# List of initialisers to call in root-inits
#
# They could be setters or attributes
var initializers = new Array[MProperty]
# Does the method take the responsibility to call `init`?
#
# If the method is used as an initializer, then
# using this information prevents to call `init` twice.
var is_calling_init = false is writable
# Does the method is a old_style_init?
#
var is_old_style_init = false is writable
# Is the method definition abstract?
var is_abstract: Bool = false is writable
# Is the method definition intern?
var is_intern = false is writable
# Is the method definition extern?
var is_extern = false is writable
# An optional constant value returned in functions.
#
# Only some specific primitife value are accepted by engines.
# Is used when there is no better implementation available.
#
# Currently used only for the implementation of the `--define`
# command-line option.
# SEE: module `mixin`.
var constant_value: nullable Object = null is writable
end
src/model/model.nit:2650,1--2693,3
redef class MMethodDef
redef fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do
if nodes.has_key(self) then return nodes[self]
var node = super
node["is_abstract"] = is_abstract
node["is_intern"] = is_intern
node["is_extern"] = is_extern
var msignature = msignature
if msignature != null then
node.out_edges.add(new NeoEdge(node, "SIGNATURE", msignature.to_node(nodes, model_name)))
end
return node
end
end
src/neo.nit:809,1--822,3
redef class MMethodDef
# Name of the entry point to the implementation function in the foreign lib
fun foreign_lib_entry_cname: String do return "entry__{cname}"
# Compile the standardized entry point as part of the foreign lib API
private fun compile_foreign_code_entry(ecc: CCompilationUnit)
do
var msignature = msignature
if msignature == null then return
# Return type
var return_mtype = msignature.return_mtype
if mproperty.is_init then return_mtype = mclassdef.mclass.mclass_type
var c_return_type
if return_mtype != null then
c_return_type = return_mtype.cname_blind
else c_return_type = "void"
var is_init = mproperty.is_init
# Params
var params = new Array[String]
if not is_init then params.add mclassdef.mclass.mclass_type.cname_blind
for param in msignature.mparameters do params.add param.mtype.cname_blind
# Declare the implementation function as extern
var impl_cname = mproperty.build_cname(mclassdef.bound_mtype,
mclassdef.mmodule, "___impl", long_signature)
ecc.body_decl.add "extern {c_return_type} {impl_cname}({params.join(", ")});\n"
# Declare the entry function
var foreign_lib_entry_cname = "int {foreign_lib_entry_cname}(int argc, nit_call_arg *argv, nit_call_arg *result)"
var fc = new CFunction(foreign_lib_entry_cname)
# Check argument count on the library side
#
# This may detect inconsistencies between the interpreter and the generated code.
var expected_argc = msignature.arity
if not is_init then expected_argc += 1
fc.exprs.add """
if (argc != {{{expected_argc}}}) {
printf("Invalid argument count in `{{{mproperty.full_name}}}`, expected %d, got %d.\\n",
argc, {{{expected_argc}}});
return 1;
}
"""
# Unpack and prepare args for the user code
var k = 0
var args_for_call = new Array[String]
if not is_init then
var mtype = mclassdef.mclass.mclass_type
var arg_name = "arg___self"
fc.decls.add " {mtype.cname_blind} {arg_name};\n"
fc.exprs.add " {arg_name} = argv[{k}].{mtype.call_arg_field};\n"
args_for_call.add arg_name
k += 1
end
for param in msignature.mparameters do
var mtype = param.mtype
var arg_name = "arg__"+param.name
fc.decls.add " {mtype.cname_blind} {arg_name};\n"
fc.exprs.add " {arg_name} = argv[{k}].{mtype.call_arg_field};\n"
args_for_call.add arg_name
k += 1
end
# Call implementation function
var args_compressed = args_for_call.join(", ")
var method_call = "{impl_cname}({args_compressed})"
if return_mtype != null then
fc.decls.add """
{{{return_mtype.cname_blind}}} return_value;
"""
fc.exprs.add """
return_value = {{{method_call}}};
result->{{{return_mtype.call_arg_field}}} = return_value;
"""
else
fc.exprs.add " {method_call};\n"
end
fc.exprs.add " return 0;\n"
ecc.add_exported_function fc
end
end
src/interpreter/dynamic_loading_ffi/on_demand_compiler.nit:283,1--375,3
redef class MMethodDef
redef fun create_ast_representation(astbuilder: nullable ASTBuilder): AMethPropdef do
if astbuilder == null then astbuilder = new ASTBuilder(mclassdef.mmodule)
var tk_redef = null
if self.mproperty.intro != self then tk_redef = new TKwredef
var n_signature = if self.msignature == null then new ASignature else self.msignature.create_ast_representation(astbuilder)
return astbuilder.make_method(visibility.create_ast_representation(astbuilder), tk_redef, self, n_signature)
end
end
src/astbuilder.nit:983,1--991,3
redef class MMethodDef
# Can the body be inlined?
fun can_inline(v: VISITOR): Bool
do
if is_abstract then return true
if constant_value != null then return true
var modelbuilder = v.compiler.modelbuilder
var node = modelbuilder.mpropdef2node(self)
if node isa APropdef then
return node.can_inline
else if node isa AClassdef then
# Automatic free init is always inlined since it is empty or contains only attribtes assigments
return true
else if node == null then
return true
else
abort
end
end
# Inline the body in another visitor
fun compile_inside_to_c(v: VISITOR, arguments: Array[RuntimeVariable]): nullable RuntimeVariable
do
var modelbuilder = v.compiler.modelbuilder
var val = constant_value
var node = modelbuilder.mpropdef2node(self)
if is_abstract then
v.add_raw_throw
var cn = v.class_name_string(arguments.first)
v.current_node = node
v.add("PRINT_ERROR(\"Runtime error: Abstract method `%s` called on `%s`\", \"{mproperty.name.escape_to_c}\", {cn});")
v.add_raw_abort
return null
end
if node isa APropdef then
var oldnode = v.current_node
v.current_node = node
self.compile_parameter_check(v, arguments)
node.compile_to_c(v, self, arguments)
v.current_node = oldnode
else if node isa AClassdef then
var oldnode = v.current_node
v.current_node = node
self.compile_parameter_check(v, arguments)
node.compile_to_c(v, self, arguments)
v.current_node = oldnode
else if val != null then
v.ret(v.value_instance(val))
else
abort
end
return null
end
# Generate type checks in the C code to check covariant parameters
fun compile_parameter_check(v: VISITOR, arguments: Array[RuntimeVariable])
do
if v.compiler.modelbuilder.toolcontext.opt_no_check_covariance.value then return
var msignature = self.msignature.as(not null)
for i in [0..msignature.arity[ do
var mp = msignature.mparameters[i]
# skip test for vararg since the array is instantiated with the correct polymorphic type
if mp.is_vararg then continue
# skip if the cast is not required
var origmtype = self.mproperty.intro.msignature.mparameters[i].mtype
if not origmtype.need_anchor then continue
# get the parameter type
var mtype = mp.mtype
# generate the cast
# note that v decides if and how to implements the cast
v.add("/* Covariant cast for argument {i} ({mp.name}) {arguments[i+1].inspect} isa {mtype} */")
v.add_cast(arguments[i+1], mtype, "covariance")
end
end
end
src/compiler/abstract_compiler.nit:2528,1--2609,3
redef class MMethodDef
redef fun write_signature_to_stream(stream)
do
var msignature = msignature
if msignature != null then
stream.write msignature.to_s
end
end
redef fun write_location(mainmodule, stream)
do
for i in 2.times do stream.write line_separator
stream.write "## Location of introduction and refinements"
# Group locations in the same file
var file_to_location = new MultiHashMap[nullable SourceFile, Location]
for c in mproperty.mpropdefs do
file_to_location[c.location.file].add c.location
end
# Write one file per location
for file, locations in file_to_location do
var l = locations.first
stream.write line_separator
stream.write "* {l}"
if locations.length > 1 then stream.write " ({locations.length-1} more)"
end
end
end
src/doc/vim_autocomplete.nit:111,1--139,3
redef class MMethodDef
# Verification of the contract facet
# Check if a contract facet already exists to use it again or if it is necessary to create it.
private fun check_contract_facet(v: ContractsVisitor, n_signature: ASignature, classdef: MClassDef, mcontract: MContract, exist_contract: Bool)
do
var exist_contract_facet = mproperty.check_exist_contract_facet(self)
if exist_contract_facet and exist_contract then return
var contract_facet: AMethPropdef
if not exist_contract_facet then
# If has no contract facet in intro just create it
if classdef != mproperty.intro_mclassdef then create_contract_facet(v, mproperty.intro_mclassdef, n_signature)
# If has no contract facet just create it
contract_facet = create_contract_facet(v, classdef, n_signature)
else
# Check if the contract facet already exist in this context (in this classdef)
if classdef.mpropdefs_by_property.has_key(mproperty.mcontract_facet) then
# get the define
contract_facet = v.toolcontext.modelbuilder.mpropdef2node(classdef.mpropdefs_by_property[mproperty.mcontract_facet]).as(AMethPropdef)
else
# create a new contract facet definition
contract_facet = create_contract_facet(v, classdef, n_signature)
var block = v.ast_builder.make_block
# super call to the contract facet
var n_super_call = v.ast_builder.make_super_call(n_signature.make_parameter_read(v.ast_builder), null)
# verification for add a return or not
if contract_facet.mpropdef.msignature.return_mtype != null then
block.add(v.ast_builder.make_return(n_super_call))
else
block.add(n_super_call)
end
contract_facet.n_block = block
end
end
contract_facet.adapt_block_to_contract(v, mcontract, contract_facet)
contract_facet.location = v.current_location
contract_facet.do_all(v.toolcontext)
end
# Method to create a contract facet of the method
private fun create_contract_facet(v: ContractsVisitor, classdef: MClassDef, n_signature: ASignature): AMethPropdef
do
var contract_facet = mproperty.mcontract_facet
assert contract_facet != null
# Defines the contract phase is an init or not
# it is necessary to use the contracts on constructor
contract_facet.is_init = self.mproperty.is_init
# check if the method has an `msignature` to copy it.
var m_signature: nullable MSignature = null
if mproperty.intro.msignature != null then m_signature = mproperty.intro.msignature.clone
var n_contractdef = classdef.mclass.create_empty_method(v, contract_facet, classdef, m_signature, n_signature)
# FIXME set the location because the callsite creation need the node location
n_contractdef.location = v.current_location
n_contractdef.validate
var block = v.ast_builder.make_block
var n_self = new ASelfExpr
var args = n_contractdef.n_signature.make_parameter_read(v.ast_builder)
var callsite = v.ast_builder.create_callsite(v.toolcontext.modelbuilder, n_contractdef, mproperty, true)
var n_call = v.ast_builder.make_call(n_self, callsite, args)
if m_signature.return_mtype == null then
block.add(n_call)
else
block.add(v.ast_builder.make_return(n_call))
end
n_contractdef.n_block = block
n_contractdef.do_all(v.toolcontext)
return n_contractdef
end
# Entry point to build contract (define the contract facet and define the contract method verification)
private fun construct_contract(v: ContractsVisitor, n_signature: ASignature, n_annotation: AAnnotation, mcontract: MContract, exist_contract: Bool)
do
if check_same_contract(v, n_annotation, mcontract) then return
if not exist_contract and not is_intro then no_intro_contract(v, n_signature, mcontract, n_annotation)
v.define_signature(mcontract, n_signature, mproperty.intro.msignature)
var conditiondef = v.build_contract(n_annotation, mcontract, mclassdef)
check_contract_facet(v, n_signature.clone, mclassdef, mcontract, exist_contract)
has_contract = true
end
# Create a contract on the introduction classdef of the property.
# Display an warning message if necessary
private fun no_intro_contract(v: ContractsVisitor, n_signature: ASignature, mcontract: MContract, n_annotation: AAnnotation)
do
mcontract.create_empty_contract(v, mcontract.intro_mclassdef, mcontract.adapt_msignature(self.mproperty.intro.msignature), mcontract.adapt_nsignature(n_signature))
mcontract.no_intro_contract(v, n_annotation)
mproperty.intro.has_contract = true
end
# Is the contract already defined in the context
#
# Exemple :
# fun foo is expect([...]), expect([...])
#
# Here `check_same_contract` display an error when the second expect is processed
private fun check_same_contract(v: ContractsVisitor, n_annotation: AAnnotation ,mcontract: MContract): Bool
do
if self.mclassdef.mpropdefs_by_property.has_key(mcontract) then
v.toolcontext.error(n_annotation.location, "The method already has a defined `{mcontract.contract_name}` contract at line {self.mclassdef.mpropdefs_by_property[mcontract].location.line_start}")
return true
end
return false
end
end
src/contracts.nit:653,1--763,3
redef class MMethodDef
# The C function associated to a mmethoddef
fun separate_runtime_function: SeparateRuntimeFunction
do
var res = self.separate_runtime_function_cache
if res == null then
var recv = mclassdef.bound_mtype
var msignature = msignature.resolve_for(recv, recv, mclassdef.mmodule, true)
res = new SeparateRuntimeFunction(self, recv, msignature, c_name)
self.separate_runtime_function_cache = res
end
return res
end
# Returns true if the current method definition differ from
# its original introduction in terms of receiver type.
fun recv_differ_from_intro: Bool
do
var intromclassdef = mproperty.intro.mclassdef
var introrecv = intromclassdef.bound_mtype
return self.mclassdef.bound_mtype != introrecv
end
# The C thunk function associated to a mmethoddef. Receives only nullable
# Object and cast them to the original mmethoddef signature.
fun callref_thunk(recv_mtype: MClassType): SeparateThunkFunction
do
var res = callref_thunk_cache
if res == null then
var object_type = mclassdef.mmodule.object_type
var nullable_object = object_type.as_nullable
var ps = new Array[MParameter]
# Replace every argument type by nullable object
for p in msignature.mparameters do
ps.push(new MParameter(p.name, nullable_object, p.is_vararg))
end
var ret: nullable MType = null
if msignature.return_mtype != null then ret = nullable_object
var msignature2 = new MSignature(ps, ret)
var intromclassdef = mproperty.intro.mclassdef
res = new SeparateThunkFunction(self, recv_mtype, msignature2, "THUNK_{c_name}", mclassdef.bound_mtype)
res.polymorph_call_flag = true
callref_thunk_cache = res
end
return res
end
private var callref_thunk_cache: nullable SeparateThunkFunction
private var separate_runtime_function_cache: nullable SeparateRuntimeFunction
# The C function associated to a mmethoddef, that can be stored into a VFT of a class
# The first parameter (the reciever) is always typed by val* in order to accept an object value
# The C-signature is always compatible with the intro
fun virtual_runtime_function: SeparateRuntimeFunction
do
var res = self.virtual_runtime_function_cache
if res == null then
# Because the function is virtual, the signature must match the one of the original class
var intromclassdef = mproperty.intro.mclassdef
var recv = intromclassdef.bound_mtype
res = separate_runtime_function
if res.called_recv == recv then
self.virtual_runtime_function_cache = res
return res
end
var msignature = mproperty.intro.msignature.resolve_for(recv, recv, intromclassdef.mmodule, true)
if recv.ctype == res.called_recv.ctype and msignature.c_equiv(res.called_signature) then
self.virtual_runtime_function_cache = res
return res
end
res = new SeparateThunkFunction(self, recv, msignature, "VIRTUAL_{c_name}", mclassdef.bound_mtype)
end
return res
end
private var virtual_runtime_function_cache: nullable SeparateRuntimeFunction
end
src/compiler/separate_compiler.nit:2364,1--2444,3
redef class MMethodDef
redef fun cs_signature(no_color) do
return msignature.as(not null).cs_signature(no_color)
end
end
src/doc/templates/term_model.nit:200,1--204,3
redef class MMethodDef
redef fun tpl_module(model) do
var t = new Template
t.add mproperty.visibility.tpl_class
t.add " "
t.add name.escape_to_dot
t.add msignature.tpl_class(model)
return t
end
end
src/uml/uml_module.nit:132,1--141,3
redef class MMethodDef
super TableCallable
# Runtime name
private fun rt_name: String do
return "RTMethod_{mclassdef.mmodule.jname}_{mclassdef.mclass.jname}_{mproperty.jname}"
end
# Generate a Java RTMethod for `self`
fun compile_to_java(v: JavaCompilerVisitor) do
v.add("public class {rt_name} extends RTMethod \{")
v.add(" protected static RTMethod instance;")
v.add(" public static RTMethod get{rt_name}() \{")
v.add(" if(instance == null) \{")
v.add(" instance = new {rt_name}();")
v.add(" \}")
v.add(" return instance;")
v.add(" \}")
v.add(" @Override")
v.add(" public RTVal exec(RTVal[] args) \{")
compile_inside_to_java(v)
v.add(" \}")
v.add("\}")
end
# Compile the body of this function
fun compile_inside_to_java(v: JavaCompilerVisitor) do
var modelbuilder = v.compiler.modelbuilder
var node = modelbuilder.mpropdef2node(self)
var recv = mclassdef.bound_mtype
var arguments = new Array[RuntimeVariable]
var frame = new JavaStaticFrame(v, self, recv, arguments)
v.frame = frame
var selfvar = v.decl_var("self", recv)
arguments.add(selfvar)
var boxed = v.new_expr("args[0]", v.compiler.mainmodule.object_type)
v.add "{selfvar} = {v.autobox(boxed, recv)};"
var msignature = self.msignature
var ret = null
if msignature != null then
ret = msignature.return_mtype
if ret != null then
var retvar = v.decl_var("ret", ret)
if ret.name == "Int" then v.add "{retvar} = 0;"
if ret.name == "Float" then v.add "{retvar} = 0.0;"
if ret.name == "Bool" then v.add "{retvar} = false;"
if ret.name == "Char" then v.add "{retvar} = 0;"
if ret.name == "Byte" then v.add "{retvar} = 0;"
frame.returnvar = retvar
end
end
frame.returnlabel = v.get_name("RET_LABEL")
v.current_node = node
if is_abstract then
v.add_abort("Abstract method `{mproperty.name}` called on `\" + {selfvar}.rtclass.class_name +\"`")
v.add("return null;")
return
end
v.current_node = null
v.add("{frame.returnlabel.as(not null)}: \{")
if node isa APropdef then
node.compile_to_java(v, self, arguments)
else if node isa AClassdef then
node.compile_to_java(v, self, arguments)
else
abort
end
v.add("\}")
if ret != null then
v.add("return {v.autobox(frame.returnvar.as(not null), v.compiler.mainmodule.object_type)};")
else
v.add("return null;")
end
end
end
src/compiler/java_compiler.nit:1399,1--1481,3
redef class MMethodDef
var line_number = 0
var total_self_call = 0
var class_call = new Counter[MClassType]
end
src/metrics/method_analyze_metrics.nit:75,1--79,3
redef class MMethodDef
redef fun html_signature(short) do
var msignature = self.msignature
if msignature == null then return new Template
return msignature.html_signature(short)
end
end
src/doc/templates/html_model.nit:252,1--258,3
redef class MMethodDef
redef fun core_serialize_to(v) do
super
v.serialize_attribute("msignature", msignature)
end
end
src/doc/templates/json_model.nit:283,1--288,3