App-perlimports

 view release on metacpan or  search on metacpan

lib/App/perlimports/Include.pm  view on Meta::CPAN

# If there's a different module in this document which has already imported
# a symbol of the same name in its original imports, the we should make
# sure we don't accidentally create a duplicate import here. For example,
# Path::Tiny and Test::TempDir::Tiny both export a tempdir() function.
# Without this check we'd add a "tempdir" to both modules if we find it
# being used in the document.

sub _is_already_imported {
    my $self      = shift;
    my $symbol    = shift;    # a string, not an object
    my $duplicate = 0;

    if ( $self->_document->is_constant_name($symbol) ) {
        $self->logger->debug("$symbol is defined as a constant");
        return 1;
    }

    foreach my $module (
        grep { $_ ne $self->module_name }
        keys %{ $self->_document->found_imports }
    ) {
        $self->logger->debug(
            "checking $module for previous imports of $symbol");
        my @imports;
        if ( is_plain_arrayref( $self->_document->found_imports->{$module} ) )
        {
            @imports = @{ $self->_document->found_imports->{$module} };
            $self->logger->debug(
                'Explicit imports found: ' . Dumper( [ sort @imports ] ) );
        }
        else {
            if ( my $inspector = $self->_document->inspector_for($module) ) {
                @imports = $inspector->implicit_export_names;
                $self->logger->debug( 'Implicit imports found: '
                        . Dumper( [ sort @imports ] ) );
            }
        }

        if ( any { $_ eq $symbol } @imports ) {
            $duplicate = 1;
            $self->logger->debug("$symbol already imported via $module");
            last;
        }
    }

    return $duplicate;
}

sub _sort_symbols {
    my @list = @_;

    ## no critic (BuiltinFunctions::RequireSimpleSortBlock)
    my @sorted = sort {
        my $A = _transform_before_cmp($a);
        my $B = _transform_before_cmp($b);
        "\L$A" cmp "\L$B";
    } @list;
    return @sorted;
}

# This looks a little weird, but basically we want to maintain a stable sort
# order with lists that look like (foo, $foo, @foo, %foo). We use "-" to begin
# the suffix because it comes earliest in a sorted list of letters and digits.
sub _transform_before_cmp {
    my $thing = shift;
    if ( $thing =~ m{\A[\$]} ) {
        $thing = substr( $thing, 1 ) . '-0';
    }
    elsif ( $thing =~ m{\A[@]} ) {
        $thing = substr( $thing, 1 ) . '-1';
    }
    elsif ( $thing =~ m{\A[%]} ) {
        $thing = substr( $thing, 1 ) . '-2';
    }
    return $thing;
}

1;

# ABSTRACT: Encapsulate one use statement in a document

__END__

=pod

=encoding UTF-8

=head1 NAME

App::perlimports::Include - Encapsulate one use statement in a document

=head1 VERSION

version 0.000060

=head1 METHODS

=head2 formatted_ppi_statement

Returns an L<PPI::Statement::Include> object. This can be stringified into an
import statement or used to replace an existing L<PPI::Statement::Include>.

=head1 AUTHOR

Olaf Alders <olaf@wundercounter.com>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2020 by Olaf Alders.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut



( run in 2.475 seconds using v1.01-cache-2.11-cpan-5a3173703d6 )