/[suikacvs]/messaging/manakai/bin/mkdisdump.pl
Suika

Contents of /messaging/manakai/bin/mkdisdump.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.15 - (hide annotations) (download)
Wed Oct 5 11:50:35 2005 UTC (19 years, 1 month ago) by wakaba
Branch: MAIN
Changes since 1.14: +42 -10 lines
File MIME type: text/plain
++ manakai/doc/ChangeLog	5 Oct 2005 11:43:46 -0000
2005-10-05  Wakaba  <wakaba@suika.fam.cx>

	* Makefile (util.xml): New modules added to option.

++ manakai/bin/ChangeLog	5 Oct 2005 11:43:22 -0000
2005-10-05  Wakaba  <wakaba@suika.fam.cx>

	* mkdisdump.pl (dd_get_qname_uri): Sets "dump:uri" attribute.

2005-10-03  Wakaba  <wakaba@suika.fam.cx>

	* mkdisdump.pl (append_module_documentation): Outputs
	any "DISCore:AnyAppName" property value in
	addition to "dis:AppName" values.  Use "dump:ref"
	property if the value is a URI.
	(append_method_documentation): Likewise.
	(append_document_documentation): Likewise.

++ manakai/lib/Message/Util/DIS/ChangeLog	5 Oct 2005 11:46:52 -0000
2005-10-05  Wakaba  <wakaba@suika.fam.cx>

	* DISDoc.dis (parseDISDocInlineText): Allows "^" in
	tag (it is part of lexical type specification and
	it should have been allowed).

++ manakai/lib/Message/DOM/ChangeLog	5 Oct 2005 11:45:44 -0000
2005-10-05  Wakaba  <wakaba@suika.fam.cx>

	* DOMFeature.dis: Description added and revised.  (Still more
	work required.)

2005-10-04  Wakaba  <wakaba@suika.fam.cx>

	* DOMMain.dis (DOMString): The "idl:perl" attribute
	value has been changed from "DISPerl:String"
	to "DISPerl:CharacterString" to clarify its semantics.

++ manakai/lib/manakai/ChangeLog	5 Oct 2005 11:49:46 -0000
2005-10-04  Wakaba  <wakaba@suika.fam.cx>

	* DISCore.dis (DISCore:AnyAppName): New superproperty
	of "dis:AppName".

	* DISIDL.dis (idl:prefix): It is now a subproperty
	of "DISCore:AnyAppName".
	(idl:unsignedLong): Missing "idl:perl" property added.
	(idl:boundType): New superproperty of "idl:perl" and so on.

	* DISLang.dis (dis:Operator): It is now a subproperty
	of "DISCore:AnyAppName".

	* ECMAScript.dis (js:name, js:typeName): Added.  "js:typeName"
	propery values added to types.

1 wakaba 1.1 #!/usr/bin/perl -w
2     use strict;
3    
4     =head1 NAME
5    
6 wakaba 1.5 mkdisdump.pl - Generating Perl Module Documentation Source
7 wakaba 1.1
8     =head1 SYNOPSIS
9    
10 wakaba 1.5 perl path/to/mkdisdump.pl input.cdis \
11 wakaba 1.1 {--module-name=ModuleName | --module-uri=module-uri} \
12     [--for=for-uri] [options] > ModuleName.pm
13     perl path/to/cdis2pm.pl --help
14    
15     =head1 DESCRIPTION
16    
17     The C<cdis2pm> script generates a Perl module from a compiled "dis"
18     ("cdis") file. It is intended to be used to generate a manakai
19     DOM Perl module files, although it might be useful for other purpose.
20    
21     This script is part of manakai.
22    
23     =cut
24    
25     use Message::Util::QName::Filter {
26 wakaba 1.3 ddel => q<http://suika.fam.cx/~wakaba/archive/2005/disdoc#>,
27 wakaba 1.1 ddoct => q<http://suika.fam.cx/~wakaba/archive/2005/8/disdump-xslt#>,
28     DIS => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/DIS#>,
29     dis => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/lang#dis-->,
30     dis2pm => q<http://suika.fam.cx/~wakaba/archive/2004/11/8/dis2pm#>,
31     DISCore => q<http://suika.fam.cx/~wakaba/archive/2004/dis/Core#>,
32     DISLang => q<http://suika.fam.cx/~wakaba/archive/2004/dis/Lang#>,
33     DISPerl => q<http://suika.fam.cx/~wakaba/archive/2004/dis/Perl#>,
34 wakaba 1.12 doc => q<http://suika.fam.cx/~wakaba/archive/2004/dis/Document#>,
35 wakaba 1.1 DOMLS => q<http://suika.fam.cx/~wakaba/archive/2004/dom/ls#>,
36     dump => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/DIS#DISDump/>,
37 wakaba 1.8 dx => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/Error/DOMException#>,
38 wakaba 1.5 ecore => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/Error/Core/>,
39 wakaba 1.13 idl => q<http://suika.fam.cx/~wakaba/archive/2004/dis/IDL#>,
40 wakaba 1.3 infoset => q<http://www.w3.org/2001/04/infoset#>,
41 wakaba 1.12 lang => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/lang#>,
42 wakaba 1.1 ManakaiDOM => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/manakai-dom#>,
43     Markup => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Markup#>,
44     Util => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/>,
45     xml => q<http://www.w3.org/XML/1998/namespace>,
46 wakaba 1.3 xmlns => q<http://www.w3.org/2000/xmlns/>,
47 wakaba 1.1 };
48    
49     =head1 OPTIONS
50    
51     =over 4
52    
53     =item --for=I<for-uri> (Optional)
54    
55     Specifies the "For" URI reference for which the outputed module is.
56     If this parameter is ommitted, the default "For" URI reference
57     for the module, if any, or the C<ManakaiDOM:all> is assumed.
58    
59     =item --help
60    
61     Shows the help message.
62    
63     =item --module-uri=I<module-uri>
64    
65     A URI reference that identifies a module to output. Either
66     C<--module-name> or C<--module-uri> is required.
67    
68 wakaba 1.5 =item --verbose / --noverbose (default)
69 wakaba 1.1
70 wakaba 1.5 Whether a verbose message mode should be selected or not.
71 wakaba 1.1
72 wakaba 1.5 =item --with-implementators-note / --nowith-implementators-note (default)
73 wakaba 1.1
74 wakaba 1.5 Whether the implemetator's notes should also be included
75     in the result or not.
76 wakaba 1.1
77     =back
78    
79     =cut
80    
81     use Getopt::Long;
82     use Pod::Usage;
83     use Storable;
84     use Message::Util::Error;
85 wakaba 1.4 my %Opt = (
86     module_uri => {},
87 wakaba 1.12 resource_uri => {},
88 wakaba 1.4 );
89 wakaba 1.1 GetOptions (
90 wakaba 1.8 'debug' => \$Opt{debug},
91 wakaba 1.10 'dis-file-suffix=s' => \$Opt{dis_suffix},
92     'daem-file-suffix=s' => \$Opt{daem_suffix},
93 wakaba 1.1 'for=s' => \$Opt{For},
94     'help' => \$Opt{help},
95 wakaba 1.4 'module-uri=s' => sub {
96     shift;
97 wakaba 1.12 my ($nuri, $furi) = split /\s+/, shift, 2;
98     $furi ||= '';
99     $Opt{module_uri}->{$nuri}->{$furi} = 1;
100     },
101     'resource-uri=s' => sub {
102     shift;
103     my ($nuri, $furi) = split /\s+/, shift, 2;
104     $furi ||= '';
105     $Opt{resource_uri}->{$nuri}->{$furi} = 1;
106 wakaba 1.4 },
107 wakaba 1.10 'search-path|I=s' => sub {
108     shift;
109     my @value = split /\s+/, shift;
110     while (my ($ns, $path) = splice @value, 0, 2, ()) {
111     unless (defined $path) {
112     die qq[$0: Search-path parameter without path: "$ns"];
113     }
114     push @{$Opt{input_search_path}->{$ns} ||= []}, $path;
115     }
116     },
117     'search-path-catalog-file-name=s' => sub {
118     shift;
119     require File::Spec;
120     my $path = my $path_base = shift;
121     $path_base =~ s#[^/]+$##;
122     $Opt{search_path_base} = $path_base;
123     open my $file, '<', $path or die "$0: $path: $!";
124     while (<$file>) {
125     if (s/^\s*\@//) { ## Processing instruction
126     my ($target, $data) = split /\s+/;
127     if ($target eq 'base') {
128     $Opt{search_path_base} = File::Spec->rel2abs ($data, $path_base);
129     } else {
130     die "$0: $target: Unknown target";
131     }
132     } elsif (/^\s*\#/) { ## Comment
133     #
134     } elsif (/\S/) { ## Catalog entry
135     s/^\s+//;
136     my ($ns, $path) = split /\s+/;
137     push @{$Opt{input_search_path}->{$ns} ||= []},
138     File::Spec->rel2abs ($path, $Opt{search_path_base});
139     }
140     }
141     ## NOTE: File paths with SPACEs are not supported
142     ## NOTE: Future version might use file: URI instead of file path.
143     },
144 wakaba 1.5 'with-implementators-note' => \$Opt{with_impl_note},
145 wakaba 1.10 'verbose!' => \$Opt{verbose},
146 wakaba 1.1 ) or pod2usage (2);
147     pod2usage ({-exitval => 0, -verbose => 1}) if $Opt{help};
148     $Opt{file_name} = shift;
149     pod2usage ({-exitval => 2, -verbose => 0}) unless $Opt{file_name};
150 wakaba 1.12 pod2usage (2) unless (keys %{$Opt{module_uri}}) + (keys %{$Opt{resource_uri}});
151 wakaba 1.8 $Message::DOM::DOMFeature::DEBUG = 1 if $Opt{debug};
152 wakaba 1.10 $Opt{dis_suffix} = '.dis' unless defined $Opt{dis_suffix};
153     $Opt{daem_suffix} = '.daem' unless defined $Opt{daem_suffix};
154 wakaba 1.1
155     sub status_msg ($) {
156     my $s = shift;
157     $s .= "\n" unless $s =~ /\n$/;
158     print STDERR $s;
159     }
160    
161     sub status_msg_ ($) {
162     my $s = shift;
163     print STDERR $s;
164     }
165    
166     sub verbose_msg ($) {
167     my $s = shift;
168     $s .= "\n" unless $s =~ /\n$/;
169 wakaba 1.10 print STDERR $s if $Opt{verbose};
170 wakaba 1.1 }
171    
172     sub verbose_msg_ ($) {
173     my $s = shift;
174 wakaba 1.10 print STDERR $s if $Opt{verbose};
175 wakaba 1.1 }
176    
177 wakaba 1.7 {
178     my $ResourceCount = 0;
179 wakaba 1.8 sub progress_inc (;$) {
180     $ResourceCount += (shift || 1);
181     if (($ResourceCount % 10) == 0) {
182 wakaba 1.7 print STDERR "*";
183     print STDERR " " if ($ResourceCount % (10 * 10)) == 0;
184     print STDERR "\n" if ($ResourceCount % (10 * 50)) == 0;
185     }
186     }
187    
188     sub progress_reset () {
189     $ResourceCount = 0;
190     }
191     }
192    
193 wakaba 1.8 my $start_time;
194     BEGIN { $start_time = time }
195    
196     use Message::DOM::GenericLS;
197     use Message::DOM::SimpleLS;
198     use Message::Util::DIS::DISDump;
199 wakaba 1.12 use Message::Util::DIS::DISDoc;
200 wakaba 1.8 use Message::Util::DIS::DNLite;
201    
202 wakaba 1.5 my $impl = $Message::DOM::ImplementationRegistry->get_implementation
203 wakaba 1.1 ({
204     ExpandedURI q<ManakaiDOM:Minimum> => '3.0',
205     '+' . ExpandedURI q<DOMLS:LS> => '3.0',
206     '+' . ExpandedURI q<DIS:Doc> => '2.0',
207 wakaba 1.8 '+' . ExpandedURI q<DIS:DNLite> => '1.0',
208 wakaba 1.1 ExpandedURI q<DIS:Dump> => '1.0',
209     });
210    
211     ## -- Load input dac database file
212     status_msg_ qq<Opening dac file "$Opt{file_name}"...>;
213 wakaba 1.8 our $db = $impl->get_feature (ExpandedURI q<DIS:DNLite> => '1.0')
214 wakaba 1.10 ->pl_load_dis_database ($Opt{file_name}, sub ($$) {
215     my ($db, $mod) = @_;
216     my $ns = $mod->namespace_uri;
217     my $ln = $mod->local_name;
218     verbose_msg qq<Database module <$ns$ln> is requested>;
219     my $name = dac_search_file_path_stem ($ns, $ln, $Opt{daem_suffix});
220     if (defined $name) {
221     return $name.$Opt{daem_suffix};
222     } else {
223     return $ln.$Opt{daem_suffix};
224     }
225     });
226 wakaba 1.1 status_msg qq<done\n>;
227    
228 wakaba 1.2 our %ReferredResource;
229 wakaba 1.5 our %ClassMembers;
230     our %ClassInheritance;
231     our @ClassInheritance;
232     our %ClassImplements;
233 wakaba 1.2
234 wakaba 1.12 sub append_module_group_documentation (%) {
235     my %opt = @_;
236     my $section = $opt{result_parent}
237     ->append_child ($opt{result_parent}->owner_document
238     ->create_element_ns (ExpandedURI q<dump:>, 'moduleGroup'));
239    
240     add_uri ($opt{source_resource} => $section);
241    
242     my $path = $opt{source_resource}->get_property_text
243     (ExpandedURI q<dis:FileName>,
244     $opt{source_resource}->local_name);
245     $section->resource_file_path_stem ($path);
246    
247     $section->set_attribute_ns
248     (ExpandedURI q<ddoct:>, 'ddoct:basePath', '../' x ($path =~ tr#/#/#));
249    
250     append_description (source_resource => $opt{source_resource},
251     result_parent => $section,
252     has_label => 1);
253    
254     ## -- Member modules
255    
256     for my $rres (@{$opt{source_resource}->get_property_module_list
257     (ExpandedURI q<DISCore:module>)}) {
258     $Opt{module_uri}->{$rres->name_uri}->{$rres->for_uri} = 1;
259     my $mod_el = $section->append_child
260     ($section->owner_document
261     ->create_element_ns (ExpandedURI q<dump:>, 'module'));
262     $mod_el->ref ($rres->uri);
263     }
264    
265     ## -- Member resources
266    
267     for my $rres (@{$opt{source_resource}->get_property_resource_list
268     (ExpandedURI q<DISCore:resource>)}) {
269     progress_inc;
270     if ($rres->is_type_uri (ExpandedURI q<doc:Document>)) {
271     append_document_documentation (source_resource => $rres,
272     result_parent => $section);
273     } else {
274     #
275     }
276     }
277     status_msg "";
278     } # append_module_group_documentation
279    
280     sub append_document_documentation (%) {
281     my %opt = @_;
282     my $section = $opt{result_parent}
283     ->append_child ($opt{result_parent}->owner_document
284     ->create_element_ns (ExpandedURI q<dump:>, 'document'));
285     my $od = $section->owner_document;
286    
287     add_uri ($opt{source_resource} => $section);
288    
289     my $path = $opt{source_resource}->get_property_text
290     (ExpandedURI q<dis:FileName>,
291     lcfirst $opt{source_resource}->local_name);
292     $section->resource_file_path_stem ($path);
293    
294     $section->set_attribute_ns
295     (ExpandedURI q<ddoct:>, 'ddoct:basePath', '../' x ($path =~ tr#/#/#));
296    
297 wakaba 1.13 if ($opt{source_resource}->is_type_uri (ExpandedURI q<doc:Document>)) {
298     $section->append_child ($od->create_element_ns (ExpandedURI q<doc:>, 'rel'))
299     ->set_attribute_ns (ExpandedURI q<dump:>, 'dump:uri',
300     ExpandedURI q<doc:Document>);
301     }
302 wakaba 1.12
303     ## TODO: Conneg
304     for my $con (@{$opt{source_resource}->get_property_value_list
305     (ExpandedURI q<doc:content>)}) {
306     my $cond = $con->get_feature (ExpandedURI q<DIS:Doc>, '2.0');
307     my $tree = $cond->get_disdoc_tree
308     ($od, ExpandedURI q<lang:disdoc>,
309     $opt{source_resource}->database,
310     default_name_uri => $opt{source_resource}->source_node_id,
311     default_for_uri => $opt{source_resource}->for_uri);
312     $section
313     ->append_child ($od->create_element_ns (ExpandedURI q<doc:>, 'content'))
314     ->append_child (transform_disdoc_tree ($tree));
315     }
316    
317 wakaba 1.13 append_document_properties
318     (source_resource => $opt{source_resource},
319     result_parent => $section);
320 wakaba 1.12
321     for my $v (@{$opt{source_resource}->get_property_value_list
322     (ExpandedURI q<doc:part>)}) {
323     my $res = $v->get_resource ($opt{source_resource}->database);
324 wakaba 1.14 $ReferredResource{$res->uri} ||= 2;
325     $ReferredResource{$res->uri} = 2
326     if $ReferredResource{$res->uri} == 1;
327 wakaba 1.12 my $doc = $section->append_child
328     ($od->create_element_ns (ExpandedURI q<dump:>, 'document'));
329     $doc->ref ($res->uri);
330 wakaba 1.13 for my $vv (@{$v->get_property (ExpandedURI q<doc:rel>)||[]}) {
331     $doc->append_child ($od->create_element_ns (ExpandedURI q<doc:>, 'rel'))
332     ->set_attribute_ns (ExpandedURI q<dump:>, 'dump:uri', $vv->uri);
333     }
334 wakaba 1.14 for my $vv (@{$v->get_property (ExpandedURI q<doc:as>)||[]}) {
335     $doc->append_child ($od->create_element_ns (ExpandedURI q<doc:>, 'as'))
336     ->set_attribute_ns (ExpandedURI q<dump:>, 'dump:uri', $vv->uri);
337     }
338 wakaba 1.12 }
339     } # append_document_documentation
340    
341 wakaba 1.1 sub append_module_documentation (%) {
342     my %opt = @_;
343     my $section = $opt{result_parent}->create_module ($opt{source_resource}->uri);
344 wakaba 1.14 my $od = $opt{result_parent}->owner_document;
345 wakaba 1.2
346     add_uri ($opt{source_resource} => $section);
347 wakaba 1.1
348     my $pl_full_name = $opt{source_resource}->pl_fully_qualified_name;
349     if (defined $pl_full_name) {
350     $section->perl_package_name ($pl_full_name);
351 wakaba 1.5
352     my $path = $opt{source_resource}->get_property_text
353     (ExpandedURI q<dis:FileName>, $pl_full_name);
354 wakaba 1.1 $path =~ s#::#/#g;
355     $section->resource_file_path_stem ($path);
356 wakaba 1.5
357 wakaba 1.1 $section->set_attribute_ns
358     (ExpandedURI q<ddoct:>, 'ddoct:basePath', '../' x ($path =~ tr#/#/#));
359 wakaba 1.2 $pl_full_name =~ s/.*:://g;
360     $section->perl_name ($pl_full_name);
361 wakaba 1.1 }
362    
363 wakaba 1.14 for my $con (@{$opt{source_resource}->get_property_value_list
364 wakaba 1.15 (ExpandedURI q<DISCore:AnyAppName>)}) {
365 wakaba 1.14 my $ns = $con->name;
366     my $ln = $1 if ($ns =~ s/(\w+)$//);
367 wakaba 1.15 if ($con->isa ('Message::Util::IF::DVURIValue')) {
368     $section->append_child ($od->create_element_ns ($ns, $ln))
369     ->set_attribute_ns (ExpandedURI q<dump:>, 'dump:ref',
370     $con->string_value);
371     $ReferredResource{$con->uri} ||= 1;
372     } else {
373     $section->append_child ($od->create_element_ns ($ns, $ln))
374     ->text_content ($con->string_value);
375     }
376 wakaba 1.14 if ($con->isa ('Message::Util::IF::DVURIValue')) {
377     $ReferredResource{$con->uri} ||= 1;
378     }
379     }
380    
381 wakaba 1.1 append_description (source_resource => $opt{source_resource},
382     result_parent => $section);
383    
384 wakaba 1.2 if ($opt{is_partial}) {
385     $section->resource_is_partial (1);
386     return;
387     }
388    
389 wakaba 1.11 for my $rres (@{$opt{source_resource}->get_resource_list}) {
390 wakaba 1.4 if ($rres->owner_module eq $opt{source_resource} and## Defined in this module
391     not ($ReferredResource{$rres->uri} < 0)) {
392 wakaba 1.1 ## TODO: Modification required to support modplans
393 wakaba 1.7 progress_inc;
394 wakaba 1.8 if ($rres->is_type_uri (ExpandedURI q<DISLang:Class>)) {
395 wakaba 1.1 append_class_documentation
396     (result_parent => $section,
397     source_resource => $rres);
398 wakaba 1.8 } elsif ($rres->is_type_uri (ExpandedURI q<DISLang:Interface>)) {
399 wakaba 1.1 append_interface_documentation
400     (result_parent => $section,
401     source_resource => $rres);
402 wakaba 1.12 } elsif ($rres->is_type_uri (ExpandedURI q<DISCore:AnyType>)) {
403 wakaba 1.3 append_datatype_documentation
404     (result_parent => $section,
405     source_resource => $rres);
406 wakaba 1.1 }
407     } else { ## Aliases
408     #
409     }
410     }
411 wakaba 1.2 status_msg "";
412 wakaba 1.1 } # append_module_documentation
413    
414 wakaba 1.3 sub append_datatype_documentation (%) {
415     my %opt = @_;
416 wakaba 1.13 my $od = $opt{result_parent}->owner_document;
417     my $section = $opt{result_parent}->can ('create_data_type')
418     ? $opt{result_parent}->create_data_type
419     ($opt{source_resource}->uri)
420     : $opt{result_parent}->append_child
421     ($od->create_element_ns
422     (ExpandedURI q<dump:>, 'dataType'));
423 wakaba 1.3
424     add_uri ($opt{source_resource} => $section);
425    
426 wakaba 1.4 my $uri = $opt{source_resource}->name_uri;
427     if ($uri) {
428     my $fu = $opt{source_resource}->for_uri;
429     unless ($fu eq ExpandedURI q<ManakaiDOM:all>) {
430     $fu =~ /([\w.-]+)[^\w.-]*$/;
431     $uri .= '-' . $1;
432     }
433     } else {
434     $opt{source_resource}->uri;
435     }
436     $uri =~ s#\b(\d\d\d\d+)/(\d\d?)/(\d\d?)#sprintf '%04d%02d%02d', $1, $2, $3#ge;
437     my @file = map {s/[^\w-]/_/g; $_} split m{[/:#?]+}, $uri;
438 wakaba 1.3
439     $section->resource_file_path_stem (join '/', @file);
440 wakaba 1.5 $section->set_attribute_ns
441     (ExpandedURI q<ddoct:>, 'ddoct:basePath', '../' x (@file - 1));
442 wakaba 1.3
443 wakaba 1.13 for my $con (@{$opt{source_resource}->get_property_value_list
444     (ExpandedURI q<dis:AppName>)},
445     @{$opt{source_resource}->get_property_value_list
446     (ExpandedURI q<dis:Def>)}) {
447     my $ns = $con->name;
448     my $ln = $1 if ($ns =~ s/(\w+)$//);
449     if ($con->isa ('Message::Util::IF::DVURIValue')) {
450 wakaba 1.15 $section->append_child ($od->create_element_ns ($ns, $ln))
451     ->set_attribute_ns (ExpandedURI q<dump:>, 'dump:ref',
452     $con->string_value);
453 wakaba 1.13 $ReferredResource{$con->uri} ||= 1;
454 wakaba 1.15 } else {
455     $section->append_child ($od->create_element_ns ($ns, $ln))
456     ->text_content ($con->string_value);
457 wakaba 1.13 }
458     }
459    
460     append_document_properties
461     (source_resource => $opt{source_resource},
462     result_parent => $section);
463    
464 wakaba 1.3 append_description (source_resource => $opt{source_resource},
465 wakaba 1.12 result_parent => $section,
466     has_label => 1);
467 wakaba 1.3
468     if ($opt{is_partial}) {
469     $section->resource_is_partial (1);
470     return;
471     }
472    
473 wakaba 1.5 append_subclassof (source_resource => $opt{source_resource},
474     result_parent => $section);
475 wakaba 1.3 } # append_datatype_documentation
476    
477 wakaba 1.1 sub append_interface_documentation (%) {
478     my %opt = @_;
479     my $section = $opt{result_parent}->create_interface
480 wakaba 1.5 (my $class_uri = $opt{source_resource}->uri);
481     push @ClassInheritance, $class_uri;
482 wakaba 1.2
483     add_uri ($opt{source_resource} => $section);
484 wakaba 1.1
485     my $pl_full_name = $opt{source_resource}->pl_fully_qualified_name;
486 wakaba 1.14 my $path;
487 wakaba 1.1 if (defined $pl_full_name) {
488     $section->perl_package_name ($pl_full_name);
489 wakaba 1.5
490 wakaba 1.14 $path = $opt{source_resource}->get_property_text
491 wakaba 1.5 (ExpandedURI q<dis:FileName>, $pl_full_name);
492 wakaba 1.1 $path =~ s#::#/#g;
493     $section->resource_file_path_stem ($path);
494 wakaba 1.2 $section->perl_name ($pl_full_name);
495 wakaba 1.14 } else {
496     $path = $opt{source_resource}->get_property_text
497     (ExpandedURI q<dis:FileName>, $opt{source_resource}->local_name);
498     $section->resource_file_path_stem ($path);
499 wakaba 1.1 }
500 wakaba 1.14 $section->set_attribute_ns
501     (ExpandedURI q<ddoct:>, 'ddoct:basePath',
502     join '', '../' x ($path =~ tr#/#/#));
503     $pl_full_name =~ s/.*:://g;
504 wakaba 1.1
505     $section->is_exception_interface (1)
506 wakaba 1.14 if $opt{source_resource}->is_type_uri (ExpandedURI q<DISLang:Exception>);
507 wakaba 1.1
508     append_description (source_resource => $opt{source_resource},
509     result_parent => $section);
510    
511 wakaba 1.2 if ($opt{is_partial}) {
512     $section->resource_is_partial (1);
513     }
514    
515 wakaba 1.11 for my $memres (@{$opt{source_resource}->get_child_resource_list}) {
516 wakaba 1.1 if ($memres->is_type_uri (ExpandedURI q<DISLang:Method>)) {
517     append_method_documentation (source_resource => $memres,
518 wakaba 1.5 result_parent => $section,
519 wakaba 1.12 class_uri => $class_uri,
520     is_partial => $opt{is_partial});
521 wakaba 1.1 } elsif ($memres->is_type_uri (ExpandedURI q<DISLang:Attribute>)) {
522     append_attr_documentation (source_resource => $memres,
523 wakaba 1.5 result_parent => $section,
524 wakaba 1.12 class_uri => $class_uri,
525     is_partial => $opt{is_partial});
526 wakaba 1.8 } elsif ($memres->is_type_uri (ExpandedURI q<DISLang:ConstGroup>)) {
527 wakaba 1.3 append_constgroup_documentation (source_resource => $memres,
528 wakaba 1.5 result_parent => $section,
529 wakaba 1.12 class_uri => $class_uri,
530     is_partial => $opt{is_partial});
531 wakaba 1.1 }
532     }
533 wakaba 1.12
534     return if $opt{is_partial};
535    
536     ## Inheritance
537     append_inheritance (source_resource => $opt{source_resource},
538     result_parent => $section,
539     class_uri => $class_uri);
540    
541 wakaba 1.14 if ($opt{source_resource}->is_type_uri (ExpandedURI q<idl:AnyInterface>)) {
542     $ReferredResource{ExpandedURI q<idl:void>} ||= 1;
543     }
544 wakaba 1.1 } # append_interface_documentation
545    
546     sub append_class_documentation (%) {
547     my %opt = @_;
548 wakaba 1.5 my $section = $opt{result_parent}->create_class
549     (my $class_uri = $opt{source_resource}->uri);
550     push @ClassInheritance, $class_uri;
551 wakaba 1.2
552     add_uri ($opt{source_resource} => $section);
553 wakaba 1.1
554     my $pl_full_name = $opt{source_resource}->pl_fully_qualified_name;
555     if (defined $pl_full_name) {
556     $section->perl_package_name ($pl_full_name);
557 wakaba 1.5
558     my $path = $opt{source_resource}->get_property_text
559     (ExpandedURI q<dis:FileName>, $pl_full_name);
560 wakaba 1.1 $path =~ s#::#/#g;
561 wakaba 1.5
562 wakaba 1.1 $section->resource_file_path_stem ($path);
563     $section->set_attribute_ns
564     (ExpandedURI q<ddoct:>, 'ddoct:basePath', '../' x ($path =~ tr#/#/#));
565 wakaba 1.2 $pl_full_name =~ s/.*:://g;
566     $section->perl_name ($pl_full_name);
567 wakaba 1.1 }
568    
569     append_description (source_resource => $opt{source_resource},
570     result_parent => $section);
571    
572 wakaba 1.2 if ($opt{is_partial}) {
573     $section->resource_is_partial (1);
574     }
575    
576 wakaba 1.5 my $has_const = 0;
577 wakaba 1.11 for my $memres (@{$opt{source_resource}->get_child_resource_list}) {
578 wakaba 1.1 if ($memres->is_type_uri (ExpandedURI q<DISLang:Method>)) {
579     append_method_documentation (source_resource => $memres,
580 wakaba 1.5 result_parent => $section,
581 wakaba 1.12 class_uri => $class_uri,
582     is_partial => $opt{is_partial});
583 wakaba 1.1 } elsif ($memres->is_type_uri (ExpandedURI q<DISLang:Attribute>)) {
584     append_attr_documentation (source_resource => $memres,
585 wakaba 1.5 result_parent => $section,
586 wakaba 1.12 class_uri => $class_uri,
587     is_partial => $opt{is_partial});
588 wakaba 1.8 } elsif ($memres->is_type_uri (ExpandedURI q<DISLang:ConstGroup>)) {
589 wakaba 1.5 $has_const = 1;
590 wakaba 1.3 append_constgroup_documentation
591     (source_resource => $memres,
592 wakaba 1.5 result_parent => $section,
593 wakaba 1.12 class_uri => $class_uri,
594     is_partial => $opt{is_partial});
595 wakaba 1.1 }
596     }
597 wakaba 1.5
598 wakaba 1.12 return if $opt{is_partial};
599    
600 wakaba 1.5 ## Inheritance
601     append_inheritance (source_resource => $opt{source_resource},
602     result_parent => $section,
603     append_implements => 1,
604     class_uri => $class_uri,
605     has_const => $has_const,
606     is_class => 1);
607    
608 wakaba 1.1 } # append_class_documentation
609    
610     sub append_method_documentation (%) {
611     my %opt = @_;
612     my $perl_name = $opt{source_resource}->pl_name;
613 wakaba 1.15 my $od = $opt{result_parent}->owner_document;
614 wakaba 1.1 my $m;
615     if (defined $perl_name) {
616     $m = $opt{result_parent}->create_method ($perl_name);
617 wakaba 1.5 $ClassMembers{$opt{class_uri}}->{$perl_name}
618     = {
619     resource => $opt{source_resource},
620     type => 'method',
621     };
622 wakaba 1.1
623     } else { ## Anonymous
624     ## TODO
625     return;
626     }
627 wakaba 1.2
628     add_uri ($opt{source_resource} => $m);
629 wakaba 1.15
630     for my $con (@{$opt{source_resource}->get_property_value_list
631     (ExpandedURI q<DISCore:AnyAppName>)}) {
632     my $ns = $con->name;
633     my $ln = $1 if ($ns =~ s/(\w+)$//);
634     if ($con->isa ('Message::Util::IF::DVURIValue')) {
635     $m->append_child ($od->create_element_ns ($ns, $ln))
636     ->set_attribute_ns (ExpandedURI q<dump:>, 'dump:ref',
637     $con->string_value);
638     $ReferredResource{$con->uri} ||= 1;
639     } else {
640     $m->append_child ($od->create_element_ns ($ns, $ln))
641     ->text_content ($con->string_value);
642     }
643     }
644 wakaba 1.1
645     append_description (source_resource => $opt{source_resource},
646 wakaba 1.4 result_parent => $m,
647     method_resource => $opt{source_resource});
648 wakaba 1.1
649 wakaba 1.12 $m->resource_access ('private')
650     if $opt{source_resource}->get_property_boolean
651     (ExpandedURI q<ManakaiDOM:isForInternal>, 0);
652    
653     if ($opt{is_partial}) {
654     $m->resource_is_partial (1);
655     return;
656     }
657    
658 wakaba 1.1 my $ret = $opt{source_resource}->get_child_resource_by_type
659     (ExpandedURI q<DISLang:MethodReturn>);
660     if ($ret) {
661     my $r = $m->dis_return;
662    
663     try {
664 wakaba 1.2 $r->resource_data_type (my $u = $ret->dis_data_type_resource->uri);
665     $ReferredResource{$u} ||= 1;
666     $r->resource_actual_data_type
667     ($u = $ret->dis_actual_data_type_resource->uri);
668     $ReferredResource{$u} ||= 1;
669    
670 wakaba 1.1 ## TODO: Exceptions
671     } catch Message::Util::DIS::ManakaiDISException with {
672    
673     };
674 wakaba 1.4
675     append_description (source_resource => $ret,
676     result_parent => $r,
677     has_case => 1,
678     method_resource => $opt{source_resource});
679 wakaba 1.5
680     append_raises (source_resource => $ret,
681     result_parent => $r,
682     method_resource => $opt{source_resource});
683 wakaba 1.1 }
684    
685 wakaba 1.11 for my $cr (@{$opt{source_resource}->get_child_resource_list}) {
686 wakaba 1.1 if ($cr->is_type_uri (ExpandedURI q<DISLang:MethodParameter>)) {
687     append_param_documentation (source_resource => $cr,
688 wakaba 1.4 result_parent => $m,
689     method_resource => $opt{source_resource});
690 wakaba 1.1 }
691     }
692     } # append_method_documentation
693    
694     sub append_attr_documentation (%) {
695     my %opt = @_;
696     my $perl_name = $opt{source_resource}->pl_name;
697     my $m;
698     if (defined $perl_name) {
699     $m = $opt{result_parent}->create_attribute ($perl_name);
700 wakaba 1.5 $ClassMembers{$opt{class_uri}}->{$perl_name}
701     = {
702     resource => $opt{source_resource},
703     type => 'attr',
704     };
705 wakaba 1.1
706     } else { ## Anonymous
707     ## TODO
708     return;
709     }
710 wakaba 1.2
711     add_uri ($opt{source_resource} => $m);
712 wakaba 1.12
713     $m->resource_access ('private')
714     if $opt{source_resource}->get_property_boolean
715     (ExpandedURI q<ManakaiDOM:isForInternal>, 0);
716    
717     if ($opt{is_partial}) {
718     $m->resource_is_partial (1);
719     $m->is_read_only_attribute (1)
720     if $opt{source_resource}->get_child_resource_by_type
721     (ExpandedURI q<DISLang:AttributeSet>);
722     return;
723     }
724 wakaba 1.1
725     append_description (source_resource => $opt{source_resource},
726     result_parent => $m,
727     has_case => 1);
728    
729     my $ret = $opt{source_resource}->get_child_resource_by_type
730     (ExpandedURI q<DISLang:AttributeGet>);
731     if ($ret) {
732     my $r = $m->dis_get;
733    
734 wakaba 1.2 $r->resource_data_type (my $u = $ret->dis_data_type_resource->uri);
735     $ReferredResource{$u} ||= 1;
736     $r->resource_actual_data_type
737     ($u = $ret->dis_actual_data_type_resource->uri);
738     $ReferredResource{$u} ||= 1;
739    
740 wakaba 1.1 append_description (source_resource => $ret,
741     result_parent => $r,
742     has_case => 1);
743    
744 wakaba 1.5 append_raises (source_resource => $ret,
745     result_parent => $r);
746 wakaba 1.1 }
747    
748     my $set = $opt{source_resource}->get_child_resource_by_type
749     (ExpandedURI q<DISLang:AttributeSet>);
750     if ($set) {
751     my $r = $m->dis_set;
752    
753 wakaba 1.2 $r->resource_data_type (my $u = $set->dis_data_type_resource->uri);
754     $ReferredResource{$u} ||= 1;
755 wakaba 1.1 $r->resource_actual_data_type ($set->dis_actual_data_type_resource->uri);
756 wakaba 1.2 $ReferredResource{$u} ||= 1;
757 wakaba 1.1
758     append_description (source_resource => $set,
759     result_parent => $r,
760     has_case => 1);
761    
762 wakaba 1.5 append_raises (source_resource => $set,
763     result_parent => $r);
764 wakaba 1.1 } else {
765     $m->is_read_only_attribute (1);
766     }
767     } # append_attr_documentation
768    
769 wakaba 1.3 sub append_constgroup_documentation (%) {
770     my %opt = @_;
771     my $perl_name = $opt{source_resource}->pl_name;
772     my $m = $opt{result_parent}->create_const_group ($perl_name);
773 wakaba 1.5 $ClassMembers{$opt{class_uri}}->{$perl_name}
774     = {
775     resource => $opt{source_resource},
776     type => 'const-group',
777     };
778 wakaba 1.3
779     add_uri ($opt{source_resource} => $m);
780 wakaba 1.12
781     if ($opt{is_partial}) {
782     $m->resource_is_partial (1);
783     return;
784     }
785 wakaba 1.3
786     append_description (source_resource => $opt{source_resource},
787     result_parent => $m);
788    
789     $m->resource_data_type
790     (my $u = $opt{source_resource}->dis_data_type_resource->uri);
791     $ReferredResource{$u} ||= 1;
792     $m->resource_actual_data_type
793     ($u = $opt{source_resource}->dis_actual_data_type_resource->uri);
794     $ReferredResource{$u} ||= 1;
795    
796 wakaba 1.5 append_subclassof (source_resource => $opt{source_resource},
797     result_parent => $m);
798 wakaba 1.3
799 wakaba 1.11 for my $cr (@{$opt{source_resource}->get_child_resource_list}) {
800 wakaba 1.3 if ($cr->is_type_uri (ExpandedURI q<ManakaiDOM:Const>)) {
801     append_const_documentation (source_resource => $cr,
802     result_parent => $m);
803     }
804     }
805     } # append_constgroup_documentation
806    
807     sub append_const_documentation (%) {
808     my %opt = @_;
809     my $perl_name = $opt{source_resource}->pl_name;
810     my $m = $opt{result_parent}->create_const ($perl_name);
811    
812     add_uri ($opt{source_resource} => $m);
813    
814     append_description (source_resource => $opt{source_resource},
815     result_parent => $m);
816    
817     $m->resource_data_type
818     (my $u = $opt{source_resource}->dis_data_type_resource->uri);
819     $ReferredResource{$u} ||= 1;
820     $m->resource_actual_data_type
821     ($u = $opt{source_resource}->dis_actual_data_type_resource->uri);
822     $ReferredResource{$u} ||= 1;
823    
824     my $value = $opt{source_resource}->pl_code_fragment;
825     if ($value) {
826     $m->create_value->text_content ($value->stringify);
827     }
828    
829 wakaba 1.11 for my $cr (@{$opt{source_resource}->get_child_resource_list}) {
830 wakaba 1.3 if ($cr->is_type_uri (ExpandedURI q<ManakaiDOM:ExceptionOrWarningSubType>)) {
831     append_xsubtype_documentation (source_resource => $cr,
832     result_parent => $m);
833     }
834     }
835     ## TODO: xparam
836     } # append_const_documentation
837    
838     sub append_xsubtype_documentation (%) {
839     my %opt = @_;
840     my $m = $opt{result_parent}->create_exception_sub_code
841     ($opt{source_resource}->uri);
842     add_uri ($opt{source_resource} => $m);
843    
844     append_description (source_resource => $opt{source_resource},
845     result_parent => $m);
846    
847     ## TODO: xparam
848     } # append_xsubtype_documentation
849    
850 wakaba 1.1 sub append_param_documentation (%) {
851     my %opt = @_;
852    
853     my $is_named_param = $opt{source_resource}->get_property_boolean
854     (ExpandedURI q<DISPerl:isNamedParameter>, 0);
855    
856     my $perl_name = $is_named_param
857     ? $opt{source_resource}->pl_name
858     : $opt{source_resource}->pl_variable_name;
859    
860     my $p = $opt{result_parent}->create_parameter ($perl_name, $is_named_param);
861    
862 wakaba 1.2 add_uri ($opt{source_resource} => $p);
863    
864 wakaba 1.1 $p->is_nullable_parameter ($opt{source_resource}->pl_is_nullable);
865 wakaba 1.2 $p->resource_data_type
866     (my $u = $opt{source_resource}->dis_data_type_resource->uri);
867     $ReferredResource{$u} ||= 1;
868 wakaba 1.1 $p->resource_actual_data_type
869 wakaba 1.2 ($u = $opt{source_resource}->dis_actual_data_type_resource->uri);
870     $ReferredResource{$u} ||= 1;
871 wakaba 1.1
872     append_description (source_resource => $opt{source_resource},
873     result_parent => $p,
874 wakaba 1.4 has_case => 1,
875     method_resource => $opt{method_resource});
876 wakaba 1.1 } # append_param_documentation
877    
878     sub append_description (%) {
879     my %opt = @_;
880 wakaba 1.2
881 wakaba 1.1 my $od = $opt{result_parent}->owner_document;
882     my $resd = $opt{source_resource}->get_feature (ExpandedURI q<DIS:Doc>, '2.0');
883 wakaba 1.5 my $doc = transform_disdoc_tree
884     ($resd->get_description
885     ($od, undef,
886     $Opt{with_impl_note},
887 wakaba 1.8 parent_value_arg => $opt{source_value}),
888 wakaba 1.5 method_resource => $opt{method_resource});
889 wakaba 1.1 $opt{result_parent}->create_description->append_child ($doc);
890     ## TODO: Negotiation
891    
892 wakaba 1.3 my $fn = $resd->get_full_name ($od);
893     if ($fn) {
894     $opt{result_parent}->create_full_name
895 wakaba 1.4 ->append_child (transform_disdoc_tree
896     ($fn,
897     method_resource => $opt{method_resource}));
898 wakaba 1.3 }
899    
900 wakaba 1.12 if ($opt{has_label}) {
901     my $label = $resd->get_label ($od);
902     if ($label) {
903     if ($opt{result_parent}->can ('create_label')) {
904     $opt{result_parent}->create_label
905     ->append_child (transform_disdoc_tree ($label));
906     } else {
907     $opt{result_parent}->append_child
908     ($od->create_element_ns (ExpandedURI q<dump:>, 'label'))
909     ->append_child (transform_disdoc_tree ($label));;
910     }
911     }
912     }
913    
914 wakaba 1.1 if ($opt{has_case}) {
915 wakaba 1.11 for my $caser (@{$opt{source_resource}->get_child_resource_list}) {
916 wakaba 1.1 if ($caser->is_type_uri (ExpandedURI q<ManakaiDOM:InCase>)) {
917     my $case = $opt{result_parent}->append_case;
918     my $cased = $caser->get_feature (ExpandedURI q<DIS:Doc>, '2.0');
919     my $label = $cased->get_label ($od);
920     if ($label) {
921 wakaba 1.4 $case->create_label->append_child
922     (transform_disdoc_tree ($label,
923     method_resource => $opt{method_resource}));
924 wakaba 1.1 }
925     my $value = $caser->pl_code_fragment;
926     if ($value) {
927     $case->create_value->text_content ($value->stringify);
928     }
929 wakaba 1.3 $case->resource_data_type
930     (my $u = $caser->dis_data_type_resource->uri);
931     $ReferredResource{$u} ||= 1;
932     $case->resource_actual_data_type
933     ($u = $caser->dis_actual_data_type_resource->uri);
934     $ReferredResource{$u} ||= 1;
935    
936 wakaba 1.1 append_description (source_resource => $caser,
937 wakaba 1.4 result_parent => $case,
938     method_resource => $opt{method_resource});
939 wakaba 1.1 }
940     }
941     }
942     } # append_description
943    
944 wakaba 1.13 sub append_document_properties (%) {
945     my %opt = @_;
946     my $od = $opt{result_parent}->owner_document;
947    
948     for my $con (@{$opt{source_resource}->get_property_value_list
949     (ExpandedURI q<dis:Label>)}) {
950     my $cond = $con->get_feature (ExpandedURI q<DIS:Doc>, '2.0');
951     my $tree = $cond->get_disdoc_tree
952     ($od, ExpandedURI q<lang:disdocInline>,
953     $opt{source_resource}->database,
954     default_name_uri => $opt{source_resource}->source_node_id,
955     default_for_uri => $opt{source_resource}->for_uri);
956     my $ns = $con->name;
957     my $ln = $1 if ($ns =~ s/(\w+)$//);
958     $opt{result_parent}->append_child ($od->create_element_ns ($ns, $ln))
959     ->append_child (transform_disdoc_tree ($tree));
960     }
961     } # append_document_properties
962    
963 wakaba 1.3 sub transform_disdoc_tree ($;%) {
964     my ($el, %opt) = @_;
965     my @el = ($el);
966     EL: while (defined (my $el = shift @el)) {
967     if ($el->node_type == $el->ELEMENT_NODE and
968     defined $el->namespace_uri) {
969     my $mmParsed = $el->get_attribute_ns (ExpandedURI q<ddel:>, 'mmParsed');
970     if ($mmParsed) {
971     my $lextype = $el->get_attribute_ns (ExpandedURI q<ddel:>, 'lexType');
972 wakaba 1.8 if ($lextype eq ExpandedURI q<DISCore:TFQNames>) {
973 wakaba 1.4 my $uri = dd_get_tfqnames_uri ($el);
974     if (defined $uri) {
975     $ReferredResource{$uri} ||= 1;
976     next EL;
977     }
978 wakaba 1.8 } elsif ($lextype eq ExpandedURI q<DISCore:QName> or
979 wakaba 1.5 $lextype eq ExpandedURI q<DISCore:NCNameOrQName>) {
980     my $uri = dd_get_qname_uri ($el);
981     if (defined $uri) {
982     $ReferredResource{$uri} ||= 1;
983     next EL;
984     }
985 wakaba 1.8 } elsif ($lextype eq ExpandedURI q<DISLang:MemberRef> or
986     $lextype eq ExpandedURI q<dx:XCRef>) {
987 wakaba 1.4 my @nm = @{$el->get_elements_by_tag_name_ns
988     (ExpandedURI q<ddel:>, 'name')};
989     if (@nm == 1) {
990 wakaba 1.5 my $uri = dd_get_tfqnames_uri ($nm[0]);
991     if (defined $uri) {
992     $el->set_attribute_ns (ExpandedURI q<dump:>, 'dump:uri', $uri);
993     $ReferredResource{$uri} ||= 1;
994     next EL;
995     }
996     } elsif (@nm == 3) {
997     my $uri = dd_get_tfqnames_uri ($nm[2]);
998 wakaba 1.4 if (defined $uri) {
999 wakaba 1.5 $el->set_attribute_ns (ExpandedURI q<dump:>, 'dump:uri', $uri);
1000 wakaba 1.4 $ReferredResource{$uri} ||= 1;
1001     next EL;
1002     }
1003     } elsif (@nm == 2) {
1004     my $uri = dd_get_tfqnames_uri ($nm[0]);
1005     if (not defined $uri) {
1006     #
1007     } elsif ($nm[1]->get_elements_by_tag_name_ns
1008     (ExpandedURI q<ddel:>, 'prefix')->[0]) {
1009     #my $luri = dd_get_qname_uri ($nm[1]);
1010     ## QName: Currently not used
1011     } else {
1012     my $lnel = $nm[1]->get_elements_by_tag_name_ns
1013     (ExpandedURI q<ddel:>, 'localName')->[0];
1014     my $lname = $lnel ? $lnel->text_content : '';
1015 wakaba 1.5 my $res;
1016 wakaba 1.8 if ($lextype eq ExpandedURI q<dx:XCRef> or
1017 wakaba 1.5 {
1018     ExpandedURI q<ddel:C> => 1,
1019     ExpandedURI q<ddel:X> => 1,
1020     }->{$el->namespace_uri . $el->local_name}) {
1021     ## NOTE: $db
1022     $res = $db->get_resource ($uri)
1023     ->get_const_resource_by_name ($lname);
1024     } else {
1025     ## NOTE: $db
1026     $res = $db->get_resource ($uri)
1027     ->get_child_resource_by_name_and_type
1028 wakaba 1.4 ($lname, ExpandedURI q<DISLang:AnyMethod>);
1029 wakaba 1.5 }
1030 wakaba 1.4 if ($res) {
1031     $el->set_attribute_ns
1032     (ExpandedURI q<dump:>, 'dump:uri', $res->uri);
1033     $ReferredResource{$res->uri} ||= 1;
1034     }
1035     next EL;
1036     }
1037     }
1038     } # lextype
1039     } # mmParsed
1040     elsif ($opt{method_resource} and
1041     $el->namespace_uri eq ExpandedURI q<ddel:> and
1042     $el->local_name eq 'P') {
1043     my $res = $opt{method_resource}
1044     ->get_child_resource_by_name_and_type
1045     ($el->text_content, ExpandedURI q<DISLang:MethodParameter>);
1046     if ($res) {
1047     $el->set_attribute_ns
1048     (ExpandedURI q<dump:>, 'dump:uri', $res->uri);
1049     $ReferredResource{$res->uri} ||= 1;
1050 wakaba 1.3 }
1051 wakaba 1.4 next EL;
1052 wakaba 1.3 }
1053 wakaba 1.4 push @el, @{$el->child_nodes};
1054 wakaba 1.3 } elsif ($el->node_type == $el->DOCUMENT_FRAGMENT_NODE or
1055     $el->node_type == $el->DOCUMENT_NODE) {
1056 wakaba 1.4 push @el, @{$el->child_nodes};
1057 wakaba 1.3 }
1058     } # EL
1059     $el;
1060     } # transform_disdoc_tree
1061    
1062 wakaba 1.4 sub dd_get_tfqnames_uri ($;%) {
1063     my ($el, %opt) = @_;
1064     return '' unless $el;
1065     my $turi = dd_get_qname_uri ($el->get_elements_by_tag_name_ns
1066     (ExpandedURI q<ddel:>, 'nameQName')->[0]);
1067     my $furi = dd_get_qname_uri ($el->get_elements_by_tag_name_ns
1068     (ExpandedURI q<ddel:>, 'forQName')->[0]);
1069     return undef if not defined $turi or not defined $furi;
1070     my $uri = tfuris2uri ($turi, $furi);
1071     $el->set_attribute_ns (ExpandedURI q<dump:>, 'dump:uri', $uri);
1072     $uri;
1073     } # dd_get_tfqnames_uri
1074 wakaba 1.3
1075     sub dd_get_qname_uri ($;%) {
1076     my ($el, %opt) = @_;
1077 wakaba 1.4 return undef unless $el;
1078 wakaba 1.3 my $plel = $el->get_elements_by_tag_name_ns
1079     (ExpandedURI q<ddel:>, 'prefix')->[0];
1080     my $lnel = $el->get_elements_by_tag_name_ns
1081     (ExpandedURI q<ddel:>, 'localName')->[0];
1082     my $nsuri = ($plel ? $plel : $el)->lookup_namespace_uri
1083     ($plel ? $plel->text_content : undef);
1084     $nsuri = '' unless defined $nsuri;
1085     if ($plel and $nsuri eq '') {
1086     $plel->remove_attribute_ns
1087 wakaba 1.4 (ExpandedURI q<xmlns:>, $plel->text_content);
1088     $el->set_attribute_ns (ExpandedURI q<dump:>, 'dump:namespaceURI', $nsuri);
1089     return undef;
1090     } else {
1091     $el->set_attribute_ns (ExpandedURI q<dump:>, 'dump:namespaceURI', $nsuri);
1092 wakaba 1.3 }
1093 wakaba 1.15 my $r;
1094 wakaba 1.3 if ($lnel) {
1095 wakaba 1.15 $r = $nsuri . $lnel->text_content;
1096 wakaba 1.3 } else {
1097 wakaba 1.15 $r = $el->get_attribute_ns (ExpandedURI q<ddel:>, 'defaultURI');
1098 wakaba 1.3 }
1099 wakaba 1.15 $el->set_attribute_ns (ExpandedURI q<dump:>, 'dump:uri', $r);
1100     $r;
1101 wakaba 1.3 } # dd_get_qname_uri
1102    
1103     sub tfuris2uri ($$) {
1104     my ($turi, $furi) = @_;
1105     my $uri;
1106 wakaba 1.5 if ($furi eq ExpandedURI q<ManakaiDOM:all>) {
1107 wakaba 1.3 $uri = $turi;
1108     } else {
1109     my $__turi = $turi;
1110     my $__furi = $furi;
1111     for my $__uri ($__turi, $__furi) {
1112 wakaba 1.12 $__uri =~ s{([^0-9A-Za-z!\$'()*,:;=?\@_./~-])}{sprintf '%%%02X', ord $1}ge;
1113 wakaba 1.3 }
1114 wakaba 1.12 $uri = qq<tag:suika.fam.cx,2005-09:$__turi+$__furi>;
1115 wakaba 1.3 }
1116     $uri;
1117     } # tfuris2uri
1118    
1119 wakaba 1.1 sub append_inheritance (%) {
1120     my %opt = @_;
1121     if (($opt{depth} ||= 0) == 100) {
1122     warn "<".$opt{source_resource}->uri.">: Loop in inheritance";
1123     return;
1124     }
1125 wakaba 1.5
1126     my $has_isa = 0;
1127 wakaba 1.1
1128     for my $isa (@{$opt{source_resource}->get_property_resource_list
1129     (ExpandedURI q<dis:ISA>,
1130 wakaba 1.8 default_media_type => ExpandedURI q<DISCore:TFQNames>)}) {
1131 wakaba 1.5 $has_isa = 1;
1132 wakaba 1.1 append_inheritance
1133     (source_resource => $isa,
1134     result_parent => $opt{result_parent}->append_new_extends ($isa->uri),
1135 wakaba 1.5 depth => $opt{depth} + 1,
1136     is_class => $opt{is_class});
1137     $ReferredResource{$isa->uri} ||= 1;
1138     if ($opt{class_uri}) {
1139     unshift @ClassInheritance, $isa->uri;
1140     push @{$ClassInheritance{$opt{class_uri}} ||= []}, $isa->uri;
1141     }
1142     }
1143    
1144     if ($opt{source_resource}->is_defined) {
1145     for my $isa_pack (@{$opt{source_resource}->pl_additional_isa_packages}) {
1146     my $isa;
1147     if ($isa_pack eq 'Message::Util::Error') {
1148     ## NOTE: $db
1149     $isa = $db->get_resource (ExpandedURI q<ecore:MUError>,
1150     for_arg => ExpandedURI q<ManakaiDOM:Perl>);
1151     } elsif ($isa_pack eq 'Tie::Array') {
1152     ## NOTE: $db
1153     $isa = $db->get_resource (ExpandedURI q<DISPerl:TieArray>);
1154     } elsif ($isa_pack eq 'Error') {
1155     ## NOTE: $db
1156     $isa = $db->get_resource (ExpandedURI q<ecore:Error>,
1157     for_arg => ExpandedURI q<ManakaiDOM:Perl>);
1158     } else {
1159     ## TODO: What to do?
1160     }
1161     if ($isa) {
1162     $has_isa = 1;
1163     append_inheritance
1164     (source_resource => $isa,
1165     result_parent => $opt{result_parent}->append_new_extends ($isa->uri),
1166     depth => $opt{depth} + 1,
1167     is_class => $opt{is_class});
1168     $ReferredResource{$isa->uri} ||= 1;
1169     if ($opt{class_uri}) {
1170     unshift @ClassInheritance, $isa->uri;
1171     push @{$ClassInheritance{$opt{class_uri}} ||= []}, $isa->uri;
1172     }
1173     }
1174     }} # AppISA
1175    
1176     if ($opt{has_const}) {
1177     ## NOTE: $db
1178     my $isa = $db->get_resource (ExpandedURI q<DISPerl:Exporter>);
1179     append_inheritance
1180     (source_resource => $isa,
1181     result_parent => $opt{result_parent}->append_new_extends ($isa->uri),
1182     depth => $opt{depth} + 1,
1183     is_class => $opt{is_class});
1184     $ReferredResource{$isa->uri} ||= 1;
1185     if ($opt{class_uri}) {
1186     unshift @ClassInheritance, $isa->uri;
1187     push @{$ClassInheritance{$opt{class_uri}} ||= []}, $isa->uri;
1188     }
1189     }
1190    
1191     if (not $has_isa and $opt{is_class} and
1192     $opt{source_resource}->uri ne ExpandedURI q<DISPerl:UNIVERSAL>) {
1193     ## NOTE: $db
1194     my $isa = $db->get_resource (ExpandedURI q<DISPerl:UNIVERSAL>);
1195     append_inheritance
1196     (source_resource => $isa,
1197     result_parent => $opt{result_parent}->append_new_extends ($isa->uri),
1198     depth => $opt{depth} + 1,
1199     is_class => $opt{is_class});
1200 wakaba 1.2 $ReferredResource{$isa->uri} ||= 1;
1201 wakaba 1.5 if ($opt{class_uri}) {
1202     unshift @ClassInheritance, $isa->uri;
1203     push @{$ClassInheritance{$opt{class_uri}} ||= []}, $isa->uri;
1204     }
1205 wakaba 1.1 }
1206    
1207     if ($opt{append_implements}) {
1208 wakaba 1.5 ## NOTE: $db
1209     my $u = $db->get_resource (ExpandedURI q<DISPerl:UNIVERSALInterface>);
1210 wakaba 1.1 for my $impl (@{$opt{source_resource}->get_property_resource_list
1211     (ExpandedURI q<dis:Implement>,
1212 wakaba 1.8 default_media_type => ExpandedURI q<DISCore:TFQNames>,
1213 wakaba 1.5 isa_recursive => 1)}, $u) {
1214 wakaba 1.1 append_inheritance
1215     (source_resource => $impl,
1216     result_parent => $opt{result_parent}->append_new_implements
1217     ($impl->uri),
1218     depth => $opt{depth});
1219 wakaba 1.2 $ReferredResource{$impl->uri} ||= 1;
1220 wakaba 1.5 $ClassImplements{$opt{class_uri}}->{$impl->uri} = 1
1221     if $opt{class_uri};
1222 wakaba 1.1 }
1223     }
1224     } # append_inheritance
1225    
1226 wakaba 1.5 sub append_subclassof (%) {
1227     my %opt = @_;
1228    
1229     ## NOTE: This subroutine directly access to internal structure
1230     ## of ManakaiDISResourceDefinition
1231    
1232     my $a;
1233     $a = sub ($$) {
1234     my ($gdb, $s) = @_;
1235     my %s = keys %$s;
1236     while (my $i = [keys %s]->[0]) {
1237     ## Removes itself
1238     delete $s->{$i};
1239     #warn $i;
1240    
1241     my $ires = $gdb->get_resource ($i);
1242     for my $j (keys %$s) {
1243     next if $i eq $j;
1244     if ($ires->{subOf}->{$j}) {
1245     $s->{$i}->{$j} = $s->{$j};
1246     delete $s->{$j};
1247     delete $s{$j};
1248     }
1249     }
1250    
1251     delete $s{$i};
1252     } # %s
1253    
1254     for my $i (keys %$s) {
1255     $a->($s->{$i}) if keys %{$s->{$i}};
1256     }
1257     };
1258    
1259     my $b;
1260     $b = sub ($$) {
1261     my ($s, $p) = @_;
1262     for my $i (keys %$s) {
1263     my $el = $p->append_new_sub_class_of ($i);
1264     $b->($s->{$i}, $el) if keys %{$s->{$i}};
1265     }
1266     };
1267    
1268    
1269     my $sub = {$opt{source_resource}->uri =>
1270     {map {$_ => {}} keys %{$opt{source_resource}->{subOf}}}};
1271     ## NOTE: $db
1272     $a->($db, $sub);
1273     $b->($sub, $opt{result_parent});
1274     } # append_subclassof
1275    
1276 wakaba 1.2 sub add_uri ($$;%) {
1277     my ($res, $el, %opt) = @_;
1278     my $canon_uri = $res->uri;
1279     for my $uri (@{$res->uris}) {
1280     $el->add_uri ($uri, $canon_uri eq $uri ? 0 : 1);
1281     $ReferredResource{$uri} = -1;
1282     }
1283 wakaba 1.3
1284     my $nsuri = $res->namespace_uri;
1285     $el->resource_namespace_uri ($nsuri) if defined $nsuri;
1286     my $lname = $res->local_name;
1287     $el->resource_local_name ($lname) if defined $lname;
1288 wakaba 1.2 } # add_uri
1289    
1290 wakaba 1.5 sub append_raises (%) {
1291     my %opt = @_;
1292    
1293 wakaba 1.8 for my $el (@{$opt{source_resource}->get_property_value_list
1294     (ExpandedURI q<dx:raises>)}) {
1295     next unless $el->isa ('Message::Util::IF::DVURIValue');
1296     my $e = $el->get_resource ($db);
1297     my ($a, $b, $c); ## NOTE: $db
1298     if ($e->is_type_uri (ExpandedURI q<ManakaiDOM:ExceptionOrWarningSubType>)) {
1299     $c = $e;
1300 wakaba 1.10 $b = $c->parent_resource;
1301     $a = $b->parent_resource->parent_resource;
1302 wakaba 1.8 } elsif ($e->is_type_uri (ExpandedURI q<DISLang:Const>)) {
1303     $b = $e;
1304 wakaba 1.10 $a = $b->parent_resource->parent_resource;
1305 wakaba 1.8 } else {
1306     $a = $e;
1307     }
1308     my $rel = $opt{result_parent}->create_raises
1309 wakaba 1.5 ($a->uri, $b ? $b->uri : undef, $c ? $c->uri : undef);
1310    
1311 wakaba 1.8 append_description (source_resource => $opt{source_resource},
1312     source_value => $el,
1313     result_parent => $rel,
1314     method_resource => $opt{method_resource});
1315 wakaba 1.5 }
1316     } # append_raises
1317 wakaba 1.4
1318    
1319 wakaba 1.1 my $doc = $impl->create_disdump_document;
1320    
1321     my $body = $doc->document_element;
1322    
1323 wakaba 1.4 ## -- Outputs requested modules
1324    
1325 wakaba 1.12 for my $res_nuri (keys %{$Opt{resource_uri}}) {
1326     for my $res_furi (keys %{$Opt{resource_uri}->{$res_nuri}}) {
1327     $res_furi = ExpandedURI q<ManakaiDOM:all> unless length $res_furi;
1328     my $res = $db->get_resource ($res_nuri, for_arg => $res_furi);
1329     unless ($res->is_defined) {
1330     die qq{$0: Resource <$res_nuri> for <$res_furi> is not defined};
1331 wakaba 1.4 }
1332    
1333 wakaba 1.12 if ($res->is_type_uri (ExpandedURI q<doc:Documentation>)) {
1334     status_msg_ qq<Document <$res_nuri> for <$res_furi>...>;
1335    
1336     append_document_documentation
1337     (result_parent => $body,
1338     source_resource => $res);
1339 wakaba 1.4
1340 wakaba 1.12 status_msg qq<done>;
1341     } elsif ($res->is_type_uri (ExpandedURI q<dis:ModuleGroup>)) {
1342     status_msg qq<Module group <$res_nuri> for <$res_furi>...>;
1343    
1344     append_module_group_documentation
1345     (result_parent => $body,
1346     source_resource => $res);
1347    
1348     status_msg qq<done>;
1349     } else {
1350     die qq{$0: --resource-uri: Resource <$res_nuri> for <$res_furi>}.
1351     qq{ is not a resource set};
1352     }
1353     } # res_furi
1354     } # res_nuri
1355 wakaba 1.5
1356 wakaba 1.12 for my $mod_uri (keys %{$Opt{module_uri}}) {
1357     for my $mod_for (keys %{$Opt{module_uri}->{$mod_uri}}) {
1358     $mod_for = $Opt{For} unless length $mod_for;
1359     my $mod = $db->get_module ($mod_uri, for_arg => $mod_for);
1360     unless (defined $mod_for) {
1361     $mod_for = $mod->get_property_text (ExpandedURI q<dis:DefaultFor>);
1362     if (defined $mod_for) {
1363     $mod = $db->get_module ($mod_uri, for_arg => $mod_for);
1364     }
1365     }
1366     unless ($mod->is_defined) {
1367     die qq<$0: Module <$mod_uri> for <$mod_for> is not defined>;
1368     }
1369    
1370     status_msg qq<Module <$mod_uri> for <$mod_for>...>;
1371     progress_reset;
1372    
1373     append_module_documentation
1374     (result_parent => $body,
1375     source_resource => $mod);
1376    
1377     status_msg qq<done>;
1378     } # mod_for
1379 wakaba 1.4 } # mod_uri
1380    
1381     ## -- Outputs referenced resources in external modules
1382 wakaba 1.2
1383 wakaba 1.5 status_msg q<Other modules...>;
1384 wakaba 1.7 progress_reset;
1385 wakaba 1.5
1386 wakaba 1.10 my %debug_res_list;
1387 wakaba 1.2 while (my @ruri = grep {$ReferredResource{$_} > 0} keys %ReferredResource) {
1388     U: while (defined (my $uri = shift @ruri)) {
1389     next U if $ReferredResource{$uri} < 0; ## Already done
1390 wakaba 1.10 if ($Opt{debug}) {
1391     warn "Resource <$uri>: $debug_res_list{$uri} times\n"
1392     if ++$debug_res_list{$uri} > 10;
1393     }
1394 wakaba 1.7 progress_inc;
1395 wakaba 1.2 my $res = $db->get_resource ($uri);
1396     unless ($res->is_defined) {
1397     $res = $db->get_module ($uri);
1398     unless ($res->is_defined) {
1399     $ReferredResource{$uri} = -1;
1400     next U;
1401     }
1402 wakaba 1.14 progress_reset;
1403     status_msg qq<Module <$uri>...>;
1404 wakaba 1.2 append_module_documentation
1405     (result_parent => $body,
1406     source_resource => $res,
1407 wakaba 1.14 is_partial => ($ReferredResource{$uri} == 1));
1408     status_msg qq<done>;
1409     progress_reset;
1410 wakaba 1.8 } elsif ($res->is_type_uri (ExpandedURI q<DISLang:Class>)) {
1411 wakaba 1.2 my $mod = $res->owner_module;
1412 wakaba 1.14 my $mod_uri = $mod->uri;
1413     unless ($ReferredResource{$mod_uri} < 0) {
1414     $ReferredResource{$mod_uri} = $ReferredResource{$uri}
1415     if $ReferredResource{$mod_uri} < $ReferredResource{$uri};
1416 wakaba 1.2 unshift @ruri, $uri;
1417 wakaba 1.14 unshift @ruri, $mod_uri;
1418 wakaba 1.2 next U;
1419     }
1420     append_class_documentation
1421 wakaba 1.14 (result_parent => $body->create_module ($mod_uri),
1422     source_resource => $res,
1423     is_partial => ($ReferredResource{$uri} == 1));
1424     } elsif ($res->is_type_uri (ExpandedURI q<DISLang:Interface>)) {
1425     my $mod = $res->owner_module;
1426     my $mod_uri = $mod->uri;
1427     unless ($ReferredResource{$mod_uri} < 0) {
1428     $ReferredResource{$mod_uri} = $ReferredResource{$uri}
1429     if $ReferredResource{$mod_uri} < $ReferredResource{$uri};
1430     unshift @ruri, $uri;
1431     unshift @ruri, $mod_uri;
1432     next U;
1433     }
1434     append_interface_documentation
1435 wakaba 1.2 (result_parent => $body->create_module ($mod->uri),
1436     source_resource => $res,
1437 wakaba 1.14 is_partial => ($ReferredResource{$uri} == 1));
1438     } elsif ($res->is_type_uri (ExpandedURI q<DISCore:AnyType>)) {
1439 wakaba 1.2 my $mod = $res->owner_module;
1440     unless ($mod->is_defined) {
1441     $ReferredResource{$uri} = -1;
1442     next U;
1443     } elsif (not ($ReferredResource{$mod->uri} < 0)) {
1444     unshift @ruri, $uri;
1445     unshift @ruri, $mod->uri;
1446     next U;
1447     }
1448 wakaba 1.14 append_datatype_documentation
1449 wakaba 1.2 (result_parent => $body->create_module ($mod->uri),
1450 wakaba 1.14 source_resource => $res);
1451 wakaba 1.3 } elsif ($res->is_type_uri (ExpandedURI q<DISLang:AnyMethod>) or
1452 wakaba 1.8 $res->is_type_uri (ExpandedURI q<DISLang:ConstGroup>)) {
1453 wakaba 1.10 my $cls = $res->parent_resource;
1454 wakaba 1.15 unless ($cls) {
1455     $ReferredResource{$res->uri} = -1;
1456     next U;
1457     }
1458 wakaba 1.2 if (not ($ReferredResource{$cls->uri} < 0) and
1459 wakaba 1.8 ($cls->is_type_uri (ExpandedURI q<DISLang:Class>) or
1460     $cls->is_type_uri (ExpandedURI q<DISLang:Interface>))) {
1461 wakaba 1.2 unshift @ruri, $uri;
1462     unshift @ruri, $cls->uri;
1463     next U;
1464     }
1465     my $model = $body->create_module ($cls->owner_module->uri);
1466 wakaba 1.8 my $clsel = $cls->is_type_uri (ExpandedURI q<DISLang:Class>)
1467 wakaba 1.2 ? $model->create_class ($cls->uri)
1468     : $model->create_interface ($cls->uri);
1469     if ($res->is_type_uri (ExpandedURI q<DISLang:Method>)) {
1470     append_method_documentation
1471     (result_parent => $clsel,
1472     source_resource => $res);
1473 wakaba 1.3 } elsif ($res->is_type_uri (ExpandedURI q<DISLang:Attribute>)) {
1474 wakaba 1.2 append_attr_documentation
1475 wakaba 1.3 (result_parent => $clsel,
1476     source_resource => $res);
1477 wakaba 1.8 } elsif ($res->is_type_uri (ExpandedURI q<DISLang:ConstGroup>)) {
1478 wakaba 1.3 append_constgroup_documentation
1479     (result_parent => $clsel,
1480 wakaba 1.2 source_resource => $res);
1481 wakaba 1.8 } else {
1482     $ReferredResource{$res->uri} = -1;
1483 wakaba 1.2 }
1484     } elsif ($res->is_type_uri (ExpandedURI q<DISLang:MethodParameter>)) {
1485 wakaba 1.10 my $m = $res->parent_resource;
1486 wakaba 1.2 if (not ($ReferredResource{$m->uri} < 0) and
1487     $m->is_type_uri (ExpandedURI q<DISLang:Method>)) {
1488     unshift @ruri, $m->uri;
1489 wakaba 1.4 $ReferredResource{$res->uri} = -1;
1490 wakaba 1.2 next U;
1491 wakaba 1.10 } else {
1492     $ReferredResource{$res->uri} = -1;
1493     }
1494 wakaba 1.8 } elsif ($res->is_type_uri (ExpandedURI q<DISLang:Const>)) {
1495 wakaba 1.10 my $m = $res->parent_resource;
1496 wakaba 1.3 if (not ($ReferredResource{$m->uri} < 0) and
1497 wakaba 1.8 $m->is_type_uri (ExpandedURI q<DISLang:ConstGroup>)) {
1498 wakaba 1.3 unshift @ruri, $m->uri;
1499 wakaba 1.4 $ReferredResource{$res->uri} = -1;
1500 wakaba 1.3 next U;
1501 wakaba 1.8 } else {
1502     $ReferredResource{$res->uri} = -1;
1503     next U;
1504     }
1505 wakaba 1.3 } elsif ($res->is_type_uri
1506     (ExpandedURI q<ManakaiDOM:ExceptionOrWarningSubType>)) {
1507 wakaba 1.10 my $m = $res->parent_resource;
1508 wakaba 1.3 if (not ($ReferredResource{$m->uri} < 0) and
1509 wakaba 1.8 $m->is_type_uri (ExpandedURI q<DISLang:Const>)) {
1510 wakaba 1.3 unshift @ruri, $m->uri;
1511 wakaba 1.4 $ReferredResource{$res->uri} = -1;
1512 wakaba 1.3 next U;
1513 wakaba 1.8 } else {
1514     $ReferredResource{$res->uri} = -1;
1515     next U;
1516     }
1517 wakaba 1.12 } elsif ($res->is_type_uri (ExpandedURI q<doc:Documentation>)) {
1518     append_document_documentation (source_resource => $res,
1519     result_parent => $body);
1520 wakaba 1.2 } else { ## Unsupported type
1521     $ReferredResource{$uri} = -1;
1522     }
1523     } # U
1524     }
1525    
1526 wakaba 1.8 status_msg '';
1527 wakaba 1.5 status_msg q<done>;
1528    
1529     ## -- Inheriting methods information
1530 wakaba 1.1
1531 wakaba 1.5 {
1532     verbose_msg_ q<Adding inheritance information...>;
1533     my %class_done;
1534     for my $class_uri (@ClassInheritance) {
1535     next if $class_done{$class_uri};
1536     $class_done{$class_uri};
1537     for my $sclass_uri (@{$ClassInheritance{$class_uri}}) {
1538     for my $scm_name (keys %{$ClassMembers{$sclass_uri}}) {
1539     if ($ClassMembers{$class_uri}->{$scm_name}) {
1540     $ClassMembers{$class_uri}->{$scm_name}->{overrides}
1541     ->{$ClassMembers{$sclass_uri}->{$scm_name}->{resource}->uri} = 1;
1542     } else {
1543     $ClassMembers{$class_uri}->{$scm_name}
1544     = {
1545     %{$ClassMembers{$sclass_uri}->{$scm_name}},
1546     is_inherited => 1,
1547     };
1548     }
1549     }
1550     } # superclasses
1551     } # classes
1552 wakaba 1.1
1553 wakaba 1.8 verbose_msg_ q<...>;
1554    
1555 wakaba 1.5 for my $class_uri (keys %ClassImplements) {
1556     for my $if_uri (keys %{$ClassImplements{$class_uri}||{}}) {
1557     for my $mem_name (keys %{$ClassMembers{$if_uri}}) {
1558     unless ($ClassMembers{$class_uri}->{$mem_name}) {
1559     ## Not defined - error
1560     $ClassMembers{$class_uri}->{$mem_name}
1561     = {
1562     %{$ClassMembers{$if_uri}->{$mem_name}},
1563     is_inherited => 1,
1564     };
1565     }
1566     $ClassMembers{$class_uri}->{$mem_name}->{implements}
1567     ->{$ClassMembers{$if_uri}->{$mem_name}->{resource}->uri} = 1;
1568     }
1569     } # interfaces
1570     } # classes
1571    
1572 wakaba 1.8 verbose_msg_ q<...>;
1573    
1574 wakaba 1.5 for my $class_uri (keys %ClassMembers) {
1575     my $cls_res = $db->get_resource ($class_uri);
1576     next unless $cls_res->is_defined;
1577     verbose_msg_ q<.>;
1578     my $cls_el = $body->create_module ($cls_res->owner_module->uri);
1579 wakaba 1.8 if ($cls_res->is_type_uri (ExpandedURI q<DISLang:Interface>)) {
1580 wakaba 1.5 $cls_el = $cls_el->create_interface ($class_uri);
1581     } else {
1582     $cls_el = $cls_el->create_class ($class_uri);
1583     }
1584     for my $mem_name (keys %{$ClassMembers{$class_uri}}) {
1585     my $mem_info = $ClassMembers{$class_uri}->{$mem_name};
1586     my $el;
1587     if ($mem_info->{type} eq 'const-group') {
1588     $el = $cls_el->create_const_group ($mem_name);
1589     } elsif ($mem_info->{type} eq 'attr') {
1590     $el = $cls_el->create_attribute ($mem_name);
1591     } else {
1592     $el = $cls_el->create_method ($mem_name);
1593     }
1594     if ($mem_info->{is_inherited}) {
1595     $el->ref ($mem_info->{resource}->uri);
1596     }
1597     for my $or (keys %{$mem_info->{overrides}||{}}) {
1598     $el->append_new_overrides ($or);
1599     }
1600     for my $or (keys %{$mem_info->{implements}||{}}) {
1601     $el->append_new_implements ($or);
1602     }
1603     } # members
1604     } # classes
1605    
1606     verbose_msg q<done>;
1607     undef %ClassMembers;
1608     }
1609    
1610     {
1611     status_msg_ qq<Writing file ""...>;
1612    
1613     require Encode;
1614     my $lsimpl = $impl->get_feature (ExpandedURI q<DOMLS:LS> => '3.0');
1615     my $serializer = $lsimpl->create_mls_serializer
1616 wakaba 1.1 ({ExpandedURI q<DOMLS:SerializeDocumentInstance> => ''});
1617 wakaba 1.10 print STDOUT Encode::encode ('utf8', $serializer->write_to_string ($doc));
1618 wakaba 1.5 close STDOUT;
1619     status_msg qq<done>;
1620 wakaba 1.9 $doc->free;
1621 wakaba 1.5 }
1622 wakaba 1.1
1623     verbose_msg_ qq<Checking undefined resources...>;
1624     $db->check_undefined_resource;
1625     verbose_msg qq<done>;
1626    
1627     verbose_msg_ qq<Closing database...>;
1628 wakaba 1.5 $db->free;
1629 wakaba 1.1 undef $db;
1630     verbose_msg qq<done>;
1631    
1632 wakaba 1.8 {
1633     use integer;
1634     my $time = time - $start_time;
1635     status_msg sprintf qq<%d'%02d''>, $time / 60, $time % 60;
1636     }
1637    
1638 wakaba 1.10 exit;
1639    
1640 wakaba 1.5 END {
1641     $db->free if $db;
1642     }
1643    
1644 wakaba 1.10 sub dac_search_file_path_stem ($$$) {
1645     my ($ns, $ln, $suffix) = @_;
1646     require Cwd;
1647     require File::Spec;
1648     for my $dir ('.', @{$Opt{input_search_path}->{$ns}||[]}) {
1649     my $name = Cwd::abs_path
1650     (File::Spec->canonpath
1651     (File::Spec->catfile ($dir, $ln)));
1652     if (-f $name.$suffix) {
1653     return $name;
1654     }
1655     }
1656     return undef;
1657     } # dac_search_file_path_stem;
1658    
1659 wakaba 1.1 =head1 SEE ALSO
1660    
1661     L<lib/manakai/dis.pl> and L<bin/cdis2pm.pl> - Old version of
1662     this script.
1663    
1664 wakaba 1.5 L<lib/Message/Util/DIS.dis> - The I<dis> object implementation.
1665 wakaba 1.1
1666     L<lib/Message/Util/PerlCode.dis> - The Perl code generator.
1667    
1668     L<lib/manakai/DISCore.dis> - The definition for the "dis" format.
1669    
1670     L<lib/manakai/DISPerl.dis> - The definition for the "dis" Perl-specific
1671     vocabulary.
1672    
1673     =head1 LICENSE
1674    
1675     Copyright 2004-2005 Wakaba <w@suika.fam.cx>. All rights reserved.
1676    
1677     This program is free software; you can redistribute it and/or
1678     modify it under the same terms as Perl itself.
1679    
1680     =cut
1681    
1682 wakaba 1.15 1; # $Date: 2005/10/02 23:35:32 $

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24