[perl-Glib-Object-Introspection] perli11ndoc: display a synopsis for callables
- From: Torsten Schönfeld <tsch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [perl-Glib-Object-Introspection] perli11ndoc: display a synopsis for callables
- Date: Mon, 7 Sep 2015 20:37:45 +0000 (UTC)
commit 2bae7d2a8da41c8752a21d56902c49843f7a9fc3
Author: Torsten Schönfeld <kaffeetisch gmx de>
Date: Mon Sep 7 22:36:38 2015 +0200
perli11ndoc: display a synopsis for callables
bin/perli11ndoc | 305 ++++++++++++++++++++++++++++++++++---------------------
1 files changed, 191 insertions(+), 114 deletions(-)
---
diff --git a/bin/perli11ndoc b/bin/perli11ndoc
index 4ef225c..f1ee2de 100755
--- a/bin/perli11ndoc
+++ b/bin/perli11ndoc
@@ -168,6 +168,62 @@ sub find_attribute {
return $attribute_list->pop->value;
}
+sub find_full_element_name {
+ my ($self, $element) = @_;
+ my $name = $self->find_attribute ($element, 'name');
+ return () unless defined $name;
+
+ if ($name =~ /\./) {
+ die "Unexpected fully qualified name '$name' encountered; aborting\n";
+ }
+
+ my $package = '';
+ my $current_element = $element;
+ while (1) {
+ my $parent = $current_element->parentNode;
+ last unless defined $parent;
+ if ($parent->nodeName eq 'namespace') {
+ $package = $self->{basename} . '::' . $package;
+ last;
+ }
+ $package = $self->find_attribute ($parent, 'name') . '::' . $package;
+ $current_element = $parent;
+ }
+
+ my $full_name = $package . $name;
+ $package =~ s/::$//;
+ return ($package, $name, $full_name);
+}
+
+sub find_parameters_and_return_value {
+ my ($self, $element) = @_;
+
+ my (@in, @out);
+ my $parameter_list = $self->{xpc}->find ('core:parameters/core:parameter', $element);
+ foreach my $parameter ($parameter_list->get_nodelist) {
+ my $direction = $self->find_attribute ($parameter, 'direction') // 'in';
+ if ($direction eq 'inout' || $direction eq 'out') {
+ push @out, $parameter;
+ }
+ if ($direction eq 'inout' || $direction eq 'in') {
+ push @in, $parameter;
+ }
+ }
+
+ my $retval = undef;
+ my $retval_list = $self->{xpc}->find ('core:return-value', $element);
+ if ($retval_list->size == 1) {
+ $retval = $retval_list->[0];
+ if (defined $retval) {
+ if ($self->find_type_name ($retval) eq 'none') {
+ $retval = undef;
+ }
+ }
+ }
+
+ return (\ in, $retval, \ out);
+}
+
sub find_type_name {
my ($self, $element) = @_;
# FIXME: Sometimes, fields or parameters have a <callback> or <array> element
@@ -395,39 +451,158 @@ sub format_bitfield_and_enumeration {
# ------------------------------------------------------------------------------
sub format_callable {
- my ($self, $element, $heading) = @_;
+ my ($self, $element, $heading, $synopsis_format, $flags_formatter) = @_;
+ $flags_formatter //= 'format_callable_flags';
+
my $text = '';
- my $full_name = $self->format_full_element_name ($element);
- my $flags = $self->format_callable_flags ($element);
+
+ my ($package, $name, $full_name) = $self->find_full_element_name ($element);
+ my $flags = $self->$flags_formatter ($element);
$text .= "$heading\n\n $full_name$flags\n";
+
+ my ($in, $retval, $out) = $self->find_parameters_and_return_value ($element);
+
+ # --- synopsis ---
+ my @in_names = map { '$' . $self->find_attribute ($_, 'name') } @$in;
+ my @out_names = map { '$' . $self->find_attribute ($_, 'name') } @$out;
+ if (defined $retval) {
+ unshift @out_names, '$retval';
+ }
+
+ my $in_list = join ', ', @in_names;
+ my $in_list_pre_comma = @in_names > 0 ? ", $in_list" : '';
+ my $in_list_post_comma = @in_names > 0 ? "$in_list, " : '';
+ my $out_list = join ', ', @out_names;
+ my $out_list_parens = @out_names > 1 ? "($out_list)" : $out_list;
+ my $out_list_assign = @out_names > 0 ? "$out_list_parens = " : '';
+
+ my $synopsis = $synopsis_format;
+ $synopsis =~ s/\[\[PACKAGE\]\]/$package/g;
+ $synopsis =~ s/\[\[NAME\]\]/$name/g;
+ $synopsis =~ s/\[\[NAME_UC\]\]/uc $name/ge;
+ $synopsis =~ s/\[\[FULL_NAME\]\]/$full_name/g;
+ $synopsis =~ s/\[\[IN_LIST\]\]/$in_list/g;
+ $synopsis =~ s/\[\[IN_LIST_PRE_COMMA\]\]/$in_list_pre_comma/g;
+ $synopsis =~ s/\[\[IN_LIST_POST_COMMA\]\]/$in_list_post_comma/g;
+ $synopsis =~ s/\[\[OUT_LIST\]\]/$out_list/g;
+ $synopsis =~ s/\[\[OUT_LIST_PARENS\]\]/$out_list_parens/g;
+ $synopsis =~ s/\[\[OUT_LIST_ASSIGN\]\]/$out_list_assign/g;
+
+ $text .= "\nSYNOPSIS\n\n $synopsis\n";
+
+ # --- description ---
$text .= $self->format_description ($element);
- $text .= $self->format_parameters_and_return_values ($element);
+
+ # --- in ---
+ if (@$in) {
+ $text .= "\nPARAMETERS\n\n";
+ foreach my $parameter (@$in) {
+ my $name = $self->find_attribute ($parameter, 'name');
+ my $type_name = $self->find_type_name ($parameter);
+ my $full_type_name = $self->format_full_type_name ($type_name);
+ $text .= " • $name: $full_type_name\n";
+ my $doc = $self->format_docs ($parameter, ' ');
+ if (defined $doc) {
+ $text .= "$doc\n";
+ }
+ $text .= "\n";
+ }
+ $text =~ s/\n\n\Z/\n/;
+ }
+
+ # --- retval & out ---
+ my $retval_type_name = 'none';
+ if (defined $retval) {
+ $retval_type_name = $self->find_type_name ($retval);
+ }
+ if ($retval_type_name ne 'none' || @$out) {
+ $text .= "\nRETURN VALUES\n\n";
+ if ($retval_type_name ne 'none') {
+ my $full_retval_type_name =
+ $self->format_full_type_name ($retval_type_name);
+ $text .= " • $full_retval_type_name\n";
+ my $doc = $self->format_docs ($retval, ' ');
+ if (defined $doc) {
+ $text .= "$doc\n\n";
+ }
+ }
+ if (@$out) {
+ foreach my $parameter (@$out) {
+ my $name = $self->find_attribute ($parameter, 'name');
+ push @out_names, $name;
+ my $type_name = $self->find_type_name ($parameter);
+ my $full_type_name = $self->format_full_type_name ($type_name);
+ $text .= " • $name: $full_type_name\n";
+ my $doc = $self->format_docs ($parameter, ' ');
+ if (defined $doc) {
+ $text .= "$doc\n\n";
+ }
+ }
+ }
+ $text =~ s/\n\n\Z/\n/;
+ }
+
return $text;
}
sub format_callback {
my ($self, $element) = @_;
- return $self->format_callable ($element, 'CALLBACK');
+ my $synopsis_format = <<'__EOS__';
+sub {
+ my ([[IN_LIST]]) = @_;
+ ...
+ return [[OUT_LIST_PARENS]];
+ }
+__EOS__
+ return $self->format_callable ($element, 'CALLBACK', $synopsis_format);
}
sub format_constructor {
my ($self, $element) = @_;
- return $self->format_callable ($element, 'CONSTRUCTOR');
+ my $synopsis_format = '$object = [[PACKAGE]]->[[NAME]] ([[IN_LIST]])';
+ return $self->format_callable ($element, 'CONSTRUCTOR', $synopsis_format);
}
sub format_function {
my ($self, $element) = @_;
- return $self->format_callable ($element, 'FUNCTION');
+ my $synopsis_format = '[[OUT_LIST_ASSIGN]][[FULL_NAME]] ([[IN_LIST]])';
+ return $self->format_callable ($element, 'FUNCTION', $synopsis_format);
}
sub format_method {
my ($self, $element) = @_;
- return $self->format_callable ($element, 'METHOD');
+ my $synopsis_format = '[[OUT_LIST_ASSIGN]]$object->[[NAME]] ([[IN_LIST]])';
+ return $self->format_callable ($element, 'METHOD', $synopsis_format);
+}
+
+sub format_signal {
+ my ($self, $element) = @_;
+ my $synopsis_format = <<'__EOS__';
+$object->signal_connect ('[[NAME]]' => sub {
+ my ($object, [[IN_LIST_POST_COMMA]]$data) = @_;
+ ...
+ return [[OUT_LIST_PARENS]];
+ }, $data);
+__EOS__
+ return $self->format_callable ($element,
+ 'SIGNAL',
+ $synopsis_format,
+ 'format_signal_flags');
}
sub format_virtual_method {
my ($self, $element) = @_;
- return $self->format_callable ($element, 'VIRTUAL METHOD');
+ my $synopsis_format = <<'__EOS__';
+sub [[NAME_UC]] {
+ my ($object[[IN_LIST_PRE_COMMA]]) = @_;
+ ...
+ return [[OUT_LIST_PARENS]];
+ }
+__EOS__
+ return $self->format_callable ($element,
+ 'VIRTUAL METHOD',
+ $synopsis_format,
+ 'format_virtual_method_flags');
}
# ------------------------------------------------------------------------------
@@ -593,19 +768,6 @@ sub format_record {
# ------------------------------------------------------------------------------
-sub format_signal {
- my ($self, $element) = @_;
- my $text = '';
- my $full_name = $self->format_full_element_name ($element);
- my $flags = $self->format_signal_flags ($element);
- $text .= "SIGNAL\n\n $full_name$flags\n";
- $text .= $self->format_description ($element);
- $text .= $self->format_parameters_and_return_values ($element);
- return $text;
-}
-
-# ------------------------------------------------------------------------------
-
sub format_sub_constructors {
my ($self, $element) = @_;
my $text = '';
@@ -730,10 +892,8 @@ sub format_sub_virtual_methods {
$text .= "\nVIRTUAL METHODS\n\n";
foreach my $vfunc ($vfunc_list->get_nodelist) {
my $name = $self->find_attribute ($vfunc, 'name');
- my $callable_flags = $self->format_callable_flags ($vfunc,
- qw/introspectable version/);
- my $vfunc_flags = $self->format_virtual_method_flags ($vfunc);
- $text .= " • $name$vfunc_flags$callable_flags\n";
+ my $flags = $self->format_virtual_method_flags ($vfunc);
+ $text .= " • $name$flags\n";
}
}
return $text;
@@ -820,27 +980,8 @@ sub format_docs {
sub format_full_element_name {
my ($self, $element) = @_;
- my $name = $self->find_attribute ($element, 'name');
- return '[unknown]' unless defined $name;
-
- if ($name =~ /\./) {
- die "Unexpected fully qualified name '$name' encountered; aborting\n";
- }
-
- my $formatted_name = $name;
- my $current_element = $element;
- while (1) {
- my $parent = $current_element->parentNode;
- last unless defined $parent;
- if ($parent->nodeName eq 'namespace') {
- return $self->{basename} . '::' . $formatted_name;
- }
- $formatted_name =
- $self->find_attribute ($parent, 'name') . '::' . $formatted_name;
- $current_element = $parent;
- }
-
- die "Could not format '$name'; aborting\n";
+ my (undef, undef, $full_name) = $self->find_full_element_name ($element);
+ return $full_name;
}
sub format_full_type_name {
@@ -869,71 +1010,6 @@ sub format_full_type_names {
return $text;
}
-sub format_parameters_and_return_values {
- my ($self, $element) = @_;
-
- my $text = '';
-
- my @inout_out;
- my $parameter_list = $self->{xpc}->find ('core:parameters/core:parameter', $element);
- if ($parameter_list->size > 0) {
- $text .= "\nPARAMETERS\n\n";
- foreach my $parameter ($parameter_list->get_nodelist) {
- my $direction = $self->find_attribute ($parameter, 'direction') // 'in';
-
- if ($direction eq 'inout' || $direction eq 'out') {
- push @inout_out, $parameter;
- }
-
- if ($direction eq 'inout' || $direction eq 'in') {
- my $name = $self->find_attribute ($parameter, 'name');
- my $type_name = $self->find_type_name ($parameter);
- my $full_type_name = $self->format_full_type_name ($type_name);
- $text .= " • $name: $full_type_name\n";
- my $doc = $self->format_docs ($parameter, ' ');
- if (defined $doc) {
- $text .= "$doc\n";
- }
- $text .= "\n";
- }
- }
- $text =~ s/\n\n\Z/\n/;
- }
-
- my $retval_list = $self->{xpc}->find ('core:return-value', $element);
- my $retval_type_name = 'none';
- if ($retval_list->size == 1) {
- $retval_type_name = $self->find_type_name ($retval_list->[0]);
- }
- if ($retval_type_name ne 'none' || @inout_out) {
- $text .= "\nRETURN VALUES\n\n";
- if ($retval_type_name ne 'none') {
- my $full_retval_type_name =
- $self->format_full_type_name ($retval_type_name);
- $text .= " • $full_retval_type_name\n";
- my $doc = $self->format_docs ($retval_list->[0], ' ');
- if (defined $doc) {
- $text .= "$doc\n\n";
- }
- }
- if (@inout_out) {
- foreach my $parameter (@inout_out) {
- my $name = $self->find_attribute ($parameter, 'name');
- my $type_name = $self->find_type_name ($parameter);
- my $full_type_name = $self->format_full_type_name ($type_name);
- $text .= " • $name: $full_type_name\n";
- my $doc = $self->format_docs ($parameter, ' ');
- if (defined $doc) {
- $text .= "$doc\n\n";
- }
- }
- }
- $text =~ s/\n\n\Z/\n/;
- }
-
- return $text;
-}
-
sub format_version_constraint {
my ($self, $element) = @_;
my $version = $self->find_attribute ($element, 'version');
@@ -1026,8 +1102,9 @@ sub format_virtual_method_flags {
my ($self, $element, @wanted) = @_;
my $name = $self->find_attribute ($element, 'name');
my @available = (
- ['invoker', undef, sub { defined $_[0] && $_[0] ne $name
- ? "invoked by $_[0]" : undef }],
+ ['introspectable', 1, sub { !$_[0] ? 'NOT INTROSPECTABLE' : undef }],
+ ['invoker', undef, sub { defined $_[0] && $_[0] ne $name ? "invoked by $_[0]" : undef }],
+ ['version', undef, sub { defined $_[0] ? "available since $_[0]" : undef }],
);
return $self->format_flags ($element, \ available, \ wanted);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]