=head1 NAME ExtUtils::XSpp::Plugin - XS++ plugin interface =head1 DESCRIPTION The XS++ plugin interface is B<EXPERIMENTAL> and subject to change. If you still want to use it, read the source of this module. =begin internal =head1 SYNTAX %loadplugin{MyPlugin}; int foo(int y) %FuncTag{Foo}; class klass { %ClassTag{Klass}; void bar() %MethodTag{Bar}; }; There are two ways a plugin can modify the code emitted by XS++: it can run after the parsing completes and modify the expression tree before it is emitted or it can handle custom annotation tags associated with a class/function/method. A custom tag can have either positional or named parameters: # positional %Foo{Id}{% multi line block %}{AnotherId}; # named %Bar{ %AParam{Id}; %AnotherParam{% block %}; %AThirdParam{AnotherId}; }; No check is performed on parameter names/types/count. The parser only gives an error if the annotation is not handled by any plugin. Positional parameters are passed to tag handlers as an array reference in the C<any_named_arguments> parameter; named handlers are passed as an hash reference in the C<any_positional_arguments> parameter. The value of a special block parameter is an array reference with an element for each line in the special block. For consistency, the value of an identifier parameter is a single-element array reference. =head1 XS++ METHODS These methods are defined in the parser object. =head2 add_post_process_plugin $parser->add_post_process_plugin( plugin => $instance ); Registers a post-processing plugin to be called after the parsing finishes. =head2 add_function_tag_plugin $parser->add_function_tag_plugin( plugin => $instance, # optional tag => $tag, ); Add a plugin to handle functions annotated with tags. =head2 add_class_tag_plugin $parser->add_class_tag_plugin( plugin => $instance, # optional tag => $tag, ); Add a plugin to handle classes annotated with tags. =head2 add_method_tag_plugin $parser->add_method_tag_plugin( plugin => $instance, # optional tag => $tag, ); Add a plugin to handle methods annotated with tags. =head2 add_toplevel_tag_plugin $parser->add_toplevel_tag_plugin( plugin => $instance, # optional tag => $tag, ); Add a plugin to handle top-level directives. =head1 PLUGIN METHODS These methods can be defined by the plugin to modify the emitted code. =head2 register_plugin sub register_plugin { my( $class, $parser ) = @_; # call the various add_*_plugin methods to register the plugin } This method is called once for each loaded plugin, the first time the parses sees the C<%load_plugin> directive. TODO add another method that is called once for each C<%loadplugin> declaration, and allow passing parameters to the plugin. =head2 post_process sub post_process { my( $self, $nodes ) = @_; # process and mutate the list of nodes } =head2 handle_function_tag sub handle_function_tag { my( $self, $function, $tag, %args ) = @_; # do something useful } C<$function> is a C<Function> node. C<$tag> is the tag string, without the C<%> prefix. C<%args> are the arguments passed to the tag. If the method handles the tag, it must return C<1> to the caller. =head2 handle_class_tag sub handle_class_tag { my( $self, $class, $tag, %args ) = @_; # do something useful } C<$class> is a C<Class> node. C<$tag> is the tag string, without the C<%> prefix. C<%args> are the arguments passed to the tag. The handler for the class is called after the handlers for its methods. If the method handles the tag, it must return C<1> to the caller. =head2 handle_method_tag sub handle_method_tag { my( $self, $method, $tag, %args ) = @_; # do something useful } C<$method> is a C<Method> node. C<$tag> is the tag string, without the C<%> prefix. C<%args> are the arguments passed to the tag. If the method handles the tag, it must return C<1> to the caller. =head2 handle_toplevel_tag sub handle_toplevel_tag { my( $self, undef, $tag, %args ) = @_; # do something useful } C<$tag> is the tag string, without the C<%> prefix. C<%args> are the arguments passed to the tag. The C<undef> value is for uniformity with other tag handlers. If the method handles the tag, it must return C<1> to the caller. =end internal =cut