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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.10 - (hide annotations) (download)
Sun Dec 19 10:57:49 2004 UTC (19 years, 11 months ago) by wakaba
Branch: MAIN
Changes since 1.9: +134 -31 lines
File MIME type: text/plain
Daily

1 wakaba 1.1 #!/usr/bin/perl -w
2     use strict;
3     use Message::Util::QName::Filter {
4     d => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/lang#dis-->,
5     dis2pm => q<http://suika.fam.cx/~wakaba/archive/2004/11/8/dis2pm#>,
6 wakaba 1.10 DISCore => q<http://suika.fam.cx/~wakaba/archive/2004/dis/Core#>,
7     DISLang => q<http://suika.fam.cx/~wakaba/archive/2004/dis/Lang#>,
8 wakaba 1.9 DISPerl => q<http://suika.fam.cx/~wakaba/archive/2004/dis/Perl#>,
9 wakaba 1.4 disPerl => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/lang#dis--Perl-->,
10 wakaba 1.1 DOMCore => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/dom-core#>,
11     DOMMain => q<http://suika.fam.cx/~wakaba/archive/2004/dom/main#>,
12     lang => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/lang#>,
13     Perl => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/lang#Perl-->,
14     license => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/license#>,
15     ManakaiDOM => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/manakai-dom#>,
16 wakaba 1.3 MDOMX => q<http://suika.fam.cx/~wakaba/archive/2004/8/4/manakai-dom-exception#>,
17 wakaba 1.1 owl => q<http://www.w3.org/2002/07/owl#>,
18     rdf => q<http://www.w3.org/1999/02/22-rdf-syntax-ns#>,
19     rdfs => q<http://www.w3.org/2000/01/rdf-schema#>,
20 wakaba 1.10 TreeCore => q<>,
21 wakaba 1.1 };
22    
23     use Getopt::Long;
24     use Pod::Usage;
25     use Storable;
26     my %Opt;
27     GetOptions (
28     'for=s' => \$Opt{For},
29     'help' => \$Opt{help},
30     'module-name=s' => \$Opt{module_name},
31     'module-uri=s' => \$Opt{module_uri},
32     'verbose!' => $Opt{verbose},
33     ) or pod2usage (2);
34     pod2usage ({-exitval => 0, -verbose => 1}) if $Opt{help};
35     $Opt{file_name} = shift;
36     pod2usage ({-exitval => 2, -verbose => 0}) unless $Opt{file_name};
37     pod2usage (2) if not $Opt{module_uri} and not $Opt{module_name};
38    
39     BEGIN {
40     require 'manakai/genlib.pl';
41     require 'manakai/dis.pl';
42     }
43     our $State = retrieve ($Opt{file_name})
44     or die "$0: $Opt{file_name}: Cannot load";
45     our $result = '';
46    
47     eval q{
48     sub impl_msg ($;%) {
49     warn shift () . "\n";
50     }
51     } unless $Opt{verbose};
52    
53     sub perl_change_package (%) {
54     my %opt = @_;
55     my $fn = $opt{full_name};
56     impl_err (qq<$fn: Bad package name>) unless $fn;
57     unless ($fn eq $State->{ExpandedURI q<dis2pm:currentPackage>}) {
58     $State->{ExpandedURI q<dis2pm:currentPackage>} = $fn;
59     return perl_statement qq<package $fn>;
60     } else {
61     return '';
62     }
63     } # perl_change_package
64    
65 wakaba 1.3 =item $code = dispm_perl_throws (%opt)
66    
67     Generates a code to throw an exception.
68    
69     =cut
70    
71     sub dispm_perl_throws (%) {
72     my %opt = @_;
73 wakaba 1.8 my $x = $opt{class_resource} || $State->{Type}->{$opt{class}};
74 wakaba 1.3 my $r = 'report ';
75     unless (defined $x->{Name}) {
76     $opt{class} = dis_typeforuris_to_uri ($opt{class}, $opt{class_for}, %opt);
77     $x = $State->{Type}->{$opt{class}};
78     }
79     valid_err (qq<Exception class <$opt{class}> is not defined>,
80     node => $opt{node}) unless defined $x->{Name};
81     if ($x->{ExpandedURI q<dis2pm:type>} and
82     {
83     ExpandedURI q<ManakaiDOM:ExceptionClass> => 1,
84     ExpandedURI q<ManakaiDOM:WarningClass> => 1,
85     }->{$x->{ExpandedURI q<dis2pm:type>}}) {
86 wakaba 1.8 $opt{type} = $opt{type_resource}->{Name} unless defined $opt{type};
87     valid_err qq{Exception code must be specified},
88     node => $opt{type_resource}->{src} || $opt{node}
89     unless defined $opt{type};
90 wakaba 1.10 $opt{subtype} = $opt{subtype_resource}->{NameURI} ||
91     $opt{subtype_resource}->{URI} unless defined $opt{subtype};
92 wakaba 1.8 $opt{xparam}->{ExpandedURI q<MDOMX:subtype>} = $opt{subtype}
93     if defined $opt{subtype};
94 wakaba 1.3 $r .= $x->{ExpandedURI q<dis2pm:packageName>} . ' ' .
95     perl_list -type => $opt{type},
96     -object => perl_code_literal ('$self'),
97     %{$opt{xparam} || {}};
98     } else {
99     no warnings 'uninitialized';
100 wakaba 1.8 valid_err (qq{Resource <$opt{class}> [<$x->{ExpandedURI q<dis2pm:type>}>] }.
101     q<is neither an exception class nor >.
102     q<a warning class>, node => $opt{node});
103 wakaba 1.3 }
104     return $r;
105     } # dispm_perl_throw
106    
107 wakaba 1.10 my $RegQNameChar = qr/[^\s<>"'\\\[\]\{\}]/;
108 wakaba 1.3 {
109     use re 'eval';
110     my $RegBlockContent;
111     $RegBlockContent = qr/(?>[^{}\\]*)(?>(?>[^{}\\]+|\\.|\{(??{$RegBlockContent})\})*)/s;
112     ## Defined by genlib.pl but overridden.
113     sub perl_code ($;%) {
114     my ($s, %opt) = @_;
115     valid_err q<Uninitialized value in perl_code>,
116     node => $opt{node} unless defined $s;
117     local $State->{Namespace}
118     = $State->{Module}->{$opt{resource}->{parentModule}}->{nsBinding};
119 wakaba 1.8 $s =~ s[<($RegQNameChar[^<>]+)>|\b(null|true|false)\b][
120 wakaba 1.3 my ($q, $l) = ($1, $2);
121 wakaba 1.4 my $r;
122 wakaba 1.3 if (defined $q) {
123     if ($q =~ /\}/) {
124 wakaba 1.4 valid_warn qq<"<$q>" has a "}" - it might be a typo>;
125     }
126     if ($q =~ s/^(.+?):://) {
127     my $et = dis_qname_to_uri
128     ($1, %opt,
129     use_default_namespace => ExpandedURI q<disPerl:>);
130     if ($et eq ExpandedURI q<disPerl:Q>) { ## QName constant
131     $r = perl_literal (dis_qname_to_uri ($q, use_default_namespace => 1,
132     %opt));
133 wakaba 1.10 } elsif ({
134     ExpandedURI q<disPerl:M> => 1,
135     ExpandedURI q<disPerl:ClassM> => 1,
136     ExpandedURI q<disPerl:AG> => 1,
137     ExpandedURI q<disPerl:AS> => 1,
138     }->{$et}) { ## Method call
139 wakaba 1.6 my ($clsq, $mtdq) = split /\s*\.\s*/, $q, 2;
140 wakaba 1.4 my $clsu = dis_typeforqnames_to_uri ($clsq,
141     use_default_namespace => 1, %opt);
142     my $cls = $State->{Type}->{$clsu};
143     my $clsp = $cls->{ExpandedURI q<dis2pm:packageName>};
144 wakaba 1.6 if ($cls->{ExpandedURI q<dis2pm:type>} and
145     {
146     ExpandedURI q<ManakaiDOM:IF> => 1,
147     ExpandedURI q<ManakaiDOM:ExceptionIF> => 1,
148     }->{$cls->{ExpandedURI q<dis2pm:type>}}) {
149     valid_err q<"disPerl:ClassM" cannot be used for interface methods>,
150     node => $opt{node} if $et eq ExpandedURI q<disPerl:ClassM>;
151     $clsp = '';
152     } else {
153     valid_err qq<Package name of class <$clsu> must be defined>,
154     node => $opt{node} unless defined $clsp;
155     $State->{Module}->{$State->{module}}
156     ->{ExpandedURI q<dis2pm:requiredModule>}
157     ->{$State->{Module}->{$cls->{parentModule}}
158     ->{ExpandedURI q<dis2pm:packageName>}} = 1;
159     }
160 wakaba 1.4 if ($mtdq =~ /:/) {
161     valid_err qq<$mtdq: Prefixed method name not supported>,
162     node => $opt{node};
163     } else {
164     my $mtd;
165     for (values %{$cls->{ExpandedURI q<dis2pm:method>}}) {
166     if (defined $_->{Name} and $_->{Name} eq $mtdq) {
167     $mtd = $_;
168     last;
169     }
170     }
171     valid_err qq<Perl method name for method "$clsp.$mtdq" must >.
172     q<be defined>, node => $mtd->{src} || $opt{node}
173     if not defined $mtd or
174     not defined $mtd->{ExpandedURI q<dis2pm:methodName>};
175 wakaba 1.6 $r = ' ' . ($clsp ? $clsp .
176 wakaba 1.10 {
177     ExpandedURI q<disPerl:M> => '::',
178     ExpandedURI q<disPerl:AG> => '::',
179     ExpandedURI q<disPerl:AS> => '::',
180     ExpandedURI q<disPerl:ClassM> => '->',
181     }->{$et}
182 wakaba 1.6 : '') .
183 wakaba 1.4 $mtd->{ExpandedURI q<dis2pm:methodName>} . ' ';
184     }
185 wakaba 1.9 } elsif ($et eq ExpandedURI q<disPerl:ClassName> ||
186     $et eq ExpandedURI q<disPerl:IFName>) {
187 wakaba 1.4 ## Perl package name
188     my $uri = dis_typeforqnames_to_uri ($q,
189     use_default_namespace => 1, %opt);
190     if (defined $State->{Type}->{$uri}->{Name} and
191     defined $State->{Type}->{$uri}
192     ->{ExpandedURI q<dis2pm:packageName>}) {
193     $r = perl_literal ($State->{Type}->{$uri}
194     ->{ExpandedURI q<dis2pm:packageName>});
195     } else {
196     valid_err qq<Package name of class <$uri> must be defined>,
197     node => $opt{node};
198     }
199 wakaba 1.9 } elsif ($et eq ExpandedURI q<disPerl:Code>) { ## CODE constant
200 wakaba 1.4 my $uri = dis_typeforqnames_to_uri ($q, use_default_namespace => 1,
201     %opt);
202     if (defined $State->{Type}->{$uri}->{Name} and
203     dis_resource_ctype_match (ExpandedURI q<dis2pm:InlineCode>,
204     $State->{Type}->{$uri}, %opt)) {
205 wakaba 1.5 ## ISSUE: It might be required to check loop referring
206 wakaba 1.4 $r = dispm_get_code (%opt, resource => $State->{Type}->{$uri},
207     For => [keys %{$State->{Type}->{$uri}
208     ->{For}}]->[0],
209     is_inline => 1);
210     } else {
211     valid_err qq<Inline code constant <$uri> must be defined>,
212     node => $opt{node};
213     }
214     } else {
215     valid_err qq<"$et": Unknown element type>, node => $opt{node};
216     }
217     } else {
218     valid_err qq<"<$q>": Element type must be specified>, node => $opt{node};
219 wakaba 1.3 }
220     } else {
221 wakaba 1.4 $r = {true => 1, false => 0, null => 'undef'}->{$l};
222 wakaba 1.3 }
223 wakaba 1.4 $r;
224 wakaba 1.3 ]ge;
225     ## TODO: Ensure Message::Util::Error imported if "try"ing.
226     ## ISSUE: __FILE__ & __LINE__ will break if multiline substition happens.
227     $s =~ s{
228     \b__([A-Z]+)
229     (?:\{($RegBlockContent)\})?
230     __\b
231     }{
232     my ($name, $data) = ($1, $2);
233     my $r;
234 wakaba 1.7 my $et = dis_qname_to_uri
235     ($name, %opt,
236     use_default_namespace => ExpandedURI q<disPerl:>);
237 wakaba 1.5 if ($name eq 'XINT') { ## Inserting point of the for-internal code
238 wakaba 1.3 if (defined $data) {
239     if ($data =~ /^{($RegBlockContent)}$/o) {
240     $data = $1;
241     my $name = $1 if $data =~ s/^\s*(\w+)\s*(?:$|:\s*)// or
242     valid_err qq<Syntax of preprocessing macro "INT" is invalid>,
243     node => $opt{node};
244     #local $Status->{preprocess_variable}
245     # = {%{$Status->{preprocess_variable}||{}}};
246     while ($data =~ /\G(\S+)\s*(?:=>\s*(\S+)\s*)?(?:,\s*|$)/g) {
247     my ($n, $v) = ($1, defined $2 ? $2 : 1);
248     for ($n, $v) {
249     s/^'([^']+)'$/$1/; ## ISSUE: Doesn't support quoted-'
250     }
251     #$Status->{preprocess_variable}->{$n} = $v;
252     }
253     valid_err q<Preprocessing macro INT{} cannot be used here>
254     unless $opt{internal};
255     $r = perl_comment ("INT: $name").
256     $opt{internal}->($name);
257     } elsif ($data =~ s/^SP://) {
258     $r = '___'.$data;
259     } else {
260     $r = perl_internal_name $data;
261     }
262     } else {
263     valid_err q<Preprocessing macro INT cannot be used here>
264     unless $opt{internal};
265     $r = $opt{internal}->();
266     }
267     } elsif ($name eq 'DEEP') { ## Deep Method Call
268 wakaba 1.6 $r = '{'.perl_statement ('local $Error::Depth = $Error::Depth + 1').
269     perl_code ($data) .
270 wakaba 1.3 '}';
271 wakaba 1.8 } elsif ($name eq 'EXCEPTION' or $name eq 'WARNING') {
272 wakaba 1.3 ## Raising an Exception or Warning
273 wakaba 1.8 if ($data =~ s/^ \s* ((?>(?! ::|\.)$RegQNameChar)+) \s*
274     (?: \. \s* ((?>(?! ::|\.)$RegQNameChar)+) \s*
275     (?: \. \s* ((?>(>! ::|\.)$RegQNameChar)+) \s*
276     )?
277     )?
278     (?: ::\s* | $)//ox) {
279     my ($q, $constq, $subtypeq) = ($1, $2, $3);
280     $q =~ s/\|\|/::/g;
281     my $clsuri;
282     my $cls;
283     my $consturi;
284     my $const;
285     my $subtypeuri;
286     my $subtype;
287     if (defined $constq and not defined $subtypeq) {
288     $clsuri = dis_typeforqnames_to_uri ($q,
289     use_default_namespace => 1,
290     %opt);
291     $cls = $State->{Type}->{$clsuri};
292     valid_err qq{Exception/warning class definition for }.
293     qq{<$clsuri> is required}, node => $opt{node}
294     unless defined $cls->{Name};
295     my ($consttq, $constfq) = split /\|\|/, $constq, 2;
296     if (defined $constfq) {
297     if ($consttq !~ /:/) {
298     valid_err qq<"$constq": Unprefixed exception code QName must >.
299     q<not be followed by a "For" QName>,
300     node => $opt{node};
301     } else {
302     $consturi = dis_typeforqnames_to_uri ($consttq.'::'.$constfq,
303     use_default_namespace => 1,
304     %opt);
305     }
306     } else {
307     if ($consttq !~ /:/) {
308     $consturi = $consttq;
309     CONSTCLS: {
310     for (values %{$cls->{ExpandedURI q<dis2pm:xConst>}}) {
311     if (defined $_->{Name} and $_->{Name} eq $consturi) {
312     $const = $_;
313     last CONSTCLS;
314     }
315     }
316     valid_err qq{Exception/warning code "$consturi" must be }.
317     qq{defined in the exception/warning class }.
318     qq{<$clsuri>}, node => $opt{node};
319     }
320     } else {
321     $consturi = dis_typeforqnames_to_uri ($consttq.'::'.$constfq,
322     use_default_namespace => 1,
323     %opt);
324     }
325     }
326     unless ($const) {
327     CONSTCLS: {
328     for (values %{$cls->{ExpandedURI q<dis2pm:xConst>}}) {
329     if (defined $_->{Name} and $_->{URI} and
330     $_->{URI} eq $consturi) {
331     $const = $_;
332     last CONSTCLS;
333     }
334     }
335     valid_err qq{Exception/warning code <$consturi> must be }.
336     qq{defined in the exception/warning class }.
337     qq{<$clsuri>}, node => $opt{node};
338     }
339     }
340     } else { ## By code/subtype QName
341     $subtypeq = $q unless defined $constq;
342     $subtypeuri = dis_typeforqnames_to_uri ($subtypeq,
343     use_default_namespace => 1,
344     %opt);
345     $subtype = $State->{Type}->{$subtypeuri};
346     valid_err qq{Exception/warning code/subtype <$subtypeuri> must }.
347     qq{be defined}, node => $opt{node}
348     unless defined $subtype->{Name} and
349     defined $subtype->{ExpandedURI q<dis2pm:type>};
350     if ($subtype->{ExpandedURI q<dis2pm:type>} eq
351     ExpandedURI q<ManakaiDOM:ExceptionOrWarningSubType>) {
352     $const = $subtype->{ExpandedURI q<dis2pm:parentResource>};
353     $cls = $subtype->{ExpandedURI q<dis2pm:grandGrandParentResource>};
354     } elsif ($subtype->{ExpandedURI q<dis2pm:type>} eq
355     ExpandedURI q<ManakaiDOM:Const>) {
356     $const = $subtype;
357     $subtype = undef;
358     $cls = $const->{ExpandedURI q<dis2pm:grandParentResource>};
359     } else {
360     valid_err qq{Type of <$subtypeuri> must be either }.
361     q{"ManakaiDOM:Const" or }.
362     q{"ManakaiDOM:ExceptionOrWarningSubType"},
363     node => $opt{node};
364     }
365     }
366    
367     ## Parameter
368     my %xparam;
369     while ($data =~ s/^\s*($RegQNameChar+)\s*//) {
370     my $pnameuri = dis_qname_to_uri ($1, use_default_namespace => 1, %opt);
371     if (defined $xparam{$pnameuri}) {
372     valid_err qq<Exception parameter <$pnameuri> is already specified>,
373     node => $opt{node};
374     }
375     if ($data =~ s/^=>\s*'([^']*)'\s*//) { ## String
376     $xparam{$pnameuri} = $1;
377     } elsif ($data =~ s/^=>\s*\{($RegBlockContent)\}\s*//) { ## Code
378     $xparam{$pnameuri} = perl_code_literal ($1);
379     } elsif ($data =~ /^,|$/) { ## Boolean
380     $xparam{$pnameuri} = 1;
381     } else {
382     valid_err qq<<$pnameuri>: Parameter value is expected>,
383     node => $opt{node};
384     }
385     $data =~ s/^\,\s*// or last;
386     }
387     valid_err qq<"$data": Broken exception parameter specification>,
388     node => $opt{node} if length $data;
389     for (
390     ExpandedURI q<MDOMX:class>,
391     ExpandedURI q<MDOMX:method>,
392     ExpandedURI q<MDOMX:attr>,
393     ExpandedURI q<MDOMX:on>,
394     ) {
395     $xparam{$_} = $opt{$_} if defined $opt{$_};
396     }
397    
398     $r = dispm_perl_throws
399     (%opt,
400     class_resource => $cls,
401     class_for => $opt{For},
402     type_resource => $const,
403     subtype_resource => $subtype,
404     xparam => \%xparam);
405 wakaba 1.3 } else {
406     valid_err qq<Exception type and name required: "$data">,
407     node => $opt{node};
408     }
409 wakaba 1.7 } elsif ($et eq ExpandedURI q<disPerl:CODE>) {
410 wakaba 1.3 my ($nm, %param);
411 wakaba 1.7 $data =~ s/^\s+//;
412     if ($data =~ s/^((?>(?!::).)+)//) {
413 wakaba 1.3 $nm = $1;
414     } else {
415 wakaba 1.7 valid_err q<Code name required>, node => $opt{node};
416 wakaba 1.3 }
417 wakaba 1.7 $data =~ s/^::\s*//;
418 wakaba 1.10 while ($data
419     =~ s/^($RegQNameChar+)\s*(?:=>\s*($RegQNameChar+)\s*)?(?:,\s*|$)//o) {
420     my ($n, $v) = ($1, $2);
421     $v = 1 unless defined $v;
422     if ($n =~ /^\$/) {
423     $param{$n} = $v;
424     } else {
425     $param{dis_qname_to_uri ($n, %opt, use_default_namespace => '')} = $v;
426     }
427 wakaba 1.3 }
428 wakaba 1.7 valid_err qq<Broken CODE argument: "$data">, node => $opt{node}
429     if length $data;
430    
431     my $uri = dis_typeforqnames_to_uri ($nm, use_default_namespace => 1,
432     %opt);
433     if (defined $State->{Type}->{$uri}->{Name} and
434     dis_resource_ctype_match (ExpandedURI q<dis2pm:BlockCode>,
435     $State->{Type}->{$uri}, %opt)) {
436 wakaba 1.10 local $State->{ExpandedURI q<dis2pm:blockCodeParam>} = \%param;
437     ## ISSUE: It might be required to detect a loop
438 wakaba 1.7 $r = dispm_get_code (%opt, resource => $State->{Type}->{$uri},
439     For => [keys %{$State->{Type}->{$uri}
440     ->{For}}]->[0]);
441     for (grep {/^\$/} keys %param) {
442     $r =~ s/\Q$_\E\b/ $param{$_} /g;
443     }
444     $r = "\n{\n$r\n}\n";
445     } else {
446     valid_err qq<Block code constant <$uri> must be defined>,
447     node => $opt{node};
448     }
449 wakaba 1.3 } elsif ($name eq 'XPACKAGE' and $data) {
450     if ($data eq 'Global') {
451     #$r = $ManakaiDOMModulePrefix;
452     } else {
453     valid_err qq<PACKAGE "$data" not supported>;
454     }
455     } elsif ($name eq 'XREQUIRE') {
456     #$r = perl_statement (q<require >. perl_package_name name => $data);
457 wakaba 1.10 } elsif ($et eq ExpandedURI q<disPerl:WHEN>) {
458 wakaba 1.3 if ($data =~ s/^\s*IS\s*\{($RegBlockContent)\}::\s*//o) {
459 wakaba 1.10 my $v = dis_qname_to_uri ($1, use_default_namespace => 1, %opt);
460     if ($State->{ExpandedURI q<dis2pm:blockCodeParam>}->{$v}) {
461     $r = perl_code ($data, %opt);
462 wakaba 1.3 }
463     } else {
464     valid_err qq<Syntax for preprocessing macro "WHEN" is invalid>,
465     node => $opt{node};
466     }
467 wakaba 1.10 } elsif ($et eq ExpandedURI q<disPerl:FOR>) {
468     if ($data =~ s/^((?>(?!::).)*)::\s*//) {
469     my @For = ($opt{For} || ExpandedURI q<ManakaiDOM:all>,
470     @{$opt{'For+'} || []});
471     V: for (split /\s*\|\s*/, $1) {
472     my $for = dis_qname_to_uri ($_, %opt, use_default_namespace => 1,
473     node => $opt{node});
474     for (@For) {
475     if (dis_uri_for_match ($for, $_, %opt)) {
476     $r = perl_code ($data, %opt);
477     last V;
478     }
479     }
480     }
481     } else {
482     valid_err (qq<Broken <$et> block: "$data">, node => $opt{node});
483     }
484 wakaba 1.3 } elsif ($name eq 'FILE' or $name eq 'LINE' or $name eq 'PACKAGE') {
485     $r = qq<__${name}__>;
486     } else {
487 wakaba 1.10 valid_err qq<Preprocessing macro <$et> not supported>, node => $opt{node};
488 wakaba 1.3 }
489     $r;
490     }goex;
491     $s;
492     }
493     }
494    
495     ## Defined in genlib.pl but overridden.
496     sub perl_code_source ($%) {
497     my ($s, %opt) = @_;
498     my $npk = [qw/Name QName Label/];
499     my $f1 = sprintf q<File <%s> Node <%s> [Chunk #%d]>,
500     $opt{file} || $State->{Module}->{$opt{resource}->{parentModule}}->{FileName},
501     $opt{path} || ($opt{resource}->{src}
502     ? $opt{resource}->{src}->node_path (key => $npk)
503     : $opt{node} ? $opt{node}->node_path (key => $npk)
504     : 'x:unknown ()'),
505     ++($State->{ExpandedURI q<dis2pm:generatedChunk>} ||= 0);
506     my $f2 = sprintf q<Module <%s> [Chunk #%d]>,
507     $opt{file} || $State->{Module}->{$State->{module}}->{URI},
508     ++($State->{ExpandedURI q<dis2pm:generatedChunk>} ||= 0);
509     $f1 =~ s/"/\"/g; $f2 =~ s/"/\"/g;
510     sprintf qq<\n#line %d "%s"\n%s\n#line 1 "%s"\n>,
511     $opt{line} || 1, $f1, $s, $f2;
512     }
513    
514    
515    
516    
517     =item $code = dispm_get_code (resource => $res, %opt)
518    
519     Generates a Perl code fragment from resource(s).
520    
521     =cut
522    
523     sub dispm_get_code (%) {
524     my %opt = @_;
525 wakaba 1.7 if (($opt{ExpandedURI q<dis2pm:getCodeNoTypeCheck>} and
526     defined $opt{resource}->{Name}) or
527     ($opt{resource}->{ExpandedURI q<dis2pm:type>} and
528 wakaba 1.4 {
529     ExpandedURI q<ManakaiDOM:DOMMethodReturn> => 1,
530     ExpandedURI q<ManakaiDOM:DOMAttrGet> => 1,
531     ExpandedURI q<ManakaiDOM:DOMAttrSet> => 1,
532     }->{$opt{resource}->{ExpandedURI q<dis2pm:type>}}) or
533     (dis_resource_ctype_match ([ExpandedURI q<dis2pm:InlineCode>,
534     ExpandedURI q<dis2pm:BlockCode>],
535     $opt{resource}, %opt,
536     node => $opt{resource}->{src}))) {
537 wakaba 1.10 local $State->{Namespace}
538     = $State->{Module}->{$opt{resource}->{parentModule}}->{nsBinding}
539     if defined $opt{resource}->{Name};
540 wakaba 1.4 my $key = $opt{ExpandedURI q<dis2pm:DefKeyName>} || ExpandedURI q<d:Def>;
541 wakaba 1.9
542 wakaba 1.4 my $n = dis_get_attr_node (%opt, parent => $opt{resource}->{src},
543     name => {uri => $key},
544 wakaba 1.10 ContentType => ExpandedURI q<d:Perl>) ||
545     dis_get_attr_node (%opt, parent => $opt{resource}->{src},
546     name => {uri => $key},
547     ContentType => ExpandedURI q<lang:dis>);
548 wakaba 1.9 if ($n) {
549     return disperl_to_perl (%opt, node => $n);
550     }
551    
552     $n = dis_get_attr_node (%opt, parent => $opt{resource}->{src},
553     name => {uri => $key},
554 wakaba 1.4 ContentType => ExpandedURI q<lang:Perl>);
555     if ($n) {
556 wakaba 1.6 my $code = '';
557     for (@{dis_get_elements_nodes (%opt, parent => $n,
558     name => 'require')}) {
559     $code .= perl_statement 'require ' . $_->value;
560     }
561     $code .= perl_code ($n->value, %opt, node => $n);
562 wakaba 1.4 if ($opt{is_inline} and
563     dis_resource_ctype_match ([ExpandedURI q<dis2pm:InlineCode>],
564     $opt{resource}, %opt,
565     node => $opt{resource}->{src})) {
566     $code =~ s/\n/\x20/g;
567     return $code;
568     } else {
569     return perl_code_source ($code, %opt, node => $n);
570     }
571     }
572     return undef;
573     } else {
574     impl_err ("Bad resource for dispm_get_code: ".
575     $opt{resource}->{ExpandedURI q<dis2pm:type>},
576     node => $opt{resource}->{src});
577 wakaba 1.3 }
578     } # dispm_get_code
579    
580     =item $code = dispm_get_value (%opt)
581    
582     Gets value property and returns it as a Perl code fragment.
583    
584     =cut
585    
586     sub dispm_get_value (%) {
587     my %opt = @_;
588     my $key = $opt{ExpandedURI q<dis2pm:DefKeyName>} || ExpandedURI q<d:Value>;
589     my $vt = $opt{ExpandedURI q<dis2pm:valueType>} || ExpandedURI q<DOMMain:any>;
590 wakaba 1.10 local $State->{Namespace}
591     = $State->{Module}->{$opt{resource}->{parentModule}}->{nsBinding}
592     if defined $opt{resource}->{Name};
593     my $n = $opt{node} ? [$opt{node}]
594     : dis_get_elements_nodes
595     (%opt, parent => $opt{resource}->{src},
596 wakaba 1.3 name => {uri => $key});
597     for my $n (@$n) {
598     my $t = dis_get_attr_node (%opt, parent => $n, name => 'ContentType');
599     my $type;
600     if ($t) {
601     $type = dis_qname_to_uri ($t->value, %opt, node => $t);
602     } else {
603 wakaba 1.5 $type = ExpandedURI q<lang:dis>;
604 wakaba 1.3 }
605     valid_err (qq<Type <$type> is not defined>, node => $t || $n)
606     unless defined $State->{Type}->{$type}->{Name};
607    
608     if (dis_uri_ctype_match (ExpandedURI q<lang:Perl>, $type, %opt)) {
609     ## ISSUE: Is some pre-process required?
610     return $n->value;
611 wakaba 1.10 } elsif (dis_uri_ctype_match (ExpandedURI q<DISCore:String>, $type, %opt)) {
612     return perl_literal $n->value;
613 wakaba 1.5 } elsif (dis_uri_ctype_match (ExpandedURI q<lang:dis>, $type, %opt)) {
614     ## NOTE: This might not be a valid Perl code fragment.
615     return $n->value;
616     }
617 wakaba 1.3 }
618    
619     ## No explicit value specified
620     if ($opt{ExpandedURI q<dis2pm:useDefaultValue>}) {
621     if (dis_uri_ctype_match (ExpandedURI q<DOMMain:DOMString>, $vt, %opt)) {
622     return q<"">;
623     }
624     }
625     return undef;
626     } # dispm_get_value
627    
628    
629 wakaba 1.5
630     =item $code = dispm_const_value (resource => $const, %opt)
631    
632 wakaba 1.10 Returns a code fragment corresponding to the vaue of C<$const>.
633 wakaba 1.5
634     =cut
635    
636     sub dispm_const_value (%) {
637     my %opt = @_;
638     my $for = [keys %{$opt{resource}->{For}}]->[0];
639     my $value = dispm_get_value
640     (%opt,
641     ExpandedURI q<dis2pm:ValueKeyName>
642     => ExpandedURI q<d:Value>,
643     ExpandedURI q<dis2pm:valueType>
644     => $opt{resource}
645     ->{ExpandedURI q<dis2pm:actualType>},
646     For => $for);
647     valid_err q<Constant value must be specified>, node => $opt{resource}->{src}
648     unless defined $value;
649 wakaba 1.10 return $value;
650     } # dispm_const_value
651    
652     =item $code = dispm_const_value_sub (resource => $const, %opt)
653    
654     Returns a code fragment to declare and define a constant function
655     corresponding to the definition of C<$const>.
656    
657     =cut
658    
659     sub dispm_const_value_sub (%) {
660     my %opt = @_;
661     my $value = dispm_const_value (%opt);
662 wakaba 1.5 return perl_sub
663     (name => $opt{resource}->{ExpandedURI q<dis2pm:constName>},
664     prototype => '',
665     code => $value);
666 wakaba 1.10 } # dispm_const_value_sub
667 wakaba 1.5
668     =item $code = dispm_const_group (resource => $const_group, %opt)
669    
670     Returns a code fragment to define a constant value group.
671    
672     =cut
673    
674     sub dispm_const_group (%) {
675     my %opt = @_;
676     my $name = $opt{resource}->{ExpandedURI q<dis2pm:constGroupName>};
677     for my $cg (values %{$opt{resource}->{ExpandedURI q<dis2pm:constGroup>}}) {
678     if (defined $cg->{ExpandedURI q<dis2pm:constGroupName>}) {
679     valid_err (qq{"$name"."$cg->{ExpandedURI q<dis2pm:constGroupName>}": }.
680     qq{Nesting constant group not supported},
681     node => $cg->{src});
682     }
683     }
684     my $result = '';
685     my @cname;
686     if (length $name) {
687     if (defined $opt{ExpandedURI q<dis2pm:constGroupParentPackage>}->{$name}) {
688     valid_err qq<Const group "$name" is already defined>,
689     node => $opt{resource}->{src};
690     }
691     $opt{ExpandedURI q<dis2pm:constGroupParentPackage>}->{$name} = \@cname;
692     }
693     for my $cv (values %{$opt{resource}->{ExpandedURI q<dis2pm:const>}}) {
694     next unless defined $cv->{ExpandedURI q<dis2pm:constName>};
695 wakaba 1.10 $result .= dispm_const_value_sub (%opt, resource => $cv);
696 wakaba 1.5 push @cname, $cv->{ExpandedURI q<dis2pm:constName>};
697     }
698     return $result;
699     } # dispm_const_group
700 wakaba 1.9
701     =item $code = disperl_to_perl (node => $node, %opt)
702    
703     Converts a C<d:Perl> node to a Perl code fragment.
704    
705     =cut
706    
707     sub disperl_to_perl (%) {
708     my %opt = @_;
709     my $code = '';
710     for (@{$opt{node}->child_nodes}) {
711     next unless $_->node_type eq '#element';
712     next unless dis_node_for_match ($_, $opt{For}, %opt);
713     my $et = dis_element_type_to_uri ($_->local_name, %opt, node => $_);
714 wakaba 1.10 if ($et eq ExpandedURI q<DISLang:constValue>) {
715     my $cn = $_->value;
716     if ($cn =~ /^((?>(?!\.)$RegQNameChar)*)\.($RegQNameChar+)$/o) {
717     my ($cls, $constn) = ($1, $2);
718     if (length $cls) {
719     my $clsu = dis_typeforqnames_to_uri ($cls, %opt,
720     use_default_namespace => 1,
721     node => $_);
722     $cls = $State->{Type}->{$clsu};
723     valid_err qq<Class/IF <$clsu> must be defined>, node => $_
724     unless defined $cls->{Name};
725     } else {
726     $cls = $State->{ExpandedURI q<dis2pm:thisClass>};
727     valid_err q<Class/IF name required in this context>, node => $_
728     unless defined $cls->{Name};
729     }
730    
731     my $const = $cls->{ExpandedURI q<dis2pm:const>}->{$constn};
732     valid_err qq<Constant value "$constn" not defined in class/IF >.
733     qq{"$cls->{Name}" (<$cls->{URI}>)}, node => $_
734     unless defined $const->{Name};
735     $code .= perl_statement
736     perl_assign
737     perl_var (type => '$', local_name => 'r')
738     => dispm_const_value (resource => $const);
739     } else {
740     valid_err q<Syntax error>, node => $_;
741     }
742     } elsif ($et eq ExpandedURI q<DISLang:value>) {
743     my $v = dispm_get_value (%opt, node => $_);
744     $code .= perl_statement
745     perl_assign
746     perl_var (type => '$', local_name => 'r') => $v;
747     } elsif ($et eq ExpandedURI q<d:GetProp> or
748     $et eq ExpandedURI q<d:GetPropNode>) {
749     my $uri = dis_qname_to_uri ($_->value, %opt, node => $_,
750     use_default_namespace => 1);
751     $code .= perl_statement
752     perl_assign
753     perl_var (type => '$', local_name => 'r')
754     => '$self->{'.(ExpandedURI q<TreeCore:node>).
755     '}->{'.(perl_literal $uri).'}';
756     if ($et eq ExpandedURI q<d:GetPropNode>) {
757     $code .= perl_if
758     'defined $r',
759     perl_code (q{<M::ManakaiDOMNode.getNodeReference> ($r)},
760     %opt, node => $_);
761     }
762     } elsif ($et eq ExpandedURI q<DISPerl:selectByProp>) {
763 wakaba 1.9 my $prop = dis_get_attr_node
764     (%opt, parent => $_,
765     name => {uri => ExpandedURI q<DISPerl:propName>});
766     my $propvalue;
767     if ($prop) {
768     $prop = dis_qname_to_uri ($prop->value,
769     use_default_namespace => 1,
770     %opt, node => $prop);
771     $prop = dis_get_attr_node
772     (%opt, parent => $opt{Type},
773     name => {uri => $prop}) if $opt{Type};
774     unless ($prop) {
775     if ($prop) {
776     valid_err q<Element "DISPerl:selectByProp" cannot be used here>,
777     node => $opt{node};
778     } else {
779     $propvalue = '';
780     }
781     } else {
782     $propvalue = $prop->value;
783     }
784     } else {
785     valid_err q<Attribute "DISPerl:propName" required>,
786     node => $_;
787     }
788     my $selcase;
789     for my $case (@{$_->child_nodes}) {
790     next unless $case->node_type eq '#element';
791     next unless dis_node_for_match ($case, $opt{For}, %opt);
792     my $et = dis_element_type_to_uri ($case->local_name,
793     %opt, node => $case);
794     if ($et eq ExpandedURI q<DISPerl:case>) {
795     my $val = dis_get_attr_node
796     (%opt, parent => $case,
797     name => 'Value',
798     ContentType => ExpandedURI q<lang:dis>,
799     defaultContentType => ExpandedURI q<lang:dis>);
800     if ($val and $val->value eq $propvalue) {
801     $selcase = $case; last;
802     } elsif (not $val and not $val->value) {
803     $selcase = $case; last;
804     }
805     } elsif ($et eq ExpandedURI q<DISPerl:else>) {
806     $selcase = $case; last;
807     } else {
808     valid_err q<Element type <$et> not allowed here>,
809     node => $case;
810     }
811     }
812     if ($selcase) {
813     my $lcode = perl_code ($selcase->value, %opt, node => $selcase);
814     $code .= perl_code_source ($lcode, %opt, node => $selcase);
815     }
816     } elsif ({
817     ExpandedURI q<d:ContentType> => 1,
818     ExpandedURI q<d:For> => 1,
819     ExpandedURI q<d:ForCheck> => 1,
820     ExpandedURI q<d:ImplNote> => 1,
821     }->{$et}) {
822     #
823     } else {
824     valid_err qq<Element type <$et> not supported>,
825     node => $opt{node};
826     }
827     }
828    
829     my $val = $opt{node}->value;
830 wakaba 1.10 if (defined $val and length $val) {
831     $code .= perl_code_source (perl_code ($val, %opt), %opt);
832 wakaba 1.9 }
833     return $code;
834     } # disperl_to_perl
835 wakaba 1.5
836    
837 wakaba 1.1 ## Outputed module and "For"
838     my $mf = dis_get_module_uri (module_name => $Opt{module_name},
839     module_uri => $Opt{module_uri},
840     For => $Opt{For});
841     $State->{DefaultFor} = $mf->{For};
842     $State->{module} = $mf->{module};
843    
844 wakaba 1.3 valid_err
845     (qq{Perl module <$State->{module}> not defined for <$State->{DefaultFor}>},
846     node => $State->{Module}->{$State->{module}}->{src})
847     unless $State->{Module}->{$State->{module}}
848     ->{ExpandedURI q<dis2pm:packageName>};
849    
850 wakaba 1.1 $State->{ExpandedURI q<dis2pm:currentPackage>} = 'main';
851     $result .= "#!/usr/bin/perl \n";
852     $result .= perl_comment q<This file is automatically generated from> . "\n" .
853     q<"> . $Opt{file_name} . q<" at > .
854     rfc3339_date (time) . qq<.\n> .
855     q<Don't edit by hand!>;
856     $result .= perl_comment qq{Module <$State->{module}>};
857     $result .= perl_comment qq{For <$State->{DefaultFor}>};
858     $result .= perl_statement q<use strict>;
859     $result .= perl_change_package
860     (full_name => $State->{Module}->{$State->{module}}
861     ->{ExpandedURI q<dis2pm:packageName>});
862     $result .= perl_statement
863     perl_assign
864     perl_var (type => '$', local_name => 'VERSION',
865     scope => 'our')
866     => perl_literal version_date time;
867    
868 wakaba 1.5 ## -- Classes
869 wakaba 1.8 my %opt;
870 wakaba 1.1 for my $pack (values %{$State->{Module}->{$State->{module}}
871     ->{ExpandedURI q<dis2pm:package>}||{}}) {
872     next unless defined $pack->{Name};
873     if ({
874     ExpandedURI q<ManakaiDOM:Class> => 1,
875     ExpandedURI q<ManakaiDOM:IF> => 1,
876     ExpandedURI q<ManakaiDOM:ExceptionClass> => 1,
877     ExpandedURI q<ManakaiDOM:ExceptionIF> => 1,
878 wakaba 1.5 ExpandedURI q<ManakaiDOM:WarningClass> => 1,
879 wakaba 1.1 }->{$pack->{ExpandedURI q<dis2pm:type>}}) {
880     ## Package name and version
881     $result .= perl_change_package
882     (full_name => $pack->{ExpandedURI q<dis2pm:packageName>});
883     $result .= perl_statement
884     perl_assign
885     perl_var (type => '$', local_name => 'VERSION',
886     scope => 'our')
887     => perl_literal version_date time;
888     ## Inheritance
889 wakaba 1.5 ## TODO: IF "isa" should be expanded
890 wakaba 1.2 my $isa = [];
891 wakaba 1.1 for my $uri (@{$pack->{ISA}||[]}, @{$pack->{Implement}||[]}) {
892     my $pack = $State->{Type}->{$uri};
893     if (defined $pack->{ExpandedURI q<dis2pm:packageName>}) {
894 wakaba 1.2 push @$isa, $pack->{ExpandedURI q<dis2pm:packageName>};
895 wakaba 1.1 } else {
896     impl_msg ("Inheriting package name for <$uri> not defined",
897     node => $pack->{src}) if $Opt{verbose};
898     }
899     }
900 wakaba 1.2 $isa = array_uniq $isa;
901     $result .= perl_inherit $isa;
902     $result .= '$' . $_ . "::;\n" for @$isa;
903 wakaba 1.1 ## Members
904     if ({
905     ExpandedURI q<ManakaiDOM:Class> => 1,
906     ExpandedURI q<ManakaiDOM:ExceptionClass> => 1,
907     ExpandedURI q<ManakaiDOM:WarningClass> => 1,
908     }->{$pack->{ExpandedURI q<dis2pm:type>}}) {
909 wakaba 1.10 local $State->{ExpandedURI q<dis2pm:thisClass>} => $pack;
910 wakaba 1.8 local $opt{ExpandedURI q<MDOMX:class>}
911     = $pack->{ExpandedURI q<dis2pm:packageName>};
912 wakaba 1.1 for my $method (values %{$pack->{ExpandedURI q<dis2pm:method>}}) {
913     next unless defined $method->{Name};
914 wakaba 1.6 next unless length $method->{ExpandedURI q<dis2pm:methodName>};
915 wakaba 1.1 if ($method->{ExpandedURI q<dis2pm:type>} eq
916     ExpandedURI q<ManakaiDOM:DOMMethod>) {
917 wakaba 1.8 local $opt{ExpandedURI q<MDOMX:method>}
918     = $method->{ExpandedURI q<dis2pm:methodName>};
919 wakaba 1.3 my $proto = '$';
920     my @param = ('self');
921 wakaba 1.7 my $param_norm = '';
922 wakaba 1.3 my $param_opt = 0;
923 wakaba 1.7 my $for = [keys %{$method->{For}}]->[0];
924 wakaba 1.3 for my $param (@{$method->{ExpandedURI q<dis2pm:param>}||[]}) {
925     if ($param->{ExpandedURI q<dis2pm:nullable>}) {
926     $proto .= ';' unless $param_opt;
927     $param_opt++;
928     }
929     $proto .= '$';
930     push @param, $param->{ExpandedURI q<dis2pm:paramName>};
931 wakaba 1.7 my $nm = dispm_get_code
932 wakaba 1.8 (%opt, resource => $State->{Type}
933 wakaba 1.7 ->{$param->{ExpandedURI q<d:actualType>}},
934     ExpandedURI q<dis2pm:DefKeyName>
935     => ExpandedURI q<ManakaiDOM:inputNormalizer>,
936     For => $for,
937     ExpandedURI q<dis2pm:getCodeNoTypeCheck> => 1);
938     if (defined $nm) {
939     $nm =~ s/\$INPUT\b/\$$param[-1] /g;
940     $param_norm .= $nm;
941     }
942 wakaba 1.3 }
943     my $code = dispm_get_code
944 wakaba 1.8 (%opt,
945     resource => $method->{ExpandedURI q<dis2pm:return>},
946 wakaba 1.4 For => $for);
947 wakaba 1.3 if (defined $code) {
948     my $my = perl_statement ('my ('.join (", ", map {"\$$_"} @param).
949     ') = @_');
950     my $return = defined $method->{ExpandedURI q<dis2pm:return>}->{Name}
951     ? $method->{ExpandedURI q<dis2pm:return>} : undef;
952     if ($return->{ExpandedURI q<d:actualType>} ? 1 : 0) {
953     my $default = dispm_get_value
954 wakaba 1.8 (%opt, resource => $return,
955 wakaba 1.3 ExpandedURI q<dis2pm:ValueKeyName>
956     => ExpandedURI q<d:DefaultValue>,
957     ExpandedURI q<dis2pm:useDefaultValue> => 1,
958     ExpandedURI q<dis2pm:valueType>
959     => $return->{ExpandedURI q<d:actualType>});
960 wakaba 1.7 $code = $my . $param_norm .
961 wakaba 1.3 perl_statement
962     (defined $default ? 'my $r = '.$default : 'my $r').
963     $code . "\n" .
964     perl_statement ('$r');
965     } else {
966     $code = $my . $code;
967     }
968     } else { ## Code not defined
969 wakaba 1.4 my $for1 = $for;
970 wakaba 1.3 unless (dis_uri_for_match (ExpandedURI q<ManakaiDOM:ManakaiDOM1>,
971     $for, node => $method->{src})) {
972 wakaba 1.4 $for1 = ExpandedURI q<ManakaiDOM:ManakaiDOMLatest>;
973 wakaba 1.3 }
974     $code = perl_statement
975     dispm_perl_throws
976     class => ExpandedURI q<DOMCore:ManakaiDOMException>,
977 wakaba 1.4 class_for => $for1,
978 wakaba 1.3 type => 'NOT_SUPPORTED_ERR',
979     subtype =>
980     ExpandedURI q<MDOMX:MDOM_IMPL_METHOD_NOT_IMPLEMENTED>,
981     xparam => {
982     ExpandedURI q<MDOMX:class>
983     => $pack->{ExpandedURI q<dis2pm:packageName>},
984     ExpandedURI q<MDOMX:method>
985     => $method->{ExpandedURI q<dis2pm:methodName>},
986     };
987     }
988 wakaba 1.1 $result .= perl_sub
989     (name => $method->{ExpandedURI q<dis2pm:methodName>},
990 wakaba 1.3 code => $code, prototype => $proto);
991 wakaba 1.1 } elsif ($method->{ExpandedURI q<dis2pm:type>} eq
992     ExpandedURI q<ManakaiDOM:DOMAttribute>) {
993 wakaba 1.8 local $opt{ExpandedURI q<MDOMX:attr>}
994     = $method->{ExpandedURI q<dis2pm:methodName>};
995 wakaba 1.3 my $getter = $method->{ExpandedURI q<dis2pm:getter>};
996 wakaba 1.5 valid_err qq{Getter for attribute "$method->{Name}" must be }.
997     q{defined}, node => $method->{src} unless $getter;
998 wakaba 1.3 my $setter = defined $method->{ExpandedURI q<dis2pm:setter>}->{Name}
999     ? $method->{ExpandedURI q<dis2pm:setter>} : undef;
1000     my $for = [keys %{$method->{For}}]->[0];
1001 wakaba 1.4 my $for1 = $for;
1002 wakaba 1.3 unless (dis_uri_for_match (ExpandedURI q<ManakaiDOM:ManakaiDOM1>,
1003     $for, node => $method->{src})) {
1004 wakaba 1.4 $for1 = ExpandedURI q<ManakaiDOM:ManakaiDOMLatest>;
1005 wakaba 1.3 }
1006 wakaba 1.8 local $opt{ExpandedURI q<MDOMX:on>} = 'get';
1007 wakaba 1.4 my $get_code = dispm_get_code (resource => $getter, For => $for);
1008 wakaba 1.3 if (defined $get_code) {
1009     my $default = dispm_get_value
1010 wakaba 1.8 (%opt, resource => $getter,
1011 wakaba 1.3 ExpandedURI q<dis2pm:ValueKeyName>
1012     => ExpandedURI q<d:DefaultValue>,
1013     ExpandedURI q<dis2pm:useDefaultValue> => 1,
1014     ExpandedURI q<dis2pm:valueType>
1015     => $getter->{ExpandedURI q<d:actualType>});
1016     $get_code = perl_statement
1017     (defined $default ? 'my $r = '.$default : 'my $r').
1018     $get_code. "\n" .
1019     perl_statement ('$r');
1020     } else { ## Get code not defined
1021     $get_code = perl_statement
1022     dispm_perl_throws
1023     class => ExpandedURI q<DOMCore:ManakaiDOMException>,
1024 wakaba 1.4 class_for => $for1,
1025 wakaba 1.3 type => 'NOT_SUPPORTED_ERR',
1026     subtype =>
1027     ExpandedURI q<MDOMX:MDOM_IMPL_ATTR_NOT_IMPLEMENTED>,
1028     xparam => {
1029     ExpandedURI q<MDOMX:class>
1030     => $pack->{ExpandedURI q<dis2pm:packageName>},
1031     ExpandedURI q<MDOMX:attr>
1032     => $method->{ExpandedURI q<dis2pm:methodName>},
1033     ExpandedURI q<MDOMX:on> => 'get',
1034     };
1035     }
1036     if ($setter) {
1037 wakaba 1.8 local $opt{ExpandedURI q<MDOMX:on>} = 'set';
1038     my $set_code = dispm_get_code
1039     (%opt, resource => $setter, For => $for);
1040 wakaba 1.3 if (defined $set_code) {
1041 wakaba 1.7 my $nm = dispm_get_code
1042 wakaba 1.8 (%opt, resource => $State->{Type}
1043 wakaba 1.7 ->{$setter->{ExpandedURI q<d:actualType>}},
1044     ExpandedURI q<dis2pm:DefKeyName>
1045     => ExpandedURI q<ManakaiDOM:inputNormalizer>,
1046     For => $for,
1047     ExpandedURI q<dis2pm:getCodeNoTypeCheck> => 1);
1048     if (defined $nm) {
1049     $nm =~ s/\$INPUT\b/\$given /g;
1050     } else {
1051     $nm = '';
1052     }
1053 wakaba 1.3 my $default = dispm_get_value
1054 wakaba 1.8 (%opt, resource => $setter,
1055 wakaba 1.3 ExpandedURI q<dis2pm:ValueKeyName>
1056     => ExpandedURI q<d:DefaultValue>,
1057     ExpandedURI q<dis2pm:useDefaultValue> => 1,
1058     ExpandedURI q<dis2pm:valueType>
1059     => $getter->{ExpandedURI q<d:actualType>});
1060 wakaba 1.7 $set_code = $nm .
1061     perl_statement
1062     (defined $default ? 'my $r = '.$default : 'my $r').
1063 wakaba 1.3 $set_code. "\n" .
1064     perl_statement ('$r');
1065     } else { ## Set code not defined
1066     $set_code = perl_statement
1067     dispm_perl_throws
1068     class => ExpandedURI q<DOMCore:ManakaiDOMException>,
1069 wakaba 1.4 class_for => $for1,
1070 wakaba 1.3 type => 'NOT_SUPPORTED_ERR',
1071     subtype =>
1072     ExpandedURI q<MDOMX:MDOM_IMPL_ATTR_NOT_IMPLEMENTED>,
1073     xparam => {
1074     ExpandedURI q<MDOMX:class>
1075     => $pack->{ExpandedURI q<dis2pm:packageName>},
1076     ExpandedURI q<MDOMX:attr>
1077     => $method->{ExpandedURI q<dis2pm:methodName>},
1078     ExpandedURI q<MDOMX:on> => 'set',
1079     };
1080     }
1081     $get_code = perl_if '@_ == 2',
1082     perl_statement ('my ($self, $given) = @_').
1083     $set_code,
1084     perl_statement ('my ($self) = @_').
1085     $get_code;
1086     } else {
1087     $get_code = perl_statement ('my ($self) = @_').
1088     $get_code;
1089     }
1090 wakaba 1.1 $result .= perl_sub
1091     (name => $method->{ExpandedURI q<dis2pm:methodName>},
1092 wakaba 1.3 prototype => $setter ? '$;$' : '$',
1093     code => $get_code);
1094 wakaba 1.1 }
1095     } # package method
1096 wakaba 1.5 for my $cg (values %{$pack->{ExpandedURI q<dis2pm:constGroup>}}) {
1097     next unless defined $cg->{Name};
1098     $result .= dispm_const_group (resource => $cg);
1099     } # package const group
1100     for my $cv (values %{$pack->{ExpandedURI q<dis2pm:const>}}) {
1101     next unless defined $cv->{Name};
1102     $result .= dispm_const_value (resource => $cv);
1103     } # package const value
1104     }
1105 wakaba 1.1 } # root object
1106 wakaba 1.6 }
1107    
1108     for (keys %{$State->{Module}->{$State->{module}}
1109     ->{ExpandedURI q<dis2pm:requiredModule>}||{}}) {
1110     next if $_ eq $State->{Module}->{$State->{module}}
1111     ->{ExpandedURI q<dis2pm:packageName>};
1112     $result .= perl_statement ('require ' . $_);
1113 wakaba 1.1 }
1114    
1115     $result .= perl_statement 1;
1116    
1117     output_result $result;
1118    
1119     1;

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24