nitc :: ExternClassesTypingPhaseAst
Assigns theftype
to class definitions, work on the AST only
nitc :: extern_classes $ MClassDef
A definition (an introduction or a refinement) of a class in a modulenitc $ ExternClassesTypingPhaseAst
Assigns theftype
to class definitions, work on the AST only
nitc :: extern_classes $ MClassDef
A definition (an introduction or a refinement) of a class in a moduleSerializable::inspect
to show more useful information
nitc :: modelbuilder
more_collections :: more_collections
Highly specific, but useful, collections-related classes.serialization :: serialization_core
Abstract services to serialize Nit objects to different formatsnitc :: toolcontext
Common command-line tool infrastructure than handle options and error messagescore :: union_find
union–find algorithm using an efficient disjoint-set data structurecflags
and ldflags
to specify
extra_java_files
to compile extra java files
nitc :: light_only
Compiler support for the light FFI only, detects unsupported usage of callbacksclone
method of the astbuilder tool
# Manages all extern classes and their associated foreign type.
module extern_classes
import light_ffi_base
import modelize
redef class ToolContext
var extern_classes_typing_phase_ast: Phase = new ExternClassesTypingPhaseAst(self, [ffi_language_assignation_phase, modelize_class_phase])
var extern_classes_typing_phase_model: Phase = new ExternClassesTypingPhaseModel(self,
[extern_classes_typing_phase_ast, modelize_class_phase, modelize_property_phase])
end
# Assigns the `ftype` to class definitions, work on the AST only
private class ExternClassesTypingPhaseAst
super Phase
redef fun process_nclassdef(nclassdef)
do
if not nclassdef isa AStdClassdef then return
var code_block = nclassdef.n_extern_code_block
if code_block == null then return
if nclassdef.n_kwredef != null then
# A redef cannot specify a different extern type
toolcontext.error(nclassdef.location, "FFI Error: only the introduction of a class can declare an extern type.")
return
end
var ftype = code_block.language.get_ftype(code_block, nclassdef)
nclassdef.mclassdef.ftype_cache = ftype
nclassdef.mclassdef.ftype_computed = true
end
end
redef class MClassDef
private var ftype_cache: nullable ForeignType = null
private var ftype_computed = false
# Associated extern type when defined on this classdef
fun ftype: nullable ForeignType
do
return ftype_cache
end
end
private class ExternClassesTypingPhaseModel
super Phase
redef fun process_nclassdef(nclassdef)
do
if not nclassdef isa AStdClassdef then return
var mclassdef = nclassdef.mclassdef
if mclassdef == null then return
var mclass = mclassdef.mclass
# We only need to do this once per class
if not mclassdef.is_intro then return
if mclass.kind != extern_kind then return
mclass.compute_ftype(self)
end
end
redef class MClass
private var ftype_cache: nullable ForeignType = null
private var ftype_computed = false
# Extern type associated to this class according to specialisation
fun ftype: nullable ForeignType do return ftype_cache
redef fun ctype do return ftype_cache.ctype
# Type in C of the extern class
# If not defined in the intro of this class will look in super-classes
# FIXME this only supports type definition at intro, extend to superclasses by redef
private fun compute_ftype(v: ExternClassesTypingPhaseModel): nullable ForeignType
do
if ftype_computed then return ftype_cache
if kind != extern_kind then return null
# base case
if name == "Pointer" then
ftype_cache = new ForeignType
ftype_computed = true
return ftype_cache
end
var ftype = intro.ftype
if ftype == null then
var ftype_b: nullable ForeignType = null # FIXME hack to circumvent bug where ftype is typed null
# look in super classes
for s in in_hierarchy(intro_mmodule).direct_greaters do
var super_ftype = s.compute_ftype(v)
if super_ftype != null then
if ftype_b == null then
ftype_b = super_ftype
continue
else
# detect conflict
if super_ftype != ftype_b then
v.toolcontext.error(null, "FFI Error: extern type conflict in `{self}`.")
return null
end
end
end
end
ftype = ftype_b
end
ftype_cache = ftype
ftype_computed = true
return ftype
end
end
src/ffi/extern_classes.nit:17,1--136,3