/usr/local/CPAN/CORBA-Python/CORBA/Python/ImportVisitor.pm
#
# Interface Definition Language (OMG IDL CORBA v3.0)
#
# Python Language Mapping Specification, Version 1.2 November 2002
#
package CORBA::Python::ImportVisitor;
use strict;
use warnings;
our $VERSION = '2.64';
use File::Basename;
# builds $node->{py_import}
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $self = {};
bless $self, $class;
my ($parser, $cpy_ext) = @_;
$self->{symbtab} = $parser->YYData->{symbtab};
$self->{module} = undef;
$self->{cpy_ext} = $cpy_ext;
my $basename = basename($parser->YYData->{srcname}, '.idl');
$basename =~ s/\./_/g;
$self->{root_module} = 'c_' . $basename;
return $self;
}
sub _get_defn {
my $self = shift;
my $defn = shift;
if (ref $defn) {
return $defn;
}
else {
return $self->{symbtab}->Lookup($defn);
}
}
sub _import {
my $self = shift;
my ($node, $flag_c) = @_;
my $full = $node->{full};
while (!$node->isa('Modules')) {
$full =~ s/::[0-9A-Z_a-z]+$//;
last unless ($full);
$node = $self->{symbtab}->Lookup($full);
}
if ($flag_c) {
if ($full) {
my @name = split /::/, $full;
$name[-1] = 'c' . $name[-1];
$full = join '::', @name;
}
else {
$full = $self->{root_module};
}
$self->{module}->{py_import}->{$full} = 1;
return;
}
unless ($full eq $self->{module}->{full}) {
$self->{module}->{py_import}->{$full} = 1;
if ($full =~ /^$self->{module}->{full}/) {
warn "possible circular import ($full in $self->{module}->{full}).\n";
}
}
}
sub _import_type {
my $self = shift;
my ($type) = @_;
if ( $type->isa('StructType')
or $type->isa('UnionType')
or $type->isa('EnumType')
or $type->isa('TypeDeclarator')
or $type->isa('BaseInterface') ) {
$self->_import($type);
}
}
#
# 3.5 OMG IDL Specification
#
sub visitSpecification {
my $self = shift;
my ($node) = @_;
$node->{py_import} = {};
$self->{module} = $node;
foreach (@{$node->{list_export}}) {
$self->{symbtab}->Lookup($_)->visit($self);
}
}
#
# 3.6 Import Declaration
#
sub visitImport {
my $self = shift;
my ($node) = @_;
foreach (@{$node->{list_decl}}) {
$self->{symbtab}->Lookup($_)->visit($self);
}
}
#
# 3.7 Module Declaration
#
sub visitModules {
my $self = shift;
my ($node) = @_;
$node->{py_import} = {};
my $save_module = $self->{module};
$self->{module} = $node;
foreach (@{$node->{list_export}}) {
$self->{symbtab}->Lookup($_)->visit($self);
}
$self->{module} = $save_module;
}
#
# 3.8 Interface Declaration
#
sub visitBaseInterface {
my $self = shift;
my ($node) = @_;
if ($self->{cpy_ext}) {
$self->_import($node, 1);
}
foreach ($node->getInheritance()) {
my $base = $self->_get_defn($_);
$self->_import($base);
}
foreach (@{$node->{list_export}}) {
$self->{symbtab}->Lookup($_)->visit($self);
}
}
sub visitForwardBaseInterface {
# empty
}
#
# 3.9 Value Declaration
#
sub visitBoxedValue {
my $self = shift;
my ($node) = @_;
my $type = $self->_get_defn($node->{type});
$self->_import_type($type);
}
sub visitStateMember {
my $self = shift;
my ($node) = @_;
my $type = $self->_get_defn($node->{type});
$self->_import_type($type);
if (exists $node->{array_size}) {
foreach (@{$node->{array_size}}) {
$_->visit($self, $node); # expression
}
}
}
sub visitInitializer {
my $self = shift;
my ($node) = @_;
foreach (@{$node->{list_param}}) {
$_->visit($self); # parameter
}
}
#
# 3.10 Constant Declaration
#
sub visitConstant {
my $self = shift;
my ($node) = @_;
$node->{value}->visit($self); # expression
}
sub visitExpression {
my $self = shift;
my ($node) = @_;
foreach my $elt (@{$node->{list_expr}}) {
unless (ref $elt) {
$elt = $self->{symbtab}->Lookup($elt);
}
if ($elt->isa('Constant')) {
$self->_import($elt);
}
}
}
#
# 3.11 Type Declaration
#
sub visitTypeDeclarator {
my $self = shift;
my ($node) = @_;
my $type = $self->_get_defn($node->{type});
$self->_import_type($type);
if (exists $node->{array_size}) {
foreach (@{$node->{array_size}}) {
$_->visit($self, $node); # expression
}
}
}
sub visitNativeType {
# empty
}
#
# 3.11.1 Basic Types
#
sub visitBasicType {
# empty
}
#
# 3.11.2 Constructed Types
#
# 3.11.2.1 Structures
#
sub visitStructType {
my $self = shift;
my ($node) = @_;
foreach (@{$node->{list_member}}) {
$self->_get_defn($_)->visit($self); # member
}
}
sub visitMember {
my $self = shift;
my ($node) = @_;
my $type = $self->_get_defn($node->{type});
$self->_import_type($type);
if (exists $node->{array_size}) {
foreach (@{$node->{array_size}}) {
$_->visit($self, $type); # expression
}
}
}
# 3.11.2.2 Discriminated Unions
#
sub visitUnionType {
my $self = shift;
my ($node) = @_;
my $type = $self->_get_defn($node->{type});
$self->_import_type($type);
foreach (@{$node->{list_expr}}) {
$_->visit($self); # case
}
}
sub visitCase {
my $self = shift;
my ($node) = @_;
foreach (@{$node->{list_label}}) {
$_->visit($self); # default or expression
}
$node->{element}->visit($self);
}
sub visitDefault {
# empty
}
sub visitElement {
my $self = shift;
my ($node) = @_;
$self->_get_defn($node->{value})->visit($self); # member
}
# 3.11.2.4 Enumerations
#
sub visitEnumType {
# empty
}
#
# 3.11.3 Template Types
#
sub visitSequenceType {
# empty
}
sub visitStringType {
# empty
}
sub visitWideStringType {
# empty
}
sub visitFixedPtType {
# empty
}
sub visitFixedPtConstType {
# empty
}
#
# 3.12 Exception Declaration
#
sub visitException {
my $self = shift;
my ($node) = @_;
if (exists $node->{list_member}) {
foreach (@{$node->{list_member}}) {
$self->_get_defn($_)->visit($self); # member
}
}
}
#
# 3.13 Operation Declaration
#
sub visitOperation {
my $self = shift;
my ($node) = @_;
my $type = $self->_get_defn($node->{type});
$self->_import_type($type);
foreach (@{$node->{list_param}}) {
$_->visit($self); # parameter
}
}
sub visitParameter {
my $self = shift;
my($node) = @_;
my $type = $self->_get_defn($node->{type});
$self->_import_type($type);
}
sub visitVoidType {
# empty
}
#
# 3.14 Attribute Declaration
#
sub visitAttribute {
my $self = shift;
my ($node) = @_;
$node->{_get}->visit($self);
$node->{_set}->visit($self) if (exists $node->{_set});
}
#
# 3.15 Repository Identity Related Declarations
#
sub visitTypeId {
# empty
}
sub visitTypePrefix {
# empty
}
#
# 3.17 Component Declaration
#
sub visitProvides {
# empty
}
sub visitUses {
# empty
}
sub visitPublishes {
# empty
}
sub visitEmits {
# empty
}
sub visitConsumes {
# empty
}
#
# 3.18 Home Declaration
#
sub visitFactory {
my $self = shift;
my ($node) = @_;
foreach (@{$node->{list_param}}) {
$_->visit($self); # parameter
}
}
sub visitFinder {
my $self = shift;
my ($node) = @_;
foreach (@{$node->{list_param}}) {
$_->visit($self); # parameter
}
}
1;