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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.10 - (hide annotations) (download)
Sun Sep 25 14:53:02 2005 UTC (19 years, 2 months ago) by wakaba
Branch: MAIN
Changes since 1.9: +92 -24 lines
File MIME type: text/plain
++ manakai/bin/ChangeLog	25 Sep 2005 14:45:44 -0000
2005-09-25  Wakaba  <wakaba@suika.fam.cx>

	* dac.pl, dac2pm.pl, mkdisdump.pl: Parameters "--dis-file-suffix",
	"--daem-file-suffix", "--search-path-catalog-file-name", and
	"--search-path" added.  New dae and daem database format support.
	(dac_search_file_stem): New function.

++ manakai/lib/Message/Markup/ChangeLog	25 Sep 2005 14:47:09 -0000
2005-09-25  Wakaba  <wakaba@suika.fam.cx>

	* Makefile (DAC_SUFFIX): Changed to ".dae".
	(DAEM_SUFFIX): New.

++ manakai/lib/Message/Util/ChangeLog	25 Sep 2005 14:50:33 -0000
2005-09-25  Wakaba  <wakaba@suika.fam.cx>

	* DIS.dis (RESOURCE_NOT_DEFINED_ERR): New error code.
	(getResource): New "dae" and "daem" database format support.
	(DISResourceList): New type.
	(uriRef, ownerModuleURI, ownerModuleURIRef): New attributes.
	(addChildResource, addDynamicChildResource): New methods.
	(getChildResourceList, getDynamicChildResourceList): New method.
	(getChildResourceListByType): New method.
	(parentResource, dynamicParentResource): New attributes.

	* Makefile (DAC_SUFFIX): Changed to ".dae".
	(DAEM_SUFFIX): New.

++ manakai/lib/Message/Util/DIS/ChangeLog	25 Sep 2005 14:52:26 -0000
2005-09-25  Wakaba  <wakaba@suika.fam.cx>

	* Perl.dis (plLoadDISDatabase): New "moduleResolver" parameter
	added.
	(plStore): New "moduleResolver" parameter added.
	(plLoadDISDatabaseModule): New method.

++ manakai/lib/Message/DOM/ChangeLog	25 Sep 2005 14:47:15 -0000
2005-09-25  Wakaba  <wakaba@suika.fam.cx>

	* Makefile (DAC_SUFFIX): Changed to ".dae".
	(DAEM_SUFFIX): New.

++ manakai/lib/manakai/ChangeLog	25 Sep 2005 14:46:50 -0000
2005-09-25  Wakaba  <wakaba@suika.fam.cx>

	* Makefile (DAC_SUFFIX): Changed to ".dae".
	(DAEM_SUFFIX): New.

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24