--- /dev/null
+name = MooseX-Compiler
+author = Dave Rolsky <autarch@urth.org>
+license = Artistic_2_0
+copyright_holder = Dave Rolsky
+
+version = 0.01
+
+[NextRelease]
+format = %-8v %{yyyy-MM-dd}d
+
+[@Basic]
+
+[InstallGuide]
+[MetaJSON]
+
+[MetaResources]
+bugtracker.web = http://rt.cpan.org/NoAuth/Bugs.html?Dist=MooseX-Compiler
+bugtracker.mailto = bug-moosex-compiler@rt.cpan.org
+repository.url = git://git.urth.org/MooseX-Compiler.git
+repository.web = http://git.urth.org/MooseX-Compiler.git
+repository.type = git
+
+[SurgicalPodWeaver]
+
+[PkgVersion]
+
+[EOLTests]
+[NoTabsTests]
+[PodSyntaxTests]
+[Test::CPAN::Changes]
+[Test::Pod::LinkCheck]
+[Test::Pod::No404s]
+
+[AutoPrereqs]
+
+[CheckPrereqsIndexed]
+
+[@Git]
--- /dev/null
+package MooseX::Compiler;
+
+use strict;
+use warnings;
+
+use Module::Runtime qw( module_notional_filename );
+use PPI::Document;
+use Scalar::Util qw( blessed );
+
+use Moose;
+use Moose::Util::TypeConstraints;
+
+my $moose_class = subtype, as 'ClassName', where {
+ $_[0]->can('meta')
+ && blessed $_[0]->meta()
+ && $_[0]->meta()->isa('Moose::Meta::Class');
+};
+
+has class => (
+ is => 'ro',
+ isa => $moose_class,
+ required => 1,
+);
+
+has _class_meta => (
+ is => 'ro',
+ isa => 'Moose::Meta::Class',
+ init_arg => undef,
+ lazy => 1,
+ default => sub { $_[0]->class()->meta() },
+);
+
+sub compile_class {
+ my $self = shift;
+
+ my $code
+ = join q{},
+ $self->_adjusted_class_content(),
+ $self->_adjusted_role_content(),
+ $self->_inlined_attribute_code();
+
+ return $code;
+}
+
+sub _adjusted_class_content {
+ my $self = shift;
+
+ my $pm_file = module_notional_filename( $self->class() );
+ my $path_to_class = $INC{$pm_file}
+ or die "Cannot find $pm_file in %INC!";
+
+ my $doc = PPI::Document->new( $path_to_class->stringify() )
+ or die PPI::Document->errstr();
+
+ my $use_nodes = $doc->find(
+ sub {
+ my $node = $_[1];
+ return undef
+ if $node->isa('PPI::Statement')
+ && !$node->isa('PPI::Statement::Include');
+ return undef if $node->isa('PPI::Structure');
+ return 1
+ if $node->isa('PPI::Statement::Include')
+ && $node->module() =~ /^Moose/;
+ return 0;
+ }
+ );
+
+ for my $node ( @{$use_nodes} ) {
+ my $replacement_code .=
+ defined $node->module_version()
+ ? join(
+ q{ },
+ 'use', $node->module(), $node->module_version(), '()', ';',
+ )
+ : '# ' . $node->content();
+
+ $node->insert_before( $_->clone() )
+ for PPI::Document->new( \$replacement_code )->children();
+ $node->remove();
+ }
+
+ return $doc->content();
+}
+
+sub _adjusted_role_content {
+ return q{};
+}
+
+sub _inlined_attribute_code {
+ return q{};
+}
+
+__PACKAGE__->meta()->make_immutable();
+
+1;
--- /dev/null
+package Test::MooseX::Compiler;
+
+use strict;
+use warnings;
+use autodie;
+
+use Exporter qw( import );
+use File::Temp qw( tempdir );
+use Module::Runtime qw( module_notional_filename );
+use Path::Class qw( dir );
+
+our @EXPORT_OK = qw(
+ save_class
+);
+
+my $Dir = dir( tempdir( CLEANUP => 1 ) );
+
+sub save_class {
+ my $class = shift;
+ my $code = shift;
+
+ {
+ local $@;
+ eval $code;
+ die $@ if $@;
+ }
+
+ my $pm_file = module_notional_filename($class);
+ my $path = $Dir->file($pm_file);
+ $path->dir()->mkpath( 0, 0755 );
+
+ open my $fh, '>', $path;
+ print {$fh} $code;
+ close $fh;
+
+ $INC{$pm_file} = $path;
+
+ return $pm_file;
+}
+
+1;
--- /dev/null
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+use Test::MooseX::Compiler qw( save_class );
+use Test::More 0.88;
+
+use MooseX::Compiler;
+
+{
+ my $code = <<'EOF';
+package Test::Class1;
+
+use strict;
+use warnings;
+
+use Moose;
+
+sub foo { 42 }
+
+1;
+EOF
+
+ save_class( 'Test::Class1', $code );
+
+ my $compiler = MooseX::Compiler->new(
+ class => 'Test::Class1',
+ );
+
+ my $compiled = $compiler->compile_class();
+ like(
+ $compiled,
+ qr/^\#\s*use Moose;\n/m,
+ 'use Moose declaration is commented out in compiled code'
+ );
+
+ unlike(
+ $compiled,
+ qr/^use Moose;\n/m,
+ 'original use Moose declaration is removed from compiled code'
+ );
+}
+
+{
+ my $code = <<'EOF';
+package Test::Class2;
+
+use strict;
+use warnings;
+
+use Moose 0.1;
+
+sub foo { 42 }
+
+1;
+EOF
+
+ save_class( 'Test::Class1', $code );
+
+ my $compiler = MooseX::Compiler->new(
+ class => 'Test::Class1',
+ );
+
+ my $compiled = $compiler->compile_class();
+ unlike(
+ $compiled,
+ qr/^\#\s*use Moose;\n/m,
+ 'use Moose declaration is not commented out in compiled code'
+ );
+
+ like(
+ $compiled,
+ qr/^use\s+Moose\s+0\.1\s+\(\)\s*;\n/m,
+ 'original use Moose declaration is preserved, but () is added to prevent importing'
+ );
+}
+
+done_testing();