blob: 039c4dd4d2d5e6767fac25f395e10384213fbb65 [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
use strict;
use warnings;
package Clownfish::Class;
use base qw( Clownfish::Symbol );
use Carp;
use Config;
use Clownfish::Function;
use Clownfish::Method;
use Clownfish::Util qw(
verify_args
a_isa_b
);
use Clownfish::Dumpable;
END { __PACKAGE__->_clear_registry() }
our %create_PARAMS = (
source_class => undef,
class_name => undef,
cnick => undef,
parent_class_name => undef,
docucomment => undef,
inert => undef,
final => undef,
parcel => undef,
exposure => 'parcel',
);
our %fetch_singleton_PARAMS = (
parcel => undef,
class_name => undef,
);
sub fetch_singleton {
my ( undef, %args ) = @_;
verify_args( \%fetch_singleton_PARAMS, %args ) or confess $@;
# Maybe prepend parcel prefix.
my $parcel = $args{parcel};
if ( defined $parcel ) {
if ( !a_isa_b( $parcel, "Clownfish::Parcel" ) ) {
$parcel = Clownfish::Parcel->singleton( name => $parcel );
}
}
return _fetch_singleton( $parcel, $args{class_name} );
}
sub new { confess("The constructor for Clownfish::Class is create()") }
sub create {
my ( $either, %args ) = @_;
verify_args( \%create_PARAMS, %args ) or confess $@;
$args{parcel} = Clownfish::Parcel->acquire( $args{parcel} );
my $package = ref($either) || $either;
return _create(
$package,
@args{
qw( parcel exposure class_name cnick micro_sym
docucomment source_class parent_class_name final inert )
}
);
}
1;
__END__
__POD__
=head1 NAME
Clownfish::Class - An object representing a single class definition.
=head1 CONSTRUCTORS
Clownfish::Class objects are stored as quasi-singletons, one for each
unique parcel/class_name combination.
=head2 fetch_singleton
my $class = Clownfish::Class->fetch_singleton(
parcel => 'Crustacean',
class_name => 'Crustacean::Lobster::LobsterClaw',
);
Retrieve a Class, if one has already been created.
=head2 create
my $class = Clownfish::Class->create(
parcel => 'Crustacean', # default: special
class_name => 'Crustacean::Lobster::LobsterClaw', # required
cnick => 'LobClaw', # default: special
exposure => 'public', # default: 'parcel'
source_class => undef, # default: same as class_name
parent_class_name => 'Crustacean::Claw', # default: undef
inert => undef, # default: undef
docucomment => $documcom, # default: undef,
);
Create and register a quasi-singleton. May only be called once for each
unique parcel/class_name combination.
=over
=item * B<parcel>, B<class_name>, B<cnick>, B<exposure> - see
L<Clownfish::Symbol>.
=item * B<source_class> - The name of the class that owns the file in which
this class was declared. Should be "Foo" if "Foo::FooJr" is defined in
C<Foo.cfh>.
=item * B<parent_class_name> - The name of this class's parent class. Needed
in order to establish the class hierarchy.
=item * B<inert> - Should be true if the class is inert, i.e. cannot be
instantiated.
=item * B<docucomment> - A Clownfish::DocuComment describing this Class.
=back
=head1 METHODS
=head2 get_cnick get_struct_sym get_parent_class_name get_source_class
get_docucomment get_parent get_autocode inert final
Accessors.
=head2 set_parent
$class->set_parent($ancestor);
Set the parent class.
=head2 add_child
$class->add_child($child_class);
Add a child class.
=head2 add_method
$class->add_method($method);
Add a Method to the class. Valid only before grow_tree() is called.
=head2 add_function
$class->add_function($function);
Add a Function to the class. Valid only before grow_tree() is called.
=head2 add_member_var
$class->add_member_var($var);
Add a member variable to the class. Valid only before grow_tree() is called.
=head2 add_inert_var
$class->add_inert_var($var);
Add an inert (class) variable to the class. Valid only before grow_tree() is
called.
=head2 add_attribute
$class->add_attribute($var, $value);
Add an arbitrary attribute to the class.
=head2 function
my $do_stuff_function = $class->function("do_stuff");
Return the inert Function object for the supplied C<micro_sym>, if any.
=head2 method
my $pinch_method = $class->method("Pinch");
Return the Method object for the supplied C<micro_sym> / C<macro_sym>, if any.
=head2 novel_method
my $pinch_method = $class->novel_method("Pinch");
Return a Method object if the Method corresponding to the supplied string is
novel.
=head2 children
my $child_classes = $class->children;
Return an array of all child classes.
=head2 functions
my $functions = $class->functions;
Return an array of all (inert) functions.
=head2 methods
my $methods = $class->methods;
Return an array of all methods.
=head2 inert_vars
my $inert_vars = $class->inert_vars;
Return an array of all inert (shared, class) variables.
=head2 member_vars
my $members = $class->member_vars;
Return an array of all member variables.
=head2 novel_methods
my $novel_methods = $class->novel_methods;
Return an array of all novel methods.
=head2 novel_member_vars
my $new_members = $class->novel_member_vars;
Return an array of all novel member variables.
=head2 grow_tree
$class->grow_tree;
Bequeath all inherited methods and members to children.
=head2 tree_to_ladder
my $ordered = $class->tree_to_ladder;
Return this class and all its child classes as an array, where all children
appear after their parent nodes.
=head2 include_h
my $relative_path = $class->include_h;
Return a relative path to a C header file, appropriately formatted for a
pound-include directive.
=head2 append_autocode
$class->append_autocode($code);
Append auxiliary C code.
=head2 short_vtable_var
The short name of the global VTable object for this class.
=head2 full_vtable_var
Fully qualified vtable variable name, including the parcel prefix.
=head2 full_vtable_type
The fully qualified C type specifier for this class's vtable, including the
parcel prefix. Each vtable needs to have its own type because each has a
variable number of methods at the end of the struct, and it's not possible to
initialize a static struct with a flexible array at the end under C89.
=head2 full_struct_sym
Fully qualified struct symbol, including the parcel prefix.
=cut