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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.8 - (hide annotations) (download)
Fri Sep 23 18:24:52 2005 UTC (19 years, 2 months ago) by wakaba
Branch: MAIN
Changes since 1.7: +88 -75 lines
File MIME type: text/plain
++ manakai/doc/ChangeLog	23 Sep 2005 17:22:30 -0000
2005-09-23  Wakaba  <wakaba@suika.fam.cx>

	* Makefile: Command-line arguments for new modules added.
	(DAC_PREFIX): Changed to ".dad".

++ manakai/bin/ChangeLog	23 Sep 2005 17:21:35 -0000
2005-09-24  Wakaba  <wakaba@suika.fam.cx>

	* dac.pl, dac2pm.pl, mkdisdump.pl: "--debug" option added.

2005-09-23  Wakaba  <wakaba@suika.fam.cx>

	* mkdisdump.pl: Fixed to support new dad database implementation.

++ manakai/lib/Message/Util/ChangeLog	23 Sep 2005 17:29:45 -0000
2005-09-23  Wakaba  <wakaba@suika.fam.cx>

	* DIS.dis (DISParser.new): New method.
	(hasFeature): Removed.  ManakaiDISAnyResource now
	extends DOMFeature:ManakaiHasFeatureByGetFeature.
	(readProperties): Support for property value data
	types DISLang:MemberRef and dx:XCRef added.
	(ManakaiDISExceptionTarget): It is now an alias
	for dx:ManakaiDefaultExceptionHandler.

++ manakai/lib/Message/Util/Error/ChangeLog	23 Sep 2005 17:41:25 -0000
2005-09-23  Wakaba  <wakaba@suika.fam.cx>

	* DOMException.dis (dx:raises): Properties dis:dataType
	and dis:multipleProperties added.

++ manakai/lib/Message/Util/DIS/ChangeLog	23 Sep 2005 17:40:22 -0000
2005-09-23  Wakaba  <wakaba@suika.fam.cx>

	* DISDoc.dis: Modified to support new "dad" implementation.
	(DISElementDISDoc): Removed.
	(DVValueDISDoc): New.
	(documentionGroupId): This attribute values now
	do not include element type names.

	* DNLite.dis (convertDISDocumentToDNLDocument): Fixed
	not to "tie" happens to cause strange segmentation fault.

	* Perl.dis (plCodeFragment): Support for the
	role "dv:ValurRole" added.  Property name "dis:AppName"
	is changed to more specific property names.  Throws
	an exception if an input processor has no Perl code
	definition.  A parameter value to "getPropertyValue"
	was missing.

	* Value.dis (dv:ValueRole): New role.
	(DVValue.getFeature): New method.
	(DVValue): Now extends DOMFeature:ManakaiHasFeatureByGetFeature
	so that it implements DOMFeature:GetFeature.

++ manakai/lib/Message/DOM/ChangeLog	23 Sep 2005 17:24:34 -0000
2005-09-23  Wakaba  <wakaba@suika.fam.cx>

	* GenericLS.dis, SimpleLS.dis: New modules separated
	from DOMLS.dis.

	* DOMFeature.dis, DOMMain.dis: "MDOM:" and "for" definitions
	moved from DOMMain to DOMFeature.  Now DOMFeature
	has no dependency on DOMMain.

	* DOMFeature.dis (DEBUG): New variable.

++ manakai/lib/manakai/ChangeLog	23 Sep 2005 17:44:24 -0000
2005-09-23  Wakaba  <wakaba@suika.fam.cx>

	* DISCore.dis (dis:Label, dis:FullName): Their "dis:multipleProperties"
	property is fixed to "DISCore:UnorderedList" to allow
	language variants.
	(dis:Author): Marked as obsolete.
	(DISCore:author): New property.
	(DISCore:Wakaba): New resource.

	* DISPerl.dis (DISPerl:name, DISPerl:constName,
	DISPerl:exportTagName, DISPerl:variableName, DISPerl:paramName):
	New properties.

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     DOMLS => q<http://suika.fam.cx/~wakaba/archive/2004/dom/ls#>,
35     dump => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/DIS#DISDump/>,
36 wakaba 1.8 dx => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/Error/DOMException#>,
37 wakaba 1.5 ecore => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/Error/Core/>,
38 wakaba 1.3 infoset => q<http://www.w3.org/2001/04/infoset#>,
39 wakaba 1.1 ManakaiDOM => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/manakai-dom#>,
40     Markup => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Markup#>,
41     Util => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/>,
42     xml => q<http://www.w3.org/XML/1998/namespace>,
43 wakaba 1.3 xmlns => q<http://www.w3.org/2000/xmlns/>,
44 wakaba 1.1 };
45    
46     =head1 OPTIONS
47    
48     =over 4
49    
50     =item --for=I<for-uri> (Optional)
51    
52     Specifies the "For" URI reference for which the outputed module is.
53     If this parameter is ommitted, the default "For" URI reference
54     for the module, if any, or the C<ManakaiDOM:all> is assumed.
55    
56     =item --help
57    
58     Shows the help message.
59    
60     =item --module-uri=I<module-uri>
61    
62     A URI reference that identifies a module to output. Either
63     C<--module-name> or C<--module-uri> is required.
64    
65 wakaba 1.5 =item --verbose / --noverbose (default)
66 wakaba 1.1
67 wakaba 1.5 Whether a verbose message mode should be selected or not.
68 wakaba 1.1
69 wakaba 1.5 =item --with-implementators-note / --nowith-implementators-note (default)
70 wakaba 1.1
71 wakaba 1.5 Whether the implemetator's notes should also be included
72     in the result or not.
73 wakaba 1.1
74     =back
75    
76     =cut
77    
78     use Getopt::Long;
79     use Pod::Usage;
80     use Storable;
81     use Message::Util::Error;
82 wakaba 1.4 my %Opt = (
83     module_uri => {},
84     );
85 wakaba 1.1 GetOptions (
86 wakaba 1.8 'debug' => \$Opt{debug},
87 wakaba 1.1 'for=s' => \$Opt{For},
88     'help' => \$Opt{help},
89 wakaba 1.4 'module-uri=s' => sub {
90     shift;
91     $Opt{module_uri}->{+shift} = 1;
92     },
93 wakaba 1.5 'with-implementators-note' => \$Opt{with_impl_note},
94 wakaba 1.1 ) or pod2usage (2);
95     pod2usage ({-exitval => 0, -verbose => 1}) if $Opt{help};
96     $Opt{file_name} = shift;
97     pod2usage ({-exitval => 2, -verbose => 0}) unless $Opt{file_name};
98 wakaba 1.4 pod2usage (2) unless keys %{$Opt{module_uri}};
99 wakaba 1.8 $Message::DOM::DOMFeature::DEBUG = 1 if $Opt{debug};
100 wakaba 1.1
101     sub status_msg ($) {
102     my $s = shift;
103     $s .= "\n" unless $s =~ /\n$/;
104     print STDERR $s;
105     }
106    
107     sub status_msg_ ($) {
108     my $s = shift;
109     print STDERR $s;
110     }
111    
112     sub verbose_msg ($) {
113     my $s = shift;
114     $s .= "\n" unless $s =~ /\n$/;
115     print STDERR $s;
116     }
117    
118     sub verbose_msg_ ($) {
119     my $s = shift;
120     print STDERR $s;
121     }
122    
123 wakaba 1.7 {
124     my $ResourceCount = 0;
125 wakaba 1.8 sub progress_inc (;$) {
126     $ResourceCount += (shift || 1);
127     if (($ResourceCount % 10) == 0) {
128 wakaba 1.7 print STDERR "*";
129     print STDERR " " if ($ResourceCount % (10 * 10)) == 0;
130     print STDERR "\n" if ($ResourceCount % (10 * 50)) == 0;
131     }
132     }
133    
134     sub progress_reset () {
135     $ResourceCount = 0;
136     }
137     }
138    
139 wakaba 1.8 my $start_time;
140     BEGIN { $start_time = time }
141    
142     use Message::DOM::GenericLS;
143     use Message::DOM::SimpleLS;
144     use Message::Util::DIS::DISDump;
145     use Message::Util::DIS::DNLite;
146    
147 wakaba 1.5 my $impl = $Message::DOM::ImplementationRegistry->get_implementation
148 wakaba 1.1 ({
149     ExpandedURI q<ManakaiDOM:Minimum> => '3.0',
150     '+' . ExpandedURI q<DOMLS:LS> => '3.0',
151     '+' . ExpandedURI q<DIS:Doc> => '2.0',
152 wakaba 1.8 '+' . ExpandedURI q<DIS:DNLite> => '1.0',
153 wakaba 1.1 ExpandedURI q<DIS:Dump> => '1.0',
154     });
155    
156     ## -- Load input dac database file
157     status_msg_ qq<Opening dac file "$Opt{file_name}"...>;
158 wakaba 1.8 our $db = $impl->get_feature (ExpandedURI q<DIS:DNLite> => '1.0')
159 wakaba 1.5 ->pl_load_dis_database ($Opt{file_name});
160 wakaba 1.1 status_msg qq<done\n>;
161    
162 wakaba 1.2 our %ReferredResource;
163 wakaba 1.5 our %ClassMembers;
164     our %ClassInheritance;
165     our @ClassInheritance;
166     our %ClassImplements;
167 wakaba 1.2
168 wakaba 1.1 sub append_module_documentation (%) {
169     my %opt = @_;
170     my $section = $opt{result_parent}->create_module ($opt{source_resource}->uri);
171 wakaba 1.2
172     add_uri ($opt{source_resource} => $section);
173 wakaba 1.1
174     my $pl_full_name = $opt{source_resource}->pl_fully_qualified_name;
175     if (defined $pl_full_name) {
176     $section->perl_package_name ($pl_full_name);
177 wakaba 1.5
178     my $path = $opt{source_resource}->get_property_text
179     (ExpandedURI q<dis:FileName>, $pl_full_name);
180 wakaba 1.1 $path =~ s#::#/#g;
181     $section->resource_file_path_stem ($path);
182 wakaba 1.5
183 wakaba 1.1 $section->set_attribute_ns
184     (ExpandedURI q<ddoct:>, 'ddoct:basePath', '../' x ($path =~ tr#/#/#));
185 wakaba 1.2 $pl_full_name =~ s/.*:://g;
186     $section->perl_name ($pl_full_name);
187 wakaba 1.1 }
188    
189     append_description (source_resource => $opt{source_resource},
190     result_parent => $section);
191    
192 wakaba 1.2 if ($opt{is_partial}) {
193     $section->resource_is_partial (1);
194     return;
195     }
196    
197 wakaba 1.1 for my $rres (@{$opt{source_resource}->get_property_resource_list
198     (ExpandedURI q<DIS:resource>)}) {
199 wakaba 1.4 if ($rres->owner_module eq $opt{source_resource} and## Defined in this module
200     not ($ReferredResource{$rres->uri} < 0)) {
201 wakaba 1.1 ## TODO: Modification required to support modplans
202 wakaba 1.7 progress_inc;
203 wakaba 1.8 if ($rres->is_type_uri (ExpandedURI q<DISLang:Class>)) {
204 wakaba 1.1 append_class_documentation
205     (result_parent => $section,
206     source_resource => $rres);
207 wakaba 1.8 } elsif ($rres->is_type_uri (ExpandedURI q<DISLang:Interface>)) {
208 wakaba 1.1 append_interface_documentation
209     (result_parent => $section,
210     source_resource => $rres);
211 wakaba 1.8 } elsif ($rres->is_type_uri (ExpandedURI q<DISCore:AnyDataType>)) {
212 wakaba 1.3 append_datatype_documentation
213     (result_parent => $section,
214     source_resource => $rres);
215 wakaba 1.1 }
216     } else { ## Aliases
217     #
218     }
219     }
220 wakaba 1.2 status_msg "";
221 wakaba 1.1 } # append_module_documentation
222    
223 wakaba 1.3 sub append_datatype_documentation (%) {
224     my %opt = @_;
225     my $section = $opt{result_parent}->create_data_type
226     ($opt{source_resource}->uri);
227    
228     add_uri ($opt{source_resource} => $section);
229    
230 wakaba 1.4 my $uri = $opt{source_resource}->name_uri;
231     if ($uri) {
232     my $fu = $opt{source_resource}->for_uri;
233     unless ($fu eq ExpandedURI q<ManakaiDOM:all>) {
234     $fu =~ /([\w.-]+)[^\w.-]*$/;
235     $uri .= '-' . $1;
236     }
237     } else {
238     $opt{source_resource}->uri;
239     }
240     $uri =~ s#\b(\d\d\d\d+)/(\d\d?)/(\d\d?)#sprintf '%04d%02d%02d', $1, $2, $3#ge;
241     my @file = map {s/[^\w-]/_/g; $_} split m{[/:#?]+}, $uri;
242 wakaba 1.3
243     $section->resource_file_path_stem (join '/', @file);
244 wakaba 1.5 $section->set_attribute_ns
245     (ExpandedURI q<ddoct:>, 'ddoct:basePath', '../' x (@file - 1));
246 wakaba 1.3
247     my $docr = $opt{source_resource}->get_feature (ExpandedURI q<DIS:Doc>, '2.0');
248     my $label = $docr->get_label ($section->owner_document);
249     if ($label) {
250     $section->create_label->append_child (transform_disdoc_tree ($label));
251     }
252    
253     append_description (source_resource => $opt{source_resource},
254     result_parent => $section);
255    
256     if ($opt{is_partial}) {
257     $section->resource_is_partial (1);
258     return;
259     }
260    
261 wakaba 1.5 append_subclassof (source_resource => $opt{source_resource},
262     result_parent => $section);
263 wakaba 1.3 } # append_datatype_documentation
264    
265 wakaba 1.1 sub append_interface_documentation (%) {
266     my %opt = @_;
267     my $section = $opt{result_parent}->create_interface
268 wakaba 1.5 (my $class_uri = $opt{source_resource}->uri);
269     push @ClassInheritance, $class_uri;
270 wakaba 1.2
271     add_uri ($opt{source_resource} => $section);
272 wakaba 1.1
273     my $pl_full_name = $opt{source_resource}->pl_fully_qualified_name;
274     if (defined $pl_full_name) {
275     $section->perl_package_name ($pl_full_name);
276 wakaba 1.5
277     my $path = $opt{source_resource}->get_property_text
278     (ExpandedURI q<dis:FileName>, $pl_full_name);
279 wakaba 1.1 $path =~ s#::#/#g;
280     $section->resource_file_path_stem ($path);
281 wakaba 1.5
282 wakaba 1.1 $section->set_attribute_ns
283     (ExpandedURI q<ddoct:>, 'ddoct:basePath',
284     join '', '../' x ($path =~ tr#/#/#));
285 wakaba 1.2 $pl_full_name =~ s/.*:://g;
286     $section->perl_name ($pl_full_name);
287 wakaba 1.1 }
288    
289     $section->is_exception_interface (1)
290 wakaba 1.8 if $opt{source_resource}->is_type_uri (ExpandedURI q<dx:Interface>);
291 wakaba 1.1
292     append_description (source_resource => $opt{source_resource},
293     result_parent => $section);
294    
295 wakaba 1.2 if ($opt{is_partial}) {
296     $section->resource_is_partial (1);
297     return;
298     }
299    
300 wakaba 1.1 ## Inheritance
301     append_inheritance (source_resource => $opt{source_resource},
302 wakaba 1.5 result_parent => $section,
303     class_uri => $class_uri);
304 wakaba 1.1
305     for my $memres (@{$opt{source_resource}->get_property_resource_list
306     (ExpandedURI q<DIS:childResource>)}) {
307     if ($memres->is_type_uri (ExpandedURI q<DISLang:Method>)) {
308     append_method_documentation (source_resource => $memres,
309 wakaba 1.5 result_parent => $section,
310     class_uri => $class_uri);
311 wakaba 1.1 } elsif ($memres->is_type_uri (ExpandedURI q<DISLang:Attribute>)) {
312     append_attr_documentation (source_resource => $memres,
313 wakaba 1.5 result_parent => $section,
314     class_uri => $class_uri);
315 wakaba 1.8 } elsif ($memres->is_type_uri (ExpandedURI q<DISLang:ConstGroup>)) {
316 wakaba 1.3 append_constgroup_documentation (source_resource => $memres,
317 wakaba 1.5 result_parent => $section,
318     class_uri => $class_uri);
319 wakaba 1.1 }
320     }
321     } # append_interface_documentation
322    
323     sub append_class_documentation (%) {
324     my %opt = @_;
325 wakaba 1.5 my $section = $opt{result_parent}->create_class
326     (my $class_uri = $opt{source_resource}->uri);
327     push @ClassInheritance, $class_uri;
328 wakaba 1.2
329     add_uri ($opt{source_resource} => $section);
330 wakaba 1.1
331     my $pl_full_name = $opt{source_resource}->pl_fully_qualified_name;
332     if (defined $pl_full_name) {
333     $section->perl_package_name ($pl_full_name);
334 wakaba 1.5
335     my $path = $opt{source_resource}->get_property_text
336     (ExpandedURI q<dis:FileName>, $pl_full_name);
337 wakaba 1.1 $path =~ s#::#/#g;
338 wakaba 1.5
339 wakaba 1.1 $section->resource_file_path_stem ($path);
340     $section->set_attribute_ns
341     (ExpandedURI q<ddoct:>, 'ddoct:basePath', '../' x ($path =~ tr#/#/#));
342 wakaba 1.2 $pl_full_name =~ s/.*:://g;
343     $section->perl_name ($pl_full_name);
344 wakaba 1.1 }
345    
346     append_description (source_resource => $opt{source_resource},
347     result_parent => $section);
348    
349 wakaba 1.2 if ($opt{is_partial}) {
350     $section->resource_is_partial (1);
351     return;
352     }
353    
354 wakaba 1.5 my $has_const = 0;
355 wakaba 1.1 for my $memres (@{$opt{source_resource}->get_property_resource_list
356     (ExpandedURI q<DIS:childResource>)}) {
357     if ($memres->is_type_uri (ExpandedURI q<DISLang:Method>)) {
358     append_method_documentation (source_resource => $memres,
359 wakaba 1.5 result_parent => $section,
360     class_uri => $class_uri);
361 wakaba 1.1 } elsif ($memres->is_type_uri (ExpandedURI q<DISLang:Attribute>)) {
362     append_attr_documentation (source_resource => $memres,
363 wakaba 1.5 result_parent => $section,
364     class_uri => $class_uri);
365 wakaba 1.8 } elsif ($memres->is_type_uri (ExpandedURI q<DISLang:ConstGroup>)) {
366 wakaba 1.5 $has_const = 1;
367 wakaba 1.3 append_constgroup_documentation
368     (source_resource => $memres,
369 wakaba 1.5 result_parent => $section,
370     class_uri => $class_uri);
371 wakaba 1.1 }
372     }
373 wakaba 1.5
374     ## Inheritance
375     append_inheritance (source_resource => $opt{source_resource},
376     result_parent => $section,
377     append_implements => 1,
378     class_uri => $class_uri,
379     has_const => $has_const,
380     is_class => 1);
381    
382 wakaba 1.1 } # append_class_documentation
383    
384     sub append_method_documentation (%) {
385     my %opt = @_;
386     my $perl_name = $opt{source_resource}->pl_name;
387     my $m;
388     if (defined $perl_name) {
389     $m = $opt{result_parent}->create_method ($perl_name);
390 wakaba 1.5 $ClassMembers{$opt{class_uri}}->{$perl_name}
391     = {
392     resource => $opt{source_resource},
393     type => 'method',
394     };
395 wakaba 1.1
396     } else { ## Anonymous
397     ## TODO
398     return;
399     }
400 wakaba 1.2
401     add_uri ($opt{source_resource} => $m);
402 wakaba 1.1
403     append_description (source_resource => $opt{source_resource},
404 wakaba 1.4 result_parent => $m,
405     method_resource => $opt{source_resource});
406 wakaba 1.1
407     my $ret = $opt{source_resource}->get_child_resource_by_type
408     (ExpandedURI q<DISLang:MethodReturn>);
409     if ($ret) {
410     my $r = $m->dis_return;
411    
412     try {
413 wakaba 1.2 $r->resource_data_type (my $u = $ret->dis_data_type_resource->uri);
414     $ReferredResource{$u} ||= 1;
415     $r->resource_actual_data_type
416     ($u = $ret->dis_actual_data_type_resource->uri);
417     $ReferredResource{$u} ||= 1;
418    
419 wakaba 1.1 ## TODO: Exceptions
420     } catch Message::Util::DIS::ManakaiDISException with {
421    
422     };
423 wakaba 1.4
424     append_description (source_resource => $ret,
425     result_parent => $r,
426     has_case => 1,
427     method_resource => $opt{source_resource});
428 wakaba 1.5
429     append_raises (source_resource => $ret,
430     result_parent => $r,
431     method_resource => $opt{source_resource});
432 wakaba 1.1 }
433    
434     for my $cr (@{$opt{source_resource}->get_property_resource_list
435     (ExpandedURI q<DIS:childResource>)}) {
436     if ($cr->is_type_uri (ExpandedURI q<DISLang:MethodParameter>)) {
437     append_param_documentation (source_resource => $cr,
438 wakaba 1.4 result_parent => $m,
439     method_resource => $opt{source_resource});
440 wakaba 1.1 }
441     }
442    
443     $m->resource_access ('private')
444     if $opt{source_resource}->get_property_boolean
445     (ExpandedURI q<ManakaiDOM:isForInternal>, 0);
446     } # append_method_documentation
447    
448     sub append_attr_documentation (%) {
449     my %opt = @_;
450     my $perl_name = $opt{source_resource}->pl_name;
451     my $m;
452     if (defined $perl_name) {
453     $m = $opt{result_parent}->create_attribute ($perl_name);
454 wakaba 1.5 $ClassMembers{$opt{class_uri}}->{$perl_name}
455     = {
456     resource => $opt{source_resource},
457     type => 'attr',
458     };
459 wakaba 1.1
460     } else { ## Anonymous
461     ## TODO
462     return;
463     }
464 wakaba 1.2
465     add_uri ($opt{source_resource} => $m);
466 wakaba 1.1
467     append_description (source_resource => $opt{source_resource},
468     result_parent => $m,
469     has_case => 1);
470    
471     my $ret = $opt{source_resource}->get_child_resource_by_type
472     (ExpandedURI q<DISLang:AttributeGet>);
473     if ($ret) {
474     my $r = $m->dis_get;
475    
476 wakaba 1.2 $r->resource_data_type (my $u = $ret->dis_data_type_resource->uri);
477     $ReferredResource{$u} ||= 1;
478     $r->resource_actual_data_type
479     ($u = $ret->dis_actual_data_type_resource->uri);
480     $ReferredResource{$u} ||= 1;
481    
482 wakaba 1.1 append_description (source_resource => $ret,
483     result_parent => $r,
484     has_case => 1);
485    
486 wakaba 1.5 append_raises (source_resource => $ret,
487     result_parent => $r);
488 wakaba 1.1 }
489    
490     my $set = $opt{source_resource}->get_child_resource_by_type
491     (ExpandedURI q<DISLang:AttributeSet>);
492     if ($set) {
493     my $r = $m->dis_set;
494    
495 wakaba 1.2 $r->resource_data_type (my $u = $set->dis_data_type_resource->uri);
496     $ReferredResource{$u} ||= 1;
497 wakaba 1.1 $r->resource_actual_data_type ($set->dis_actual_data_type_resource->uri);
498 wakaba 1.2 $ReferredResource{$u} ||= 1;
499 wakaba 1.1
500     append_description (source_resource => $set,
501     result_parent => $r,
502     has_case => 1);
503    
504 wakaba 1.5 append_raises (source_resource => $set,
505     result_parent => $r);
506 wakaba 1.1 } else {
507     $m->is_read_only_attribute (1);
508     }
509    
510     $m->resource_access ('private')
511     if $opt{source_resource}->get_property_boolean
512     (ExpandedURI q<ManakaiDOM:isForInternal>, 0);
513     } # append_attr_documentation
514    
515 wakaba 1.3 sub append_constgroup_documentation (%) {
516     my %opt = @_;
517     my $perl_name = $opt{source_resource}->pl_name;
518     my $m = $opt{result_parent}->create_const_group ($perl_name);
519 wakaba 1.5 $ClassMembers{$opt{class_uri}}->{$perl_name}
520     = {
521     resource => $opt{source_resource},
522     type => 'const-group',
523     };
524 wakaba 1.3
525     add_uri ($opt{source_resource} => $m);
526    
527     append_description (source_resource => $opt{source_resource},
528     result_parent => $m);
529    
530     $m->resource_data_type
531     (my $u = $opt{source_resource}->dis_data_type_resource->uri);
532     $ReferredResource{$u} ||= 1;
533     $m->resource_actual_data_type
534     ($u = $opt{source_resource}->dis_actual_data_type_resource->uri);
535     $ReferredResource{$u} ||= 1;
536    
537 wakaba 1.5 append_subclassof (source_resource => $opt{source_resource},
538     result_parent => $m);
539 wakaba 1.3
540     for my $cr (@{$opt{source_resource}->get_property_resource_list
541     (ExpandedURI q<DIS:childResource>)}) {
542     if ($cr->is_type_uri (ExpandedURI q<ManakaiDOM:Const>)) {
543     append_const_documentation (source_resource => $cr,
544     result_parent => $m);
545     }
546     }
547     } # append_constgroup_documentation
548    
549     sub append_const_documentation (%) {
550     my %opt = @_;
551     my $perl_name = $opt{source_resource}->pl_name;
552     my $m = $opt{result_parent}->create_const ($perl_name);
553    
554     add_uri ($opt{source_resource} => $m);
555    
556     append_description (source_resource => $opt{source_resource},
557     result_parent => $m);
558    
559     $m->resource_data_type
560     (my $u = $opt{source_resource}->dis_data_type_resource->uri);
561     $ReferredResource{$u} ||= 1;
562     $m->resource_actual_data_type
563     ($u = $opt{source_resource}->dis_actual_data_type_resource->uri);
564     $ReferredResource{$u} ||= 1;
565    
566     my $value = $opt{source_resource}->pl_code_fragment;
567     if ($value) {
568     $m->create_value->text_content ($value->stringify);
569     }
570    
571     for my $cr (@{$opt{source_resource}->get_property_resource_list
572     (ExpandedURI q<DIS:childResource>)}) {
573     if ($cr->is_type_uri (ExpandedURI q<ManakaiDOM:ExceptionOrWarningSubType>)) {
574     append_xsubtype_documentation (source_resource => $cr,
575     result_parent => $m);
576     }
577     }
578     ## TODO: xparam
579     } # append_const_documentation
580    
581     sub append_xsubtype_documentation (%) {
582     my %opt = @_;
583     my $m = $opt{result_parent}->create_exception_sub_code
584     ($opt{source_resource}->uri);
585     add_uri ($opt{source_resource} => $m);
586    
587     append_description (source_resource => $opt{source_resource},
588     result_parent => $m);
589    
590     ## TODO: xparam
591     } # append_xsubtype_documentation
592    
593 wakaba 1.1 sub append_param_documentation (%) {
594     my %opt = @_;
595    
596     my $is_named_param = $opt{source_resource}->get_property_boolean
597     (ExpandedURI q<DISPerl:isNamedParameter>, 0);
598    
599     my $perl_name = $is_named_param
600     ? $opt{source_resource}->pl_name
601     : $opt{source_resource}->pl_variable_name;
602    
603     my $p = $opt{result_parent}->create_parameter ($perl_name, $is_named_param);
604    
605 wakaba 1.2 add_uri ($opt{source_resource} => $p);
606    
607 wakaba 1.1 $p->is_nullable_parameter ($opt{source_resource}->pl_is_nullable);
608 wakaba 1.2 $p->resource_data_type
609     (my $u = $opt{source_resource}->dis_data_type_resource->uri);
610     $ReferredResource{$u} ||= 1;
611 wakaba 1.1 $p->resource_actual_data_type
612 wakaba 1.2 ($u = $opt{source_resource}->dis_actual_data_type_resource->uri);
613     $ReferredResource{$u} ||= 1;
614 wakaba 1.1
615     append_description (source_resource => $opt{source_resource},
616     result_parent => $p,
617 wakaba 1.4 has_case => 1,
618     method_resource => $opt{method_resource});
619 wakaba 1.1 } # append_param_documentation
620    
621     sub append_description (%) {
622     my %opt = @_;
623 wakaba 1.2
624 wakaba 1.1 my $od = $opt{result_parent}->owner_document;
625     my $resd = $opt{source_resource}->get_feature (ExpandedURI q<DIS:Doc>, '2.0');
626 wakaba 1.5 my $doc = transform_disdoc_tree
627     ($resd->get_description
628     ($od, undef,
629     $Opt{with_impl_note},
630 wakaba 1.8 parent_value_arg => $opt{source_value}),
631 wakaba 1.5 method_resource => $opt{method_resource});
632 wakaba 1.1 $opt{result_parent}->create_description->append_child ($doc);
633     ## TODO: Negotiation
634    
635 wakaba 1.3 my $fn = $resd->get_full_name ($od);
636     if ($fn) {
637     $opt{result_parent}->create_full_name
638 wakaba 1.4 ->append_child (transform_disdoc_tree
639     ($fn,
640     method_resource => $opt{method_resource}));
641 wakaba 1.3 }
642    
643 wakaba 1.1 if ($opt{has_case}) {
644     for my $caser (@{$opt{source_resource}->get_property_resource_list
645     (ExpandedURI q<DIS:childResource>)}) {
646     if ($caser->is_type_uri (ExpandedURI q<ManakaiDOM:InCase>)) {
647     my $case = $opt{result_parent}->append_case;
648     my $cased = $caser->get_feature (ExpandedURI q<DIS:Doc>, '2.0');
649     my $label = $cased->get_label ($od);
650     if ($label) {
651 wakaba 1.4 $case->create_label->append_child
652     (transform_disdoc_tree ($label,
653     method_resource => $opt{method_resource}));
654 wakaba 1.1 }
655     my $value = $caser->pl_code_fragment;
656     if ($value) {
657     $case->create_value->text_content ($value->stringify);
658     }
659 wakaba 1.3 $case->resource_data_type
660     (my $u = $caser->dis_data_type_resource->uri);
661     $ReferredResource{$u} ||= 1;
662     $case->resource_actual_data_type
663     ($u = $caser->dis_actual_data_type_resource->uri);
664     $ReferredResource{$u} ||= 1;
665    
666 wakaba 1.1 append_description (source_resource => $caser,
667 wakaba 1.4 result_parent => $case,
668     method_resource => $opt{method_resource});
669 wakaba 1.1 }
670     }
671     }
672     } # append_description
673    
674 wakaba 1.3 sub transform_disdoc_tree ($;%) {
675     my ($el, %opt) = @_;
676     my @el = ($el);
677     EL: while (defined (my $el = shift @el)) {
678     if ($el->node_type == $el->ELEMENT_NODE and
679     defined $el->namespace_uri) {
680     my $mmParsed = $el->get_attribute_ns (ExpandedURI q<ddel:>, 'mmParsed');
681     if ($mmParsed) {
682     my $lextype = $el->get_attribute_ns (ExpandedURI q<ddel:>, 'lexType');
683 wakaba 1.8 if ($lextype eq ExpandedURI q<DISCore:TFQNames>) {
684 wakaba 1.4 my $uri = dd_get_tfqnames_uri ($el);
685     if (defined $uri) {
686     $ReferredResource{$uri} ||= 1;
687     next EL;
688     }
689 wakaba 1.8 } elsif ($lextype eq ExpandedURI q<DISCore:QName> or
690 wakaba 1.5 $lextype eq ExpandedURI q<DISCore:NCNameOrQName>) {
691     my $uri = dd_get_qname_uri ($el);
692     if (defined $uri) {
693     $ReferredResource{$uri} ||= 1;
694     next EL;
695     }
696 wakaba 1.8 } elsif ($lextype eq ExpandedURI q<DISLang:MemberRef> or
697     $lextype eq ExpandedURI q<dx:XCRef>) {
698 wakaba 1.4 my @nm = @{$el->get_elements_by_tag_name_ns
699     (ExpandedURI q<ddel:>, 'name')};
700     if (@nm == 1) {
701 wakaba 1.5 my $uri = dd_get_tfqnames_uri ($nm[0]);
702     if (defined $uri) {
703     $el->set_attribute_ns (ExpandedURI q<dump:>, 'dump:uri', $uri);
704     $ReferredResource{$uri} ||= 1;
705     next EL;
706     }
707     } elsif (@nm == 3) {
708     my $uri = dd_get_tfqnames_uri ($nm[2]);
709 wakaba 1.4 if (defined $uri) {
710 wakaba 1.5 $el->set_attribute_ns (ExpandedURI q<dump:>, 'dump:uri', $uri);
711 wakaba 1.4 $ReferredResource{$uri} ||= 1;
712     next EL;
713     }
714     } elsif (@nm == 2) {
715     my $uri = dd_get_tfqnames_uri ($nm[0]);
716     if (not defined $uri) {
717     #
718     } elsif ($nm[1]->get_elements_by_tag_name_ns
719     (ExpandedURI q<ddel:>, 'prefix')->[0]) {
720     #my $luri = dd_get_qname_uri ($nm[1]);
721     ## QName: Currently not used
722     } else {
723     my $lnel = $nm[1]->get_elements_by_tag_name_ns
724     (ExpandedURI q<ddel:>, 'localName')->[0];
725     my $lname = $lnel ? $lnel->text_content : '';
726 wakaba 1.5 my $res;
727 wakaba 1.8 if ($lextype eq ExpandedURI q<dx:XCRef> or
728 wakaba 1.5 {
729     ExpandedURI q<ddel:C> => 1,
730     ExpandedURI q<ddel:X> => 1,
731     }->{$el->namespace_uri . $el->local_name}) {
732     ## NOTE: $db
733     $res = $db->get_resource ($uri)
734     ->get_const_resource_by_name ($lname);
735     } else {
736     ## NOTE: $db
737     $res = $db->get_resource ($uri)
738     ->get_child_resource_by_name_and_type
739 wakaba 1.4 ($lname, ExpandedURI q<DISLang:AnyMethod>);
740 wakaba 1.5 }
741 wakaba 1.4 if ($res) {
742     $el->set_attribute_ns
743     (ExpandedURI q<dump:>, 'dump:uri', $res->uri);
744     $ReferredResource{$res->uri} ||= 1;
745     }
746     next EL;
747     }
748     }
749     } # lextype
750     } # mmParsed
751     elsif ($opt{method_resource} and
752     $el->namespace_uri eq ExpandedURI q<ddel:> and
753     $el->local_name eq 'P') {
754     my $res = $opt{method_resource}
755     ->get_child_resource_by_name_and_type
756     ($el->text_content, ExpandedURI q<DISLang:MethodParameter>);
757     if ($res) {
758     $el->set_attribute_ns
759     (ExpandedURI q<dump:>, 'dump:uri', $res->uri);
760     $ReferredResource{$res->uri} ||= 1;
761 wakaba 1.3 }
762 wakaba 1.4 next EL;
763 wakaba 1.3 }
764 wakaba 1.4 push @el, @{$el->child_nodes};
765 wakaba 1.3 } elsif ($el->node_type == $el->DOCUMENT_FRAGMENT_NODE or
766     $el->node_type == $el->DOCUMENT_NODE) {
767 wakaba 1.4 push @el, @{$el->child_nodes};
768 wakaba 1.3 }
769     } # EL
770     $el;
771     } # transform_disdoc_tree
772    
773 wakaba 1.4 sub dd_get_tfqnames_uri ($;%) {
774     my ($el, %opt) = @_;
775     return '' unless $el;
776     my $turi = dd_get_qname_uri ($el->get_elements_by_tag_name_ns
777     (ExpandedURI q<ddel:>, 'nameQName')->[0]);
778     my $furi = dd_get_qname_uri ($el->get_elements_by_tag_name_ns
779     (ExpandedURI q<ddel:>, 'forQName')->[0]);
780     return undef if not defined $turi or not defined $furi;
781     my $uri = tfuris2uri ($turi, $furi);
782     $el->set_attribute_ns (ExpandedURI q<dump:>, 'dump:uri', $uri);
783     $uri;
784     } # dd_get_tfqnames_uri
785 wakaba 1.3
786     sub dd_get_qname_uri ($;%) {
787     my ($el, %opt) = @_;
788 wakaba 1.4 return undef unless $el;
789 wakaba 1.3 my $plel = $el->get_elements_by_tag_name_ns
790     (ExpandedURI q<ddel:>, 'prefix')->[0];
791     my $lnel = $el->get_elements_by_tag_name_ns
792     (ExpandedURI q<ddel:>, 'localName')->[0];
793     my $nsuri = ($plel ? $plel : $el)->lookup_namespace_uri
794     ($plel ? $plel->text_content : undef);
795     $nsuri = '' unless defined $nsuri;
796     if ($plel and $nsuri eq '') {
797     $plel->remove_attribute_ns
798 wakaba 1.4 (ExpandedURI q<xmlns:>, $plel->text_content);
799     $el->set_attribute_ns (ExpandedURI q<dump:>, 'dump:namespaceURI', $nsuri);
800     return undef;
801     } else {
802     $el->set_attribute_ns (ExpandedURI q<dump:>, 'dump:namespaceURI', $nsuri);
803 wakaba 1.3 }
804     if ($lnel) {
805     $nsuri . $lnel->text_content;
806     } else {
807     $el->get_attribute_ns (ExpandedURI q<ddel:>, 'defaultURI');
808     }
809     } # dd_get_qname_uri
810    
811     sub tfuris2uri ($$) {
812     my ($turi, $furi) = @_;
813     my $uri;
814 wakaba 1.5 if ($furi eq ExpandedURI q<ManakaiDOM:all>) {
815 wakaba 1.3 $uri = $turi;
816     } else {
817     my $__turi = $turi;
818     my $__furi = $furi;
819     for my $__uri ($__turi, $__furi) {
820     $__uri =~ s{([^0-9A-Za-z:;?=_./-])}{sprintf '%%%02X', ord $1}ge;
821     }
822     $uri = qq<data:,200411tf#xmlns(t=data:,200411tf%23)>.
823     qq<t:tf($__turi,$__furi)>;
824     }
825     $uri;
826     } # tfuris2uri
827    
828 wakaba 1.1 sub append_inheritance (%) {
829     my %opt = @_;
830     if (($opt{depth} ||= 0) == 100) {
831     warn "<".$opt{source_resource}->uri.">: Loop in inheritance";
832     return;
833     }
834 wakaba 1.5
835     my $has_isa = 0;
836 wakaba 1.1
837     for my $isa (@{$opt{source_resource}->get_property_resource_list
838     (ExpandedURI q<dis:ISA>,
839 wakaba 1.8 default_media_type => ExpandedURI q<DISCore:TFQNames>)}) {
840 wakaba 1.5 $has_isa = 1;
841 wakaba 1.1 append_inheritance
842     (source_resource => $isa,
843     result_parent => $opt{result_parent}->append_new_extends ($isa->uri),
844 wakaba 1.5 depth => $opt{depth} + 1,
845     is_class => $opt{is_class});
846     $ReferredResource{$isa->uri} ||= 1;
847     if ($opt{class_uri}) {
848     unshift @ClassInheritance, $isa->uri;
849     push @{$ClassInheritance{$opt{class_uri}} ||= []}, $isa->uri;
850     }
851     }
852    
853     if ($opt{source_resource}->is_defined) {
854     for my $isa_pack (@{$opt{source_resource}->pl_additional_isa_packages}) {
855     my $isa;
856     if ($isa_pack eq 'Message::Util::Error') {
857     ## NOTE: $db
858     $isa = $db->get_resource (ExpandedURI q<ecore:MUError>,
859     for_arg => ExpandedURI q<ManakaiDOM:Perl>);
860     } elsif ($isa_pack eq 'Tie::Array') {
861     ## NOTE: $db
862     $isa = $db->get_resource (ExpandedURI q<DISPerl:TieArray>);
863     } elsif ($isa_pack eq 'Error') {
864     ## NOTE: $db
865     $isa = $db->get_resource (ExpandedURI q<ecore:Error>,
866     for_arg => ExpandedURI q<ManakaiDOM:Perl>);
867     } else {
868     ## TODO: What to do?
869     }
870     if ($isa) {
871     $has_isa = 1;
872     append_inheritance
873     (source_resource => $isa,
874     result_parent => $opt{result_parent}->append_new_extends ($isa->uri),
875     depth => $opt{depth} + 1,
876     is_class => $opt{is_class});
877     $ReferredResource{$isa->uri} ||= 1;
878     if ($opt{class_uri}) {
879     unshift @ClassInheritance, $isa->uri;
880     push @{$ClassInheritance{$opt{class_uri}} ||= []}, $isa->uri;
881     }
882     }
883     }} # AppISA
884    
885     if ($opt{has_const}) {
886     ## NOTE: $db
887     my $isa = $db->get_resource (ExpandedURI q<DISPerl:Exporter>);
888     append_inheritance
889     (source_resource => $isa,
890     result_parent => $opt{result_parent}->append_new_extends ($isa->uri),
891     depth => $opt{depth} + 1,
892     is_class => $opt{is_class});
893     $ReferredResource{$isa->uri} ||= 1;
894     if ($opt{class_uri}) {
895     unshift @ClassInheritance, $isa->uri;
896     push @{$ClassInheritance{$opt{class_uri}} ||= []}, $isa->uri;
897     }
898     }
899    
900     if (not $has_isa and $opt{is_class} and
901     $opt{source_resource}->uri ne ExpandedURI q<DISPerl:UNIVERSAL>) {
902     ## NOTE: $db
903     my $isa = $db->get_resource (ExpandedURI q<DISPerl:UNIVERSAL>);
904     append_inheritance
905     (source_resource => $isa,
906     result_parent => $opt{result_parent}->append_new_extends ($isa->uri),
907     depth => $opt{depth} + 1,
908     is_class => $opt{is_class});
909 wakaba 1.2 $ReferredResource{$isa->uri} ||= 1;
910 wakaba 1.5 if ($opt{class_uri}) {
911     unshift @ClassInheritance, $isa->uri;
912     push @{$ClassInheritance{$opt{class_uri}} ||= []}, $isa->uri;
913     }
914 wakaba 1.1 }
915    
916     if ($opt{append_implements}) {
917 wakaba 1.5 ## NOTE: $db
918     my $u = $db->get_resource (ExpandedURI q<DISPerl:UNIVERSALInterface>);
919 wakaba 1.1 for my $impl (@{$opt{source_resource}->get_property_resource_list
920     (ExpandedURI q<dis:Implement>,
921 wakaba 1.8 default_media_type => ExpandedURI q<DISCore:TFQNames>,
922 wakaba 1.5 isa_recursive => 1)}, $u) {
923 wakaba 1.1 append_inheritance
924     (source_resource => $impl,
925     result_parent => $opt{result_parent}->append_new_implements
926     ($impl->uri),
927     depth => $opt{depth});
928 wakaba 1.2 $ReferredResource{$impl->uri} ||= 1;
929 wakaba 1.5 $ClassImplements{$opt{class_uri}}->{$impl->uri} = 1
930     if $opt{class_uri};
931 wakaba 1.1 }
932     }
933     } # append_inheritance
934    
935 wakaba 1.5 sub append_subclassof (%) {
936     my %opt = @_;
937    
938     ## NOTE: This subroutine directly access to internal structure
939     ## of ManakaiDISResourceDefinition
940    
941     my $a;
942     $a = sub ($$) {
943     my ($gdb, $s) = @_;
944     my %s = keys %$s;
945     while (my $i = [keys %s]->[0]) {
946     ## Removes itself
947     delete $s->{$i};
948     #warn $i;
949    
950     my $ires = $gdb->get_resource ($i);
951     for my $j (keys %$s) {
952     next if $i eq $j;
953     if ($ires->{subOf}->{$j}) {
954     $s->{$i}->{$j} = $s->{$j};
955     delete $s->{$j};
956     delete $s{$j};
957     }
958     }
959    
960     delete $s{$i};
961     } # %s
962    
963     for my $i (keys %$s) {
964     $a->($s->{$i}) if keys %{$s->{$i}};
965     }
966     };
967    
968     my $b;
969     $b = sub ($$) {
970     my ($s, $p) = @_;
971     for my $i (keys %$s) {
972     my $el = $p->append_new_sub_class_of ($i);
973     $b->($s->{$i}, $el) if keys %{$s->{$i}};
974     }
975     };
976    
977    
978     my $sub = {$opt{source_resource}->uri =>
979     {map {$_ => {}} keys %{$opt{source_resource}->{subOf}}}};
980     ## NOTE: $db
981     $a->($db, $sub);
982     $b->($sub, $opt{result_parent});
983     } # append_subclassof
984    
985 wakaba 1.2 sub add_uri ($$;%) {
986     my ($res, $el, %opt) = @_;
987     my $canon_uri = $res->uri;
988     for my $uri (@{$res->uris}) {
989     $el->add_uri ($uri, $canon_uri eq $uri ? 0 : 1);
990     $ReferredResource{$uri} = -1;
991     }
992 wakaba 1.3
993     my $nsuri = $res->namespace_uri;
994     $el->resource_namespace_uri ($nsuri) if defined $nsuri;
995     my $lname = $res->local_name;
996     $el->resource_local_name ($lname) if defined $lname;
997 wakaba 1.2 } # add_uri
998    
999 wakaba 1.5 sub append_raises (%) {
1000     my %opt = @_;
1001    
1002 wakaba 1.8 for my $el (@{$opt{source_resource}->get_property_value_list
1003     (ExpandedURI q<dx:raises>)}) {
1004     next unless $el->isa ('Message::Util::IF::DVURIValue');
1005     my $e = $el->get_resource ($db);
1006     my ($a, $b, $c); ## NOTE: $db
1007     if ($e->is_type_uri (ExpandedURI q<ManakaiDOM:ExceptionOrWarningSubType>)) {
1008     $c = $e;
1009     $b = $c->get_property_resource (ExpandedURI q<dis2pm:parentResource>);
1010     $a = $b->get_property_resource (ExpandedURI q<dis2pm:parentResource>);
1011     } elsif ($e->is_type_uri (ExpandedURI q<DISLang:Const>)) {
1012     $b = $e;
1013     $a = $b->get_property_resource (ExpandedURI q<dis2pm:parentResource>);
1014     } else {
1015     $a = $e;
1016     }
1017     my $rel = $opt{result_parent}->create_raises
1018 wakaba 1.5 ($a->uri, $b ? $b->uri : undef, $c ? $c->uri : undef);
1019    
1020 wakaba 1.8 append_description (source_resource => $opt{source_resource},
1021     source_value => $el,
1022     result_parent => $rel,
1023     method_resource => $opt{method_resource});
1024 wakaba 1.5 }
1025     } # append_raises
1026 wakaba 1.4
1027    
1028 wakaba 1.1 my $doc = $impl->create_disdump_document;
1029    
1030     my $body = $doc->document_element;
1031    
1032    
1033 wakaba 1.4 ## -- Outputs requested modules
1034    
1035     for my $mod_uri (keys %{$Opt{module_uri}}) {
1036 wakaba 1.5 my $mod_for = $Opt{For};
1037     my $mod = $db->get_module ($mod_uri, for_arg => $mod_for);
1038 wakaba 1.8 unless (defined $mod_for) {
1039     $mod_for = $mod->get_property_text (ExpandedURI q<dis:DefaultFor>);
1040     if (defined $mod_for) {
1041 wakaba 1.5 $mod = $db->get_module ($mod_uri, for_arg => $mod_for);
1042 wakaba 1.4 }
1043     }
1044     unless ($mod->is_defined) {
1045 wakaba 1.5 die qq<$0: Module <$mod_uri> for <$mod_for> is not defined>;
1046 wakaba 1.4 }
1047    
1048 wakaba 1.5 status_msg qq<Module <$mod_uri> for <$mod_for>...>;
1049 wakaba 1.7 progress_reset;
1050 wakaba 1.4
1051     append_module_documentation
1052     (result_parent => $body,
1053     source_resource => $mod);
1054 wakaba 1.5
1055     status_msg qq<done>;
1056 wakaba 1.4 } # mod_uri
1057    
1058     ## -- Outputs referenced resources in external modules
1059 wakaba 1.2
1060 wakaba 1.5 status_msg q<Other modules...>;
1061 wakaba 1.7 progress_reset;
1062 wakaba 1.5
1063 wakaba 1.2 while (my @ruri = grep {$ReferredResource{$_} > 0} keys %ReferredResource) {
1064     U: while (defined (my $uri = shift @ruri)) {
1065     next U if $ReferredResource{$uri} < 0; ## Already done
1066 wakaba 1.7 progress_inc;
1067 wakaba 1.2 my $res = $db->get_resource ($uri);
1068     unless ($res->is_defined) {
1069     $res = $db->get_module ($uri);
1070     unless ($res->is_defined) {
1071     $ReferredResource{$uri} = -1;
1072     next U;
1073     }
1074     append_module_documentation
1075     (result_parent => $body,
1076     source_resource => $res,
1077     is_partial => 1);
1078 wakaba 1.8 } elsif ($res->is_type_uri (ExpandedURI q<DISLang:Class>)) {
1079 wakaba 1.2 my $mod = $res->owner_module;
1080     unless ($ReferredResource{$mod->uri} < 0) {
1081     unshift @ruri, $uri;
1082     unshift @ruri, $mod->uri;
1083     next U;
1084     }
1085     append_class_documentation
1086     (result_parent => $body->create_module ($mod->uri),
1087     source_resource => $res,
1088     is_partial => 1);
1089 wakaba 1.8 } elsif ($res->is_type_uri (ExpandedURI q<DISLang:Interface>)) {
1090 wakaba 1.2 my $mod = $res->owner_module;
1091     unless ($mod->is_defined) {
1092     $ReferredResource{$uri} = -1;
1093     next U;
1094     } elsif (not ($ReferredResource{$mod->uri} < 0)) {
1095     unshift @ruri, $uri;
1096     unshift @ruri, $mod->uri;
1097     next U;
1098     }
1099     append_interface_documentation
1100     (result_parent => $body->create_module ($mod->uri),
1101     source_resource => $res,
1102     is_partial => 1);
1103 wakaba 1.8 } elsif ($res->is_type_uri (ExpandedURI q<DISLang:AnyDataType>)) {
1104 wakaba 1.3 my $mod = $res->owner_module;
1105     unless ($mod->is_defined) {
1106     $ReferredResource{$uri} = -1;
1107     next U;
1108     } elsif (not ($ReferredResource{$mod->uri} < 0)) {
1109     unshift @ruri, $uri;
1110     unshift @ruri, $mod->uri;
1111     next U;
1112     }
1113     append_datatype_documentation
1114     (result_parent => $body->create_module ($mod->uri),
1115     source_resource => $res);
1116     } elsif ($res->is_type_uri (ExpandedURI q<DISLang:AnyMethod>) or
1117 wakaba 1.8 $res->is_type_uri (ExpandedURI q<DISLang:ConstGroup>)) {
1118 wakaba 1.2 my $cls = $res->get_property_resource
1119     (ExpandedURI q<dis2pm:parentResource>);
1120     if (not ($ReferredResource{$cls->uri} < 0) and
1121 wakaba 1.8 ($cls->is_type_uri (ExpandedURI q<DISLang:Class>) or
1122     $cls->is_type_uri (ExpandedURI q<DISLang:Interface>))) {
1123 wakaba 1.2 unshift @ruri, $uri;
1124     unshift @ruri, $cls->uri;
1125     next U;
1126     }
1127     my $model = $body->create_module ($cls->owner_module->uri);
1128 wakaba 1.8 my $clsel = $cls->is_type_uri (ExpandedURI q<DISLang:Class>)
1129 wakaba 1.2 ? $model->create_class ($cls->uri)
1130     : $model->create_interface ($cls->uri);
1131     if ($res->is_type_uri (ExpandedURI q<DISLang:Method>)) {
1132     append_method_documentation
1133     (result_parent => $clsel,
1134     source_resource => $res);
1135 wakaba 1.3 } elsif ($res->is_type_uri (ExpandedURI q<DISLang:Attribute>)) {
1136 wakaba 1.2 append_attr_documentation
1137 wakaba 1.3 (result_parent => $clsel,
1138     source_resource => $res);
1139 wakaba 1.8 } elsif ($res->is_type_uri (ExpandedURI q<DISLang:ConstGroup>)) {
1140 wakaba 1.3 append_constgroup_documentation
1141     (result_parent => $clsel,
1142 wakaba 1.2 source_resource => $res);
1143 wakaba 1.8 } else {
1144     $ReferredResource{$res->uri} = -1;
1145 wakaba 1.2 }
1146     } elsif ($res->is_type_uri (ExpandedURI q<DISLang:MethodParameter>)) {
1147     my $m = $res->get_property_resource
1148     (ExpandedURI q<dis2pm:parentResource>);
1149     if (not ($ReferredResource{$m->uri} < 0) and
1150     $m->is_type_uri (ExpandedURI q<DISLang:Method>)) {
1151     unshift @ruri, $m->uri;
1152 wakaba 1.4 $ReferredResource{$res->uri} = -1;
1153 wakaba 1.2 next U;
1154     }
1155 wakaba 1.8 } elsif ($res->is_type_uri (ExpandedURI q<DISLang:Const>)) {
1156 wakaba 1.3 my $m = $res->get_property_resource
1157     (ExpandedURI q<dis2pm:parentResource>);
1158     if (not ($ReferredResource{$m->uri} < 0) and
1159 wakaba 1.8 $m->is_type_uri (ExpandedURI q<DISLang:ConstGroup>)) {
1160 wakaba 1.3 unshift @ruri, $m->uri;
1161 wakaba 1.4 $ReferredResource{$res->uri} = -1;
1162 wakaba 1.3 next U;
1163 wakaba 1.8 } else {
1164     $ReferredResource{$res->uri} = -1;
1165     next U;
1166     }
1167 wakaba 1.3 } elsif ($res->is_type_uri
1168     (ExpandedURI q<ManakaiDOM:ExceptionOrWarningSubType>)) {
1169     my $m = $res->get_property_resource
1170     (ExpandedURI q<dis2pm:parentResource>);
1171     if (not ($ReferredResource{$m->uri} < 0) and
1172 wakaba 1.8 $m->is_type_uri (ExpandedURI q<DISLang:Const>)) {
1173 wakaba 1.3 unshift @ruri, $m->uri;
1174 wakaba 1.4 $ReferredResource{$res->uri} = -1;
1175 wakaba 1.3 next U;
1176 wakaba 1.8 } else {
1177     $ReferredResource{$res->uri} = -1;
1178     next U;
1179     }
1180 wakaba 1.2 } else { ## Unsupported type
1181     $ReferredResource{$uri} = -1;
1182     }
1183     } # U
1184     }
1185    
1186 wakaba 1.8 status_msg '';
1187 wakaba 1.5 status_msg q<done>;
1188    
1189     ## -- Inheriting methods information
1190 wakaba 1.1
1191 wakaba 1.5 {
1192     verbose_msg_ q<Adding inheritance information...>;
1193     my %class_done;
1194     for my $class_uri (@ClassInheritance) {
1195     next if $class_done{$class_uri};
1196     $class_done{$class_uri};
1197     for my $sclass_uri (@{$ClassInheritance{$class_uri}}) {
1198     for my $scm_name (keys %{$ClassMembers{$sclass_uri}}) {
1199     if ($ClassMembers{$class_uri}->{$scm_name}) {
1200     $ClassMembers{$class_uri}->{$scm_name}->{overrides}
1201     ->{$ClassMembers{$sclass_uri}->{$scm_name}->{resource}->uri} = 1;
1202     } else {
1203     $ClassMembers{$class_uri}->{$scm_name}
1204     = {
1205     %{$ClassMembers{$sclass_uri}->{$scm_name}},
1206     is_inherited => 1,
1207     };
1208     }
1209     }
1210     } # superclasses
1211     } # classes
1212 wakaba 1.1
1213 wakaba 1.8 verbose_msg_ q<...>;
1214    
1215 wakaba 1.5 for my $class_uri (keys %ClassImplements) {
1216     for my $if_uri (keys %{$ClassImplements{$class_uri}||{}}) {
1217     for my $mem_name (keys %{$ClassMembers{$if_uri}}) {
1218     unless ($ClassMembers{$class_uri}->{$mem_name}) {
1219     ## Not defined - error
1220     $ClassMembers{$class_uri}->{$mem_name}
1221     = {
1222     %{$ClassMembers{$if_uri}->{$mem_name}},
1223     is_inherited => 1,
1224     };
1225     }
1226     $ClassMembers{$class_uri}->{$mem_name}->{implements}
1227     ->{$ClassMembers{$if_uri}->{$mem_name}->{resource}->uri} = 1;
1228     }
1229     } # interfaces
1230     } # classes
1231    
1232 wakaba 1.8 verbose_msg_ q<...>;
1233    
1234 wakaba 1.5 for my $class_uri (keys %ClassMembers) {
1235     my $cls_res = $db->get_resource ($class_uri);
1236     next unless $cls_res->is_defined;
1237     verbose_msg_ q<.>;
1238     my $cls_el = $body->create_module ($cls_res->owner_module->uri);
1239 wakaba 1.8 if ($cls_res->is_type_uri (ExpandedURI q<DISLang:Interface>)) {
1240 wakaba 1.5 $cls_el = $cls_el->create_interface ($class_uri);
1241     } else {
1242     $cls_el = $cls_el->create_class ($class_uri);
1243     }
1244     for my $mem_name (keys %{$ClassMembers{$class_uri}}) {
1245     my $mem_info = $ClassMembers{$class_uri}->{$mem_name};
1246     my $el;
1247     if ($mem_info->{type} eq 'const-group') {
1248     $el = $cls_el->create_const_group ($mem_name);
1249     } elsif ($mem_info->{type} eq 'attr') {
1250     $el = $cls_el->create_attribute ($mem_name);
1251     } else {
1252     $el = $cls_el->create_method ($mem_name);
1253     }
1254     if ($mem_info->{is_inherited}) {
1255     $el->ref ($mem_info->{resource}->uri);
1256     }
1257     for my $or (keys %{$mem_info->{overrides}||{}}) {
1258     $el->append_new_overrides ($or);
1259     }
1260     for my $or (keys %{$mem_info->{implements}||{}}) {
1261     $el->append_new_implements ($or);
1262     }
1263     } # members
1264     } # classes
1265    
1266     verbose_msg q<done>;
1267     undef %ClassMembers;
1268     }
1269    
1270     {
1271     status_msg_ qq<Writing file ""...>;
1272    
1273     require Encode;
1274     my $lsimpl = $impl->get_feature (ExpandedURI q<DOMLS:LS> => '3.0');
1275     my $serializer = $lsimpl->create_mls_serializer
1276 wakaba 1.1 ({ExpandedURI q<DOMLS:SerializeDocumentInstance> => ''});
1277 wakaba 1.5 my $serialized = $serializer->write_to_string ($doc);
1278 wakaba 1.6 verbose_msg_ qq< serialized, >;
1279     my $encoded = Encode::encode ('utf8', $serialized);
1280     verbose_msg_ qq<bytenized, and >;
1281     print STDOUT $encoded;
1282 wakaba 1.5 close STDOUT;
1283     status_msg qq<done>;
1284     }
1285 wakaba 1.1
1286     verbose_msg_ qq<Checking undefined resources...>;
1287     $db->check_undefined_resource;
1288     verbose_msg qq<done>;
1289    
1290     verbose_msg_ qq<Closing database...>;
1291 wakaba 1.5 $db->free;
1292 wakaba 1.1 undef $db;
1293     verbose_msg qq<done>;
1294    
1295 wakaba 1.8
1296     {
1297     use integer;
1298     my $time = time - $start_time;
1299     status_msg sprintf qq<%d'%02d''>, $time / 60, $time % 60;
1300     }
1301    
1302 wakaba 1.5 END {
1303     $db->free if $db;
1304     }
1305    
1306 wakaba 1.1 =head1 SEE ALSO
1307    
1308     L<lib/manakai/dis.pl> and L<bin/cdis2pm.pl> - Old version of
1309     this script.
1310    
1311 wakaba 1.5 L<lib/Message/Util/DIS.dis> - The I<dis> object implementation.
1312 wakaba 1.1
1313     L<lib/Message/Util/PerlCode.dis> - The Perl code generator.
1314    
1315     L<lib/manakai/DISCore.dis> - The definition for the "dis" format.
1316    
1317     L<lib/manakai/DISPerl.dis> - The definition for the "dis" Perl-specific
1318     vocabulary.
1319    
1320     =head1 LICENSE
1321    
1322     Copyright 2004-2005 Wakaba <w@suika.fam.cx>. All rights reserved.
1323    
1324     This program is free software; you can redistribute it and/or
1325     modify it under the same terms as Perl itself.
1326    
1327     =cut
1328    
1329 wakaba 1.8 1; # $Date: 2005/09/19 16:17:50 $

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24