A definition of all kind of method (including constructors)

Introduced properties

private var _auto_super_call: Bool

nitc :: AMethPropdef :: _auto_super_call

In case of redefined constructors, is an implicit call-to-super required?
private var _auto_super_inits: nullable Array[CallSite]

nitc :: AMethPropdef :: _auto_super_inits

In case of introduced constructor, the list of implicit auto super init constructors invoked (if needed)
private var _foreign_entry_cache: nullable ForeignCodeEntry

nitc :: AMethPropdef :: _foreign_entry_cache

Handle to the entrypoint of this method in the foreign code library
private var _is_autoinit: Bool

nitc :: AMethPropdef :: _is_autoinit

Is the method annotated autoinit?
private var _n_block: nullable AExpr

nitc :: AMethPropdef :: _n_block

The body (in Nit) of the method, if any
private var _n_extern_calls: nullable AExternCalls

nitc :: AMethPropdef :: _n_extern_calls

The list of declared callbacks (for extern methods)
private var _n_extern_code_block: nullable AExternCodeBlock

nitc :: AMethPropdef :: _n_extern_code_block

The body (in extern code) of the method, if any
private var _n_kwdo: nullable TKwdo

nitc :: AMethPropdef :: _n_kwdo

The do keyword
private var _n_kwend: nullable TKwend

nitc :: AMethPropdef :: _n_kwend

The end keyword
private var _n_kwinit: nullable TKwinit

nitc :: AMethPropdef :: _n_kwinit

The init keyword, if any
private var _n_kwisa: nullable TKwisa

nitc :: AMethPropdef :: _n_kwisa

The isa keyword, if any
private var _n_kwmeth: nullable TKwmeth

nitc :: AMethPropdef :: _n_kwmeth

The fun keyword, if any
private var _n_kwnew: nullable TKwnew

nitc :: AMethPropdef :: _n_kwnew

The new keyword, if any
private var _n_methid: nullable AMethid

nitc :: AMethPropdef :: _n_methid

The name of the method, if any
private var _n_signature: nullable ASignature

nitc :: AMethPropdef :: _n_signature

The signature of the method, if any
fun accept_externmeth: Bool

nitc :: AMethPropdef :: accept_externmeth

Should we compile the extern method self?
private fun adapt_block_to_contract(v: ContractsVisitor, contract: MContract, n_mpropdef: AMethPropdef)

nitc :: AMethPropdef :: adapt_block_to_contract

Adapt the block to use the contracts
fun auto_super_call: Bool

nitc :: AMethPropdef :: auto_super_call

In case of redefined constructors, is an implicit call-to-super required?
protected fun auto_super_call=(auto_super_call: Bool)

nitc :: AMethPropdef :: auto_super_call=

In case of redefined constructors, is an implicit call-to-super required?
fun auto_super_inits: nullable Array[CallSite]

nitc :: AMethPropdef :: auto_super_inits

In case of introduced constructor, the list of implicit auto super init constructors invoked (if needed)
protected fun auto_super_inits=(auto_super_inits: nullable Array[CallSite])

nitc :: AMethPropdef :: auto_super_inits=

In case of introduced constructor, the list of implicit auto super init constructors invoked (if needed)
fun call_commons(v: NaiveInterpreter, mpropdef: MMethodDef, arguments: Array[Instance], f: Frame): nullable Instance

nitc :: AMethPropdef :: call_commons

Execution of the body of the method
protected fun call_extern(v: NaiveInterpreter, mpropdef: MMethodDef, arguments: Array[Instance], f: Frame): nullable Instance

nitc :: AMethPropdef :: call_extern

Call this extern method
private fun check_annotation(v: ContractsVisitor, n_annotation: AAnnotation)

nitc :: AMethPropdef :: check_annotation

Verification of the annotation to know if it is a contract annotation.
private fun check_redef(v: ContractsVisitor)

nitc :: AMethPropdef :: check_redef

Verification if the method have an inherited contract to apply it.
fun compile_ffi_method(mmodule: MModule)

nitc :: AMethPropdef :: compile_ffi_method

Compile the necessary wrapper around this extern method or constructor
private fun compile_inside_to_java(v: JavaCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable])

nitc :: AMethPropdef :: compile_inside_to_java

Compile the inside of the method body
fun compile_intern_to_java(v: JavaCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable]): Bool

nitc :: AMethPropdef :: compile_intern_to_java

Compile an intern method using Java primitives
private fun do_all(toolcontext: ToolContext)

nitc :: AMethPropdef :: do_all

Execute all method verification scope flow and typing.
fun do_auto_super_init(modelbuilder: ModelBuilder)

nitc :: AMethPropdef :: do_auto_super_init

Collect initializers and build the auto-init
fun foreign_callbacks: ForeignCallbackSet

nitc :: AMethPropdef :: foreign_callbacks

All foreign callbacks from this method
private fun foreign_callbacks_cache=(foreign_callbacks_cache: nullable ForeignCallbackSet)

nitc :: AMethPropdef :: foreign_callbacks_cache=

private fun foreign_entry_cache: nullable ForeignCodeEntry

nitc :: AMethPropdef :: foreign_entry_cache

Handle to the entrypoint of this method in the foreign code library
private fun foreign_entry_cache=(foreign_entry_cache: nullable ForeignCodeEntry)

nitc :: AMethPropdef :: foreign_entry_cache=

Handle to the entrypoint of this method in the foreign code library
private fun get_super_candidatedefs(modelbuilder: ModelBuilder): Array[MMethodDef]

nitc :: AMethPropdef :: get_super_candidatedefs

This method returns the list of possible candidates for the current definition.
init init_amethpropdef(n_doc: nullable ADoc, n_kwredef: nullable TKwredef, n_visibility: nullable AVisibility, n_kwmeth: nullable TKwmeth, n_kwinit: nullable TKwinit, n_kwisa: nullable TKwisa, n_kwnew: nullable TKwnew, n_methid: nullable AMethid, n_signature: nullable ASignature, n_annotations: nullable AAnnotations, n_extern_calls: nullable AExternCalls, n_extern_code_block: nullable AExternCodeBlock, n_kwdo: nullable TKwdo, n_block: nullable AExpr, n_kwend: nullable TKwend)

nitc :: AMethPropdef :: init_amethpropdef

private fun insert_artificial_callbacks(toolcontext: ToolContext)

nitc :: AMethPropdef :: insert_artificial_callbacks

Insert additional explicit calls to get the current JNIEnv
private fun intern_call(v: NaiveInterpreter, mpropdef: MMethodDef, args: Array[Instance]): nullable Instance

nitc :: AMethPropdef :: intern_call

Interprets a intern or a shortcut extern method.
fun is_autoinit: Bool

nitc :: AMethPropdef :: is_autoinit

Is the method annotated autoinit?
protected fun is_autoinit=(is_autoinit: Bool)

nitc :: AMethPropdef :: is_autoinit=

Is the method annotated autoinit?
private fun look_like_a_root_init(modelbuilder: ModelBuilder, mclassdef: MClassDef): Bool

nitc :: AMethPropdef :: look_like_a_root_init

Can self be used as a root init?
private init make(n_visibility: nullable AVisibility, tk_redef: nullable TKwredef, mmethoddef: nullable MMethodDef, n_signature: nullable ASignature, n_annotations: nullable AAnnotations, n_extern_calls: nullable AExternCalls, n_extern_code_block: nullable AExternCodeBlock, n_block: nullable AExpr)

nitc :: AMethPropdef :: make

fun n_block: nullable AExpr

nitc :: AMethPropdef :: n_block

The body (in Nit) of the method, if any
fun n_block=(n_block: nullable AExpr)

nitc :: AMethPropdef :: n_block=

The body (in Nit) of the method, if any
fun n_extern_calls: nullable AExternCalls

nitc :: AMethPropdef :: n_extern_calls

The list of declared callbacks (for extern methods)
fun n_extern_calls=(n_extern_calls: nullable AExternCalls)

nitc :: AMethPropdef :: n_extern_calls=

The list of declared callbacks (for extern methods)
fun n_extern_code_block: nullable AExternCodeBlock

nitc :: AMethPropdef :: n_extern_code_block

The body (in extern code) of the method, if any
fun n_extern_code_block=(n_extern_code_block: nullable AExternCodeBlock)

nitc :: AMethPropdef :: n_extern_code_block=

The body (in extern code) of the method, if any
fun n_kwdo: nullable TKwdo

nitc :: AMethPropdef :: n_kwdo

The do keyword
fun n_kwdo=(n_kwdo: nullable TKwdo)

nitc :: AMethPropdef :: n_kwdo=

The do keyword
fun n_kwend: nullable TKwend

nitc :: AMethPropdef :: n_kwend

The end keyword
fun n_kwend=(n_kwend: nullable TKwend)

nitc :: AMethPropdef :: n_kwend=

The end keyword
fun n_kwinit: nullable TKwinit

nitc :: AMethPropdef :: n_kwinit

The init keyword, if any
fun n_kwinit=(n_kwinit: nullable TKwinit)

nitc :: AMethPropdef :: n_kwinit=

The init keyword, if any
fun n_kwisa: nullable TKwisa

nitc :: AMethPropdef :: n_kwisa

The isa keyword, if any
fun n_kwisa=(n_kwisa: nullable TKwisa)

nitc :: AMethPropdef :: n_kwisa=

The isa keyword, if any
fun n_kwmeth: nullable TKwmeth

nitc :: AMethPropdef :: n_kwmeth

The fun keyword, if any
fun n_kwmeth=(n_kwmeth: nullable TKwmeth)

nitc :: AMethPropdef :: n_kwmeth=

The fun keyword, if any
fun n_kwnew: nullable TKwnew

nitc :: AMethPropdef :: n_kwnew

The new keyword, if any
fun n_kwnew=(n_kwnew: nullable TKwnew)

nitc :: AMethPropdef :: n_kwnew=

The new keyword, if any
fun n_methid: nullable AMethid

nitc :: AMethPropdef :: n_methid

The name of the method, if any
fun n_methid=(n_methid: nullable AMethid)

nitc :: AMethPropdef :: n_methid=

The name of the method, if any
fun n_signature: nullable ASignature

nitc :: AMethPropdef :: n_signature

The signature of the method, if any
fun n_signature=(n_signature: nullable ASignature)

nitc :: AMethPropdef :: n_signature=

The signature of the method, if any
fun supported_by_dynamic_ffi: Bool

nitc :: AMethPropdef :: supported_by_dynamic_ffi

Does this method definition use the FFI and is it supported by the interpreter?
fun verify_nitni_callbacks(toolcontext: ToolContext)

nitc :: AMethPropdef :: verify_nitni_callbacks

Verifiy the validity of the explicit callbacks to Nit

Redefined properties

redef type MPROPDEF: MMethodDef

nitc :: modelize_property $ AMethPropdef :: MPROPDEF

The associated main model entity
redef type SELF: AMethPropdef

nitc $ AMethPropdef :: SELF

Type of this instance, automatically specialized in every class
redef fun accept_externmeth: Bool

nitc :: light_only $ AMethPropdef :: accept_externmeth

Should we compile the extern method self?
redef fun accept_forward_analysis(v: ForwardAnalysis)

nitc :: saf_base $ AMethPropdef :: accept_forward_analysis

Apply the forward analysis v to self.
redef fun accept_pretty_printer(v: PrettyPrinterVisitor)

nitc :: pretty $ AMethPropdef :: accept_pretty_printer

Start visit of self using a PrettyPrinterVisitor
redef fun build_property(modelbuilder: ModelBuilder, mclassdef: MClassDef)

nitc :: modelize_property $ AMethPropdef :: build_property

redef fun call(v: NaiveInterpreter, mpropdef: MMethodDef, args: Array[Instance]): nullable Instance

nitc :: naive_interpreter $ AMethPropdef :: call

Execute a mpropdef associated with the current node.
redef fun call_extern(v: NaiveInterpreter, mpropdef: MMethodDef, args: Array[Instance], frame: Frame): nullable Instance

nitc :: dynamic_loading_ffi $ AMethPropdef :: call_extern

Call this extern method
redef fun can_inline: Bool

nitc :: separate_compiler $ AMethPropdef :: can_inline

The semi-global compilation does not support inlining calls to extern news
redef fun check_repeated_types(modelbuilder: ModelBuilder)

nitc :: modelize_property $ AMethPropdef :: check_repeated_types

For parameters, type is always useless in a redef.
redef fun compile_externinit_to_c(v: AbstractCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable]): Bool

nitc :: light $ AMethPropdef :: compile_externinit_to_c

Compile an extern factory
redef fun compile_externmeth_to_c(v: AbstractCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable]): Bool

nitc :: light $ AMethPropdef :: compile_externmeth_to_c

Compile an extern method
redef fun compile_to_java(v: JavaCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable])

nitc :: java_compiler $ AMethPropdef :: compile_to_java

Compile that property definition to java code
redef fun create_contracts(v: ContractsVisitor)

nitc :: contracts $ AMethPropdef :: create_contracts

Entry point to create a contract (verification of inheritance, or new contract).
redef fun do_typing(modelbuilder: ModelBuilder)

nitc :: typing $ AMethPropdef :: do_typing

The entry point of the whole typing analysis
redef fun generate_basic_blocks(ssa: SSA)

nitc :: ssa $ AMethPropdef :: generate_basic_blocks

Generate all basic blocks for this code
redef fun hot_location: Location

nitc $ AMethPropdef :: hot_location

The location of the important part of the node (identifier or whatever)
redef fun is_inlinable: Bool

nitc :: pretty $ AMethPropdef :: is_inlinable

Can be inlined if:
redef fun n_annotations=(node: nullable AAnnotations)

nitc :: parser_prod $ AMethPropdef :: n_annotations=

All the annotations attached directly to the node
redef fun n_block=(node: nullable AExpr)

nitc :: parser_prod $ AMethPropdef :: n_block=

The body (in Nit) of the method, if any
redef fun n_doc=(node: nullable ADoc)

nitc :: parser_prod $ AMethPropdef :: n_doc=

The documentation
redef fun n_extern_calls=(node: nullable AExternCalls)

nitc :: parser_prod $ AMethPropdef :: n_extern_calls=

The list of declared callbacks (for extern methods)
redef fun n_extern_code_block=(node: nullable AExternCodeBlock)

nitc :: parser_prod $ AMethPropdef :: n_extern_code_block=

The body (in extern code) of the method, if any
redef fun n_kwdo=(node: nullable TKwdo)

nitc :: parser_prod $ AMethPropdef :: n_kwdo=

The do keyword
redef fun n_kwend=(node: nullable TKwend)

nitc :: parser_prod $ AMethPropdef :: n_kwend=

The end keyword
redef fun n_kwinit=(node: nullable TKwinit)

nitc :: parser_prod $ AMethPropdef :: n_kwinit=

The init keyword, if any
redef fun n_kwisa=(node: nullable TKwisa)

nitc :: parser_prod $ AMethPropdef :: n_kwisa=

The isa keyword, if any
redef fun n_kwmeth=(node: nullable TKwmeth)

nitc :: parser_prod $ AMethPropdef :: n_kwmeth=

The fun keyword, if any
redef fun n_kwnew=(node: nullable TKwnew)

nitc :: parser_prod $ AMethPropdef :: n_kwnew=

The new keyword, if any
redef fun n_kwredef=(node: nullable TKwredef)

nitc :: parser_prod $ AMethPropdef :: n_kwredef=

The redef keyword
redef fun n_methid=(node: nullable AMethid)

nitc :: parser_prod $ AMethPropdef :: n_methid=

The name of the method, if any
redef fun n_signature=(node: nullable ASignature)

nitc :: parser_prod $ AMethPropdef :: n_signature=

The signature of the method, if any
redef fun n_visibility=(node: nullable AVisibility)

nitc :: parser_prod $ AMethPropdef :: n_visibility=

The declared visibility
redef fun numbering_variables(vm: VirtualMachine)

nitc :: variables_numbering $ AMethPropdef :: numbering_variables

Assign a position in the environment to each local variable
redef fun replace_child(old_child: ANode, new_child: nullable ANode)

nitc :: parser_prod $ AMethPropdef :: replace_child

Replace a child with an other node in the AST
redef fun verify_nitni_callbacks(toolcontext: ToolContext)

nitc :: java $ AMethPropdef :: verify_nitni_callbacks

Verifiy the validity of the explicit callbacks to Nit
redef fun visit_all(v: Visitor)

nitc :: parser_prod $ AMethPropdef :: visit_all

Visit all nodes in order.

All properties

fun !=(other: nullable Object): Bool

core :: Object :: !=

Have self and other different values?
fun ==(other: nullable Object): Bool

core :: Object :: ==

Have self and other the same value?
type CLASS: Class[SELF]

core :: Object :: CLASS

The type of the class of self.
type MPROPDEF: MPropDef

nitc :: APropdef :: MPROPDEF

The associated main model entity
type SELF: Object

core :: Object :: SELF

Type of this instance, automatically specialized in every class
private var _after_flow_context: nullable FlowContext

nitc :: APropdef :: _after_flow_context

The ending flow
private var _auto_super_call: Bool

nitc :: AMethPropdef :: _auto_super_call

In case of redefined constructors, is an implicit call-to-super required?
private var _auto_super_inits: nullable Array[CallSite]

nitc :: AMethPropdef :: _auto_super_inits

In case of introduced constructor, the list of implicit auto super init constructors invoked (if needed)
private var _basic_block: nullable BasicBlock

nitc :: APropdef :: _basic_block

The first basic block of the code
private var _before_flow_context: nullable FlowContext

nitc :: APropdef :: _before_flow_context

The starting flow
private var _environment_size: Int

nitc :: APropdef :: _environment_size

The size of the environment to create to call this method
private var _first_location: nullable Location

nitc :: Prod :: _first_location

Location on the first token after the start of a production
private var _first_token: nullable Token

nitc :: Prod :: _first_token

The first token of the production in the AST
private var _force_block: Bool

nitc :: ANode :: _force_block

Force self to be rendered as a block.
private var _force_inline: Bool

nitc :: ANode :: _force_inline

Force self to be rendered as a line.
private var _foreign_entry_cache: nullable ForeignCodeEntry

nitc :: AMethPropdef :: _foreign_entry_cache

Handle to the entrypoint of this method in the foreign code library
private var _is_autoinit: Bool

nitc :: AMethPropdef :: _is_autoinit

Is the method annotated autoinit?
private var _is_broken: Bool

nitc :: ANode :: _is_broken

The indication that the node did not pass some semantic verifications.
private var _is_compiled: Bool

nitc :: APropdef :: _is_compiled

Indicite if this propdef was compile
private var _is_generated: Bool

nitc :: APropdef :: _is_generated

If true, the basic blocks where generated
private var _is_numbering: Bool

nitc :: APropdef :: _is_numbering

Indicate if the variables numbering has been done
private var _is_phased: Bool

nitc :: APropdef :: _is_phased

Is the propdef already analyzed by run_phases_on_npropdef.
private var _last_token: nullable Token

nitc :: Prod :: _last_token

The last token of the production in the AST
private var _location: Location

nitc :: ANode :: _location

Location is set during AST building. Once built, location can not be null.
private var _mpropdef: nullable MPROPDEF

nitc :: APropdef :: _mpropdef

The associated propdef once build by a ModelBuilder
private var _n_annotations: nullable AAnnotations

nitc :: Prod :: _n_annotations

All the annotations attached directly to the node
private var _n_block: nullable AExpr

nitc :: AMethPropdef :: _n_block

The body (in Nit) of the method, if any
private var _n_doc: nullable ADoc

nitc :: ADefinition :: _n_doc

The documentation
private var _n_extern_calls: nullable AExternCalls

nitc :: AMethPropdef :: _n_extern_calls

The list of declared callbacks (for extern methods)
private var _n_extern_code_block: nullable AExternCodeBlock

nitc :: AMethPropdef :: _n_extern_code_block

The body (in extern code) of the method, if any
private var _n_kwdo: nullable TKwdo

nitc :: AMethPropdef :: _n_kwdo

The do keyword
private var _n_kwend: nullable TKwend

nitc :: AMethPropdef :: _n_kwend

The end keyword
private var _n_kwinit: nullable TKwinit

nitc :: AMethPropdef :: _n_kwinit

The init keyword, if any
private var _n_kwisa: nullable TKwisa

nitc :: AMethPropdef :: _n_kwisa

The isa keyword, if any
private var _n_kwmeth: nullable TKwmeth

nitc :: AMethPropdef :: _n_kwmeth

The fun keyword, if any
private var _n_kwnew: nullable TKwnew

nitc :: AMethPropdef :: _n_kwnew

The new keyword, if any
private var _n_kwredef: nullable TKwredef

nitc :: ADefinition :: _n_kwredef

The redef keyword
private var _n_methid: nullable AMethid

nitc :: AMethPropdef :: _n_methid

The name of the method, if any
private var _n_signature: nullable ASignature

nitc :: AMethPropdef :: _n_signature

The signature of the method, if any
private var _n_visibility: nullable AVisibility

nitc :: ADefinition :: _n_visibility

The declared visibility
private var _object_sites: Array[AExpr]

nitc :: APropdef :: _object_sites

Contain all AST-parts related to object mechanisms the propdef has:
private var _parent: nullable ANode

nitc :: ANode :: _parent

Parent of the node in the AST
private var _return_mark: nullable EscapeMark

nitc :: APropdef :: _return_mark

The break escape mark associated with the return
private var _returnvar: Variable

nitc :: APropdef :: _returnvar

The return variable of the propdef
private var _selfvariable: nullable Variable

nitc :: APropdef :: _selfvariable

The variable associated to the receiver (if any)
private var _variables: HashSet[Variable]

nitc :: APropdef :: _variables

The variables contained in the body on this propdef
fun accept_externmeth: Bool

nitc :: AMethPropdef :: accept_externmeth

Should we compile the extern method self?
fun accept_forward_analysis(v: ForwardAnalysis)

nitc :: ANode :: accept_forward_analysis

Apply the forward analysis v to self.
private abstract fun accept_pretty_printer(v: PrettyPrinterVisitor)

nitc :: ANode :: accept_pretty_printer

Start visit of self using a PrettyPrinterVisitor
fun accept_reaching_defs(v: ReachingDefsAnalysis)

nitc :: ANode :: accept_reaching_defs

Apply a ReachingDefsAnalysis to self.
private fun adapt_block_to_contract(v: ContractsVisitor, contract: MContract, n_mpropdef: AMethPropdef)

nitc :: AMethPropdef :: adapt_block_to_contract

Adapt the block to use the contracts
fun after_flow_context: nullable FlowContext

nitc :: APropdef :: after_flow_context

The ending flow
protected fun after_flow_context=(after_flow_context: nullable FlowContext)

nitc :: APropdef :: after_flow_context=

The ending flow
fun auto_super_call: Bool

nitc :: AMethPropdef :: auto_super_call

In case of redefined constructors, is an implicit call-to-super required?
protected fun auto_super_call=(auto_super_call: Bool)

nitc :: AMethPropdef :: auto_super_call=

In case of redefined constructors, is an implicit call-to-super required?
fun auto_super_inits: nullable Array[CallSite]

nitc :: AMethPropdef :: auto_super_inits

In case of introduced constructor, the list of implicit auto super init constructors invoked (if needed)
protected fun auto_super_inits=(auto_super_inits: nullable Array[CallSite])

nitc :: AMethPropdef :: auto_super_inits=

In case of introduced constructor, the list of implicit auto super init constructors invoked (if needed)
private fun bad_expr_message(child: AExpr): nullable String

nitc :: ANode :: bad_expr_message

An additional information message to explain the role of a child expression.
fun basic_block: nullable BasicBlock

nitc :: APropdef :: basic_block

The first basic block of the code
protected fun basic_block=(basic_block: nullable BasicBlock)

nitc :: APropdef :: basic_block=

The first basic block of the code
fun before_flow_context: nullable FlowContext

nitc :: APropdef :: before_flow_context

The starting flow
protected fun before_flow_context=(before_flow_context: nullable FlowContext)

nitc :: APropdef :: before_flow_context=

The starting flow
private fun build_property(modelbuilder: ModelBuilder, mclassdef: MClassDef)

nitc :: APropdef :: build_property

private fun build_signature(modelbuilder: ModelBuilder)

nitc :: APropdef :: build_signature

private fun call(v: NaiveInterpreter, mpropdef: MMethodDef, args: Array[Instance]): nullable Instance

nitc :: APropdef :: call

Execute a mpropdef associated with the current node.
fun call_commons(v: NaiveInterpreter, mpropdef: MMethodDef, arguments: Array[Instance], f: Frame): nullable Instance

nitc :: AMethPropdef :: call_commons

Execution of the body of the method
protected fun call_extern(v: NaiveInterpreter, mpropdef: MMethodDef, arguments: Array[Instance], f: Frame): nullable Instance

nitc :: AMethPropdef :: call_extern

Call this extern method
private fun check_annotation(v: ContractsVisitor, n_annotation: AAnnotation)

nitc :: AMethPropdef :: check_annotation

Verification of the annotation to know if it is a contract annotation.
private fun check_redef(v: ContractsVisitor)

nitc :: AMethPropdef :: check_redef

Verification if the method have an inherited contract to apply it.
private fun check_redef_keyword(modelbuilder: ModelBuilder, mclassdef: MClassDef, kwredef: nullable Token, need_redef: Bool, mprop: MProperty): Bool

nitc :: APropdef :: check_redef_keyword

private fun check_redef_property_visibility(modelbuilder: ModelBuilder, nvisibility: nullable AVisibility, mprop: MProperty)

nitc :: APropdef :: check_redef_property_visibility

private fun check_repeated_types(modelbuilder: ModelBuilder)

nitc :: APropdef :: check_repeated_types

Checks for useless type in redef signatures.
private fun check_signature(modelbuilder: ModelBuilder)

nitc :: APropdef :: check_signature

protected fun class_factory(name: String): CLASS

core :: Object :: class_factory

Implementation used by get_class to create the specific class.
fun class_name: String

core :: Object :: class_name

The class name of the object.
abstract fun clone: SELF

core :: Cloneable :: clone

Duplicate self
fun collect_annotations_by_name(name: String): Array[AAnnotation]

nitc :: ANode :: collect_annotations_by_name

Do a deep search and return an array of node that are annotated
private fun collect_comments: Array[TComment]

nitc :: Prod :: collect_comments

Collect all TComment contained in the production
private abstract fun collect_length: Int

nitc :: ANode :: collect_length

Collect the length (in Char) of the node.
fun collect_text: String

nitc :: Prod :: collect_text

Join the text of all visited tokens
fun collect_tokens_by_text(text: String): Array[Token]

nitc :: ANode :: collect_tokens_by_text

Do a deep search and return an array of tokens that match a given text
fun common_parent(other: ANode): nullable ANode

nitc :: ANode :: common_parent

The most specific common parent between self and other
fun compile(vm: VirtualMachine)

nitc :: APropdef :: compile

Compile this propdef
fun compile_ffi_method(mmodule: MModule)

nitc :: AMethPropdef :: compile_ffi_method

Compile the necessary wrapper around this extern method or constructor
private fun compile_inside_to_java(v: JavaCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable])

nitc :: AMethPropdef :: compile_inside_to_java

Compile the inside of the method body
fun compile_intern_to_java(v: JavaCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable]): Bool

nitc :: AMethPropdef :: compile_intern_to_java

Compile an intern method using Java primitives
fun compile_to_java(v: JavaCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable])

nitc :: APropdef :: compile_to_java

Compile that property definition to java code
fun compute_phi(ssa: SSA)

nitc :: APropdef :: compute_phi

Compute the first phase of SSA algorithm: placing phi-functions
fun compute_ssa(ssa: SSA)

nitc :: APropdef :: compute_ssa

Compute the three steps of SSA-algorithm
fun debug(message: String)

nitc :: ANode :: debug

Display a message for the colored location of the node
protected fun decorate_tag(v: HtmlightVisitor, res: HTMLTag, token: Token): nullable HInfoBox

nitc :: ANode :: decorate_tag

Add aditionnal information on a child-token and return an additionnal HInfoBox on it
fun depth: Int

nitc :: ANode :: depth

Number of nodes between self and the root of the AST
fun detach

nitc :: ANode :: detach

Detach a node from its parent
private fun do_all(toolcontext: ToolContext)

nitc :: AMethPropdef :: do_all

Execute all method verification scope flow and typing.
fun do_auto_super_init(modelbuilder: ModelBuilder)

nitc :: AMethPropdef :: do_auto_super_init

Collect initializers and build the auto-init
private fun do_cloneable(v: CloneVisitor)

nitc :: ANode :: do_cloneable

fun do_flow(toolcontext: ToolContext)

nitc :: APropdef :: do_flow

The entry point of the whole flow analysis
fun do_local_var_init(toolcontext: ToolContext)

nitc :: APropdef :: do_local_var_init

Entry point of the whole local variable initialization verifier
fun do_scope(toolcontext: ToolContext)

nitc :: APropdef :: do_scope

Entry point of the scope analysis
fun do_typing(modelbuilder: ModelBuilder)

nitc :: APropdef :: do_typing

The entry point of the whole typing analysis
fun dump_info(v: ASTDump): String

nitc :: ANode :: dump_info

Information to display on a node
fun dump_tree(display_structural: nullable Bool, display_line: nullable Bool)

nitc :: ANode :: dump_tree

Write the subtree on stdout.
private fun environment_size: Int

nitc :: APropdef :: environment_size

The size of the environment to create to call this method
private fun environment_size=(environment_size: Int)

nitc :: APropdef :: environment_size=

The size of the environment to create to call this method
fun fatal(v: NaiveInterpreter, message: String)

nitc :: ANode :: fatal

Aborts the program with a message
fun first_location: nullable Location

nitc :: Prod :: first_location

Location on the first token after the start of a production
protected fun first_location=(first_location: nullable Location)

nitc :: Prod :: first_location=

Location on the first token after the start of a production
fun first_token: nullable Token

nitc :: Prod :: first_token

The first token of the production in the AST
protected fun first_token=(first_token: nullable Token)

nitc :: Prod :: first_token=

The first token of the production in the AST
private fun force_block: Bool

nitc :: ANode :: force_block

Force self to be rendered as a block.
private fun force_block=(force_block: Bool)

nitc :: ANode :: force_block=

Force self to be rendered as a block.
private fun force_inline: Bool

nitc :: ANode :: force_inline

Force self to be rendered as a line.
private fun force_inline=(force_inline: Bool)

nitc :: ANode :: force_inline=

Force self to be rendered as a line.
fun foreign_callbacks: ForeignCallbackSet

nitc :: AMethPropdef :: foreign_callbacks

All foreign callbacks from this method
private fun foreign_callbacks_cache=(foreign_callbacks_cache: nullable ForeignCallbackSet)

nitc :: AMethPropdef :: foreign_callbacks_cache=

private fun foreign_entry_cache: nullable ForeignCodeEntry

nitc :: AMethPropdef :: foreign_entry_cache

Handle to the entrypoint of this method in the foreign code library
private fun foreign_entry_cache=(foreign_entry_cache: nullable ForeignCodeEntry)

nitc :: AMethPropdef :: foreign_entry_cache=

Handle to the entrypoint of this method in the foreign code library
abstract fun generate_basic_blocks(ssa: SSA)

nitc :: APropdef :: generate_basic_blocks

Generate all basic blocks for this code
fun generate_name(v: Variable, counter: HashMap[Variable, Int], expr: ANode, ssa: SSA): Variable

nitc :: APropdef :: generate_name

Generate a new version of the variable v and return it
fun get_annotations(name: String): Array[AAnnotation]

nitc :: Prod :: get_annotations

Return all its annotations of a given name in the order of their declaration
fun get_class: CLASS

core :: Object :: get_class

The meta-object representing the dynamic type of self.
fun get_single_annotation(name: String, modelbuilder: ModelBuilder): nullable AAnnotation

nitc :: Prod :: get_single_annotation

Try to get its single annotation with a given name
private fun get_super_candidatedefs(modelbuilder: ModelBuilder): Array[MMethodDef]

nitc :: AMethPropdef :: get_super_candidatedefs

This method returns the list of possible candidates for the current definition.
fun hash: Int

core :: Object :: hash

The hash code of the object.
fun hot_location: Location

nitc :: ANode :: hot_location

The location of the important part of the node (identifier or whatever)
fun infobox(v: HtmlightVisitor): nullable HInfoBox

nitc :: ANode :: infobox

Return a optional infobox
init init

core :: Object :: init

init init_amethpropdef(n_doc: nullable ADoc, n_kwredef: nullable TKwredef, n_visibility: nullable AVisibility, n_kwmeth: nullable TKwmeth, n_kwinit: nullable TKwinit, n_kwisa: nullable TKwisa, n_kwnew: nullable TKwnew, n_methid: nullable AMethid, n_signature: nullable ASignature, n_annotations: nullable AAnnotations, n_extern_calls: nullable AExternCalls, n_extern_code_block: nullable AExternCodeBlock, n_kwdo: nullable TKwdo, n_block: nullable AExpr, n_kwend: nullable TKwend)

nitc :: AMethPropdef :: init_amethpropdef

private fun insert_artificial_callbacks(toolcontext: ToolContext)

nitc :: AMethPropdef :: insert_artificial_callbacks

Insert additional explicit calls to get the current JNIEnv
fun inspect: String

core :: Object :: inspect

Developer readable representation of self.
protected fun inspect_head: String

core :: Object :: inspect_head

Return "CLASSNAME:#OBJECTID".
private fun intern_call(v: NaiveInterpreter, mpropdef: MMethodDef, args: Array[Instance]): nullable Instance

nitc :: AMethPropdef :: intern_call

Interprets a intern or a shortcut extern method.
fun is_autoinit: Bool

nitc :: AMethPropdef :: is_autoinit

Is the method annotated autoinit?
protected fun is_autoinit=(is_autoinit: Bool)

nitc :: AMethPropdef :: is_autoinit=

Is the method annotated autoinit?
fun is_block: Bool

nitc :: Prod :: is_block

Is the production contained in full block of line?
fun is_broken: Bool

nitc :: ANode :: is_broken

The indication that the node did not pass some semantic verifications.
fun is_broken=(is_broken: Bool)

nitc :: ANode :: is_broken=

The indication that the node did not pass some semantic verifications.
fun is_compiled: Bool

nitc :: APropdef :: is_compiled

Indicite if this propdef was compile
protected fun is_compiled=(is_compiled: Bool)

nitc :: APropdef :: is_compiled=

Indicite if this propdef was compile
fun is_generated: Bool

nitc :: APropdef :: is_generated

If true, the basic blocks where generated
protected fun is_generated=(is_generated: Bool)

nitc :: APropdef :: is_generated=

If true, the basic blocks where generated
private fun is_inlinable: Bool

nitc :: ANode :: is_inlinable

Is self printable in one line?
private fun is_noserialize: Bool

nitc :: ANode :: is_noserialize

Is this node annotated to not be made serializable?
private fun is_numbering: Bool

nitc :: APropdef :: is_numbering

Indicate if the variables numbering has been done
private fun is_numbering=(is_numbering: Bool)

nitc :: APropdef :: is_numbering=

Indicate if the variables numbering has been done
private fun is_phased: Bool

nitc :: APropdef :: is_phased

Is the propdef already analyzed by run_phases_on_npropdef.
private fun is_phased=(is_phased: Bool)

nitc :: APropdef :: is_phased=

Is the propdef already analyzed by run_phases_on_npropdef.
intern fun is_same_instance(other: nullable Object): Bool

core :: Object :: is_same_instance

Return true if self and other are the same instance (i.e. same identity).
fun is_same_serialized(other: nullable Object): Bool

core :: Object :: is_same_serialized

Is self the same as other in a serialization context?
intern fun is_same_type(other: Object): Bool

core :: Object :: is_same_type

Return true if self and other have the same dynamic type.
private fun is_serialize: Bool

nitc :: ANode :: is_serialize

Is this node annotated to be made serializable?
fun is_span: Bool

nitc :: Prod :: is_span

Is the production a part of a single line (without being a block)
fun is_structural: Bool

nitc :: ANode :: is_structural

Is self a token or a pure-structural production like AQId?
fun last_token: nullable Token

nitc :: Prod :: last_token

The last token of the production in the AST
protected fun last_token=(last_token: nullable Token)

nitc :: Prod :: last_token=

The last token of the production in the AST
fun lexer_accept(i: Int): Int

nitc :: TablesCapable :: lexer_accept

The accept value of the lexer at i
fun lexer_goto(i: Int, j: Int): Int

nitc :: TablesCapable :: lexer_goto

The goto value of the lexer at row i, column j-1
fun location: Location

nitc :: ANode :: location

Location is set during AST building. Once built, location can not be null.
fun location=(location: Location)

nitc :: ANode :: location=

Location is set during AST building. Once built, location can not be null.
private fun look_like_a_root_init(modelbuilder: ModelBuilder, mclassdef: MClassDef): Bool

nitc :: AMethPropdef :: look_like_a_root_init

Can self be used as a root init?
private init make(n_visibility: nullable AVisibility, tk_redef: nullable TKwredef, mmethoddef: nullable MMethodDef, n_signature: nullable ASignature, n_annotations: nullable AAnnotations, n_extern_calls: nullable AExternCalls, n_extern_code_block: nullable AExternCodeBlock, n_block: nullable AExpr)

nitc :: AMethPropdef :: make

protected fun make_tag(v: HtmlightVisitor): nullable HTMLTag

nitc :: ANode :: make_tag

Optionally creates a tag that encapsulate the AST element on HTML rendering
fun mpropdef: nullable MPROPDEF

nitc :: APropdef :: mpropdef

The associated propdef once build by a ModelBuilder
fun mpropdef=(mpropdef: nullable MPROPDEF)

nitc :: APropdef :: mpropdef=

The associated propdef once build by a ModelBuilder
private fun must_be_block: Bool

nitc :: ANode :: must_be_block

Does self have to be rendered as a block?
private fun must_be_inline: Bool

nitc :: ANode :: must_be_inline

Does self have be rendered as a line?
fun n_annotations: nullable AAnnotations

nitc :: Prod :: n_annotations

All the annotations attached directly to the node
fun n_annotations=(n_annotations: nullable AAnnotations)

nitc :: Prod :: n_annotations=

All the annotations attached directly to the node
fun n_block: nullable AExpr

nitc :: AMethPropdef :: n_block

The body (in Nit) of the method, if any
fun n_block=(n_block: nullable AExpr)

nitc :: AMethPropdef :: n_block=

The body (in Nit) of the method, if any
fun n_doc: nullable ADoc

nitc :: ADefinition :: n_doc

The documentation
fun n_doc=(n_doc: nullable ADoc)

nitc :: ADefinition :: n_doc=

The documentation
fun n_extern_calls: nullable AExternCalls

nitc :: AMethPropdef :: n_extern_calls

The list of declared callbacks (for extern methods)
fun n_extern_calls=(n_extern_calls: nullable AExternCalls)

nitc :: AMethPropdef :: n_extern_calls=

The list of declared callbacks (for extern methods)
fun n_extern_code_block: nullable AExternCodeBlock

nitc :: AMethPropdef :: n_extern_code_block

The body (in extern code) of the method, if any
fun n_extern_code_block=(n_extern_code_block: nullable AExternCodeBlock)

nitc :: AMethPropdef :: n_extern_code_block=

The body (in extern code) of the method, if any
fun n_kwdo: nullable TKwdo

nitc :: AMethPropdef :: n_kwdo

The do keyword
fun n_kwdo=(n_kwdo: nullable TKwdo)

nitc :: AMethPropdef :: n_kwdo=

The do keyword
fun n_kwend: nullable TKwend

nitc :: AMethPropdef :: n_kwend

The end keyword
fun n_kwend=(n_kwend: nullable TKwend)

nitc :: AMethPropdef :: n_kwend=

The end keyword
fun n_kwinit: nullable TKwinit

nitc :: AMethPropdef :: n_kwinit

The init keyword, if any
fun n_kwinit=(n_kwinit: nullable TKwinit)

nitc :: AMethPropdef :: n_kwinit=

The init keyword, if any
fun n_kwisa: nullable TKwisa

nitc :: AMethPropdef :: n_kwisa

The isa keyword, if any
fun n_kwisa=(n_kwisa: nullable TKwisa)

nitc :: AMethPropdef :: n_kwisa=

The isa keyword, if any
fun n_kwmeth: nullable TKwmeth

nitc :: AMethPropdef :: n_kwmeth

The fun keyword, if any
fun n_kwmeth=(n_kwmeth: nullable TKwmeth)

nitc :: AMethPropdef :: n_kwmeth=

The fun keyword, if any
fun n_kwnew: nullable TKwnew

nitc :: AMethPropdef :: n_kwnew

The new keyword, if any
fun n_kwnew=(n_kwnew: nullable TKwnew)

nitc :: AMethPropdef :: n_kwnew=

The new keyword, if any
fun n_kwredef: nullable TKwredef

nitc :: ADefinition :: n_kwredef

The redef keyword
fun n_kwredef=(n_kwredef: nullable TKwredef)

nitc :: ADefinition :: n_kwredef=

The redef keyword
fun n_methid: nullable AMethid

nitc :: AMethPropdef :: n_methid

The name of the method, if any
fun n_methid=(n_methid: nullable AMethid)

nitc :: AMethPropdef :: n_methid=

The name of the method, if any
fun n_signature: nullable ASignature

nitc :: AMethPropdef :: n_signature

The signature of the method, if any
fun n_signature=(n_signature: nullable ASignature)

nitc :: AMethPropdef :: n_signature=

The signature of the method, if any
fun n_visibility: nullable AVisibility

nitc :: ADefinition :: n_visibility

The declared visibility
fun n_visibility=(n_visibility: nullable AVisibility)

nitc :: ADefinition :: n_visibility=

The declared visibility
private intern fun native_class_name: CString

core :: Object :: native_class_name

The class name of the object in CString format.
private fun new_property_visibility(modelbuilder: ModelBuilder, mclassdef: MClassDef, nvisibility: nullable AVisibility): MVisibility

nitc :: APropdef :: new_property_visibility

abstract fun numbering_variables(vm: VirtualMachine)

nitc :: APropdef :: numbering_variables

Numbering the variable inside the propdef
intern fun object_id: Int

core :: Object :: object_id

An internal hash code for the object based on its identity.
fun object_sites: Array[AExpr]

nitc :: APropdef :: object_sites

Contain all AST-parts related to object mechanisms the propdef has:
protected fun object_sites=(object_sites: Array[AExpr])

nitc :: APropdef :: object_sites=

Contain all AST-parts related to object mechanisms the propdef has:
fun output

core :: Object :: output

Display self on stdout (debug only).
intern fun output_class_name

core :: Object :: output_class_name

Display class name on stdout (debug only).
fun parent: nullable ANode

nitc :: ANode :: parent

Parent of the node in the AST
protected fun parent=(parent: nullable ANode)

nitc :: ANode :: parent=

Parent of the node in the AST
fun parentize_tokens

nitc :: ANode :: parentize_tokens

Visit the AST and computes advanced AST attributes on Tokens and Prod
fun parser_action(i: Int, j: Int): Int

nitc :: TablesCapable :: parser_action

The action value of the parser at row i, column j-1
fun parser_goto(i: Int, j: Int): Int

nitc :: TablesCapable :: parser_goto

The goto value of the parser at row i, column j-1
fun propagate_dependences(phi: PhiFunction, block: BasicBlock)

nitc :: APropdef :: propagate_dependences

Propagate the dependences of the phi-functions into following variables
fun rename(block: BasicBlock, counter: HashMap[Variable, Int], ssa: SSA)

nitc :: APropdef :: rename

Recursively rename each variable from block
fun rename_variables(ssa: SSA)

nitc :: APropdef :: rename_variables

Compute the second phase of SSA algorithm: renaming variables
private abstract fun replace_child(old_child: ANode, new_child: nullable ANode)

nitc :: ANode :: replace_child

Replace a child with an other node in the AST
fun replace_clone

nitc :: ANode :: replace_clone

Create a new clone of self
fun replace_with(node: ANode)

nitc :: ANode :: replace_with

Replace itself with an other node in the AST
fun return_mark: nullable EscapeMark

nitc :: APropdef :: return_mark

The break escape mark associated with the return
protected fun return_mark=(return_mark: nullable EscapeMark)

nitc :: APropdef :: return_mark=

The break escape mark associated with the return
fun returnvar: Variable

nitc :: APropdef :: returnvar

The return variable of the propdef
protected fun returnvar=(returnvar: Variable)

nitc :: APropdef :: returnvar=

The return variable of the propdef
fun root: ANode

nitc :: ANode :: root

The topmost ancestor of the element
fun selfvariable: nullable Variable

nitc :: APropdef :: selfvariable

The variable associated to the receiver (if any)
protected fun selfvariable=(selfvariable: nullable Variable)

nitc :: APropdef :: selfvariable=

The variable associated to the receiver (if any)
fun serialization_hash: Int

core :: Object :: serialization_hash

Hash value use for serialization
private fun set_doc(mpropdef: MPropDef, modelbuilder: ModelBuilder)

nitc :: APropdef :: set_doc

fun ssa_destruction(ssa: SSA)

nitc :: APropdef :: ssa_destruction

Transform SSA-representation into an executable code (delete phi-functions)
private fun start_token: nullable Token

nitc :: Prod :: start_token

The token where the production really start (skipping ADoc).
fun supported_by_dynamic_ffi: Bool

nitc :: AMethPropdef :: supported_by_dynamic_ffi

Does this method definition use the FFI and is it supported by the interpreter?
intern fun sys: Sys

core :: Object :: sys

Return the global sys object, the only instance of the Sys class.
private fun tag(mpd: MPropDef): HTMLTag

nitc :: APropdef :: tag

abstract fun to_jvalue(env: JniEnv): JValue

core :: Object :: to_jvalue

fun to_s: String

core :: Object :: to_s

User readable representation of self.
fun to_xml: HTMLTag

nitc :: Prod :: to_xml

A XML representation of the AST
fun validate

nitc :: ANode :: validate

Recursively validate a AST node.
fun variables: HashSet[Variable]

nitc :: APropdef :: variables

The variables contained in the body on this propdef
protected fun variables=(variables: HashSet[Variable])

nitc :: APropdef :: variables=

The variables contained in the body on this propdef
fun verify_nitni_callbacks(toolcontext: ToolContext)

nitc :: AMethPropdef :: verify_nitni_callbacks

Verifiy the validity of the explicit callbacks to Nit
abstract fun visit_all(v: Visitor)

nitc :: ANode :: visit_all

Visit all nodes in order.
fun visit_annotations(v: PrettyPrinterVisitor, n_annotations: nullable AAnnotations): Bool

nitc :: APropdef :: visit_annotations

Factorize annotations visit for all APropdef.
fun visit_block(v: PrettyPrinterVisitor, n_block: nullable AExpr, annot_inline: Bool)

nitc :: APropdef :: visit_block

Factorize block visit for APropdefs.
private abstract fun was_inline: Bool

nitc :: ANode :: was_inline

Does self was written in one line before transformation?
package_diagram nitc::AMethPropdef AMethPropdef nitc::TablesCapable TablesCapable nitc::AMethPropdef->nitc::TablesCapable nitc::APropdef APropdef nitc::AMethPropdef->nitc::APropdef core::Object Object nitc::TablesCapable->core::Object nitc::ADefinition ADefinition nitc::APropdef->nitc::ADefinition ...core::Object ... ...core::Object->core::Object ...nitc::ADefinition ... ...nitc::ADefinition->nitc::ADefinition nitc::AMainMethPropdef AMainMethPropdef nitc::AMainMethPropdef->nitc::AMethPropdef

Ancestors

abstract class ADefinition

nitc :: ADefinition

Abstract class for definition of entities
abstract class ANode

nitc :: ANode

Root of the AST class-hierarchy
interface Cloneable

core :: Cloneable

Something that can be cloned
interface Object

core :: Object

The root of the class hierarchy.
abstract class Prod

nitc :: Prod

Ancestor of all productions

Parents

abstract class APropdef

nitc :: APropdef

The definition of a property
interface TablesCapable

nitc :: TablesCapable

Interface allowing the acces of the tables used during the parsing.

Children

class AMainMethPropdef

nitc :: AMainMethPropdef

The implicit main method

Class definitions

nitc $ AMethPropdef
# A definition of all kind of method (including constructors)
class AMethPropdef
	super APropdef

	# The `fun` keyword, if any
	var n_kwmeth: nullable TKwmeth = null is writable

	# The `init` keyword, if any
	var n_kwinit: nullable TKwinit = null is writable

	# The `isa` keyword, if any
	var n_kwisa: nullable TKwisa = null is writable

	# The `new` keyword, if any
	var n_kwnew: nullable TKwnew = null is writable

	# The name of the method, if any
	var n_methid: nullable AMethid = null is writable

	# The signature of the method, if any
	var n_signature: nullable ASignature = null is writable

	# The `do` keyword
	var n_kwdo: nullable TKwdo = null is writable

	# The body (in Nit) of the method, if any
	var n_block: nullable AExpr = null is writable

	# The `end` keyword
	var n_kwend: nullable TKwend = null is writable

	# The list of declared callbacks (for extern methods)
	var n_extern_calls: nullable AExternCalls = null is writable

	# The body (in extern code) of the method, if any
	var n_extern_code_block: nullable AExternCodeBlock = null is writable

	redef fun hot_location
	do
		if n_methid != null then
			return n_methid.location
		else if n_kwinit != null then
			return n_kwinit.location
		else if n_kwnew != null then
			return n_kwnew.location
		else
			return location
		end
	end
end
src/parser/parser_nodes.nit:1404,1--1453,3

nitc :: parser_prod $ AMethPropdef
redef class AMethPropdef
	init init_amethpropdef (
		n_doc: nullable ADoc,
		n_kwredef: nullable TKwredef,
		n_visibility: nullable AVisibility,
		n_kwmeth: nullable TKwmeth,
		n_kwinit: nullable TKwinit,
		n_kwisa: nullable TKwisa,
		n_kwnew: nullable TKwnew,
		n_methid: nullable AMethid,
		n_signature: nullable ASignature,
		n_annotations: nullable AAnnotations,
		n_extern_calls: nullable AExternCalls,
		n_extern_code_block: nullable AExternCodeBlock,
		n_kwdo: nullable TKwdo,
		n_block: nullable AExpr,
		n_kwend: nullable TKwend
	)
	do
		_n_doc = n_doc
		if n_doc != null then n_doc.parent = self
		_n_kwredef = n_kwredef
		if n_kwredef != null then n_kwredef.parent = self
		_n_visibility = n_visibility.as(not null)
		n_visibility.parent = self
		_n_kwmeth = n_kwmeth
		if n_kwmeth != null then n_kwmeth.parent = self
		_n_kwinit = n_kwinit
		if n_kwinit != null then n_kwinit.parent = self
		_n_kwisa = n_kwisa
		if n_kwisa != null then n_kwisa.parent = self
		_n_kwnew = n_kwnew
		if n_kwnew != null then n_kwnew.parent = self
		_n_methid = n_methid
		if n_methid != null then n_methid.parent = self
		_n_signature = n_signature.as(not null)
		n_signature.parent = self
		_n_annotations = n_annotations
		if n_annotations != null then n_annotations.parent = self
		_n_extern_calls = n_extern_calls
		if n_extern_calls != null then n_extern_calls.parent = self
		_n_extern_code_block = n_extern_code_block
		if n_extern_code_block != null then n_extern_code_block.parent = self
		_n_kwdo = n_kwdo
		if n_kwdo != null then n_kwdo.parent = self
		_n_block = n_block
		if n_block != null then n_block.parent = self
		_n_kwend = n_kwend
		if n_kwend != null then n_kwend.parent = self
	end

	redef fun replace_child(old_child: ANode, new_child: nullable ANode)
	do
		if _n_doc == old_child then
			n_doc = new_child.as(nullable ADoc)
			return
		end
		if _n_kwredef == old_child then
			n_kwredef = new_child.as(nullable TKwredef)
			return
		end
		if _n_visibility == old_child then
			n_visibility = new_child.as(AVisibility)
			return
		end
		if _n_kwmeth == old_child then
			n_kwmeth = new_child.as(nullable TKwmeth)
			return
		end
		if _n_kwinit == old_child then
			n_kwinit = new_child.as(nullable TKwinit)
			return
		end
		if _n_kwisa == old_child then
			n_kwisa = new_child.as(nullable TKwisa)
			return
		end
		if _n_kwnew == old_child then
			n_kwnew = new_child.as(nullable TKwnew)
			return
		end
		if _n_methid == old_child then
			n_methid = new_child.as(nullable AMethid)
			return
		end
		if _n_signature == old_child then
			n_signature = new_child.as(ASignature)
			return
		end
		if _n_annotations == old_child then
			n_annotations = new_child.as(nullable AAnnotations)
			return
		end
		if _n_extern_calls == old_child then
			n_extern_calls = new_child.as(nullable AExternCalls)
			return
		end
		if _n_extern_code_block == old_child then
			n_extern_code_block = new_child.as(nullable AExternCodeBlock)
			return
		end
		if _n_kwdo == old_child then
			n_kwdo = new_child.as(nullable TKwdo)
			return
		end
		if _n_block == old_child then
			n_block = new_child.as(nullable AExpr)
			return
		end
		if _n_kwend == old_child then
			n_kwend = new_child.as(nullable TKwend)
			return
		end
	end

	redef fun n_doc=(node)
	do
		_n_doc = node
		if node != null then node.parent = self
	end
	redef fun n_kwredef=(node)
	do
		_n_kwredef = node
		if node != null then node.parent = self
	end
	redef fun n_visibility=(node)
	do
		_n_visibility = node
		node.parent = self
	end
	redef fun n_kwmeth=(node)
	do
		_n_kwmeth = node
		if node != null then node.parent = self
	end
	redef fun n_kwinit=(node)
	do
		_n_kwinit = node
		if node != null then node.parent = self
	end
	redef fun n_kwisa=(node)
	do
		_n_kwisa = node
		if node != null then node.parent = self
	end
	redef fun n_kwnew=(node)
	do
		_n_kwnew = node
		if node != null then node.parent = self
	end
	redef fun n_methid=(node)
	do
		_n_methid = node
		if node != null then node.parent = self
	end
	redef fun n_signature=(node)
	do
		_n_signature = node
		node.parent = self
	end
	redef fun n_annotations=(node)
	do
		_n_annotations = node
		if node != null then node.parent = self
	end
	redef fun n_extern_calls=(node)
	do
		_n_extern_calls = node
		if node != null then node.parent = self
	end
	redef fun n_extern_code_block=(node)
	do
		_n_extern_code_block = node
		if node != null then node.parent = self
	end
	redef fun n_kwdo=(node)
	do
		_n_kwdo = node
		if node != null then node.parent = self
	end
	redef fun n_block=(node)
	do
		_n_block = node
		if node != null then node.parent = self
	end
	redef fun n_kwend=(node)
	do
		_n_kwend = node
		if node != null then node.parent = self
	end


	redef fun visit_all(v: Visitor)
	do
		v.enter_visit(_n_doc)
		v.enter_visit(_n_kwredef)
		v.enter_visit(_n_visibility)
		v.enter_visit(_n_kwmeth)
		v.enter_visit(_n_kwinit)
		v.enter_visit(_n_kwisa)
		v.enter_visit(_n_kwnew)
		v.enter_visit(_n_methid)
		v.enter_visit(_n_signature)
		v.enter_visit(_n_annotations)
		v.enter_visit(_n_extern_calls)
		v.enter_visit(_n_extern_code_block)
		v.enter_visit(_n_kwdo)
		v.enter_visit(_n_block)
		v.enter_visit(_n_kwend)
	end
end
src/parser/parser_prod.nit:1140,1--1350,3

nitc :: modelize_property $ AMethPropdef
redef class AMethPropdef
	redef type MPROPDEF: MMethodDef

	# Is the method annotated `autoinit`?
	var is_autoinit = false

	# Can self be used as a root init?
	private fun look_like_a_root_init(modelbuilder: ModelBuilder, mclassdef: MClassDef): Bool
	do
		# Need the `init` keyword
		if n_kwinit == null then return false
		# Need to by anonymous
		if self.n_methid != null then return false
		# No annotation on itself
		if get_single_annotation("old_style_init", modelbuilder) != null then return false
		# Nor on its module
		var amod = self.parent.parent.as(AModule)
		var amoddecl = amod.n_moduledecl
		if amoddecl != null then
			var old = amoddecl.get_single_annotation("old_style_init", modelbuilder)
			if old != null then return false
		end
		# No parameters
		if self.n_signature.n_params.length > 0 then
			modelbuilder.advice(self, "old-init", "Warning: init with signature in {mclassdef}")
			return false
		end
		# Cannot be private or something
		if not self.n_visibility isa APublicVisibility then
			modelbuilder.advice(self, "old-init", "Warning: non-public init in {mclassdef}")
			return false
		end

		return true
	end

	redef fun build_property(modelbuilder, mclassdef)
	do
		var n_kwinit = n_kwinit
		var n_kwnew = n_kwnew
		var is_new = n_kwnew != null
		var is_init = n_kwinit != null or is_new
		var name: String
		var amethodid = self.n_methid
		var name_node: ANode
		var is_old_style_init = false
		if amethodid == null then
			if n_kwinit != null then
				name = "init"
				name_node = n_kwinit
				var old_style_annot = get_single_annotation("old_style_init", modelbuilder)
				if  old_style_annot != null or self.n_signature.n_params.not_empty then
					name = "defaultinit"
					if old_style_annot != null then is_old_style_init = true
				end
			else if n_kwnew != null then
				name = "new"
				name_node = n_kwnew
			else
				name = "main"
				name_node = self
			end
		else if amethodid isa AIdMethid then
			name = amethodid.n_id.text
			name_node = amethodid
		else
			# operator, bracket or assign
			name = amethodid.collect_text
			name_node = amethodid

			var arity = self.n_signature.n_params.length
			if name == "+" and arity == 0 then
				name = "unary +"
			else if name == "-" and arity == 0 then
				name = "unary -"
			else if name == "~" and arity == 0 then
				name = "unary ~"
			else
				if amethodid.is_binary and arity != 1 then
					modelbuilder.error(self.n_signature, "Syntax Error: binary operator `{name}` requires exactly one parameter; got {arity}.")
				else if amethodid.min_arity > arity then
					modelbuilder.error(self.n_signature, "Syntax Error: `{name}` requires at least {amethodid.min_arity} parameter(s); got {arity}.")
				end
			end
		end

		var look_like_a_root_init = look_like_a_root_init(modelbuilder, mclassdef)
		var mprop: nullable MMethod = null
		if not is_init or n_kwredef != null or look_like_a_root_init then mprop = modelbuilder.try_get_mproperty_by_name(name_node, mclassdef, name).as(nullable MMethod)
		if mprop == null and look_like_a_root_init then
			mprop = modelbuilder.the_root_init_mmethod
			var nb = n_block
			if nb isa ABlockExpr and nb.n_expr.is_empty and n_doc == null then
				modelbuilder.advice(self, "useless-init", "Warning: useless empty init in {mclassdef}")
			end
		end
		if mprop == null then
			var mvisibility = new_property_visibility(modelbuilder, mclassdef, self.n_visibility)
			mprop = new MMethod(mclassdef, name, self.location, mvisibility)
			if look_like_a_root_init and modelbuilder.the_root_init_mmethod == null then
				modelbuilder.the_root_init_mmethod = mprop
				mprop.is_root_init = true
			end
			mprop.is_init = is_init
			mprop.is_new = is_new
			if is_new then mclassdef.mclass.has_new_factory = true
			if name == "sys" then mprop.is_toplevel = true # special case for sys allowed in `new` factories
			if not self.check_redef_keyword(modelbuilder, mclassdef, n_kwredef, false, mprop) then
				mprop.is_broken = true
				return
			end
		else
			if mprop.is_broken then return
			if not self.check_redef_keyword(modelbuilder, mclassdef, n_kwredef, not self isa AMainMethPropdef, mprop) then return
			check_redef_property_visibility(modelbuilder, self.n_visibility, mprop)
		end

		# Check name conflicts in the local class for constructors.
		if is_init then
			for p, n in mclassdef.mprop2npropdef do
				if p != mprop and p isa MMethod and p.name == name then
					if not check_redef_keyword(modelbuilder, mclassdef, n_kwredef, false, p) then
						mprop.is_broken = true
						return
					end
					break
				end
			end
		end

		mclassdef.mprop2npropdef[mprop] = self

		var mpropdef = new MMethodDef(mclassdef, mprop, self.location)
		if mpropdef.name == "defaultinit" and mclassdef.is_intro then
			assert mclassdef.default_init == null
			mpropdef.is_old_style_init = is_old_style_init
			mclassdef.default_init = mpropdef
			# Set the initializers with the mproperty.
			# This point is need when a super class define this own default_init and inherited class use the default_init generated automaticlely.
			mpropdef.initializers.add mprop
			mpropdef.is_calling_init = true
		end

		set_doc(mpropdef, modelbuilder)

		self.mpropdef = mpropdef
		modelbuilder.mpropdef2npropdef[mpropdef] = self
		if mpropdef.is_intro then
			modelbuilder.toolcontext.info("{mpropdef} introduces new method {mprop.full_name}", 4)
		else
			modelbuilder.toolcontext.info("{mpropdef} redefines method {mprop.full_name}", 4)
		end
	end

	redef fun build_signature(modelbuilder)
	do
		var mpropdef = self.mpropdef
		if mpropdef == null then return # Error thus skiped
		var mproperty = mpropdef.mproperty
		var mclassdef = mpropdef.mclassdef
		var mmodule = mclassdef.mmodule
		var nsig = self.n_signature

		var accept_special_last_parameter = self.n_methid == null or self.n_methid.accept_special_last_parameter
		var return_is_mandatory = self.n_methid != null and self.n_methid.return_is_mandatory

		# Retrieve info from the signature AST
		var param_names = new Array[String] # Names of parameters from the AST
		var param_types = new Array[MType] # Types of parameters from the AST
		var vararg_rank = -1
		var ret_type: nullable MType = null # Return type from the AST
		if nsig != null then
			if not nsig.visit_signature(modelbuilder, mclassdef) then return
			param_names = nsig.param_names
			param_types = nsig.param_types
			vararg_rank = nsig.vararg_rank
			ret_type = nsig.ret_type
		end

		# Look for some signature to inherit
		# FIXME: do not inherit from the intro, but from the most specific
		var msignature: nullable MSignature = null
		if not mpropdef.is_intro then
			msignature = mproperty.intro.msignature
			if msignature == null then return # Skip error

			# The local signature is adapted to use the local formal types, if any.
			msignature = msignature.resolve_for(mclassdef.mclass.mclass_type, mclassdef.bound_mtype, mmodule, false)

			# Check inherited signature arity
			if param_names.length != msignature.arity then
				var node: ANode
				if nsig != null then node = nsig else node = self
				modelbuilder.error(node, "Redef Error: expected {msignature.arity} parameter(s) for `{mproperty.name}{msignature}`; got {param_names.length}. See introduction at `{mproperty.full_name}`.")
				return
			end
		else if mproperty.is_init and not mproperty.is_new then
			# FIXME UGLY: inherit signature from a super-constructor
			for msupertype in mclassdef.supertypes do
				msupertype = msupertype.anchor_to(mmodule, mclassdef.bound_mtype)
				var candidate = modelbuilder.try_get_mproperty_by_name2(self, mmodule, msupertype, mproperty.name)
				if candidate != null then
					if msignature == null then
						msignature = candidate.intro.as(MMethodDef).msignature
					end
				end
			end
		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 = 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
			ret_type = msignature.return_mtype
		end

		if param_names.length != param_types.length then
			# Some parameters are typed, other parameters are not typed.
			modelbuilder.error(nsig.n_params[param_types.length], "Error: untyped parameter `{param_names[param_types.length]}'.")
			return
		end

		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)
			if nsig != null then nsig.n_params[i].mparameter = mparameter
			mparameters.add(mparameter)
		end

		# In `new`-factories, the return type is by default the classtype.
		if ret_type == null and mproperty.is_new then ret_type = mclassdef.mclass.mclass_type

		# Special checks for operator methods
		if not accept_special_last_parameter and mparameters.not_empty and mparameters.last.is_vararg then
			modelbuilder.error(self.n_signature.n_params.last, "Error: illegal variadic parameter `{mparameters.last}` for `{mproperty.name}`.")
		end
		if ret_type == null and return_is_mandatory then
			modelbuilder.error(self.n_methid, "Error: mandatory return type for `{mproperty.name}`.")
		end

		msignature = new MSignature(mparameters, ret_type)
		mpropdef.msignature = msignature
		mpropdef.is_abstract = self.get_single_annotation("abstract", modelbuilder) != null
		mpropdef.is_intern = self.get_single_annotation("intern", modelbuilder) != null
		mpropdef.is_extern = self.n_extern_code_block != null or self.get_single_annotation("extern", modelbuilder) != null

		# Check annotations
		var at = self.get_single_annotation("lazy", modelbuilder)
		if at != null then modelbuilder.error(at, "Syntax Error: `lazy` must be used on attributes.")

		var atautoinit = self.get_single_annotation("autoinit", modelbuilder)
		if atautoinit != null then
			if not mpropdef.is_intro then
				modelbuilder.error(atautoinit, "Error: `autoinit` cannot be set on redefinitions.")
			else if not mclassdef.is_intro then
				modelbuilder.error(atautoinit, "Error: `autoinit` cannot be used in class refinements.")
			else
				self.is_autoinit = true
			end
		end
	end

	redef fun check_signature(modelbuilder)
	do
		var mpropdef = self.mpropdef
		if mpropdef == null then return # Error thus skiped
		var mclassdef = mpropdef.mclassdef
		var mmodule = mclassdef.mmodule
		var nsig = self.n_signature
		var mysignature = mpropdef.msignature
		if mysignature == null then return # Error thus skiped

		# Check
		if nsig != null then
			if not nsig.check_signature(modelbuilder, mclassdef) then
				mpropdef.msignature = null # invalidate
				mpropdef.is_broken = true
				return # Forward error
			end
		end

		# Lookup for signature in the precursor
		# FIXME all precursors should be considered
		if not mpropdef.is_intro then
			var msignature = mpropdef.mproperty.intro.msignature
			if msignature == null then return

			var precursor_ret_type = msignature.return_mtype
			var ret_type = mysignature.return_mtype
			if ret_type != null and precursor_ret_type == null then
				modelbuilder.error(nsig.n_type, "Redef Error: `{mpropdef.mproperty}` is a procedure, not a function.")
				mpropdef.msignature = null
				mpropdef.is_broken = true
				return
			end

			if mysignature.arity > 0 then
				# Check parameters types
				for i in [0..mysignature.arity[ do
					var myt = mysignature.mparameters[i].mtype
					var prt = msignature.mparameters[i].mtype
					var node = nsig.n_params[i]
					if not modelbuilder.check_sametype(node, mmodule, mclassdef.bound_mtype, myt, prt) then
						modelbuilder.error(node, "Redef Error: expected `{prt}` for parameter `{mysignature.mparameters[i].name}'; got `{myt}`.")
						mpropdef.msignature = null
						mpropdef.is_broken = true
					end
				end
			end
			if precursor_ret_type != null then
				var node: nullable ANode = null
				if nsig != null then node = nsig.n_type
				if node == null then node = self
				if ret_type == null then
					# Inherit the return type
					ret_type = precursor_ret_type
				else if not modelbuilder.check_subtype(node, mmodule, mclassdef.bound_mtype, ret_type, precursor_ret_type) then
					modelbuilder.error(node, "Redef Error: expected `{precursor_ret_type}` for return type; got `{ret_type}`.")
					mpropdef.msignature = null
					mpropdef.is_broken = true
				end
			end
		end

		if nsig != null then
			# Check parameters visibility
			for i in [0..mysignature.arity[ do
				var nt = nsig.n_params[i].n_type
				if nt != null then modelbuilder.check_visibility(nt, nt.mtype.as(not null), mpropdef)
			end
			var nt = nsig.n_type
			if nt != null then modelbuilder.check_visibility(nt, nt.mtype.as(not null), mpropdef)
		end
		check_repeated_types(modelbuilder)
	end

	# For parameters, type is always useless in a redef.
	# For return type, type is useless if not covariant with introduction.
	redef fun check_repeated_types(modelbuilder) do
		var mpropdef = self.mpropdef
		if mpropdef == null then return
		if mpropdef.is_intro or n_signature == null then return
		# check params
		for param in n_signature.n_params do
			if param.n_type != null then
				modelbuilder.advice(param.n_type, "useless-signature", "Warning: useless type repetition on parameter `{param.n_id.text}` for redefined method `{mpropdef.name}`")
			end
		end
		# get intro
		var intro = mpropdef.mproperty.intro
		var n_intro = modelbuilder.mpropdef2npropdef.get_or_null(intro)
		if n_intro == null or not n_intro isa AMethPropdef then return
		# check return type
		var ret_type = n_signature.ret_type
		if ret_type != null and ret_type == n_intro.n_signature.ret_type then
			modelbuilder.advice(n_signature.n_type, "useless-signature", "Warning: useless return type repetition for redefined method `{mpropdef.name}`")
		end
	end
end
src/modelize/modelize_property.nit:758,1--1123,3

nitc :: light_ffi $ AMethPropdef
redef class AMethPropdef
	# Compile the necessary wrapper around this extern method or constructor
	fun compile_ffi_method(mmodule: MModule)
	do
		assert n_extern_code_block != null

		if mmodule.compiled_ffi_methods.has(self) then return
		mmodule.compiled_ffi_methods.add self

		var language = n_extern_code_block.language
		assert language != null
		mmodule.present_languages.add(language)
		n_extern_code_block.language.compile_extern_method(
			n_extern_code_block.as(not null), self, mmodule.ffi_ccu.as(not null), mmodule)
	end
end
src/ffi/light_ffi.nit:116,1--131,3

nitc :: pretty $ AMethPropdef
redef class AMethPropdef
	redef fun accept_pretty_printer(v) do
		#  TODO: Handle extern annotations

		var before = v.indent
		super
		if n_kwinit != null then v.visit n_kwinit
		if n_kwmeth != null then v.visit n_kwmeth
		if n_kwnew != null then v.visit n_kwnew

		if not n_methid == null then
			v.adds
			v.visit n_methid
		end

		v.visit n_signature

		var annot_inline = visit_annotations(v, n_annotations)

		if n_extern_calls != null or n_extern_code_block != null then
			v.adds
			if n_extern_calls != null then v.visit n_extern_calls
			if n_extern_code_block != null then v.visit n_extern_code_block
		end

		visit_block(v, n_block, annot_inline)
		v.addn
		assert v.indent == before
	end

	# Can be inlined if:
	# * block is empty or can be inlined
	# * contains no comments
	redef fun is_inlinable do
		if not super then return false
		if n_annotations != null and not n_annotations.is_inlinable then return false
		if n_block != null and not n_block.is_inlinable then return false
		if n_extern_calls != null and not n_extern_calls.is_inlinable then return false
		if n_extern_code_block != null and not n_extern_code_block.is_inlinable then return false
		if not collect_comments.is_empty then return false
		return true
	end
end
src/pretty.nit:960,1--1002,3

nitc :: typing $ AMethPropdef
redef class AMethPropdef
	redef fun do_typing(modelbuilder: ModelBuilder)
	do
		var mpropdef = self.mpropdef
		if mpropdef == null then return # skip error

		var v = new TypeVisitor(modelbuilder, mpropdef)
		self.selfvariable = v.selfvariable

		var mmethoddef = self.mpropdef.as(not null)
		var msignature = mmethoddef.msignature
		if msignature == null then return # skip error
		for i in [0..msignature.arity[ do
			var mtype = msignature.mparameters[i].mtype
			if msignature.vararg_rank == i then
				var arrayclass = v.get_mclass(self.n_signature.n_params[i], "Array")
				if arrayclass == null then return # Skip error
				mtype = arrayclass.get_mtype([mtype])
			end
			var variable = self.n_signature.n_params[i].variable
			assert variable != null
			variable.declared_type = mtype
		end

		var nblock = self.n_block
		if nblock == null then return

		loop
			v.dirty = false
			v.visit_stmt(nblock)
			if not v.has_loop or not v.dirty then break
		end

		var post_visitor = new PostTypingVisitor(v)
		post_visitor.enter_visit(self)

		if not nblock.after_flow_context.is_unreachable and msignature.return_mtype != null then
			# We reach the end of the function without having a return, it is bad
			v.error(self, "Error: reached end of function; expected `return` with a value.")
		end
	end
end
src/semantize/typing.nit:896,1--937,3

nitc :: auto_super_init $ AMethPropdef
redef class AMethPropdef
	# In case of introduced constructor, the list of implicit auto super init constructors invoked (if needed)
	var auto_super_inits: nullable Array[CallSite] = null

	# In case of redefined constructors, is an implicit call-to-super required?
	var auto_super_call = false

	# Collect initializers and build the auto-init
	fun do_auto_super_init(modelbuilder: ModelBuilder)
	do
		var mclassdef = self.parent.as(AClassdef).mclassdef
		if mclassdef == null or mclassdef.is_broken then return # skip error
		var mpropdef = self.mpropdef
		if mpropdef == null or mpropdef.is_broken then return # skip error
		var mmodule = mpropdef.mclassdef.mmodule
		var anchor = mclassdef.bound_mtype
		var recvtype = mclassdef.mclass.mclass_type

		# Get the annotation, but check its pertinence before returning
		var nosuper = get_single_annotation("nosuper", modelbuilder)

		# Collect only for constructors
		if not mpropdef.mproperty.is_init or mpropdef.mproperty.is_new then
			if nosuper != null then modelbuilder.error(nosuper, "Error: `nosuper` only allowed in `init`.")
			return
		end

		# Now we search for the absence of any explicit super-init invocation
		#  * via a "super"
		#  * via a call of an other init
		var nblock = self.n_block
		if nblock != null then
			var v = new AutoSuperInitVisitor
			v.enter_visit(nblock)
			var anode = v.has_explicit_super_init
			if anode != null then
				if nosuper != null then modelbuilder.error(anode, "Error: method is annotated `nosuper` but a super-constructor call is present.")
				return
			end
			if v.is_broken then return # skip
		end

		if nosuper != null then return

		# Still here? So it means that we must add an implicit super-call on redefinitions.
		if not mpropdef.is_intro then
			auto_super_call = true
			mpropdef.has_supercall = true
			modelbuilder.toolcontext.info("Auto-super call for {mpropdef}", 4)
			return
		end

		# Still here? So it means that we must determine what super inits need to be automatically invoked
		# The code that follow is required to deal with complex cases with old-style and new-style inits

		var auto_super_inits = new Array[CallSite]

		# The look for new-style super constructors (called from a old style constructor)
		var candidatedefs = get_super_candidatedefs(modelbuilder)

		if not candidatedefs.is_empty and auto_super_inits.is_empty then

			var candidatedef = candidatedefs.first
			if candidatedefs.length > 1 then
				var cd2 = candidatedefs[1]
				modelbuilder.error(self, "Error: cannot do an implicit constructor call to conflicting inherited inits `{cd2}({cd2.initializers.join(", ")}`) and `{candidatedef}({candidatedef.initializers.join(", ")}`). NOTE: Do not mix old-style and new-style init!")
				is_broken = true
				return
			end

			var msignature = candidatedef.msignature
			msignature = msignature.resolve_for(recvtype, anchor, mmodule, true)

			if msignature.arity > mpropdef.msignature.arity then
				modelbuilder.error(self, "Error: cannot do an implicit constructor call to `{candidatedef}{msignature}`. Expected at least `{msignature.arity}` arguments.")
				is_broken = true
				return
			end

			if candidatedef.mproperty != mpropdef.mproperty then
				var i = 0
				for candidat_mparameter in msignature.mparameters do
					var actual_mparameter = mpropdef.msignature.mparameters[i]
					if not candidat_mparameter.mtype.is_subtype(mmodule, anchor, actual_mparameter.mtype) then
						modelbuilder.error(self, "Type Error: expected argument #{i} of type `{candidat_mparameter.mtype}`, got implicit argument `{candidat_mparameter.name}` of type `{actual_mparameter.mtype}`. Signature is {msignature}")
						return
					end
					i += 1
				end
			end

			var callsite = new CallSite(hot_location, recvtype, mmodule, anchor, true, candidatedef.mproperty, candidatedef, msignature, false)
			auto_super_inits.add(callsite)
			modelbuilder.toolcontext.info("Auto-super init for {mpropdef} to {candidatedef.full_name}", 4)
		else if candidatedefs.is_empty then
			# skip broken
			is_broken = true
			return
		end
		if auto_super_inits.is_empty then
			modelbuilder.error(self, "Error: no constructors to call implicitly in `{mpropdef}`. Call one explicitly.")
			return
		end

		self.auto_super_inits = auto_super_inits
	end

	# This method returns the list of possible candidates for the current definition.
	#
	# Warning this method supports super call from old_style_init to default_inits without signature verification!!!
	private fun get_super_candidatedefs(modelbuilder: ModelBuilder): Array[MMethodDef]
	do
		var candidatedefs = new Array[MMethodDef]

		var mclassdef = self.parent.as(AClassdef).mclassdef
		if mclassdef == null or mclassdef.is_broken then return candidatedefs # skip error
		var mpropdef = self.mpropdef
		if mpropdef == null or mpropdef.is_broken then return candidatedefs # skip error
		var mmodule = mpropdef.mclassdef.mmodule
		var anchor = mclassdef.bound_mtype
		var mproperty = mpropdef.mproperty

		# The look for new-style super constructors (called from a old style constructor)
		var the_root_init_mmethod = modelbuilder.the_root_init_mmethod

		if mpropdef.is_old_style_init then
			var superprop: nullable MMethodDef = null
			for mclass in mclassdef.mclass.in_hierarchy(mmodule).direct_greaters do
				candidatedefs.add(mclass.intro.default_init.as(not null))
			end
		else
			candidatedefs = the_root_init_mmethod.lookup_definitions(mmodule, anchor)
		end
		return candidatedefs
	end
end
src/semantize/auto_super_init.nit:49,1--184,3

nitc :: astbuilder $ AMethPropdef
redef class AMethPropdef
	private init make(n_visibility: nullable AVisibility,
					tk_redef: nullable TKwredef,
					mmethoddef: nullable MMethodDef,
					n_signature: nullable ASignature,
					n_annotations: nullable AAnnotations,
					n_extern_calls: nullable AExternCalls,
					n_extern_code_block: nullable AExternCodeBlock,
					n_block: nullable AExpr)
	do
		var n_tid = new TId
		var n_methid = new AIdMethid.init_aidmethid(n_tid)
		if n_signature == null then n_signature = new ASignature
		if n_visibility == null then n_visibility = new APublicVisibility
		self.init_amethpropdef(null,tk_redef,n_visibility,new TKwmeth,null,null,null,n_methid,n_signature,n_annotations,n_extern_calls,n_extern_code_block,new TKwdo,n_block,new TKwend)
		self.mpropdef = mmethoddef
		if mpropdef != null then self.location = mmethoddef.location
	end
end
src/astbuilder.nit:403,1--421,3

nitc :: nitni_callbacks $ AMethPropdef
redef class AMethPropdef
	private var foreign_callbacks_cache: nullable ForeignCallbackSet = null

	# All foreign callbacks from this method
	fun foreign_callbacks: ForeignCallbackSet
	do
		var fcs = foreign_callbacks_cache
		assert fcs != null else print "Error: attempting to access nitni callbacks before phase 'verify_nitni_callback_phase'."
		return fcs
	end

	# Verifiy the validity of the explicit callbacks to Nit
	# also fills the set returned by foreign_callbacks
	fun verify_nitni_callbacks(toolcontext: ToolContext)
	do
		if foreign_callbacks_cache != null then return

		var fcs = new ForeignCallbackSet

		var mmodule = mpropdef.mclassdef.mmodule

		# receiver
		var recv_type = mpropdef.mclassdef.bound_mtype
		fcs.types.add(recv_type)

		# return type
		var rmt = mpropdef.msignature.return_mtype
		if rmt != null then
			if rmt isa MFormalType then
				var mclass_type = mpropdef.mclassdef.bound_mtype
				rmt = rmt.anchor_to(mmodule, mclass_type)
			end
			var mtype = rmt.resolve_for(recv_type, recv_type, mmodule, true)
			fcs.types.add(mtype)
		end

		# params
		for p in mpropdef.msignature.mparameters do
			var mtype = p.mtype.resolve_for(recv_type, recv_type, mmodule, true)
			if mtype isa MFormalType then
				var mclass_type = mpropdef.mclassdef.bound_mtype
				mtype = mtype.anchor_to(mmodule, mclass_type)
			end
			fcs.types.add( mtype )
		end

		# explicit callbacks
		if n_extern_calls != null then
			for ec in n_extern_calls.n_extern_calls do
				ec.verify_and_collect(self, fcs, toolcontext)
			end
		end

		# store result
		foreign_callbacks_cache = fcs
	end

	redef fun accept_rapid_type_visitor(v)
	do
		if foreign_callbacks_cache == null then return

		for cb in foreign_callbacks.callbacks do v.add_send(cb.recv_mtype, cb.mproperty.as(MMethod))
		for cast in foreign_callbacks.casts do v.add_cast_type(cast.to)
		for sup in foreign_callbacks.supers do
			v.analysis.add_super_send(sup.from.mclassdef.mclass.mclass_type, sup.from.as(MMethodDef))
		end
		for t in foreign_callbacks.types do if t isa MClassType then v.add_type t
	end
end
src/nitni/nitni_callbacks.nit:86,1--154,3

nitc :: java $ AMethPropdef
redef class AMethPropdef
	redef fun verify_nitni_callbacks(toolcontext)
	do
		super

		var block = n_extern_code_block
		if block != null and block.is_java then
			insert_artificial_callbacks(toolcontext)
		end
	end

	# Insert additional explicit calls to get the current `JNIEnv`
	#
	# This forces declaration of callbacks to Nit. The callbacks will be available in Java
	# but will be used mainly by the FFI itself.
	#
	# The developer can also customize the JNIEnv used by the FFI by redefining `Sys::jni_env`.
	private fun insert_artificial_callbacks(toolcontext: ToolContext)
	do
		var fcc = foreign_callbacks

		var modelbuilder = toolcontext.modelbuilder
		var mmodule = mpropdef.mclassdef.mmodule

		# We use callbacks from the C FFI since they will be called from generated C
		var c_language_visitor = toolcontext.ffi_language_assignation_phase.as(FFILanguageAssignationPhase).c_language
		if not mmodule.ffi_callbacks.keys.has(c_language_visitor) then
			mmodule.ffi_callbacks[c_language_visitor] = new HashSet[NitniCallback]
		end

		# Pointer::sys
		var pointer_class = modelbuilder.try_get_mclass_by_name(self, mmodule, "Pointer")
		assert pointer_class != null
		var pointer_sys_meth = modelbuilder.try_get_mproperty_by_name2(self, mmodule, pointer_class.mclass_type, "sys")
		assert pointer_sys_meth != null and pointer_sys_meth isa MMethod

		var explicit_call = new MExplicitCall(pointer_class.mclass_type, pointer_sys_meth, mmodule)
		fcc.callbacks.add(explicit_call)
		mmodule.ffi_callbacks[c_language_visitor].add(explicit_call)

		# Sys::jni_env
		var sys_class = modelbuilder.try_get_mclass_by_name(self, mmodule, "Sys")
		assert sys_class != null
		var sys_jni_env_meth = modelbuilder.try_get_mproperty_by_name2(self, mmodule, sys_class.mclass_type, "jni_env")
		if sys_jni_env_meth == null or not sys_jni_env_meth isa MMethod then
			toolcontext.error(self.location, "Java FFI Error: you must import the `java` module when using the FFI with Java")
			return
		end

		explicit_call = new MExplicitCall(sys_class.mclass_type, sys_jni_env_meth, mmodule)
		fcc.callbacks.add(explicit_call)
		mmodule.ffi_callbacks[c_language_visitor].add(explicit_call)

		# Sys::load_jclass
		var sys_jni_load_jclass_meth = modelbuilder.try_get_mproperty_by_name2(self, mmodule, sys_class.mclass_type, "load_jclass")
		assert sys_jni_load_jclass_meth != null
		assert sys_jni_load_jclass_meth isa MMethod

		explicit_call = new MExplicitCall(sys_class.mclass_type, sys_jni_load_jclass_meth, mmodule)
		fcc.callbacks.add(explicit_call)
		mmodule.ffi_callbacks[c_language_visitor].add(explicit_call)
		explicit_call.fill_type_for(fcc, mmodule)
	end
end
src/ffi/java.nit:317,1--380,3

nitc :: naive_interpreter $ AMethPropdef
redef class AMethPropdef
	super TablesCapable

	redef fun call(v, mpropdef, args)
	do
		var f = v.new_frame(self, mpropdef, args)
		var res = call_commons(v, mpropdef, args, f)
		v.frames.shift
		if v.is_escape(self.return_mark) then
			res = v.escapevalue
			return res
		end
		return res
	end

	# Execution of the body of the method
	#
	# It handle the common special cases: super, intern, extern
	fun call_commons(v: NaiveInterpreter, mpropdef: MMethodDef, arguments: Array[Instance], f: Frame): nullable Instance
	do
		v.frames.unshift(f)

		for i in [0..mpropdef.msignature.arity[ do
			var variable = self.n_signature.n_params[i].variable
			assert variable != null
			v.write_variable(variable, arguments[i+1])
		end

		# Call the implicit super-init
		var auto_super_inits = self.auto_super_inits
		if auto_super_inits != null then
			var args = [arguments.first]
			for auto_super_init in auto_super_inits do
				args.clear
				for i in [0..auto_super_init.msignature.arity+1[ do
					args.add(arguments[i])
				end
				assert auto_super_init.mproperty != mpropdef.mproperty
				v.callsite(auto_super_init, args)
			end
		end
		if auto_super_call then
			# standard call-next-method
			var superpd = mpropdef.lookup_next_definition(v.mainmodule, arguments.first.mtype)
			v.call(superpd, arguments)
		end

		# First, try intern
		if mpropdef.is_intern or mpropdef.is_extern then
			var res = intern_call(v, mpropdef, arguments)
			if res != v.error_instance then return res
		end
		# Then, try extern
		if mpropdef.is_extern then
			var res = call_extern(v, mpropdef, arguments, f)
			if res != v.error_instance then return res
		end
		# Else try block
		if n_block != null then
			v.stmt(self.n_block)
			return null
		end

		# Fail if nothing succeed
		if mpropdef.is_intern then
			fatal(v, "NOT YET IMPLEMENTED intern {mpropdef}")
		else if mpropdef.is_extern then
			fatal(v, "NOT YET IMPLEMENTED extern {mpropdef}")
		else
			fatal(v, "NOT YET IMPLEMENTED <wat?> {mpropdef}")
		end
		abort
	end

	# Call this extern method
	protected fun call_extern(v: NaiveInterpreter, mpropdef: MMethodDef, arguments: Array[Instance], f: Frame): nullable Instance
	do
		return v.error_instance
	end

	# Interprets a intern or a shortcut extern method.
	# Returns the result for a function, `null` for a procedure, or `error_instance` if the method is unknown.
	private fun intern_call(v: NaiveInterpreter, mpropdef: MMethodDef, args: Array[Instance]): nullable Instance
	do
		var pname = mpropdef.mproperty.name
		var cname = mpropdef.mclassdef.mclass.name

		if pname == "call" and v.routine_types.has(cname) then
			var routine = args.shift
			assert routine isa CallrefInstance
			# Swap the receiver position with the original recv of the call form.
			args.unshift routine.recv
			var res = v.callsite(routine.callsite, args)
			# recover the old args state
			args.shift
			args.unshift routine
			return res
		end

		if pname == "output" then
			var recv = args.first
			recv.val.output
			return null
		else if pname == "object_id" then
			var recv = args.first
			if recv isa PrimitiveInstance[Object] then
				return v.int_instance(recv.val.object_id)
			else
				return v.int_instance(recv.object_id)
			end
		else if pname == "output_class_name" then
			var recv = args.first
			print recv.mtype
			return null
		else if pname == "native_class_name" then
			var recv = args.first
			var txt = recv.mtype.to_s
			return v.c_string_instance(txt)
		else if pname == "==" then
			# == is correctly redefined for instances
			return v.bool_instance(args[0] == args[1])
		else if pname == "!=" then
			return v.bool_instance(args[0] != args[1])
		else if pname == "is_same_type" then
			return v.bool_instance(args[0].mtype == args[1].mtype)
		else if pname == "is_same_instance" then
			return v.bool_instance(args[0].eq_is(args[1]))
		else if pname == "class_inheritance_metamodel_json" then
			return v.c_string_instance(v.mainmodule.flatten_mclass_hierarchy.to_thin_json)
		else if pname == "exit" then
			exit(args[1].to_i)
			abort
		else if pname == "buffer_mode_full" then
			return v.int_instance(sys.buffer_mode_full)
		else if pname == "buffer_mode_line" then
			return v.int_instance(sys.buffer_mode_line)
		else if pname == "buffer_mode_none" then
			return v.int_instance(sys.buffer_mode_none)
		else if pname == "sys" then
			return v.mainobj
		else if cname == "Int" then
			var recvval = args[0].to_i
			if pname == "unary -" then
				return v.int_instance(-recvval)
			else if pname == "unary +" then
				return args[0]
			else if pname == "+" then
				return v.int_instance(recvval + args[1].to_i)
			else if pname == "-" then
				return v.int_instance(recvval - args[1].to_i)
			else if pname == "*" then
				return v.int_instance(recvval * args[1].to_i)
			else if pname == "%" then
				return v.int_instance(recvval % args[1].to_i)
			else if pname == "/" then
				return v.int_instance(recvval / args[1].to_i)
			else if pname == "<" then
				return v.bool_instance(recvval < args[1].to_i)
			else if pname == ">" then
				return v.bool_instance(recvval > args[1].to_i)
			else if pname == "<=" then
				return v.bool_instance(recvval <= args[1].to_i)
			else if pname == ">=" then
				return v.bool_instance(recvval >= args[1].to_i)
			else if pname == "<=>" then
				return v.int_instance(recvval <=> args[1].to_i)
			else if pname == "&" then
				return v.int_instance(recvval & args[1].to_i)
			else if pname == "|" then
				return v.int_instance(recvval | args[1].to_i)
			else if pname == "to_f" then
				return v.float_instance(recvval.to_f)
			else if pname == "to_b" then
				return v.byte_instance(recvval.to_b)
			else if pname == "<<" then
				return v.int_instance(recvval << args[1].to_i)
			else if pname == ">>" then
				return v.int_instance(recvval >> args[1].to_i)
			else if pname == "to_i8" then
				return v.int8_instance(recvval.to_i8)
			else if pname == "to_i16" then
				return v.int16_instance(recvval.to_i16)
			else if pname == "to_u16" then
				return v.uint16_instance(recvval.to_u16)
			else if pname == "to_i32" then
				return v.int32_instance(recvval.to_i32)
			else if pname == "to_u32" then
				return v.uint32_instance(recvval.to_u32)
			end
		else if cname == "Byte" then
			var recvval = args[0].to_b
			if pname == "unary -" then
				return v.byte_instance(-recvval)
			else if pname == "unary +" then
				return args[0]
			else if pname == "+" then
				return v.byte_instance(recvval + args[1].to_b)
			else if pname == "-" then
				return v.byte_instance(recvval - args[1].to_b)
			else if pname == "*" then
				return v.byte_instance(recvval * args[1].to_b)
			else if pname == "%" then
				return v.byte_instance(recvval % args[1].to_b)
			else if pname == "/" then
				return v.byte_instance(recvval / args[1].to_b)
			else if pname == "<" then
				return v.bool_instance(recvval < args[1].to_b)
			else if pname == ">" then
				return v.bool_instance(recvval > args[1].to_b)
			else if pname == "<=" then
				return v.bool_instance(recvval <= args[1].to_b)
			else if pname == ">=" then
				return v.bool_instance(recvval >= args[1].to_b)
			else if pname == "<=>" then
				return v.int_instance(recvval <=> args[1].to_b)
			else if pname == "&" then
				return v.byte_instance(recvval & args[1].to_b)
			else if pname == "|" then
				return v.byte_instance(recvval | args[1].to_b)
			else if pname == "to_f" then
				return v.float_instance(recvval.to_f)
			else if pname == "to_i" then
				return v.int_instance(recvval.to_i)
			else if pname == "<<" then
				return v.byte_instance(recvval << args[1].to_i)
			else if pname == ">>" then
				return v.byte_instance(recvval >> args[1].to_i)
			else if pname == "to_i8" then
				return v.int8_instance(recvval.to_i8)
			else if pname == "to_i16" then
				return v.int16_instance(recvval.to_i16)
			else if pname == "to_u16" then
				return v.uint16_instance(recvval.to_u16)
			else if pname == "to_i32" then
				return v.int32_instance(recvval.to_i32)
			else if pname == "to_u32" then
				return v.uint32_instance(recvval.to_u32)
			else if pname == "byte_to_s_len" then
				return v.int_instance(recvval.to_s.length)
			end
		else if cname == "Char" then
			var recv = args[0].val.as(Char)
			if pname == "successor" then
				return v.char_instance(recv.successor(args[1].to_i))
			else if pname == "predecessor" then
				return v.char_instance(recv.predecessor(args[1].to_i))
			else if pname == "<" then
				return v.bool_instance(recv < args[1].val.as(Char))
			else if pname == ">" then
				return v.bool_instance(recv > args[1].val.as(Char))
			else if pname == "<=" then
				return v.bool_instance(recv <= args[1].val.as(Char))
			else if pname == ">=" then
				return v.bool_instance(recv >= args[1].val.as(Char))
			else if pname == "<=>" then
				return v.int_instance(recv <=> args[1].val.as(Char))
			end
		else if cname == "Float" then
			var recv = args[0].to_f
			if pname == "unary -" then
				return v.float_instance(-recv)
			else if pname == "unary +" then
				return args[0]
			else if pname == "+" then
				return v.float_instance(recv + args[1].to_f)
			else if pname == "-" then
				return v.float_instance(recv - args[1].to_f)
			else if pname == "*" then
				return v.float_instance(recv * args[1].to_f)
			else if pname == "/" then
				return v.float_instance(recv / args[1].to_f)
			else if pname == "<" then
				return v.bool_instance(recv < args[1].to_f)
			else if pname == ">" then
				return v.bool_instance(recv > args[1].to_f)
			else if pname == "<=" then
				return v.bool_instance(recv <= args[1].to_f)
			else if pname == ">=" then
				return v.bool_instance(recv >= args[1].to_f)
			else if pname == "to_i" then
				return v.int_instance(recv.to_i)
			else if pname == "to_b" then
				return v.byte_instance(recv.to_b)
			else if pname == "to_i8" then
				return v.int8_instance(recv.to_i8)
			else if pname == "to_i16" then
				return v.int16_instance(recv.to_i16)
			else if pname == "to_u16" then
				return v.uint16_instance(recv.to_u16)
			else if pname == "to_i32" then
				return v.int32_instance(recv.to_i32)
			else if pname == "to_u32" then
				return v.uint32_instance(recv.to_u32)
			else if pname == "cos" then
				return v.float_instance(args[0].to_f.cos)
			else if pname == "sin" then
				return v.float_instance(args[0].to_f.sin)
			else if pname == "tan" then
				return v.float_instance(args[0].to_f.tan)
			else if pname == "acos" then
				return v.float_instance(args[0].to_f.acos)
			else if pname == "asin" then
				return v.float_instance(args[0].to_f.asin)
			else if pname == "atan" then
				return v.float_instance(args[0].to_f.atan)
			else if pname == "sqrt" then
				return v.float_instance(args[0].to_f.sqrt)
			else if pname == "exp" then
				return v.float_instance(args[0].to_f.exp)
			else if pname == "log" then
				return v.float_instance(args[0].to_f.log)
			else if pname == "pow" then
				return v.float_instance(args[0].to_f.pow(args[1].to_f))
			else if pname == "abs" then
				return v.float_instance(args[0].to_f.abs)
			else if pname == "hypot_with" then
				return v.float_instance(args[0].to_f.hypot_with(args[1].to_f))
			else if pname == "is_nan" then
				return v.bool_instance(args[0].to_f.is_nan)
			else if pname == "is_inf_extern" then
				return v.bool_instance(args[0].to_f.is_inf != 0)
			else if pname == "round" then
				return v.float_instance(args[0].to_f.round)
			end
		else if cname == "CString" then
			if pname == "new" then
				return v.c_string_instance_len(args[1].to_i)
			end
			var recvval = args.first.val.as(CString)
			if pname == "[]" then
				var arg1 = args[1].to_i
				return v.int_instance(recvval[arg1])
			else if pname == "[]=" then
				var arg1 = args[1].to_i
				recvval[arg1] = args[2].val.as(Int)
				return null
			else if pname == "copy_to" then
				# sig= copy_to(dest: CString, length: Int, from: Int, to: Int)
				var destval = args[1].val.as(CString)
				var lenval = args[2].to_i
				var fromval = args[3].to_i
				var toval = args[4].to_i
				recvval.copy_to(destval, lenval, fromval, toval)
				return null
			else if pname == "atoi" then
				return v.int_instance(recvval.atoi)
			else if pname == "fast_cstring" then
				return v.c_string_instance_fast_cstr(args[0].val.as(CString), args[1].to_i)
			else if pname == "fetch_4_chars" then
				return v.uint32_instance(args[0].val.as(CString).fetch_4_chars(args[1].to_i))
			else if pname == "fetch_4_hchars" then
				return v.uint32_instance(args[0].val.as(CString).fetch_4_hchars(args[1].to_i))
			else if pname == "utf8_length" then
				return v.int_instance(args[0].val.as(CString).utf8_length(args[1].to_i, args[2].to_i))
			end
		else if cname == "NativeArray" then
			if pname == "new" then
				var val = new Array[Instance].filled_with(v.null_instance, args[1].to_i)
				var instance = new PrimitiveInstance[Array[Instance]](args[0].mtype, val)
				v.init_instance_primitive(instance)
				return instance
			end
			var recvval = args.first.val.as(Array[Instance])
			if pname == "[]" then
				return recvval[args[1].to_i]
			else if pname == "[]=" then
				recvval[args[1].to_i] = args[2]
				return null
			else if pname == "length" then
				return v.int_instance(recvval.length)
			else if pname == "copy_to" then
				recvval.copy_to(0, args[2].to_i, args[1].val.as(Array[Instance]), 0)
				return null
			end
		else if cname == "Int8" then
			var recvval = args[0].to_i8
			if pname == "unary -" then
				return v.int8_instance(-recvval)
			else if pname == "unary +" then
				return args[0]
			else if pname == "+" then
				return v.int8_instance(recvval + args[1].to_i8)
			else if pname == "-" then
				return v.int8_instance(recvval - args[1].to_i8)
			else if pname == "*" then
				return v.int8_instance(recvval * args[1].to_i8)
			else if pname == "%" then
				return v.int8_instance(recvval % args[1].to_i8)
			else if pname == "/" then
				return v.int8_instance(recvval / args[1].to_i8)
			else if pname == "<" then
				return v.bool_instance(recvval < args[1].to_i8)
			else if pname == ">" then
				return v.bool_instance(recvval > args[1].to_i8)
			else if pname == "<=" then
				return v.bool_instance(recvval <= args[1].to_i8)
			else if pname == ">=" then
				return v.bool_instance(recvval >= args[1].to_i8)
			else if pname == "<=>" then
				return v.int_instance(recvval <=> args[1].to_i8)
			else if pname == "to_f" then
				return v.float_instance(recvval.to_f)
			else if pname == "to_i" then
				return v.int_instance(recvval.to_i)
			else if pname == "to_b" then
				return v.byte_instance(recvval.to_b)
			else if pname == "to_i16" then
				return v.int16_instance(recvval.to_i16)
			else if pname == "to_u16" then
				return v.uint16_instance(recvval.to_u16)
			else if pname == "to_i32" then
				return v.int32_instance(recvval.to_i32)
			else if pname == "to_u32" then
				return v.uint32_instance(recvval.to_u32)
			else if pname == "<<" then
				return v.int8_instance(recvval << (args[1].to_i))
			else if pname == ">>" then
				return v.int8_instance(recvval >> (args[1].to_i))
			else if pname == "&" then
				return v.int8_instance(recvval & args[1].to_i8)
			else if pname == "|" then
				return v.int8_instance(recvval | args[1].to_i8)
			else if pname == "^" then
				return v.int8_instance(recvval ^ args[1].to_i8)
			else if pname == "unary ~" then
				return v.int8_instance(~recvval)
			end
		else if cname == "Int16" then
			var recvval = args[0].to_i16
			if pname == "unary -" then
				return v.int16_instance(-recvval)
			else if pname == "unary +" then
				return args[0]
			else if pname == "+" then
				return v.int16_instance(recvval + args[1].to_i16)
			else if pname == "-" then
				return v.int16_instance(recvval - args[1].to_i16)
			else if pname == "*" then
				return v.int16_instance(recvval * args[1].to_i16)
			else if pname == "%" then
				return v.int16_instance(recvval % args[1].to_i16)
			else if pname == "/" then
				return v.int16_instance(recvval / args[1].to_i16)
			else if pname == "<" then
				return v.bool_instance(recvval < args[1].to_i16)
			else if pname == ">" then
				return v.bool_instance(recvval > args[1].to_i16)
			else if pname == "<=" then
				return v.bool_instance(recvval <= args[1].to_i16)
			else if pname == ">=" then
				return v.bool_instance(recvval >= args[1].to_i16)
			else if pname == "<=>" then
				return v.int_instance(recvval <=> args[1].to_i16)
			else if pname == "to_f" then
				return v.float_instance(recvval.to_f)
			else if pname == "to_i" then
				return v.int_instance(recvval.to_i)
			else if pname == "to_b" then
				return v.byte_instance(recvval.to_b)
			else if pname == "to_i8" then
				return v.int8_instance(recvval.to_i8)
			else if pname == "to_u16" then
				return v.uint16_instance(recvval.to_u16)
			else if pname == "to_i32" then
				return v.int32_instance(recvval.to_i32)
			else if pname == "to_u32" then
				return v.uint32_instance(recvval.to_u32)
			else if pname == "<<" then
				return v.int16_instance(recvval << (args[1].to_i))
			else if pname == ">>" then
				return v.int16_instance(recvval >> (args[1].to_i))
			else if pname == "&" then
				return v.int16_instance(recvval & args[1].to_i16)
			else if pname == "|" then
				return v.int16_instance(recvval | args[1].to_i16)
			else if pname == "^" then
				return v.int16_instance(recvval ^ args[1].to_i16)
			else if pname == "unary ~" then
				return v.int16_instance(~recvval)
			end
		else if cname == "UInt16" then
			var recvval = args[0].to_u16
			if pname == "unary -" then
				return v.uint16_instance(-recvval)
			else if pname == "unary +" then
				return args[0]
			else if pname == "+" then
				return v.uint16_instance(recvval + args[1].to_u16)
			else if pname == "-" then
				return v.uint16_instance(recvval - args[1].to_u16)
			else if pname == "*" then
				return v.uint16_instance(recvval * args[1].to_u16)
			else if pname == "%" then
				return v.uint16_instance(recvval % args[1].to_u16)
			else if pname == "/" then
				return v.uint16_instance(recvval / args[1].to_u16)
			else if pname == "<" then
				return v.bool_instance(recvval < args[1].to_u16)
			else if pname == ">" then
				return v.bool_instance(recvval > args[1].to_u16)
			else if pname == "<=" then
				return v.bool_instance(recvval <= args[1].to_u16)
			else if pname == ">=" then
				return v.bool_instance(recvval >= args[1].to_u16)
			else if pname == "<=>" then
				return v.int_instance(recvval <=> args[1].to_u16)
			else if pname == "to_f" then
				return v.float_instance(recvval.to_f)
			else if pname == "to_i" then
				return v.int_instance(recvval.to_i)
			else if pname == "to_b" then
				return v.byte_instance(recvval.to_b)
			else if pname == "to_i8" then
				return v.int8_instance(recvval.to_i8)
			else if pname == "to_i16" then
				return v.int16_instance(recvval.to_i16)
			else if pname == "to_i32" then
				return v.int32_instance(recvval.to_i32)
			else if pname == "to_u32" then
				return v.uint32_instance(recvval.to_u32)
			else if pname == "<<" then
				return v.uint16_instance(recvval << (args[1].to_i))
			else if pname == ">>" then
				return v.uint16_instance(recvval >> (args[1].to_i))
			else if pname == "&" then
				return v.uint16_instance(recvval & args[1].to_u16)
			else if pname == "|" then
				return v.uint16_instance(recvval | args[1].to_u16)
			else if pname == "^" then
				return v.uint16_instance(recvval ^ args[1].to_u16)
			else if pname == "unary ~" then
				return v.uint16_instance(~recvval)
			end
		else if cname == "Int32" then
			var recvval = args[0].to_i32
			if pname == "unary -" then
				return v.int32_instance(-recvval)
			else if pname == "unary +" then
				return args[0]
			else if pname == "+" then
				return v.int32_instance(recvval + args[1].to_i32)
			else if pname == "-" then
				return v.int32_instance(recvval - args[1].to_i32)
			else if pname == "*" then
				return v.int32_instance(recvval * args[1].to_i32)
			else if pname == "%" then
				return v.int32_instance(recvval % args[1].to_i32)
			else if pname == "/" then
				return v.int32_instance(recvval / args[1].to_i32)
			else if pname == "<" then
				return v.bool_instance(recvval < args[1].to_i32)
			else if pname == ">" then
				return v.bool_instance(recvval > args[1].to_i32)
			else if pname == "<=" then
				return v.bool_instance(recvval <= args[1].to_i32)
			else if pname == ">=" then
				return v.bool_instance(recvval >= args[1].to_i32)
			else if pname == "<=>" then
				return v.int_instance(recvval <=> args[1].to_i32)
			else if pname == "to_f" then
				return v.float_instance(recvval.to_f)
			else if pname == "to_i" then
				return v.int_instance(recvval.to_i)
			else if pname == "to_b" then
				return v.byte_instance(recvval.to_b)
			else if pname == "to_i8" then
				return v.int8_instance(recvval.to_i8)
			else if pname == "to_i16" then
				return v.int16_instance(recvval.to_i16)
			else if pname == "to_u16" then
				return v.uint16_instance(recvval.to_u16)
			else if pname == "to_u32" then
				return v.uint32_instance(recvval.to_u32)
			else if pname == "<<" then
				return v.int32_instance(recvval << (args[1].to_i))
			else if pname == ">>" then
				return v.int32_instance(recvval >> (args[1].to_i))
			else if pname == "&" then
				return v.int32_instance(recvval & args[1].to_i32)
			else if pname == "|" then
				return v.int32_instance(recvval | args[1].to_i32)
			else if pname == "^" then
				return v.int32_instance(recvval ^ args[1].to_i32)
			else if pname == "unary ~" then
				return v.int32_instance(~recvval)
			end
		else if cname == "UInt32" then
			var recvval = args[0].to_u32
			if pname == "unary -" then
				return v.uint32_instance(-recvval)
			else if pname == "unary +" then
				return args[0]
			else if pname == "+" then
				return v.uint32_instance(recvval + args[1].to_u32)
			else if pname == "-" then
				return v.uint32_instance(recvval - args[1].to_u32)
			else if pname == "*" then
				return v.uint32_instance(recvval * args[1].to_u32)
			else if pname == "%" then
				return v.uint32_instance(recvval % args[1].to_u32)
			else if pname == "/" then
				return v.uint32_instance(recvval / args[1].to_u32)
			else if pname == "<" then
				return v.bool_instance(recvval < args[1].to_u32)
			else if pname == ">" then
				return v.bool_instance(recvval > args[1].to_u32)
			else if pname == "<=" then
				return v.bool_instance(recvval <= args[1].to_u32)
			else if pname == ">=" then
				return v.bool_instance(recvval >= args[1].to_u32)
			else if pname == "<=>" then
				return v.int_instance(recvval <=> args[1].to_u32)
			else if pname == "to_f" then
				return v.float_instance(recvval.to_f)
			else if pname == "to_i" then
				return v.int_instance(recvval.to_i)
			else if pname == "to_b" then
				return v.byte_instance(recvval.to_b)
			else if pname == "to_i8" then
				return v.int8_instance(recvval.to_i8)
			else if pname == "to_i16" then
				return v.int16_instance(recvval.to_i16)
			else if pname == "to_u16" then
				return v.uint16_instance(recvval.to_u16)
			else if pname == "to_i32" then
				return v.int32_instance(recvval.to_i32)
			else if pname == "<<" then
				return v.uint32_instance(recvval << (args[1].to_i))
			else if pname == ">>" then
				return v.uint32_instance(recvval >> (args[1].to_i))
			else if pname == "&" then
				return v.uint32_instance(recvval & args[1].to_u32)
			else if pname == "|" then
				return v.uint32_instance(recvval | args[1].to_u32)
			else if pname == "^" then
				return v.uint32_instance(recvval ^ args[1].to_u32)
			else if pname == "unary ~" then
				return v.uint32_instance(~recvval)
			end
		else if pname == "native_argc" then
			return v.int_instance(v.arguments.length)
		else if pname == "native_argv" then
			var txt = v.arguments[args[1].to_i]
			return v.c_string_instance(txt)
		else if pname == "lexer_goto" then
			return v.int_instance(lexer_goto(args[1].to_i, args[2].to_i))
		else if pname == "lexer_accept" then
			return v.int_instance(lexer_accept(args[1].to_i))
		else if pname == "parser_goto" then
			return v.int_instance(parser_goto(args[1].to_i, args[2].to_i))
		else if pname == "parser_action" then
			return v.int_instance(parser_action(args[1].to_i, args[2].to_i))
		end
		return v.error_instance
	end
end
src/interpreter/naive_interpreter.nit:898,1--1553,3

nitc :: abstract_compiler $ AMethPropdef
redef class AMethPropdef
	redef fun compile_to_c(v, mpropdef, arguments)
	do
		# Call the implicit super-init
		var auto_super_inits = self.auto_super_inits
		if auto_super_inits != null then
			var args = [arguments.first]
			for auto_super_init in auto_super_inits do
				assert auto_super_init.mproperty != mpropdef.mproperty
				args.clear
				for i in [0..auto_super_init.msignature.arity+1[ do
					args.add(arguments[i])
				end
				assert auto_super_init.mproperty != mpropdef.mproperty
				v.compile_callsite(auto_super_init, args)
			end
		end
		if auto_super_call then
			v.supercall(mpropdef, arguments.first.mtype.as(MClassType), arguments)
		end

		# Try special compilation
		if mpropdef.is_intern then
			if compile_intern_to_c(v, mpropdef, arguments) then return
		end
		if mpropdef.is_extern then
			if mpropdef.mproperty.is_init then
				if compile_externinit_to_c(v, mpropdef, arguments) then return
			else
				if compile_externmeth_to_c(v, mpropdef, arguments) then return
			end
		end

		# Compile block if any
		var n_block = n_block
		if n_block != null then
			for i in [0..mpropdef.msignature.arity[ do
				var variable = self.n_signature.n_params[i].variable.as(not null)
				v.assign(v.variable(variable), arguments[i+1])
			end
			v.stmt(n_block)
			return
		end

		# We have a problem
		v.add_raw_throw
		var cn = v.class_name_string(arguments.first)
		v.add("PRINT_ERROR(\"Runtime error: uncompiled method `%s` called on `%s`. NOT YET IMPLEMENTED\", \"{mpropdef.mproperty.name.escape_to_c}\", {cn});")
		v.add_raw_abort
	end

	redef fun can_inline
	do
		if self.auto_super_inits != null then return false
		var nblock = self.n_block
		if nblock == null then return true
		if (mpropdef.mproperty.name == "==" or mpropdef.mproperty.name == "!=") and mpropdef.mclassdef.mclass.name == "Object" then return true
		if nblock isa ABlockExpr and nblock.n_expr.length == 0 then return true
		return false
	end

	fun compile_intern_to_c(v: AbstractCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable]): Bool
	do
		var pname = mpropdef.mproperty.name
		var cname = mpropdef.mclassdef.mclass.name
		var ret = mpropdef.msignature.return_mtype
		var compiler = v.compiler

		# WARNING: we must not resolve the return type when it's a functional type.
		# Otherwise, we get a compile error exactly here. Moreover, `routine_ref_call`
		# already handles the return type. NOTE: this warning only apply when compiling
		# in `semi-global`.
		if ret != null and not compiler.all_routine_types_name.has(cname) then
			ret = v.resolve_for(ret, arguments.first)
		end

		if pname != "==" and pname != "!=" then
			v.adapt_signature(mpropdef, arguments)
			v.unbox_signature_extern(mpropdef, arguments)
		end
		if cname == "Int" then
			if pname == "output" then
				v.add("printf(\"%ld\\n\", {arguments.first});")
				return true
			else if pname == "object_id" then
				v.ret(arguments.first)
				return true
			else if pname == "+" then
				v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "-" then
				v.ret(v.new_expr("{arguments[0]} - {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "unary -" then
				v.ret(v.new_expr("-{arguments[0]}", ret.as(not null)))
				return true
			else if pname == "unary +" then
				v.ret(arguments[0])
				return true
			else if pname == "*" then
				v.ret(v.new_expr("{arguments[0]} * {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "/" then
				v.ret(v.new_expr("{arguments[0]} / {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "%" then
				v.ret(v.new_expr("{arguments[0]} % {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "==" then
				v.ret(v.equal_test(arguments[0], arguments[1]))
				return true
			else if pname == "!=" then
				var res = v.equal_test(arguments[0], arguments[1])
				v.ret(v.new_expr("!{res}", ret.as(not null)))
				return true
			else if pname == "<" then
				v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">" then
				v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "<=" then
				v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">=" then
				v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "to_i8" then
				v.ret(v.new_expr("(int8_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_i16" then
				v.ret(v.new_expr("(int16_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_u16" then
				v.ret(v.new_expr("(uint16_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_i32" then
				v.ret(v.new_expr("(int32_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_u32" then
				v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_f" then
				v.ret(v.new_expr("(double){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_b" then
				v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "code_point" then
				v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "&" then
				v.ret(v.new_expr("{arguments[0]} & {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "|" then
				v.ret(v.new_expr("{arguments[0]} | {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">>" then
				v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "<<" then
				v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null)))
				return true
			end
		else if cname == "Char" then
			if pname == "object_id" then
				v.ret(v.new_expr("(long){arguments.first}", ret.as(not null)))
				return true
			else if pname == "successor" then
				v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "predecessor" then
				v.ret(v.new_expr("{arguments[0]} - {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "==" then
				v.ret(v.equal_test(arguments[0], arguments[1]))
				return true
			else if pname == "!=" then
				var res = v.equal_test(arguments[0], arguments[1])
				v.ret(v.new_expr("!{res}", ret.as(not null)))
				return true
			else if pname == "<" then
				v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">" then
				v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "<=" then
				v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">=" then
				v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "to_i" then
				v.ret(v.new_expr("{arguments[0]}-'0'", ret.as(not null)))
				return true
			else if pname == "code_point" then
				v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null)))
				return true
			end
		else if cname == "Byte" then
			if pname == "output" then
				v.add("printf(\"%x\\n\", {arguments.first});")
				return true
			else if pname == "object_id" then
				v.ret(v.new_expr("(long){arguments.first}", ret.as(not null)))
				return true
			else if pname == "+" then
				v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "-" then
				v.ret(v.new_expr("{arguments[0]} - {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "unary -" then
				v.ret(v.new_expr("-{arguments[0]}", ret.as(not null)))
				return true
			else if pname == "unary +" then
				v.ret(arguments[0])
				return true
			else if pname == "*" then
				v.ret(v.new_expr("{arguments[0]} * {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "/" then
				v.ret(v.new_expr("{arguments[0]} / {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "%" then
				v.ret(v.new_expr("{arguments[0]} % {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "==" then
				v.ret(v.equal_test(arguments[0], arguments[1]))
				return true
			else if pname == "!=" then
				var res = v.equal_test(arguments[0], arguments[1])
				v.ret(v.new_expr("!{res}", ret.as(not null)))
				return true
			else if pname == "<" then
				v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">" then
				v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "<=" then
				v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">=" then
				v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">>" then
				v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "<<" then
				v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "&" then
				v.ret(v.new_expr("{arguments[0]} & {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "to_i" then
				v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_f" then
				v.ret(v.new_expr("(double){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_i8" then
				v.ret(v.new_expr("(int8_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_i16" then
				v.ret(v.new_expr("(int16_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_u16" then
				v.ret(v.new_expr("(uint16_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_i32" then
				v.ret(v.new_expr("(int32_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_u32" then
				v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "ascii" then
				v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null)))
				return true
			end
		else if cname == "Bool" then
			if pname == "output" then
				v.add("printf({arguments.first}?\"true\\n\":\"false\\n\");")
				return true
			else if pname == "object_id" then
				v.ret(v.new_expr("(long){arguments.first}", ret.as(not null)))
				return true
			else if pname == "==" then
				v.ret(v.equal_test(arguments[0], arguments[1]))
				return true
			else if pname == "!=" then
				var res = v.equal_test(arguments[0], arguments[1])
				v.ret(v.new_expr("!{res}", ret.as(not null)))
				return true
			end
		else if cname == "Float" then
			if pname == "output" then
				v.add("printf(\"%f\\n\", {arguments.first});")
				return true
			else if pname == "object_id" then
				v.ret(v.new_expr("(double){arguments.first}", ret.as(not null)))
				return true
			else if pname == "+" then
				v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "-" then
				v.ret(v.new_expr("{arguments[0]} - {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "unary -" then
				v.ret(v.new_expr("-{arguments[0]}", ret.as(not null)))
				return true
			else if pname == "unary +" then
				v.ret(arguments[0])
				return true
			else if pname == "succ" then
				v.ret(v.new_expr("{arguments[0]}+1", ret.as(not null)))
				return true
			else if pname == "prec" then
				v.ret(v.new_expr("{arguments[0]}-1", ret.as(not null)))
				return true
			else if pname == "*" then
				v.ret(v.new_expr("{arguments[0]} * {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "/" then
				v.ret(v.new_expr("{arguments[0]} / {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "==" then
				v.ret(v.equal_test(arguments[0], arguments[1]))
				return true
			else if pname == "!=" then
				var res = v.equal_test(arguments[0], arguments[1])
				v.ret(v.new_expr("!{res}", ret.as(not null)))
				return true
			else if pname == "<" then
				v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">" then
				v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "<=" then
				v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">=" then
				v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "to_i" then
				v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_b" then
				v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_i8" then
				v.ret(v.new_expr("(int8_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_i16" then
				v.ret(v.new_expr("(int16_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_u16" then
				v.ret(v.new_expr("(uint16_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_i32" then
				v.ret(v.new_expr("(int32_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_u32" then
				v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null)))
				return true
			end
		else if cname == "CString" then
			if pname == "[]" then
				v.ret(v.new_expr("(unsigned char)((int){arguments[0]}[{arguments[1]}])", ret.as(not null)))
				return true
			else if pname == "[]=" then
				v.add("{arguments[0]}[{arguments[1]}]=(unsigned char){arguments[2]};")
				return true
			else if pname == "copy_to" then
				v.add("memmove({arguments[1]}+{arguments[4]},{arguments[0]}+{arguments[3]},{arguments[2]});")
				return true
			else if pname == "atoi" then
				v.ret(v.new_expr("atoi({arguments[0]});", ret.as(not null)))
				return true
			else if pname == "fast_cstring" then
				v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "==" then
				v.ret(v.equal_test(arguments[0], arguments[1]))
				return true
			else if pname == "!=" then
				var res = v.equal_test(arguments[0], arguments[1])
				v.ret(v.new_expr("!{res}", ret.as(not null)))
				return true
			else if pname == "new" then
				var alloc = v.nit_alloc(arguments[1].to_s, "CString")
				v.ret(v.new_expr("(char*){alloc}", ret.as(not null)))
				return true
			else if pname == "fetch_4_chars" then
				v.ret(v.new_expr("*((uint32_t*)({arguments[0]} + {arguments[1]}))", ret.as(not null)))
				return true
			else if pname == "fetch_4_hchars" then
				v.ret(v.new_expr("(uint32_t)be32toh(*((uint32_t*)({arguments[0]} + {arguments[1]})))", ret.as(not null)))
				return true
			end
		else if cname == "NativeArray" then
			return v.native_array_def(pname, ret, arguments)
		else if cname == "Int8" then
			if pname == "output" then
				v.add("printf(\"%\"PRIi8 \"\\n\", {arguments.first});")
				return true
			else if pname == "object_id" then
				v.ret(v.new_expr("(long){arguments.first}", ret.as(not null)))
				return true
			else if pname == "+" then
				v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "-" then
				v.ret(v.new_expr("{arguments[0]} - {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "unary -" then
				v.ret(v.new_expr("-{arguments[0]}", ret.as(not null)))
				return true
			else if pname == "unary +" then
				v.ret(arguments[0])
				return true
			else if pname == "*" then
				v.ret(v.new_expr("{arguments[0]} * {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "/" then
				v.ret(v.new_expr("{arguments[0]} / {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "%" then
				v.ret(v.new_expr("{arguments[0]} % {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "<<" then
				v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">>" then
				v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "==" then
				v.ret(v.equal_test(arguments[0], arguments[1]))
				return true
			else if pname == "!=" then
				var res = v.equal_test(arguments[0], arguments[1])
				v.ret(v.new_expr("!{res}", ret.as(not null)))
				return true
			else if pname == "<" then
				v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">" then
				v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "<=" then
				v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">=" then
				v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "to_i" then
				v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_b" then
				v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_i16" then
				v.ret(v.new_expr("(int16_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_u16" then
				v.ret(v.new_expr("(uint16_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_i32" then
				v.ret(v.new_expr("(int32_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_u32" then
				v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_f" then
				v.ret(v.new_expr("(double){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "&" then
				v.ret(v.new_expr("{arguments[0]} & {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "|" then
				v.ret(v.new_expr("{arguments[0]} | {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "^" then
				v.ret(v.new_expr("{arguments[0]} ^ {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "unary ~" then
				v.ret(v.new_expr("~{arguments[0]}", ret.as(not null)))
				return true
			end
		else if cname == "Int16" then
			if pname == "output" then
				v.add("printf(\"%\"PRIi16 \"\\n\", {arguments.first});")
				return true
			else if pname == "object_id" then
				v.ret(v.new_expr("(long){arguments.first}", ret.as(not null)))
				return true
			else if pname == "+" then
				v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "-" then
				v.ret(v.new_expr("{arguments[0]} - {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "unary -" then
				v.ret(v.new_expr("-{arguments[0]}", ret.as(not null)))
				return true
			else if pname == "unary +" then
				v.ret(arguments[0])
				return true
			else if pname == "*" then
				v.ret(v.new_expr("{arguments[0]} * {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "/" then
				v.ret(v.new_expr("{arguments[0]} / {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "%" then
				v.ret(v.new_expr("{arguments[0]} % {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "<<" then
				v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">>" then
				v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "==" then
				v.ret(v.equal_test(arguments[0], arguments[1]))
				return true
			else if pname == "!=" then
				var res = v.equal_test(arguments[0], arguments[1])
				v.ret(v.new_expr("!{res}", ret.as(not null)))
				return true
			else if pname == "<" then
				v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">" then
				v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "<=" then
				v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">=" then
				v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "to_i" then
				v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_b" then
				v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_i8" then
				v.ret(v.new_expr("(int8_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_u16" then
				v.ret(v.new_expr("(uint16_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_i32" then
				v.ret(v.new_expr("(int32_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_u32" then
				v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_f" then
				v.ret(v.new_expr("(double){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "&" then
				v.ret(v.new_expr("{arguments[0]} & {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "|" then
				v.ret(v.new_expr("{arguments[0]} | {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "^" then
				v.ret(v.new_expr("{arguments[0]} ^ {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "unary ~" then
				v.ret(v.new_expr("~{arguments[0]}", ret.as(not null)))
				return true
			end
		else if cname == "UInt16" then
			if pname == "output" then
				v.add("printf(\"%\"PRIu16 \"\\n\", {arguments.first});")
				return true
			else if pname == "object_id" then
				v.ret(v.new_expr("(long){arguments.first}", ret.as(not null)))
				return true
			else if pname == "+" then
				v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "-" then
				v.ret(v.new_expr("{arguments[0]} - {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "unary -" then
				v.ret(v.new_expr("-{arguments[0]}", ret.as(not null)))
				return true
			else if pname == "unary +" then
				v.ret(arguments[0])
				return true
			else if pname == "*" then
				v.ret(v.new_expr("{arguments[0]} * {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "/" then
				v.ret(v.new_expr("{arguments[0]} / {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "%" then
				v.ret(v.new_expr("{arguments[0]} % {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "<<" then
				v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">>" then
				v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "==" then
				v.ret(v.equal_test(arguments[0], arguments[1]))
				return true
			else if pname == "!=" then
				var res = v.equal_test(arguments[0], arguments[1])
				v.ret(v.new_expr("!{res}", ret.as(not null)))
				return true
			else if pname == "<" then
				v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">" then
				v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "<=" then
				v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">=" then
				v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "to_i" then
				v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_b" then
				v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_i8" then
				v.ret(v.new_expr("(int8_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_i16" then
				v.ret(v.new_expr("(int16_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_i32" then
				v.ret(v.new_expr("(int32_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_u32" then
				v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_f" then
				v.ret(v.new_expr("(double){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "&" then
				v.ret(v.new_expr("{arguments[0]} & {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "|" then
				v.ret(v.new_expr("{arguments[0]} | {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "^" then
				v.ret(v.new_expr("{arguments[0]} ^ {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "unary ~" then
				v.ret(v.new_expr("~{arguments[0]}", ret.as(not null)))
				return true
			end
		else if cname == "Int32" then
			if pname == "output" then
				v.add("printf(\"%\"PRIi32 \"\\n\", {arguments.first});")
				return true
			else if pname == "object_id" then
				v.ret(v.new_expr("(long){arguments.first}", ret.as(not null)))
				return true
			else if pname == "+" then
				v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "-" then
				v.ret(v.new_expr("{arguments[0]} - {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "unary -" then
				v.ret(v.new_expr("-{arguments[0]}", ret.as(not null)))
				return true
			else if pname == "unary +" then
				v.ret(arguments[0])
				return true
			else if pname == "*" then
				v.ret(v.new_expr("{arguments[0]} * {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "/" then
				v.ret(v.new_expr("{arguments[0]} / {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "%" then
				v.ret(v.new_expr("{arguments[0]} % {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "<<" then
				v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">>" then
				v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "==" then
				v.ret(v.equal_test(arguments[0], arguments[1]))
				return true
			else if pname == "!=" then
				var res = v.equal_test(arguments[0], arguments[1])
				v.ret(v.new_expr("!{res}", ret.as(not null)))
				return true
			else if pname == "<" then
				v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">" then
				v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "<=" then
				v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">=" then
				v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "to_i" then
				v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_b" then
				v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_i8" then
				v.ret(v.new_expr("(int8_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_i16" then
				v.ret(v.new_expr("(int16_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_u16" then
				v.ret(v.new_expr("(uint16_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_u32" then
				v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_f" then
				v.ret(v.new_expr("(double){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "&" then
				v.ret(v.new_expr("{arguments[0]} & {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "|" then
				v.ret(v.new_expr("{arguments[0]} | {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "^" then
				v.ret(v.new_expr("{arguments[0]} ^ {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "unary ~" then
				v.ret(v.new_expr("~{arguments[0]}", ret.as(not null)))
				return true
			end
		else if cname == "UInt32" then
			if pname == "output" then
				v.add("printf(\"%\"PRIu32 \"\\n\", {arguments.first});")
				return true
			else if pname == "object_id" then
				v.ret(v.new_expr("(long){arguments.first}", ret.as(not null)))
				return true
			else if pname == "+" then
				v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "-" then
				v.ret(v.new_expr("{arguments[0]} - {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "unary -" then
				v.ret(v.new_expr("-{arguments[0]}", ret.as(not null)))
				return true
			else if pname == "unary +" then
				v.ret(arguments[0])
				return true
			else if pname == "*" then
				v.ret(v.new_expr("{arguments[0]} * {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "/" then
				v.ret(v.new_expr("{arguments[0]} / {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "%" then
				v.ret(v.new_expr("{arguments[0]} % {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "<<" then
				v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">>" then
				v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "==" then
				v.ret(v.equal_test(arguments[0], arguments[1]))
				return true
			else if pname == "!=" then
				var res = v.equal_test(arguments[0], arguments[1])
				v.ret(v.new_expr("!{res}", ret.as(not null)))
				return true
			else if pname == "<" then
				v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">" then
				v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "<=" then
				v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">=" then
				v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "to_i" then
				v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_b" then
				v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_i8" then
				v.ret(v.new_expr("(int8_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_i16" then
				v.ret(v.new_expr("(int16_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_u16" then
				v.ret(v.new_expr("(uint16_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_i32" then
				v.ret(v.new_expr("(int32_t){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_f" then
				v.ret(v.new_expr("(double){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "&" then
				v.ret(v.new_expr("{arguments[0]} & {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "|" then
				v.ret(v.new_expr("{arguments[0]} | {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "^" then
				v.ret(v.new_expr("{arguments[0]} ^ {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "unary ~" then
				v.ret(v.new_expr("~{arguments[0]}", ret.as(not null)))
				return true
			end
		else if compiler.all_routine_types_name.has(cname) then
			v.routine_ref_call(mpropdef, arguments)
			return true
		end
		if pname == "exit" then
			v.add("exit((int){arguments[1]});")
			return true
		else if pname == "sys" then
			v.ret(v.new_expr("glob_sys", ret.as(not null)))
			return true
		else if pname == "object_id" then
			v.ret(v.new_expr("(long){arguments.first}", ret.as(not null)))
			return true
		else if pname == "is_same_type" then
			v.ret(v.is_same_type_test(arguments[0], arguments[1]))
			return true
		else if pname == "is_same_instance" then
			v.ret(v.equal_test(arguments[0], arguments[1]))
			return true
		else if pname == "output_class_name" then
			var nat = v.class_name_string(arguments.first)
			v.add("printf(\"%s\\n\", {nat});")
			return true
		else if pname == "native_class_name" then
			var nat = v.class_name_string(arguments.first)
			v.ret(v.new_expr("(char*){nat}", ret.as(not null)))
			return true
		else if pname == "force_garbage_collection" then
			v.add("nit_gcollect();")
			return true
		else if pname == "native_argc" then
			v.ret(v.new_expr("glob_argc", ret.as(not null)))
			return true
		else if pname == "native_argv" then
			v.ret(v.new_expr("glob_argv[{arguments[1]}]", ret.as(not null)))
			return true
		end
		return false
	end

	# Compile an extern method
	# Return `true` if the compilation was successful, `false` if a fall-back is needed
	fun compile_externmeth_to_c(v: AbstractCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable]): Bool
	do
		var externname
		var at = self.get_single_annotation("extern", v.compiler.modelbuilder)
		if at != null and at.n_args.length == 1 then
			externname = at.arg_as_string(v.compiler.modelbuilder)
			if externname == null then return false
		else
			return false
		end
		v.add_extern(mpropdef.mclassdef.mmodule)
		var res: nullable RuntimeVariable = null
		var ret = mpropdef.msignature.return_mtype
		if ret != null then
			ret = v.resolve_for(ret, arguments.first)
			res = v.new_var_extern(ret)
		end
		v.adapt_signature(mpropdef, arguments)
		v.unbox_signature_extern(mpropdef, arguments)

		if res == null then
			v.add("{externname}({arguments.join(", ")});")
		else
			v.add("{res} = {externname}({arguments.join(", ")});")
			res = v.box_extern(res, ret.as(not null))
			v.ret(res)
		end
		return true
	end

	# Compile an extern factory
	# Return `true` if the compilation was successful, `false` if a fall-back is needed
	fun compile_externinit_to_c(v: AbstractCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable]): Bool
	do
		var externname
		var at = self.get_single_annotation("extern", v.compiler.modelbuilder)
		if at != null then
			externname = at.arg_as_string(v.compiler.modelbuilder)
			if externname == null then return false
		else
			return false
		end
		v.add_extern(mpropdef.mclassdef.mmodule)
		v.adapt_signature(mpropdef, arguments)
		v.unbox_signature_extern(mpropdef, arguments)
		var ret = arguments.first.mtype
		var res = v.new_var_extern(ret)

		arguments.shift

		v.add("{res} = {externname}({arguments.join(", ")});")
		res = v.box_extern(res, ret)
		v.ret(res)
		return true
	end
end
src/compiler/abstract_compiler.nit:2623,1--3559,3

nitc :: ssa $ AMethPropdef
redef class AMethPropdef
	redef fun generate_basic_blocks(ssa: SSA)
	do
		basic_block = new BasicBlock
		basic_block.first = self
		basic_block.last = self

		# If the method has a signature
		if n_signature != null then
			for p in n_signature.n_params do
				# Add parameters to the local variables
				variables.add(p.variable.as(not null))
				p.variable.parameter = true
			end
		end

		# Add the return variable
		variables.add(returnvar)

		# Add the self variable
		if self.selfvariable != null then variables.add(selfvariable.as(not null))

		# Recursively goes into the nodes
		if n_block != null then
			n_block.generate_basic_blocks(ssa, basic_block.as(not null))
			is_generated = true
		end
	end
end
src/ssa.nit:492,1--520,3

nitc :: separate_compiler $ AMethPropdef
redef class AMethPropdef
	# The semi-global compilation does not support inlining calls to extern news
	redef fun can_inline
	do
		var m = mpropdef
		if m != null and m.mproperty.is_init and m.is_extern then return false
		return super
	end
end
src/compiler/separate_compiler.nit:2656,1--2664,3

nitc :: compiler_serialization $ AMethPropdef
redef class AMethPropdef
	redef fun compile_intern_to_c(v, mpropdef, arguments)
	do
		var pname = mpropdef.mproperty.name
		var ret = mpropdef.msignature.as(not null).return_mtype
		if pname == "class_inheritance_metamodel_json" then
			v.add("extern char* nit_class_inheritance_metamodel;")
			v.ret(v.new_expr("nit_class_inheritance_metamodel", ret.as(not null)))
			return true
		end

		return super
	end
end
src/compiler/compiler_serialization.nit:55,1--68,3

nitc :: contracts $ AMethPropdef
redef class AMethPropdef

	# Execute all method verification scope flow and typing.
	# It also execute an ast validation to define all parents and all locations
	private fun do_all(toolcontext: ToolContext)
	do
		self.validate
		# FIXME: The `do_` usage it is maybe to much (verification...). Solution: Cut the `do_` methods into simpler parts
		self.do_scope(toolcontext)
		self.do_flow(toolcontext)
		self.do_typing(toolcontext.modelbuilder)
	end

	# Entry point to create a contract (verification of inheritance, or new contract).
	redef fun create_contracts(v)
	do
		v.ast_builder.check_mmodule(mpropdef.mclassdef.mmodule)

		v.current_location = self.location
		v.is_intro_contract = mpropdef.is_intro

		if n_annotations != null then
			for n_annotation in n_annotations.n_items do
				check_annotation(v,n_annotation)
			end
		end

		if not mpropdef.is_intro and not v.find_no_contract then
			self.check_redef(v)
		end

		# reset the flag
		v.find_no_contract = false
	end

	# Verification of the annotation to know if it is a contract annotation.
	# If this is the case, we built the appropriate contract.
	private fun check_annotation(v: ContractsVisitor, n_annotation: AAnnotation)
	do
		if n_annotation.name == "expect" then
			if not v.check_usage_expect(mpropdef.mclassdef.mmodule) then return
			var exist_contract = mpropdef.mproperty.check_exist_expect
			mpropdef.construct_contract(v, self.n_signature.as(not null), n_annotation, mpropdef.mproperty.mexpect.as(not null), exist_contract)
		else if n_annotation.name == "ensure" then
			if not v.check_usage_ensure(mpropdef.mclassdef.mmodule) then return
			var exist_contract = mpropdef.mproperty.check_exist_ensure
			mpropdef.construct_contract(v, self.n_signature.as(not null), n_annotation, mpropdef.mproperty.mensure.as(not null), exist_contract)
		else if n_annotation.name == "no_contract" then
			# no_contract found set the flag to true
			v.find_no_contract = true
		end
	end

	# Verification if the method have an inherited contract to apply it.
	private fun check_redef(v: ContractsVisitor)
	do
		# Check if the method has an attached contract
		if not mpropdef.has_contract then
			if mpropdef.mproperty.intro.has_contract then
				mpropdef.has_contract = true
			end
		end
	end

	# Adapt the block to use the contracts
	private fun adapt_block_to_contract(v: ContractsVisitor, contract: MContract, n_mpropdef: AMethPropdef)
	do
		contract.adapt_block_to_contract(v, n_mpropdef)
		mpropdef.has_contract = true
		n_mpropdef.do_all(v.toolcontext)
	end
end
src/contracts.nit:777,1--848,3

nitc :: variables_numbering $ AMethPropdef
redef class AMethPropdef
	# Assign a position in the environment to each local variable
	# *`vm` The current VirtualMachine
	redef fun numbering_variables(vm: VirtualMachine)
	do
		# The position in the environment
		var position = 0

		# The `self` variable has the first position
		if self.selfvariable != null then
			self.selfvariable.position = position
			position += 1
		end

		# Number the parameters
		for i in [0..mpropdef.msignature.arity[ do
			var variable = self.n_signature.n_params[i].variable
			variable.as(not null).position = position
			position += 1
		end

		# Recursively go into the AST nodes to number all local variables
		if n_block != null then
			position = vm.numbering(self.n_block, position)
		end

		is_numbering = true

		# The size of the environment to create to execute a call to this method
		environment_size = position
	end
end
src/vm/variables_numbering.nit:119,1--150,3

nitc :: light $ AMethPropdef
redef class AMethPropdef
	private fun compile_ffi_support_to_c(v: AbstractCompilerVisitor)
	do
		var mmodule = mpropdef.mclassdef.mmodule
		var amodule = v.compiler.modelbuilder.mmodule2node(mmodule)
		var mclass_type = mpropdef.mclassdef.bound_mtype

		# Declare as extern
		var csignature = mpropdef.mproperty.build_csignature(mclass_type, mmodule, "___impl", long_signature, internal_call_context)
		v.declare_once("{csignature};")

		# FFI part
		amodule.ensure_compile_ffi_wrapper
		compile_ffi_method(mmodule)

		# nitni - Compile missing callbacks
		mmodule.ensure_compile_nitni_base(v)
	end

	# Should we compile the extern method `self`?
	#
	# Returns false when restricting to the light FFI on methods using callbacks.
	fun accept_externmeth: Bool do return true

	redef fun compile_externmeth_to_c(v, mpropdef, arguments)
	do
		# if using the old native interface fallback on previous implementation
		if n_extern_code_block == null then return super

		if not accept_externmeth then return false

		var mmodule = mpropdef.mclassdef.mmodule
		mmodule.uses_ffi = true

		var mclass_type = mpropdef.mclassdef.bound_mtype

		# Outgoing code in compiler
		var externname = mpropdef.mproperty.build_cname(mpropdef.mclassdef.bound_mtype, mmodule, "___impl", long_signature)
		var recv_var: nullable RuntimeVariable = null
		var return_mtype = mpropdef.msignature.return_mtype
		if return_mtype != null then
			return_mtype = return_mtype.anchor_to(mmodule, mclass_type)
			recv_var = v.new_var(return_mtype)
		end

		v.adapt_signature(mpropdef, arguments)
		v.unbox_signature_extern(mpropdef, arguments)

		var arguments_for_c = new Array[String]
		for a in [0..arguments.length[ do
			var arg = arguments[a]
			var param_mtype: MType
			if a == 0 then
				param_mtype = mpropdef.mclassdef.mclass.mclass_type
			else param_mtype = mpropdef.msignature.mparameters[a-1].mtype

			param_mtype = param_mtype.anchor_to(mmodule, mclass_type)

			if param_mtype.is_cprimitive then
				arguments_for_c.add(arg.name)
			else
				v.add("struct nitni_instance* var_for_c_{a};")
				v.add("var_for_c_{a} = nit_alloc(sizeof(struct nitni_instance));")
				v.add("var_for_c_{a}->value = {arg.name};")
				arguments_for_c.add("var_for_c_{a}")
			end
		end

		if recv_var == null then
			v.add("{externname}({arguments_for_c.join(", ")});")
		else
			assert return_mtype != null
			if return_mtype.is_cprimitive then
				v.add("{recv_var} = {externname}({arguments_for_c.join(", ")});")
			else
				v.add("struct nitni_instance* ret_var;")
				v.add("ret_var = {externname}({arguments_for_c.join(", ")});")
				v.add("{recv_var} = ret_var->value;")
			end
			recv_var = v.box_extern(recv_var, return_mtype)
			v.ret(recv_var)
		end

		compile_ffi_support_to_c(v)
		return true
	end

	redef fun compile_externinit_to_c(v, mpropdef, arguments)
	do
		# if using the old native interface fallback on previous implementation
		if n_extern_code_block == null then return super

		if not accept_externmeth then return false

		var mmodule = mpropdef.mclassdef.mmodule
		mmodule.uses_ffi = true

		var mclass_type = mpropdef.mclassdef.bound_mtype

		var externname = mpropdef.mproperty.build_cname(mpropdef.mclassdef.bound_mtype, mmodule, "___impl", long_signature)
		var return_mtype = arguments.first.mtype
		var recv_var = v.new_var(return_mtype)

		v.adapt_signature(mpropdef, arguments)
		v.unbox_signature_extern(mpropdef, arguments)

		arguments.shift

		var arguments_for_c = new Array[String]
		for a in [0..arguments.length[ do
			var arg = arguments[a]
			var param_mtype: MType
			param_mtype = mpropdef.msignature.mparameters[a].mtype
			param_mtype = param_mtype.anchor_to(mmodule, mclass_type)

			if param_mtype.is_cprimitive then
				arguments_for_c.add(arg.name)
			else
				v.add("struct nitni_instance* var_for_c_{a};")
				v.add("var_for_c_{a} = nit_alloc(sizeof(struct nitni_instance));")
				v.add("var_for_c_{a}->value = {arg.name};")
				arguments_for_c.add("var_for_c_{a}")
			end
		end

		if return_mtype.is_cprimitive then
			v.add("{recv_var} = {externname}({arguments_for_c.join(", ")});")
		else
			v.add("struct nitni_instance* ret_var;")
			v.add("ret_var = {externname}({arguments_for_c.join(", ")});")
			v.add("{recv_var} = ret_var->value;")
		end
		recv_var = v.box_extern(recv_var, return_mtype)
		v.ret(recv_var)

		compile_ffi_support_to_c(v)
		return true
	end
end
src/compiler/compiler_ffi/light.nit:83,1--221,3

nitc :: compiler_ffi $ AMethPropdef
redef class AMethPropdef
	redef fun compile_ffi_support_to_c(v)
	do
		super

		var mmodule = mpropdef.mclassdef.mmodule
		var mainmodule = v.compiler.mainmodule
		var ccu = mmodule.nitni_ccu.as(not null)

		for mtype in foreign_callbacks.types do
			if not mtype.is_cprimitive then
				mtype.compile_extern_type(v, ccu)

				# has callbacks already been compiled? (this may very well happen with global compilation)
				mtype.compile_extern_helper_functions(v, ccu, mmodule.check_callback_compilation(mtype))
			end
		end

		# compile callbacks
		for cb in foreign_callbacks.callbacks do
			cb.compile_extern_callback(v, ccu, mainmodule.check_callback_compilation(cb))
		end

		for cb in foreign_callbacks.supers do
			cb.compile_extern_callback(v, ccu, mainmodule.check_callback_compilation(cb))
		end

		for cb in foreign_callbacks.casts do
			cb.compile_extern_callbacks(v, ccu, mainmodule.check_callback_compilation(cb))
		end

		# manage nitni callback set
		mmodule.foreign_callbacks.join(foreign_callbacks)
	end
end
src/compiler/compiler_ffi/compiler_ffi.nit:47,1--81,3

nitc :: light_only $ AMethPropdef
redef class AMethPropdef
	redef fun accept_externmeth do return n_extern_calls == null
end
src/compiler/compiler_ffi/light_only.nit:24,1--26,3

nitc :: on_demand_compiler $ AMethPropdef
redef class AMethPropdef
	# Does this method definition use the FFI and is it supported by the interpreter?
	#
	# * Must use the nested foreign code block of the FFI.
	# * Must not have callbacks.
	# * Must be implemented in C.
	# * Must not have a parameter or return typed with a Nit standard class.
	fun supported_by_dynamic_ffi: Bool
	do
		# If the user specfied `is light_ffi`, it must be supported
		var nats = get_annotations("light_ffi")
		if nats.not_empty then return true

		var n_extern_code_block = n_extern_code_block
		if not (n_extern_calls == null and n_extern_code_block != null and
		        n_extern_code_block.is_c) then return false

		for mparam in mpropdef.msignature.mparameters do
			if not mparam.mtype.is_cprimitive then
				return false
			end
		end

		var return_mtype = mpropdef.msignature.return_mtype
		if return_mtype != null and not return_mtype.is_cprimitive then
			return false
		end

		return true
	end
end
src/interpreter/dynamic_loading_ffi/on_demand_compiler.nit:33,1--63,3

nitc :: dynamic_loading_ffi $ AMethPropdef
redef class AMethPropdef
	# Handle to the entrypoint of this method in the foreign code library
	private var foreign_entry_cache: nullable ForeignCodeEntry = null

	redef fun call_extern(v, mpropdef, args, frame)
	do
		# Fallback the default error if this method is not supported
		if not supported_by_dynamic_ffi then return super

		var entry = foreign_entry_cache
		if entry == null then
			# Get handle to foreign code lib
			var amodule = v.modelbuilder.mmodule2node(mpropdef.mclassdef.mmodule)
			assert amodule != null

			var lib = amodule.foreign_code_lib(v)
			if lib == null then return v.error_instance

			# Get handle to implementation function
			entry = lib.dlsym(mpropdef.foreign_lib_entry_cname.to_cstring)
			if entry.address_is_null then
				print mpropdef.foreign_lib_entry_cname
				v.fatal "FFI Error: Cannot find method {mpropdef.name} in foreign code library."
				return v.error_instance
			end

			foreign_entry_cache = entry
		end

		# Prepare to send args to foreign code lib
		var is_init = mpropdef.mproperty.is_init
		if is_init then args.shift
		var native_args_length = args.length

		var native_args = new CallArg(args.length)
		var a = 0
		if not is_init then
			var arg = args[a]
			var native_arg = native_args[a]
			native_arg.from_static_type(arg, mpropdef.mclassdef.mclass.mclass_type)
			a += 1
		end
		for param in mpropdef.msignature.mparameters do
			var arg = args[a]
			var native_arg = native_args[a]
			native_arg.from_static_type(arg, param.mtype)
			a += 1
		end

		# Allocate memory for the return value
		var native_return = new CallArg(1)
		var error = entry.call(native_args_length, native_args, native_return)

		if error then
			v.fatal "FFI Error: Native code library reported an error"
			return null
		end

		# Get the result
		var return_mtype = mpropdef.msignature.return_mtype
		if is_init then return_mtype = mpropdef.mclassdef.mclass.mclass_type

		var return_value
		if return_mtype == null then
			return_value = null
		else
			return_value = native_return.to_instance(return_mtype, v)
		end

		native_args.free
		native_return.free

		return return_value
	end
end
src/interpreter/dynamic_loading_ffi/dynamic_loading_ffi.nit:249,1--323,3

nitc :: java_compiler $ AMethPropdef
redef class AMethPropdef
	redef fun compile_to_java(v, mpropdef, arguments) do
		if mpropdef.msignature != null then
			var i = 0
			for mparam in mpropdef.msignature.as(not null).mparameters do
				var variable = n_signature.as(not null).n_params[i].variable
				if variable == null then continue
				var argvar = v.variable(variable)
				v.assign(argvar, v.new_expr("args[{i + 1}]", v.compiler.mainmodule.object_type))
				arguments.add(argvar)
				i += 1
			end
		end

		# Call the implicit super-init
		var auto_super_inits = self.auto_super_inits
		if auto_super_inits != null then
			var args = [arguments.first]
			for auto_super_init in auto_super_inits do
				assert auto_super_init.mproperty != mpropdef.mproperty
				args.clear
				for i in [0..auto_super_init.msignature.arity+1[ do
					args.add(arguments[i])
				end
				assert auto_super_init.mproperty != mpropdef.mproperty
				v.compile_callsite(auto_super_init, args)
			end
		end
		if auto_super_call then
			v.supercall(mpropdef, arguments.first.mtype.as(MClassType), arguments)
		end

		compile_inside_to_java(v, mpropdef, arguments)
	end

	# Compile the inside of the method body
	private fun compile_inside_to_java(v: JavaCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable]) do
		# Compile intern methods
		if mpropdef.is_intern then
			if compile_intern_to_java(v, mpropdef, arguments) then return
			v.info("NOT YET IMPLEMENTED compile_intern for {mpropdef}")
			v.ret(v.null_instance)
			return
		end

		# Compile block if any
		var n_block = n_block
		if n_block != null then
			v.stmt(n_block)
			return
		end
	end

	# Compile an intern method using Java primitives
	fun compile_intern_to_java(v: JavaCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable]): Bool do
		var pname = mpropdef.mproperty.name
		var cname = mpropdef.mclassdef.mclass.name
		var ret = mpropdef.msignature.as(not null).return_mtype
		if cname == "Int" then
			if pname == "output" then
				v.add("System.out.println({arguments[0]});")
				v.ret(v.null_instance)
				return true
			else if pname == "object_id" then
				v.ret(arguments.first)
				return true
			else if pname == "+" then
				v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "-" then
				v.ret(v.new_expr("{arguments[0]} - {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "unary -" then
				v.ret(v.new_expr("-{arguments[0]}", ret.as(not null)))
				return true
			else if pname == "unary +" then
				v.ret(arguments[0])
				return true
			else if pname == "*" then
				v.ret(v.new_expr("{arguments[0]} * {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "/" then
				v.ret(v.new_expr("{arguments[0]} / {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "%" then
				v.ret(v.new_expr("{arguments[0]} % {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "<<" then
				v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">>" then
				v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "==" then
				v.ret(v.equal_test(arguments[0], arguments[1]))
				return true
			else if pname == "!=" then
				var res = v.equal_test(arguments[0], arguments[1])
				v.ret(v.new_expr("!{res}", ret.as(not null)))
				return true
			else if pname == "<" then
				v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">" then
				v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "<=" then
				v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">=" then
				v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "to_f" then
				v.ret(v.new_expr("(double){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_b" then
				v.ret(v.new_expr("(byte){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "ascii" then
				v.ret(v.new_expr("(char){arguments[0]}", ret.as(not null)))
				return true
			end
		else if cname == "Char" then
			if pname == "output" then
				v.add("System.out.print({arguments[0]});")
				v.ret(v.null_instance)
				return true
			else if pname == "object_id" then
				v.ret(v.new_expr("(int){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "successor" then
				v.ret(v.new_expr("(char)({arguments[0]} + {arguments[1]})", ret.as(not null)))
				return true
			else if pname == "predecessor" then
				v.ret(v.new_expr("(char)({arguments[0]} - {arguments[1]})", ret.as(not null)))
				return true
			else if pname == "==" then
				v.ret(v.equal_test(arguments[0], arguments[1]))
				return true
			else if pname == "!=" then
				var res = v.equal_test(arguments[0], arguments[1])
				v.ret(v.new_expr("!{res}", ret.as(not null)))
				return true
			else if pname == "<" then
				v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">" then
				v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "<=" then
				v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">=" then
				v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "to_i" then
				v.ret(v.new_expr("(int){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "ascii" then
				v.ret(v.new_expr("(int){arguments[0]}", ret.as(not null)))
				return true
			end
		else if cname == "Byte" then
			if pname == "output" then
				v.add("System.out.println({arguments[0]});")
				v.ret(v.null_instance)
				return true
			else if pname == "object_id" then
				v.ret(v.new_expr("(int){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "+" then
				v.ret(v.new_expr("(byte)({arguments[0]} + {arguments[1]})", ret.as(not null)))
				return true
			else if pname == "-" then
				v.ret(v.new_expr("(byte)({arguments[0]} - {arguments[1]})", ret.as(not null)))
				return true
			else if pname == "unary -" then
				v.ret(v.new_expr("(byte)(-{arguments[0]})", ret.as(not null)))
				return true
			else if pname == "unary +" then
				v.ret(arguments[0])
				return true
			else if pname == "*" then
				v.ret(v.new_expr("(byte)({arguments[0]} * {arguments[1]})", ret.as(not null)))
				return true
			else if pname == "/" then
				v.ret(v.new_expr("(byte)({arguments[0]} / {arguments[1]})", ret.as(not null)))
				return true
			else if pname == "%" then
				v.ret(v.new_expr("(byte)({arguments[0]} % {arguments[1]})", ret.as(not null)))
				return true
			else if pname == "<<" then
				v.ret(v.new_expr("(byte)({arguments[0]} << {arguments[1]})", ret.as(not null)))
				return true
			else if pname == ">>" then
				v.ret(v.new_expr("(byte)({arguments[0]} >> {arguments[1]})", ret.as(not null)))
				return true
			else if pname == "==" then
				v.ret(v.equal_test(arguments[0], arguments[1]))
				return true
			else if pname == "!=" then
				var res = v.equal_test(arguments[0], arguments[1])
				v.ret(v.new_expr("!{res}", ret.as(not null)))
				return true
			else if pname == "<" then
				v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">" then
				v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "<=" then
				v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">=" then
				v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "to_i" then
				v.ret(v.new_expr("(int){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_f" then
				v.ret(v.new_expr("(double){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "ascii" then
				v.ret(v.new_expr("{arguments[0]}", ret.as(not null)))
				return true
			end
		else if cname == "Bool" then
			if pname == "output" then
				v.add("System.out.println({arguments[0]});")
				v.ret(v.null_instance)
				return true
			else if pname == "object_id" then
				v.ret(v.new_expr("{arguments[0]}?1:0", ret.as(not null)))
				return true
			else if pname == "==" then
				v.ret(v.equal_test(arguments[0], arguments[1]))
				return true
			else if pname == "!=" then
				var res = v.equal_test(arguments[0], arguments[1])
				v.ret(v.new_expr("!{res}", ret.as(not null)))
				return true
			end
		else if cname == "Float" then
			if pname == "output" then
				v.add "if({arguments[0]} == Double.POSITIVE_INFINITY) \{"
				v.add "System.out.println(\"inf\");"
				v.add "\} else if({arguments[0]} == Double.POSITIVE_INFINITY) \{"
				v.add "System.out.println(\"-inf\");"
				v.add "\} else \{"
				var df = v.get_name("df")
				v.add "java.text.DecimalFormat {df} = new java.text.DecimalFormat(\"0.000000\");"
				v.add "System.out.println({df}.format({arguments[0]}));"
				v.add "\}"
				v.ret(v.null_instance)
				return true
			else if pname == "object_id" then
				v.ret(v.new_expr("(int){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "+" then
				v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "-" then
				v.ret(v.new_expr("{arguments[0]} - {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "unary -" then
				v.ret(v.new_expr("-{arguments[0]}", ret.as(not null)))
				return true
			else if pname == "unary +" then
				v.ret(arguments[0])
				return true
			else if pname == "succ" then
				v.ret(v.new_expr("{arguments[0]} + 1", ret.as(not null)))
				return true
			else if pname == "prec" then
				v.ret(v.new_expr("{arguments[0]} - 1", ret.as(not null)))
				return true
			else if pname == "*" then
				v.ret(v.new_expr("{arguments[0]} * {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "/" then
				v.ret(v.new_expr("{arguments[0]} / {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "==" then
				v.ret(v.equal_test(arguments[0], arguments[1]))
				return true
			else if pname == "!=" then
				var res = v.equal_test(arguments[0], arguments[1])
				v.ret(v.new_expr("!{res}", ret.as(not null)))
				return true
			else if pname == "<" then
				v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">" then
				v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "<=" then
				v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == ">=" then
				v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
				return true
			else if pname == "to_i" then
				v.ret(v.new_expr("(int){arguments[0]}", ret.as(not null)))
				return true
			else if pname == "to_b" then
				v.ret(v.new_expr("(byte){arguments[0]}", ret.as(not null)))
				return true
			end
		end
		if pname == "exit" then
			v.add("System.exit({arguments[1]});")
			v.ret(v.null_instance)
			return true
		else if pname == "sys" then
			# TODO singleton
			var main_type = v.compiler.mainmodule.sys_type.as(not null)
			var sys = main_type.mclass
			v.ret(v.new_expr("new RTVal({sys.rt_name}.get{sys.rt_name}())", main_type))
			return true
		else if pname == "object_id" then
			v.ret(v.new_expr("{arguments[0]}.hashCode()", ret.as(not null)))
			return true
		else if pname == "is_same_type" then
			v.ret(v.is_same_type_test(arguments[0], arguments[1]))
			return true
		else if pname == "is_same_instance" then
			v.ret(v.equal_test(arguments[0], arguments[1]))
			return true
		else if pname == "output_class_name" then
			v.add("System.out.println({arguments[0]}.rtclass.class_name);")
			v.ret(v.null_instance)
			return true
		end
		return false
	end
end
src/compiler/java_compiler.nit:1503,1--1838,3