123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- package Logos::Generator::Base::Property;
- use strict;
- use Logos::Util;
- sub key {
- my $self = shift;
- my $property = shift;
- my $build = "_logos_property_key\$" . $property->group . "\$" . $property->class . "\$" . $property->name;
- return $build;
- }
- sub getter {
- my $self = shift;
- my $property = shift;
- my $name = shift;
- my $key = shift;
- my $type = $property->type;
- $type =~ s/\s+$//;
- if(!$name){
- # Use property name if no getter specified
- $name = $property->name;
- }
- # Build function start
- my $build = "static " . $type . " _logos_method\$" . $property->group . "\$" . $property->class . "\$" . $name . "\$" . "(" . $property->class . "* self, SEL _cmd){";
- # Build function body
- $build .= " return ";
- if ($type =~ /^(BOOL|(unsigned )?char|double|float|CGFloat|(unsigned )?int|NSInteger|unsigned|NSUInteger|(unsigned )?long (long)?|(unsigned )?short|NSRange|CGPoint|CGVector|CGSize|CGRect|CGAffineTransform|UIEdgeInsets|UIOffset|CATransform3D|CMTime(Range|Mapping)?|MKCoordinate(Span)?|SCNVector[34]|SCNMatrix4)$/){
- $build .= "[";
- }
- $build .= "objc_getAssociatedObject(self, &" . $key . ")";
- if ($type eq "BOOL"){
- $build .= " boolValue]";
- } elsif ($type eq "char"){
- $build .= " charValue]";
- } elsif ($type eq "unsigned char"){
- $build .= " unsignedCharValue]";
- } elsif ($type eq "double"){
- $build .= " doubleValue]";
- } elsif ($type =~ /^(float|CGFloat)$/){
- $build .= " floatValue]";
- } elsif ($type eq "int"){
- $build .= " intValue]";
- } elsif ($type eq "NSInteger"){
- $build .= " integerValue]";
- } elsif ($type =~ /^unsigned( int)?$/){
- $build .= " unsignedIntValue]";
- } elsif ($type eq "NSUInteger"){
- $build .= " unsignedIntegerValue]";
- } elsif ($type eq "long"){
- $build .= " longValue]";
- } elsif ($type eq "unsigned long"){
- $build .= " unsignedLongValue]";
- } elsif ($type eq "long long"){
- $build .= " longLongValue]";
- } elsif ($type eq "unsigned long long"){
- $build .= " unsignedLongLongValue]";
- } elsif ($type eq "short"){
- $build .= " shortValue]";
- } elsif ($type eq "unsigned short"){
- $build .= " unsignedShortValue]";
- } elsif ($type =~ /^(NSRange|CGPoint|CGVector|CGSize|CGRect|CGAffineTransform|UIEdgeInsets|UIOffset|CATransform3D|CMTime(Range|Mapping)?|MKCoordinate(Span)?|SCNVector[34]|SCNMatrix4)$/){
- $build .= " " . $type . "Value]";
- }
- $build .= "; }";
- return $build;
- }
- sub setter {
- my $self = shift;
- my $property = shift;
- my $name = shift;
- my $policy = shift;
- my $key = shift;
- my $type = $property->type;
- $type =~ s/\s+$//;
- if(!$name){
- # Capitalize first letter
- $_ = $property->name;
- $_ =~ s/^([a-z])/\u$1/;
- $name = "set" . $_;
- }
- # Remove semicolon
- $name =~ s/://;
- my $build = "static void _logos_method\$" . $property->group . "\$" . $property->class . "\$" . $name . "\$" . "(" . $property->class . "* self, SEL _cmd, " . $type . " arg){ ";
- $build .= "objc_setAssociatedObject(self, &" . $key . ", ";
- my $hasOpening = 1;
- if ($type eq "BOOL"){
- $build .= "[NSNumber numberWithBool:";
- } elsif ($type eq "char"){
- $build .= "[NSNumber numberWithChar:";
- } elsif ($type eq "unsigned char"){
- $build .= "[NSNumber numberWithUnsignedChar:";
- } elsif ($type eq "double"){
- $build .= "[NSNumber numberWithDouble:";
- } elsif ($type =~ /^(float|CGFloat)$/){
- $build .= "[NSNumber numberWithFloat:";
- } elsif ($type eq "int"){
- $build .= "[NSNumber numberWithInt:";
- } elsif ($type eq "NSInteger"){
- $build .= "[NSNumber numberWithInteger:";
- } elsif ($type =~ /^unsigned( int)?$/){
- $build .= "[NSNumber numberWithUnsignedInt:";
- } elsif ($type eq "NSUInteger"){
- $build .= "[NSNumber numberWithUnsignedInteger:";
- } elsif ($type eq "long"){
- $build .= "[NSNumber numberWithLong:";
- } elsif ($type eq "unsigned long"){
- $build .= "[NSNumber numberWithUnsignedLong:";
- } elsif ($type eq "long long"){
- $build .= "[NSNumber numberWithLongLong:";
- } elsif ($type eq "unsigned long long"){
- $build .= "[NSNumber numberWithUnsignedLongLong:";
- } elsif ($type eq "short"){
- $build .= "[NSNumber numberWithShort:";
- } elsif ($type eq "unsigned short"){
- $build .= "[NSNumber numberWithUnsignedShort:";
- } elsif ($type =~ /^(NSRange|CGPoint|CGVector|CGSize|CGRect|CGAffineTransform|UIEdgeInsets|UIOffset|CATransform3D|CMTime(Range|Mapping)?|MKCoordinate(Span)?|SCNVector[34]|SCNMatrix4)$/){
- $build .= "[NSValue valueWith " . $type . ":";
- } else {
- $hasOpening = 0;
- }
- $build .= "arg";
- if ($hasOpening){
- $build .= "]";
- }
- $build .= ", ".$policy.")";
- $build .= "; }";
- return $build;
- }
- sub getters_setters {
- my $self = shift;
- my $property = shift;
- my ($assign, $retain, $nonatomic, $copy, $getter, $setter);
- for(my $i = 0; $i < $property->numattr; $i++){
- my $attr = $property->attributes->[$i];
- if($attr =~ /assign/){
- $assign = 1;
- }elsif($attr =~ /retain/){
- $retain = 1;
- }elsif($attr =~ /nonatomic/){
- $nonatomic = 1;
- }elsif($attr =~ /copy/){
- $copy = 1;
- }elsif($attr =~ /getter=(\w+)/){
- $getter = $1;
- }elsif($attr =~ /setter=(\w+:)/){
- $setter = $1;
- }
- }
- my $policy = "OBJC_ASSOCIATION_";
- if($retain){
- $policy .= "RETAIN";
- }elsif($copy){
- $policy .= "COPY";
- }elsif($assign){
- $policy .= "ASSIGN";
- }else{
- print "error: no 'assign', 'retain', or 'copy' attribu...wait, how did you manage to get here?\n";
- }
- if($nonatomic){
- # The 'assign' attribute appears to be nonatomic by default.
- if(!$assign){
- $policy .= "_NONATOMIC";
- }
- }
- $property->associationPolicy($policy);
- my $build;
- my $key = $self->key($property);
- my $getter_func = $self->getter($property, $getter, $key);
- my $setter_func = $self->setter($property, $setter, $policy, $key);
- $build .= $build . "static char " . $key . ";";
- $build .= $getter_func;
- $build .= $setter_func;
- return $build;
- }
- sub initializers {
- my $self = shift;
- my $property = shift;
- my ($getter, $setter);
- for(my $i = 0; $i < $property->numattr; $i++){ # This could be more efficient
- my $attr = $property->attributes->[$i];
- if($attr =~ /getter=(\w+)/){
- $getter = $1;
- }elsif($attr =~ /setter=(\w+:)/){
- $setter = $1;
- $setter =~ s/://;
- }
- }
- if(!$setter){
- # Capitalize first letter
- $_ = $property->name;
- $_ =~ s/^([a-z])/\u$1/;
- $setter = "set" . $_;
- }
- if(!$getter){
- # Use property name if no getter specified
- $getter = $property->name;
- }
- my $build = "";
- $build .= "{ ";
- # Getter
- $build .= "class_addMethod(";
- $build .= "_logos_class\$" . $property->group . "\$" . $property->class . ", ";
- $build .= "\@selector(" . $getter . "), " . "(IMP)&" . "_logos_method\$" . $property->group . "\$" . $property->class . "\$" . $getter . "\$, [[NSString stringWithFormat:\@\"%s\@:\", \@encode(".$property->type.")] UTF8String]);";
- # Setter
- $build .= "class_addMethod(";
- $build .= "_logos_class\$" . $property->group . "\$" . $property->class . ", ";
- $build .= "\@selector(" . $setter . ":), " . "(IMP)&" . "_logos_method\$" . $property->group . "\$" . $property->class . "\$" . $setter . "\$, [[NSString stringWithFormat:\@\"v\@:%s\", \@encode(".$property->type.")] UTF8String]);";
- $build .= "} ";
- return $build;
- }
- 1;
|