Re: DBDI Status

[email protected] (Sentra Systems) Fri, 10 Jul 2009 23:45:46 +0100
Newsgroups perl.dbdi.dev
Message-ID <[email protected]>
--------------080602020509010106030806
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Tim

Attached is a modified copy of the Generator::Std that emits current 
perl6. It's been amended to add the correct sigils and 'use' statements. 
Do you want to give it a try and see if it does what you want?

:)
Dave
 

Tim Bunce wrote:
> On Mon, Jul 06, 2009 at 02:08:17PM +0100, Sentra Systems wrote:
>   
>> Tim
>>
>> Is there a particular reference implementation of java.sql(x) you're 
>> planning on running the java2perl on? A quick google shows a reference API 
>> but no obvious reference implementation.
>>     
>
> Any implementation that has the classes will do.  java2perl6 is only
> concerned with the class interfaces.  It just runs javap on the class
> you give it, parses the class and interfaces definitions it outputs, and
> writes corresponding perl6 clasess and roles definitions.
>
> Try running
>
>     java2perl6 --outdir jdbc --recurse --nest java.sql.Connection
>
> I've just checked in a file I had on my disk that lists all the
> java.sql and javax.sql classess, so you can run
>
>     java2perl6 --outdir jdbc --recurse --nest $(cat jdbc_classes.txt)
>
> Tim.
>
>   
>> Regards
>> Dave
>>
>>
>> Tim Bunce wrote:
>>     
>>> On Sat, Jul 04, 2009 at 07:09:20PM +0100, Sentra Systems wrote:
>>>   
>>>       
>>>> Hi
>>>>     
>>>>         
>>> Hi Dave.
>>>
>>>   
>>>       
>>>> Has anything happened with a Parrot JDBC implementation?
>>>> Is Parrot stable enough yet?
>>>> Has anyone mapped out the minimun subset of JDBC that would be required 
>>>> to get DBI working in Perl6?
>>>>     
>>>>         
>>> Here's the (current) plan...
>>>
>>> 1. Dust off java2perl6
>>>         http://search.cpan.org/perldoc?java2perl6
>>>         http://code.google.com/p/java2perl6/
>>>     and update it to generate valid current perl6 code.
>>>
>>> 2. Add a type aliasing mechanism (ie "for the Java URL type use a Perl
>>>     Str type") to java2perl6 so we don't have to implement loads of Java
>>>     types before we can get started.
>>>
>>> 3. Write some kind of very dumb "Hello World" skeleton JDBC driver,
>>>     as a proof of concept that uses the interfaces generated by java2perl
>>>
>>> 4. Refactor Simon Cozens's SQLite3 DBDI driver to use ('consume') the
>>>     generated JDBC interfaces.
>>>     http://dev.simon-cozens.org/6pan/browser/trunk/DBDI/DBDI/Driver/SQLite3.pm
>>>     That's not working right now, so here's a cached version:
>>>     http://google.com/search?q=cache:T8FN2WYvgm0J:dev.simon-cozens.org/6pan/browser/trunk/DBDI/DBDI/Driver/SQLite3.pm
>>>
>>> Making a move on this has been high on my list of pre-OSCON tasks
>>> but working on NYTProf has remained a higher priority (there are some
>>> great new features in the next release).
>>>
>>> If anyone wants to help out with 1 and 2, you'd be more than welcome!
>>> Send me your email address and I'll give you a commit bit.
>>>
>>> Tim.
>>>
>>>   
>>>       
>
>   


--------------080602020509010106030806
Content-Type: application/x-perl;
 name="Std.pm"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="Std.pm"

package Java::Javap::Generator::Std;
use strict; use warnings;
our $VERSION = 0.0.5;

use Template;
use Java::Javap;
use Java::Javap::TypeCast;

sub new {
    my $class   = shift;
    my $tt_args = { POST_CHOMP => 1 };

    my $self    = bless { }, $class;
    $self->tt_args_set( $tt_args );

    return $self;
}

sub tt_args_set {
    my $self = shift;
    my $args = shift;

    $self->{__TT_ARGS__} = $args;
}

sub tt_args {
    my $self = shift;
    return $self->{__TT_ARGS__};
}

sub generate {
    my $self        = shift;
    my $params      = shift;

    my $class_file  = $params->{ class_file  };
    my $ast         = $params->{ ast         };
    my $javap_flags = $params->{ javap_flags };

    my $template    = $self->_get_template( $ast );

    my $tt         = Template->new( $self->tt_args );
    my @modules    = $self->_get_modules($ast);
    my $tt_vars = {
        ast        => $ast,
        gen_time   => scalar localtime(),
        version    => $Java::Javap::VERSION,
        class_file => $class_file,
        type_caster=> Java::Javap::TypeCast->new(),
        javap_flags=> $javap_flags,
        modules    => \@modules,
    };

    my $retval;
    $tt->process( \$template, $tt_vars, \$retval ) || die $tt->error();

    return $retval;
}

sub _get_template {
    my $self = shift;
    my $ast  = shift;

    my $method = "_get_template_for_$ast->{ class_or_interface }";

    return $self->$method( $ast );
}

sub _get_modules {
    my $self = shift;
    my $ast  = shift;
    
    my %mod;
    my %ignore = ( Str => 1, Int => 1, Bool => 1, void => 1);
    
    use Data::Dumper::Simple;
    #print STDERR Dumper($ast);
    my $target;
    foreach my $element (@{$ast->{contents}}) {
        #print STDERR Dumper($element);
        next unless $element->{body_element} eq 'method';
        $target = Java::Javap::TypeCast->new()->cast($element->{returns}->{name});
        next if $ignore{$target};
        next if $target =~ /^$ast->{perl_qualified_name}\s*$/;
        $mod{$target}++;
        
        foreach my $arg (@{$element->{args}}) {
            $target = Java::Javap::TypeCast->new()->cast($arg->{name});
            next if $ignore{$target};
            $mod{$target}++;
        }       
    }
    return keys %mod;
}

sub _get_template_for_interface {
    return << 'EO_Template';
# This file was automatically generated [% gen_time +%]
# by java2perl6 [% version %] from decompiling
# [% class_file %] using command line flags:
#   [% javap_flags +%]
[% FOREACH package IN modules %]
use [% package -%];
[% END %]

role [% ast.perl_qualified_name %] {
[% FOREACH element IN ast.contents %]
[% IF element.body_element == 'method' %]
[% IF ast.methods.${ element.name } > 1 %]
    multi method [% element.name %](
[% ELSE %]
    method [% element.name %](
[% END %][% arg_counter = 0 %]
[% FOREACH arg IN element.args %][% arg_counter = arg_counter + 1 %]
        [% arg.array_text %][% type_caster.cast( arg.name ) %] [% arg.array_text.search('Array of') ? '@' : '$' %]v[% arg_counter %], 
[% END %]
    [% IF element.returns.name != 'void' %] --> [% element.returns.array_text %][% type_caster.cast( element.returns.name ) %][% END %] ) { ... }
[% END %]

[% END %]
}
EO_Template
}

sub _get_template_for_class {
    return << 'EO_Class_Template';
# This file was automatically generated [% gen_time +%]
# by java2perl6 [% version %] from decompliling
# [% class_file %] using command line flags:
#   [% javap_flags +%]

[% FOREACH package IN modules %]
use [% package -%];
[% END %]

class [% ast.perl_qualified_name %] {
[% FOREACH element IN ast.contents %]
[%  IF element.body_element == 'method' %]
[%      IF ast.methods.${ element.name } > 1 %]
    multi method [% element.name %](
[%      ELSE %]
    method [% element.name %](
[%      END %][% arg_counter = 0 %]
[%      FOREACH arg IN element.args %][% arg_counter = arg_counter + 1 %]
        [% arg.array_text %][% type_caster.cast( arg.name ) %] [% arg.array_text.search('Array of') ? '@' : '$' %]v[% arg_counter %], 
[%      END %]
    [% IF element.returns.name != 'void' %] --> [% element.returns.array_text %][% type_caster.cast( element.returns.name ) %][% END %] ) { ... }
[%  ELSE %]
[%# I spy with my little eye, I spy a constructor %]
[%  END %]

[% END %]
}
EO_Class_Template
}

1;

=head1 NAME

Java::Javap::Generator::Std - uses TT to spit out Perl 6

=head1 SYNOPSIS

    useJava::Javap::Generator; 
    my $gen = Java::Javap::Generator->get_generator( 'Std' );
    my $output = $gen->generate(
        {
            $class_file  => 'com.example.InterfaceName',
            $ast         => $tree,
            $javap_flags => $javap_flags,
        }
    );

where C<$tree> is a Java::Javap abstract syntax tree (AST).  Note that
parameters are named.

=head1 DESCRIPTION

This is a generator which uses TT to make output.  It's templates are
strings inside this module.  To change templates, subclass and override
C<_get_template_for_interface> and/or C<_get_template_for_class>.

=head1 METHODS

=over 4

=item get_generator

Call this as a class method on C<Java::Javap::Generator>.  Pass it
C<Std> to ask it for an instance of this class.

=item generate

This is the workhorse of this module.  It takes information about your
java .class file and generates Perl 6 code.

Parameters (these are named, pass them in a hashref, see below):

=over 4

=item class_file

for documentation, the name of the java .class file

=item ast

the syntax tree you got from the parser

=item javap_flags

for documentation, the flags used on the javap command line

=back

Use C<Java::Javap::Grammar> to generate the ast.

Example:

 my $parser = Java::Javap::Grammar->new();
 my $decomp = `javap com.example.SomeInterface`;
 my $tree   = $parser->comp_unit( $decomp );
 my $jenny  = Java::Javap::Generator->get_generator( 'Std' );
 my $output = $jenny->generate( 
      {
          class_file  => $class_file,
          ast         => $tree,
      }
 );

=item new

For use by C<Java::Javap::Generator>.  You could call it directly, that
would bypass the factory.

=item tt_args_set

By default, the TT objects used internally will have this TT constructor
parameter:

    { POST_CHOMP   => 1 }

Use this accessor to change the TT constructor arguments.  You may call this
at any time.  The C<new> method uses this accessor.

Since C<generate> makes a new TT object for each call, any changes you
make via this method will apply to subsequent calls.

=item tt_args

Accessr for getting the TT constructor arguments.  Mainly for internal
use.

=back

=head1 EXPORT

Nothing, it's all OO

=head2 SEE ALSO

    Java::Javap::Generator
    Java::Javap
    Java::Javap::Grammar
    java2perl6

=head1 AUTHOR

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2007, Phil Crow

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.6 or,
at your option, any later version of Perl 5 you may have available.

=cut

--------------080602020509010106030806--