package Logos::Generator::Base::Method; use strict; use Logos::Util; sub originalFunctionName { my $self = shift; my $method = shift; return Logos::sigil(($method->scope eq "+" ? "meta_" : "")."orig").$method->groupIdentifier."\$".$method->class->name."\$".$method->_new_selector; } sub newFunctionName { my $self = shift; my $method = shift; return Logos::sigil(($method->scope eq "+" ? "meta_" : "")."method").$method->groupIdentifier."\$".$method->class->name."\$".$method->_new_selector; } sub definition { ::fileError(-1, "generator does not implement Method::definition"); } sub originalCall { ::fileError(-1, "generator does not implement Method::originalCall"); } sub selectorRef { my $self = shift; my $selector = shift; if ($selector eq "dealloc") { return "sel_registerName(\"".$selector."\")"; } return "\@selector(".$selector.")"; } sub selfTypeForMethod { my $self = shift; my $method = shift; if($method->scope eq "+") { return "_LOGOS_SELF_TYPE_NORMAL Class _LOGOS_SELF_CONST"; } if($method->methodFamily eq "init") { return "_LOGOS_SELF_TYPE_INIT ".$method->class->type; } return "_LOGOS_SELF_TYPE_NORMAL ".$method->class->type." _LOGOS_SELF_CONST"; } sub returnTypeForMethod { my $self = shift; my $method = shift; if($method->methodFamily ne "") { return $method->class->type; } my $result = $method->return; if ($result eq "instancetype") { return $method->class->type; } return $result; } sub functionAttributesForMethod { my $self = shift; my $method = shift; if($method->methodFamily ne "") { return " _LOGOS_RETURN_RETAINED"; } return ""; } sub buildLogCall { my $self = shift; my $method = shift; my $args = shift; # Log preamble my $build = "HBLogDebug(\@\"".$method->scope."[<".$method->class->name.": %p>"; my $argnamelist = ""; if($method->numArgs > 0) { # For each argument, add its keyword and a format char to the log string. map $build .= " ".$method->selectorParts->[$_].":".Logos::Method::formatCharForArgType($method->argtypes->[$_]), (0..$method->numArgs - 1); # This builds a list of args by making sure the format char isn't -- (or, what we're using for non-operational types) # Map (in list context) "format char == -- ? nothing : arg name" over the indices of the arg list. my @newarglist = map(Logos::Method::printArgForArgType($method->argtypes->[$_], $method->argnames->[$_]), (0..$method->numArgs - 1)); my @existingargs = grep(defined($_), @newarglist); if(scalar(@existingargs) > 0) { $argnamelist = ", ".join(", ", grep(defined($_), @existingargs)); } } else { # Space and then the only keyword in the selector. $build .= " ".$method->selector; } my @extraFormatSpecifiers; my @extraArguments; for(Logos::Util::smartSplit(qr/\s*,\s*/, $args)) { my ($popen, $pclose) = matchedParenthesisSet($_); my $type = "id"; if(defined $popen) { $type = substr($_, $popen, $pclose-$popen-1); } push(@extraFormatSpecifiers, Logos::Method::formatCharForArgType($type)); my $n = Logos::Method::printArgForArgType($type, "($_)"); push(@extraArguments, $n) if $n; } # Log postamble $build .= "]"; $build .= ": ".join(", ", @extraFormatSpecifiers) if @extraFormatSpecifiers > 0; $build .= "\", self".$argnamelist; $build .= ", ".join(", ", @extraArguments) if @extraArguments > 0; $build .= ")"; } sub declarations { ::fileError(-1, "generator does not implement Method::declarations"); } sub initializers { ::fileError(-1, "generator does not implement Method::initializers"); } 1;