/usr/local/CPAN/CORBA-JAVA/CORBA/JAVA/NameVisitor.pm
#
# Interface Definition Language (OMG IDL CORBA v3.0)
#
# IDL to Java Language Mapping Specification, Version 1.2 August 2002
#
package CORBA::JAVA::NameVisitor;
use strict;
use warnings;
our $VERSION = '2.60';
# builds $node->{java_name} and $node->{java_package}
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $self = {};
bless $self, $class;
my ($parser, $prefix, $translate) = @_;
$self->{key} = 'java_name';
$self->{srcname} = $parser->YYData->{srcname};
$self->{symbtab} = $parser->YYData->{symbtab};
$self->{num_key} = 'num_java_name';
$self->{pkg_prefix} = {};
if (defined $prefix) {
foreach (split /;/, $prefix) {
my @kv = split /=/, $_;
if (scalar(@kv) == 2) {
$self->{pkg_prefix}->{$kv[0]} = $kv[1];
}
}
}
$self->{pkg_translate} = {};
if (defined $translate) {
foreach (split /;/, $translate) {
my @kv = split /=/, $_;
if (scalar(@kv) == 2) {
next if ($kv[0] eq 'org' or $kv[0] eq 'org.omg' or $kv[0] =~ /^org\.omg\./);
$self->{pkg_translate}->{$kv[0]} = $kv[1];
}
}
}
$self->{java_keywords} = {
# The keywords in the Java Language :
# (from the Java Language Specification 1.0 First Edition, Section 3.9)
'abstract' => 1,
'boolean' => 1,
'break' => 1,
'byte' => 1,
'case' => 1,
'catch' => 1,
'char' => 1,
'class' => 1,
'const' => 1,
'continue' => 1,
'default' => 1,
'do' => 1,
'double' => 1,
'else' => 1,
'extends' => 1,
'final' => 1,
'finally' => 1,
'float' => 1,
'for' => 1,
'goto' => 1,
'if' => 1,
'implements' => 1,
'import' => 1,
'instanceof' => 1,
'int' => 1,
'interface' => 1,
'long' => 1,
'native' => 1,
'new' => 1,
'package' => 1,
'private' => 1,
'protected' => 1,
'public' => 1,
'return' => 1,
'short' => 1,
'static' => 1,
'super' => 1,
'switch' => 1,
'synchronized' => 1,
'this' => 1,
'throw' => 1,
'throws' => 1,
'transcient' => 1,
'try' => 1,
'void' => 1,
'volatile' => 1,
'while' => 1,
# additionnal Java constant
'true' => 1,
'false' => 1,
'null' => 1,
# methods on java.lang.Object
# (from the Java Language Specification 1.0 First Edition, Section 20.1)
'clone' => 1,
'equals' => 1,
'finalize' => 1,
'getClass' => 1,
'hashCode' => 1,
'notify' => 1,
'notifyAll' => 1,
'toString' => 1,
'wait' => 1
};
return $self;
}
sub _get_defn {
my $self = shift;
my ($defn) = @_;
if (ref $defn) {
return $defn;
}
else {
return $self->{symbtab}->Lookup($defn);
}
}
sub _get_name {
my $self = shift;
my ($node) = @_;
my $name = $node->{idf};
$name =~ s/^_get_//;
$name =~ s/^_set_//;
return '_' . $name if (exists $self->{java_keywords}->{$name});
return '_' . $name if ($name =~ /Helper$/);
return '_' . $name if ($name =~ /Holder$/);
return '_' . $name if ($name =~ /Operations$/);
return '_' . $name if ($name =~ /POA$/);
return '_' . $name if ($name =~ /POATie$/);
return '_' . $name if ($name =~ /Package$/);
return $name;
}
sub _get_pkg {
my $self = shift;
my ($node) = @_;
my $pkg = $node->{full};
$pkg =~ s/::[0-9A-Z_a-z]+$//;
return q{} unless ($pkg);
my $defn = $self->{symbtab}->Lookup($pkg);
my $package = $defn->{java_Name};
if ( ( $node->isa('StructType')
or $node->isa('UnionType')
or $node->isa('EnumType')
or $node->isa('Exception')
or $node->isa('TypeDeclarator') )
and ( $defn->isa('BaseInterface')
or $defn->isa('UnionType')
or $defn->isa('StructType') ) ) {
$package .= 'Package';
}
foreach (keys %{$self->{pkg_prefix}}) {
if ($package =~ /^$_/) {
$package = $self->{pkg_prefix}->{$_} . '.' . $package;
last;
}
}
foreach (keys %{$self->{pkg_translate}}) {
if ($package =~ s/^$_/$self->{pkg_translate}->{$_}/) {
last;
}
}
return $package;
}
sub _get_Name {
my $self = shift;
my ($node, $java_package) = @_;
$java_package = $node->{java_package} unless (defined $java_package);
if ($java_package) {
return $java_package . '.' . $node->{java_name};
}
else {
return $node->{java_name};
}
}
#
# 3.5 OMG IDL Specification
#
sub visitSpecification {
my $self = shift;
my ($node) = @_;
if (exists $node->{list_import}) {
foreach (@{$node->{list_import}}) {
$self->_get_defn($_)->visit($self);
}
}
foreach (@{$node->{list_decl}}) {
$self->_get_defn($_)->visit($self);
}
}
#
# 3.6 Import Declaration
#
sub visitImport {
my $self = shift;
my ($node) = @_;
foreach (@{$node->{list_decl}}) {
$self->_get_defn($_)->visit($self);
}
}
#
# 3.7 Module Declaration
#
sub visitModules {
my $self = shift;
my ($node) = @_;
unless (exists $node->{$self->{num_key}}) {
$node->{$self->{num_key}} = 0;
$node->{java_package} = $self->_get_pkg($node);
$node->{java_name} = $self->_get_name($node);
$node->{java_Name} = $self->_get_Name($node);
}
my $module = ${$node->{list_decl}}[$node->{$self->{num_key}}];
$module->visit($self);
$node->{$self->{num_key}} ++;
}
sub visitModule {
my $self = shift;
my ($node) = @_;
foreach (@{$node->{list_decl}}) {
$self->_get_defn($_)->visit($self);
}
}
#
# 3.8 Interface Declaration
#
sub visitBaseInterface {
my $self = shift;
my ($node) = @_;
return if (exists $node->{java_package});
$node->{java_package} = $self->_get_pkg($node);
$node->{java_name} = $self->_get_name($node);
$node->{java_Name} = $self->_get_Name($node);
foreach (@{$node->{list_decl}}) {
$self->_get_defn($_)->visit($self);
}
}
sub visitForwardBaseInterface {
my $self = shift;
my ($node) = @_;
return if (exists $node->{java_package});
$node->{java_package} = $self->_get_pkg($node);
$node->{java_name} = $self->_get_name($node);
$node->{java_Name} = $self->_get_Name($node);
}
#
# 3.9 Value Declaration
#
sub visitStateMembers {
my $self = shift;
my ($node) = @_;
foreach (@{$node->{list_decl}}) {
$self->_get_defn($_)->visit($self);
}
}
sub visitStateMember {
shift->visitMember(@_);
}
sub visitInitializer {
shift->visitOperation(@_);
}
sub visitBoxedValue {
my $self = shift;
my ($node) = @_;
return if (exists $node->{java_package});
my $type = $self->_get_defn($node->{type});
if ( $type->isa('FloatingPtType')
or $type->isa('IntegerType')
or $type->isa('CharType')
or $type->isa('WideCharType')
or $type->isa('BooleanType')
or $type->isa('OctetType') ) {
$type->visit($self);
$node->{java_package} = $self->_get_pkg($node);
$node->{java_name} = $self->_get_name($node);
$node->{java_Name} = $self->_get_Name($node);
$node->{java_primitive} = 1;
}
else {
if ($type->isa('SequenceType')) {
$type->visit($self);
$type->{repos_id} = $node->{repos_id};
$type = $self->_get_defn($type->{type});
$node->{java_name} = $type->{java_name} . '[]';
while ($type->isa('SequenceType')) {
$node->{java_name} .= '[]';
$type = $self->_get_defn($type->{type});
}
$node->{java_Name} = $self->_get_Name($node, $type->{java_package});
$node->{java_package} = $self->_get_pkg($node);
}
else {
$node->{java_package} = $self->_get_pkg($node);
$node->{java_name} = $self->_get_name($node);
$node->{java_Name} = $self->_get_Name($node);
$type->visit($self);
}
}
}
#
# 3.10 Constant Declaration
#
sub visitConstant {
my $self = shift;
my ($node) = @_;
$node->{java_package} = $self->_get_pkg($node);
$node->{java_name} = $self->_get_name($node);
my $type = $self->_get_defn($node->{type});
my $defn;
my $pkg = $node->{full};
$pkg =~ s/::[0-9A-Z_a-z]+$//;
$defn = $self->{symbtab}->Lookup($pkg) if ($pkg);
if ( defined $defn and $defn->isa('BaseInterface') ) {
$node->{java_Name} = $self->_get_Name($node);
}
else {
$node->{java_Name} = $self->_get_Name($node) . '.value';
}
$type->visit($self);
}
sub visitExpression {
# empty
}
#
# 3.11 Type Declaration
#
sub visitTypeDeclarators {
my $self = shift;
my ($node) = @_;
foreach (@{$node->{list_decl}}) {
$self->_get_defn($_)->visit($self);
}
}
sub visitTypeDeclarator {
my $self = shift;
my ($node) = @_;
return if (exists $node->{java_package});
my $type = $self->_get_defn($node->{type});
$type->visit($self);
if ( $type->isa('BasicType')
or $type->isa('StringType')
or $type->isa('WideStringType')
or $type->isa('FixedPtType') ) {
$node->{java_primitive} = 1;
}
else {
$node->{java_primitive} = 1 if (exists $type->{java_primitive});
}
if (exists $node->{array_size}) {
$node->{java_package} = $self->_get_pkg($node);
$node->{java_name} = $self->_get_name($node);
$node->{java_Name} = $self->_get_Name($node);
}
else {
if ($type->isa('SequenceType')) {
$type->{repos_id} = $node->{repos_id};
$type = $self->_get_defn($type->{type});
$node->{java_name} = $type->{java_name} . '[]';
while ($type->isa('SequenceType')) {
$node->{java_name} .= '[]';
$type = $self->_get_defn($type->{type});
}
$node->{java_Name} = $self->_get_Name($node, $type->{java_package});
$node->{java_package} = $self->_get_pkg($node);
}
else {
if ( $type->isa('BasicType')
or $type->isa('StringType')
or $type->isa('WideStringType')
or $type->isa('FixedPtType') ) {
$node->{java_name} = $type->{java_name};
$node->{java_Name} = $type->{java_Name};
$node->{java_package} = $self->_get_pkg($node);
}
else {
$node->{java_package} = $self->_get_pkg($node);
$node->{java_name} = $self->_get_name($node);
$node->{java_Name} = $self->_get_Name($node);
}
}
}
}
sub visitNativeType {
my $self = shift;
my ($node) = @_;
$node->{java_package} = $self->_get_pkg($node);
$node->{java_name} = $self->_get_name($node);
$node->{java_Name} = $self->_get_Name($node);
}
#
# 3.11.1 Basic Types
#
# See 1.4 Mapping for Basic Data Types
#
sub visitIntegerType {
my $self = shift;
my ($node) = @_;
$node->{java_package} = q{};
if ($node->{value} eq 'short') {
$node->{java_name} = 'short';
$node->{java_Name} = 'short';
}
elsif ($node->{value} eq 'unsigned short') {
$node->{java_name} = 'short';
$node->{java_Name} = 'short';
}
elsif ($node->{value} eq 'long') {
$node->{java_name} = 'int';
$node->{java_Name} = 'int';
}
elsif ($node->{value} eq 'unsigned long') {
$node->{java_name} = 'int';
$node->{java_Name} = 'int';
}
elsif ($node->{value} eq 'long long') {
$node->{java_name} = 'long';
$node->{java_Name} = 'long';
}
elsif ($node->{value} eq 'unsigned long long') {
$node->{java_name} = 'long';
$node->{java_Name} = 'long';
}
else {
warn __PACKAGE__,"::visitIntegerType $node->{value}.\n";
}
}
sub visitFloatingPtType {
my $self = shift;
my ($node) = @_;
$node->{java_package} = q{};
if ($node->{value} eq 'float') {
$node->{java_name} = 'float';
$node->{java_Name} = 'float';
}
elsif ($node->{value} eq 'double') {
$node->{java_name} = 'double';
$node->{java_Name} = 'double';
}
elsif ($node->{value} eq 'long double') {
warn __PACKAGE__," 'long double' not available at this time for Java.\n";
$node->{java_name} = 'double';
$node->{java_Name} = 'double';
}
else {
warn __PACKAGE__,"::visitFloatingPtType $node->{value}.\n";
}
}
sub visitCharType {
my $self = shift;
my ($node) = @_;
$node->{java_package} = q{};
$node->{java_name} = 'char';
$node->{java_Name} = 'char';
}
sub visitWideCharType {
my $self = shift;
my ($node) = @_;
$node->{java_package} = q{};
$node->{java_name} = 'char';
$node->{java_Name} = 'char';
}
sub visitBooleanType {
my $self = shift;
my ($node) = @_;
$node->{java_package} = q{};
$node->{java_name} = 'boolean';
$node->{java_Name} = 'boolean';
}
sub visitOctetType {
my $self = shift;
my ($node) = @_;
$node->{java_package} = q{};
$node->{java_name} = 'byte';
$node->{java_Name} = 'byte';
}
sub visitAnyType {
my $self = shift;
my ($node) = @_;
$node->{java_package} = 'org.omg.CORBA';
$node->{java_name} = 'Any';
$node->{java_Name} = 'org.omg.CORBA.Any';
}
sub visitObjectType {
my $self = shift;
my ($node) = @_;
$node->{java_package} = 'org.omg.CORBA';
$node->{java_name} = 'Object';
$node->{java_Name} = 'org.omg.CORBA.Object';
}
sub visitValueBaseType {
my $self = shift;
my ($node) = @_;
$node->{java_package} = 'java.io';
$node->{java_name} = 'Serializable';
$node->{java_Name} = 'java.io.Serializable';
}
#
# 3.11.2 Constructed Types
#
# 3.11.2.1 Structures
#
sub visitStructType {
my $self = shift;
my ($node) = @_;
return if (exists $node->{java_package});
$node->{java_package} = $self->_get_pkg($node);
$node->{java_name} = $self->_get_name($node);
$node->{java_Name} = $self->_get_Name($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});
$node->{java_name} = $self->_get_name($node);
while ($type->isa('TypeDeclarator') and !exists($type->{array_size})) {
$type = $self->_get_defn($type->{type});
}
if ($type->isa('SequenceType') or exists ($type->{array_size})) {
while ($type->isa('SequenceType')) {
$type = $self->_get_defn($type->{type});
while ($type->isa('TypeDeclarator')) {
$type = $self->_get_defn($type->{type});
}
}
$type->visit($self);
}
else {
$type->visit($self);
}
}
# 3.11.2.2 Discriminated Unions
#
sub visitUnionType {
my $self = shift;
my ($node) = @_;
return if (exists $node->{java_package});
$node->{java_package} = $self->_get_pkg($node);
$node->{java_name} = $self->_get_name($node);
$node->{java_Name} = $self->_get_Name($node);
$self->_get_defn($node->{type})->visit($self);
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'
}
sub visitForwardStructType {
# empty
}
sub visitForwardUnionType {
# empty
}
# 3.11.2.4 Enumerations
#
sub visitEnumType {
my $self = shift;
my ($node) = @_;
$node->{java_package} = $self->_get_pkg($node);
$node->{java_name} = $self->_get_name($node);
$node->{java_Name} = $self->_get_Name($node);
foreach (@{$node->{list_expr}}) {
$_->visit($self); # enum
}
}
sub visitEnum {
my $self = shift;
my ($node) = @_;
my $type = $self->_get_defn($node->{type});
$node->{java_package} = $type->{java_Name};
$node->{java_name} = $self->_get_name($node);
$node->{java_Name} = $self->_get_Name($node);
}
#
# 3.11.3 Template Types
#
# See 1.11 Mapping for Sequence Types
#
sub visitSequenceType {
my $self = shift;
my ($node, $name) = @_;
return if (exists $node->{java_package});
$node->{java_package} = $self->_get_pkg($node);
my $type = $self->_get_defn($node->{type});
$type->visit($self);
unless (defined $name) {
$name = '_seq_' . $type->{java_name};
if (exists $node->{max}) {
$name .= '_' . $node->{max}->{value};
$name =~ s/\+//g;
}
}
$node->{java_name} = $name;
$node->{java_Name} = $self->_get_Name($node);
}
#
# See 1.12 Mapping for Strings
#
sub visitStringType {
my $self = shift;
my ($node) = @_;
$node->{java_package} = 'java.lang';
$node->{java_name} = 'String';
$node->{java_Name} = 'java.lang.String';
}
#
# See 1.13 Mapping for Wide Strings
#
sub visitWideStringType {
shift->visitStringType(@_);
}
#
# See 1.14 Mapping for Fixed
#
sub visitFixedPtType {
my $self = shift;
my ($node) = @_;
$node->{java_package} = 'java.math';
$node->{java_name} = 'BigDecimal';
$node->{java_Name} = 'java.math.BigDecimal';
}
sub visitFixedPtConstType {
shift->visitFixedPtType(@_);
}
#
# 3.12 Exception Declaration
#
sub visitException {
shift->visitStructType(@_);
}
#
# 3.13 Operation Declaration
#
# See 1.4 Inheritance and Operation Names
#
sub visitOperation {
my $self = shift;
my ($node) = @_;
$node->{java_package} = $self->_get_pkg($node);
$node->{java_name} = $self->_get_name($node);
$node->{java_Name} = $self->_get_Name($node);
$self->_get_defn($node->{type})->visit($self)
if (exists $node->{type}); # initializer or factory or finder
foreach (@{$node->{list_param}}) {
$_->visit($self); # parameter
}
}
sub visitParameter {
my $self = shift;
my($node) = @_;
$node->{java_name} = $self->_get_name($node);
$self->_get_defn($node->{type})->visit($self);
}
sub visitVoidType {
my $self = shift;
my ($node) = @_;
$node->{java_Name} = 'void';
}
#
# 3.14 Attribute Declaration
#
sub visitAttributes {
my $self = shift;
my ($node) = @_;
foreach (@{$node->{list_decl}}) {
$self->_get_defn($_)->visit($self);
}
}
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.16 Event Declaration
#
#
# 3.17 Component Declaration
#
sub visitProvides {
my $self = shift;
my ($node) = @_;
$node->{java_package} = $self->_get_pkg($node);
$node->{java_name} = $self->_get_name($node);
$node->{java_Name} = $self->_get_Name($node);
}
sub visitUses {
my $self = shift;
my ($node) = @_;
$node->{java_package} = $self->_get_pkg($node);
$node->{java_name} = $self->_get_name($node);
$node->{java_Name} = $self->_get_Name($node);
}
sub visitPublishes {
my $self = shift;
my ($node) = @_;
$node->{java_package} = $self->_get_pkg($node);
$node->{java_name} = $self->_get_name($node);
$node->{java_Name} = $self->_get_Name($node);
}
sub visitEmits {
my $self = shift;
my ($node) = @_;
$node->{java_package} = $self->_get_pkg($node);
$node->{java_name} = $self->_get_name($node);
$node->{java_Name} = $self->_get_Name($node);
}
sub visitConsumes {
my $self = shift;
my ($node) = @_;
$node->{java_package} = $self->_get_pkg($node);
$node->{java_name} = $self->_get_name($node);
$node->{java_Name} = $self->_get_Name($node);
}
#
# 3.18 Home Declaration
#
sub visitFactory {
shift->visitOperation(@_);
}
sub visitFinder {
shift->visitOperation(@_);
}
1;