class Bindgen::Processor::Inheritance

Overview

Processor wrapping single- and multiple-inheritance.

Only non-private wrapped classes are possible candidates for this. Of all candidates, the first one is chosen as parent class in Crystal. All others get a #as_X() : X casting method.

Take this C++ class: class Foo : public Bar, public Baz If both Bar and Baz are wrapped, the resulting Crystal wrapper will look like this:

class Foo < Bar # First one is inherited
  def as_baz : Baz
    ...
  end # Later ones converted
end

Classes with further wrapped bases, and polymorphic classes with wrapped polymorphic ancestors or descendants, get a #to?(T.class) method, casting self to the wrapper class T. It returns self for its own class, calls #as_X for the further bases, and casts down to polymorphic sub-classes through a dynamic_cast, returning nil if the instance isn't a T. The result wraps the same C++ object. Other types are passed on to the #to? of the Crystal superclass, or are a compile-time error.

x = Bar.create # Returns a `Bar`, which actually is a `Foo`
x.to?(Foo)     # => #<Foo:...>
x.to?(Baz)     # Compile-time error

Every wrapper class gets the Crystal class method Graph::Class::DISCOVER_METHOD, see SPEC.md §2.3.7, which wraps a pointer in the Crystal object which constructed the object, if any, and else in a new wrapper. A polymorphic class with wrapped sub-classes in Crystal gets type discovery too: a C++ DISCOVER function finding the wrapper class of the dynamic type of an object, which the method wraps in. Crystal::Pass#from_wrapper converts a pointer or reference result, and the argument of a callback, through it: x above is a Foo already.

Defined in:

bindgen/processor/inheritance.cr

Constant Summary

Log = ::Log.for(self)

Processor wrapping single- and multiple-inheritance.

Only non-private wrapped classes are possible candidates for this. Of all candidates, the first one is chosen as parent class in Crystal. All others get a #as_X() : X casting method.

Take this C++ class: class Foo : public Bar, public Baz If both Bar and Baz are wrapped, the resulting Crystal wrapper will look like this:

class Foo < Bar # First one is inherited
  def as_baz : Baz
    ...
  end # Later ones converted
end

Classes with further wrapped bases, and polymorphic classes with wrapped polymorphic ancestors or descendants, get a #to?(T.class) method, casting self to the wrapper class T. It returns self for its own class, calls #as_X for the further bases, and casts down to polymorphic sub-classes through a dynamic_cast, returning nil if the instance isn't a T. The result wraps the same C++ object. Other types are passed on to the #to? of the Crystal superclass, or are a compile-time error.

x = Bar.create # Returns a `Bar`, which actually is a `Foo`
x.to?(Foo)     # => #<Foo:...>
x.to?(Baz)     # Compile-time error

Every wrapper class gets the Crystal class method Graph::Class::DISCOVER_METHOD, see SPEC.md §2.3.7, which wraps a pointer in the Crystal object which constructed the object, if any, and else in a new wrapper. A polymorphic class with wrapped sub-classes in Crystal gets type discovery too: a C++ DISCOVER function finding the wrapper class of the dynamic type of an object, which the method wraps in. Crystal::Pass#from_wrapper converts a pointer or reference result, and the argument of a callback, through it: x above is a Foo already.

Constructors

Instance Method Summary

Instance methods inherited from class Bindgen::Processor::Base

inherited_rules(class_name : String, & : TypeDatabase::TypeConfig -> TypeDatabase::KeepAlive) : TypeDatabase::KeepAlive inherited_rules, process(graph : Graph::Container, doc : Parser::Document) process, unmatched_patterns(klass : Graph::Class, rules : TypeDatabase::KeepAlive) : Array(Regex) unmatched_patterns

Constructor methods inherited from class Bindgen::Processor::Base

new(config : Configuration, db : TypeDatabase) new

Instance methods inherited from module Bindgen::Graph::Visitor

visit_alias(alias_name) visit_alias, visit_children(container : Container) visit_children, visit_class(klass) visit_class, visit_constant(constant) visit_constant, visit_enum(enumeration) visit_enum, visit_library(library) visit_library, visit_method(method) visit_method, visit_namespace(ns) visit_namespace, visit_node(node : Node) visit_node, visit_node?(node : Node) visit_node?, visit_platform_specific(specific) visit_platform_specific, visit_struct(structure) visit_struct, visit_union(structure) visit_union

Constructor Detail

def self.new(config, db) #

[View source]

Instance Method Detail

def process(graph : Graph::Container, doc : Parser::Document) #
Description copied from class Bindgen::Processor::Base

Runs the processor. You may change graph as you see fit.


[View source]
def visit_class(klass : Graph::Class) #

[View source]