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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.11 - (hide annotations) (download)
Mon Sep 26 14:37:34 2005 UTC (19 years, 2 months ago) by wakaba
Branch: MAIN
Changes since 1.10: +8 -15 lines
File MIME type: text/plain
++ manakai/lib/Message/Markup/ChangeLog	26 Sep 2005 14:25:44 -0000
2005-09-26  Wakaba  <wakaba@suika.fam.cx>

	* SuikaWikiConfig21.dis: New mn:* properties added.
	(swcfg21:parent): Abbrevation added.

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

	* ManakaiNode.dis (new): New "className" parameter added.
	(mn:NodeRefRole): New role.
	(mn:type): New property.
	(mn:subnode0, mn:subnode1, mn:subnode2, mn:irefnode0,
	mn:origin0, mn:anydata1, mn:anydata2, mn:noderef): New properties.

	* Makefile: Rules to make "DIS/DISDump" is separeted
	from "DIS/DISDoc".

	* DIS.dis (getFor): Loads database module if unread
	"for" is referenced.
	(addResourceList, getResourceList): New method.
	(ManakaiDISModuleLite): New class.

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

	* DISDump.dis: Removes reference to DISDoc module.
	(DIS:DISDump10): Requires "XML" version "3.0" and
	"XMLVersion" version "1.1".
	(ManakaiDISImplementationDISDump): No longer extends
	the "ManakaiDISImplementationDISDoc" class.

	* Perl.dis (plLoadDISDatabaseModule): Support
	for loading "for"s and modules.
	(plCodeFragment): New "mn:NodeRefRole" role support added.

++ manakai/lib/Message/DOM/ChangeLog	26 Sep 2005 14:24:56 -0000
2005-09-26  Wakaba  <wakaba@suika.fam.cx>

	* DOMCore.dis, DOMXML.dis: New mn:* properties added.

++ manakai/lib/manakai/ChangeLog	26 Sep 2005 14:37:23 -0000
2005-09-26  Wakaba  <wakaba@suika.fam.cx>

	* DISPerl.dis (DISPerl:Regexp): New type.

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24