File Coverage

blib/lib/HTML/Mason/Compiler.pm
Criterion Covered Total %
statement 305 339 89.9
branch 102 132 77.2
condition 18 29 62.0
subroutine 41 44 93.1
pod 18 25 72.0
total 484 569 85.0


line stmt bran cond sub pod time code
1             # Copyright (c) 1998-2005 by Jonathan Swartz. All rights reserved.
2             # This program is free software; you can redistribute it and/or modify it
3             # under the same terms as Perl itself.
4              
5             package HTML::Mason::Compiler;
6             $HTML::Mason::Compiler::VERSION = '1.59';
7 30     30   208 use strict;
  30         168  
  30         915  
8 30     30   166 use warnings;
  30         57  
  30         1007  
9 30     30   20368 use Data::Dumper;
  30         198269  
  30         2254  
10 30     30   13763 use HTML::Mason::Component::FileBased;
  30         79  
  30         846  
11 30     30   13436 use HTML::Mason::Component::Subcomponent;
  30         85  
  30         1062  
12 30     30   200 use HTML::Mason::Exceptions( abbr => [qw(param_error compiler_error syntax_error)] );
  30         72  
  30         196  
13 30     30   14583 use HTML::Mason::Lexer;
  30         85  
  30         1188  
14 30     30   229 use HTML::Mason::Tools qw(checksum);
  30         77  
  30         1808  
15 30     30   249 use Params::Validate qw(:all);
  30         69  
  30         4889  
16             Params::Validate::validation_options( on_fail => sub { param_error join '', @_ } );
17              
18 30     30   237 use Class::Container;
  30         77  
  30         627  
19 30     30   137 use base qw(Class::Container);
  30         68  
  30         7941  
20              
21             BEGIN
22             {
23 30     30   961 __PACKAGE__->valid_params
24             (
25             allow_globals =>
26             { parse => 'list', type => ARRAYREF, default => [],
27             descr => "An array of names of Perl variables that are allowed globally within components" },
28              
29             default_escape_flags =>
30             { parse => 'string', type => SCALAR|ARRAYREF, default => [],
31             descr => "Escape flags that will apply by default to all Mason tag output" },
32              
33             enable_autoflush =>
34             { parse => 'boolean', type => SCALAR, default => 1,
35             descr => "Whether to include support for autoflush when compiling components" },
36              
37             lexer =>
38             { isa => 'HTML::Mason::Lexer',
39             descr => "A Lexer object that will scan component text during compilation" },
40              
41             preprocess =>
42             { parse => 'code', type => CODEREF, optional => 1,
43             descr => "A subroutine through which all component text will be sent during compilation" },
44              
45             postprocess_perl =>
46             { parse => 'code', type => CODEREF, optional => 1,
47             descr => "A subroutine through which all Perl code will be sent during compilation" },
48              
49             postprocess_text =>
50             { parse => 'code', type => CODEREF, optional => 1,
51             descr => "A subroutine through which all plain text will be sent during compilation" },
52              
53             use_source_line_numbers =>
54             { parse => 'boolean', type => SCALAR, default => 1,
55             descr => "Whether to use source line numbers in errors and debugger" },
56             );
57              
58 30         1549 __PACKAGE__->contained_objects
59             ( lexer => { class => 'HTML::Mason::Lexer',
60             descr => "This class generates compiler events based on the components source" },
61             );
62              
63             # Define an IN_PERL_DB compile-time constant indicating whether we are
64             # in the Perl debugger. This is used in the object file to
65             # determine whether to call $m->debug_hook.
66             #
67 30 50       583 if (defined($DB::sub)) {
68 0         0 *IN_PERL_DB = sub () { 1 };
69             } else {
70 30         1600 *IN_PERL_DB = sub () { 0 };
71             }
72             }
73              
74             use HTML::Mason::MethodMaker
75 30         275 ( read_only => [qw(
76             enable_autoflush
77             lexer
78             object_id
79             preprocess
80             postprocess_perl
81             postprocess_text
82             use_source_line_numbers
83             )
84             ],
85 30     30   220 );
  30         70  
86              
87             my $old_escape_re = qr/^[hnu]+$/;
88              
89             sub new
90             {
91 391     391 1 176653 my $class = shift;
92 391         1831 my $self = $class->SUPER::new(@_);
93              
94             $self->default_escape_flags( $self->{default_escape_flags} )
95 391 50       103305 if defined $self->{default_escape_flags};
96              
97             # Verify the validity of the global names
98 391         646 $self->allow_globals( @{$self->{allow_globals}} );
  391         1877  
99              
100             # Compute object_id once, on the assumption that all of compiler's
101             # and lexer's parameters are read-only.
102 391         1466 $self->compute_object_id;
103            
104 391         1167 return $self;
105             }
106              
107             sub compute_object_id
108             {
109 391     391 0 693 my $self = shift;
110              
111             # Can't use object keys because they stringify differently every
112             # time the program is loaded, whether they are a reference to the
113             # same object or not.
114 391         1117 my $spec = $self->validation_spec;
115             my @id_keys =
116 6648   66     18887 ( grep { ! exists $spec->{$_}{isa} && ! exists $spec->{$_}{can} }
117 391         4753 grep { $_ ne 'container' } keys %$spec );
  7039         10942  
118              
119 391         1216 my @vals = ('HTML::Mason::VERSION', $HTML::Mason::VERSION);
120 391         2651 foreach my $k ( sort @id_keys ) {
121 6257         9805 push @vals, $k, $self->{$k};
122             }
123 391         3185 my $dumped_vals = Data::Dumper->new(\@vals)->Indent(0)->Sortkeys(1)->Dump;
124 391         58888 $self->{object_id} = checksum($dumped_vals);
125             }
126              
127             my %top_level_only_block = map { $_ => 1 } qw( cleanup once shared );
128             my %valid_comp_flag = map { $_ => 1 } qw( inherit );
129              
130             sub add_allowed_globals
131             {
132 12     12 0 25 my $self = shift;
133 12         28 my @globals = @_;
134              
135 12 50       28 if ( my @bad = grep { ! /^[\$@%]/ } @globals )
  12         84  
136             {
137 0         0 param_error "add_allowed_globals: bad parameters '@bad', must begin with one of \$, \@, %\n";
138             }
139              
140 12         24 $self->{allow_globals} = [ sort keys %{ { map { $_ => 1 } @globals, @{ $self->{allow_globals} } } } ];
  12         20  
  12         69  
  12         27  
141 12         31 return @{ $self->{allow_globals} };
  12         32  
142             }
143              
144             sub allow_globals
145             {
146 922     922 1 1412 my $self = shift;
147              
148 922 100       2114 if (@_)
149             {
150 5         12 $self->{allow_globals} = [];
151 5 50 33     48 return if @_ == 1 and not defined $_[0]; # @_ is (undef)
152 5         33 $self->add_allowed_globals(@_);
153             }
154              
155 922         1245 return @{ $self->{allow_globals} };
  922         3658  
156             }
157              
158             sub default_escape_flags
159             {
160 413     413 1 824 my $self = shift;
161              
162 413 100       1101 return $self->{default_escape_flags} unless @_;
163              
164 391         585 my $flags = shift;
165              
166 391 50       954 unless ( defined $flags )
167             {
168 0         0 $self->{default_escape_flags} = [];
169 0         0 return;
170             }
171              
172             # make sure this is always an arrayref
173 391 100       1060 unless ( ref $flags )
174             {
175 4 50       28 if ( $flags =~ /^[hu]+$/ )
176             {
177 4         16 $self->{default_escape_flags} = [ split //, $flags ];
178             }
179             else
180             {
181 0         0 $self->{default_escape_flags} = [ $flags ];
182             }
183             }
184              
185 391         707 return $self->{default_escape_flags};
186             }
187              
188             sub compile
189             {
190 547     547 1 983 my $self = shift;
191 547         19565 my %p = validate( @_, { comp_source => { type => SCALAR|SCALARREF },
192             name => { type => SCALAR },
193             comp_path => { type => SCALAR },
194             fh => { type => HANDLE, optional => 1 },
195             } );
196 547 100       4909 my $src = ref($p{comp_source}) ? $p{comp_source} : \$p{comp_source};
197              
198             # The current compile - initially the main component, then each subcomponent/method
199 547         1464 local $self->{current_compile} = {};
200            
201             # Useful for implementing features that affect both main body and methods/subcomps
202 547         1136 local $self->{main_compile} = $self->{current_compile};
203              
204             # So we're re-entrant in subcomps
205 547         1202 local $self->{paused_compiles} = [];
206              
207 547         1157 local $self->{comp_path} = $p{comp_path};
208              
209             # Preprocess the source. The preprocessor routine is handed a
210             # reference to the entire source.
211 547 100       1717 if ($self->preprocess)
212             {
213 1         2 eval { $self->preprocess->( $src ) };
  1         3  
214 1 50       27 compiler_error "Error during custom preprocess step: $@" if $@;
215             }
216              
217 547         1432 $self->lexer->lex( comp_source => $src, name => $p{name}, compiler => $self );
218              
219 530 100       2669 return $self->compiled_component( exists($p{fh}) ? (fh => $p{fh}) : () );
220             }
221              
222             sub start_component
223             {
224 547     547 1 981 my $self = shift;
225 547         861 my $c = $self->{current_compile};
226              
227 547         1157 $c->{in_main} = 1;
228              
229 547         940 $c->{in_block} = undef;
230              
231 547         1459 $self->_init_comp_data($c);
232             }
233              
234             sub _init_comp_data
235             {
236 661     661   969 my $self = shift;
237 661         905 my $data = shift;
238              
239 661         1384 $data->{body} = '';
240 661         1165 $data->{last_body_code_type} = '';
241              
242 661         1308 foreach ( qw( def method ) )
243             {
244 1322         3080 $data->{$_} = {};
245             }
246              
247 661         1325 $data->{args} = [];
248 661         1741 $data->{flags} = {};
249 661         1376 $data->{attr} = {};
250              
251 661         1313 $data->{comp_with_content_stack} = [];
252              
253 661         1343 foreach ( qw( cleanup filter init once shared ) )
254             {
255 3305         7414 $data->{blocks}{$_} = [];
256             }
257             }
258              
259             sub end_component
260             {
261 547     547 1 882 my $self = shift;
262 547         846 my $c = $self->{current_compile};
263              
264             $self->lexer->throw_syntax_error("Not enough component-with-content ending tags found")
265 547 100       724 if @{ $c->{comp_with_content_stack} };
  547         1663  
266             }
267              
268             sub start_block
269             {
270 265     265 1 462 my $self = shift;
271 265         510 my $c = $self->{current_compile};
272 265         791 my %p = @_;
273              
274             $self->lexer->throw_syntax_error("Cannot define a $p{block_type} section inside a method or subcomponent")
275 265 50 66     1017 if $top_level_only_block{ $p{block_type} } && ! $c->{in_main};
276              
277             $self->lexer->throw_syntax_error("Cannot nest a $p{block_type} inside a $c->{in_block} block")
278 265 50       658 if $c->{in_block};
279              
280 265         792 $c->{in_block} = $p{block_type};
281             }
282              
283             sub raw_block
284             {
285             # These blocks contain Perl code - so don't include <%text> and so on.
286              
287 163     163 0 417 my $self = shift;
288 163         306 my $c = $self->{current_compile};
289 163         540 my %p = @_;
290              
291 163 100       276 eval { $self->postprocess_perl->( \$p{block} ) if $self->postprocess_perl };
  163         447  
292 163 50       422 compiler_error $@ if $@;
293              
294 163         372 my $method = "$p{block_type}_block";
295 163 100       1429 return $self->$method(%p) if $self->can($method);
296              
297 129         289 my $comment = '';
298 129 50 33     338 if ( $self->lexer->line_number && $self->use_source_line_numbers )
299             {
300 129         306 my $line = $self->lexer->line_number;
301 129         325 my $file = $self->_escape_filename( $self->lexer->name );
302 129         447 $comment = qq{#line $line "$file"\n};
303             }
304              
305 129         236 push @{ $self->{current_compile}{blocks}{ $p{block_type} } }, "$comment$p{block}";
  129         630  
306             }
307              
308             sub doc_block
309       2 0   {
310             # Don't do anything - just discard the comment.
311             }
312              
313             sub perl_block
314             {
315 34     34 0 76 my $self = shift;
316 34         108 my %p = @_;
317              
318 34         147 $self->_add_body_code( $p{block} );
319              
320 34         127 $self->{current_compile}{last_body_code_type} = 'perl_block';
321             }
322              
323             sub text
324             {
325 1133     1133 1 3629 my ($self, %p) = @_;
326 1133 100       2997 my $tref = ref($p{text}) ? $p{text} : \$p{text}; # Allow a reference
327              
328 1133 100       2989 eval { $self->postprocess_text->($tref) } if $self->postprocess_text;
  5         12  
329 1133 50       2245 compiler_error $@ if $@;
330              
331 1133         2614 $$tref =~ s,([\'\\]),\\$1,g;
332              
333 1133 100       2498 if ($self->enable_autoflush) {
334 1115         2717 $self->_add_body_code("\$m->print( '", $$tref, "' );\n");
335             } else {
336 18         42 $self->_add_body_code("\$\$_outbuf .= '", $$tref, "';\n");
337             }
338              
339 1133         3205 $self->{current_compile}{last_body_code_type} = 'text';
340             }
341              
342             sub text_block
343             {
344 2     2 0 5 my $self = shift;
345 2         8 my %p = @_;
346 2         8 $self->text(text => \$p{block});
347             }
348              
349             sub end_block
350             {
351 263     263 1 465 my $self = shift;
352 263         458 my $c = $self->{current_compile};
353 263         650 my %p = @_;
354              
355             $self->lexer->throw_syntax_error("End of $p{block_type} encountered while in $c->{in_block} block")
356 263 50       701 unless $c->{in_block} eq $p{block_type};
357              
358 263         840 $c->{in_block} = undef;
359             }
360              
361             sub variable_declaration
362             {
363 85     85 1 165 my $self = shift;
364 85         488 my %p = @_;
365              
366             $self->lexer->throw_syntax_error("variable_declaration called inside a $p{block_type} block")
367 85 50       317 unless $p{block_type} eq 'args';
368              
369 85         213 my $arg = "$p{type}$p{name}";
370              
371             $self->lexer->throw_syntax_error("$arg already defined")
372 85 50       124 if grep { "$_->{type}$_->{name}" eq $arg } @{ $self->{current_compile}{args} };
  56         182  
  85         274  
373              
374 85         350 push @{ $self->{current_compile}{args} }, { type => $p{type},
375             name => $p{name},
376             default => $p{default},
377 85         149 line => $self->lexer->line_number,
378             file => $self->lexer->name,
379             };
380             }
381              
382             sub key_value_pair
383             {
384 62     62 1 104 my $self = shift;
385 62         319 my %p = @_;
386              
387             compiler_error "key_value_pair called inside a $p{block_type} block"
388 62 50 66     301 unless $p{block_type} eq 'flags' || $p{block_type} eq 'attr';
389              
390 62 100       168 my $type = $p{block_type} eq 'flags' ? 'flag' : 'attribute';
391             $self->lexer->throw_syntax_error("$p{key} $type already defined")
392 62 50       192 if exists $self->{current_compile}{ $p{block_type} }{ $p{key} };
393              
394             $self->{current_compile}{ $p{block_type} }{ $p{key} } = $p{value}
395 62         312 }
396              
397             sub start_named_block
398             {
399 119     119 1 205 my $self = shift;
400 119         378 my $c = $self->{current_compile};
401 119         433 my %p = @_;
402              
403             # Error if defining one def or method inside another
404             $self->lexer->throw_syntax_error
405             ("Cannot define a $p{block_type} block inside a method or subcomponent")
406 119 50       354 unless $c->{in_main};
407              
408             # Error for invalid character in name
409             $self->lexer->throw_syntax_error("Invalid $p{block_type} name: $p{name}")
410 119 100       458 if $p{name} =~ /[^.\w-]/;
411              
412             # Error if two defs or two methods defined with same name
413             $self->lexer->throw_syntax_error
414             (sprintf("Duplicate definition of %s '%s'",
415             $p{block_type} eq 'def' ? 'subcomponent' : 'method', $p{name}))
416 117 100       401 if exists $c->{$p{block_type}}{ $p{name} };
    100          
417            
418             # Error if def and method defined with same name
419 115 100       444 my $other_type = $p{block_type} eq 'def' ? 'method' : 'def';
420             $self->lexer->throw_syntax_error
421             ("Cannot define a method and subcomponent with the same name ($p{name})")
422 115 100       381 if exists $c->{$other_type}{ $p{name} };
423              
424 114         194 $c->{in_main}--;
425              
426 114         414 $c->{ $p{block_type} }{ $p{name} } = {};
427 114         406 $self->_init_comp_data( $c->{ $p{block_type} }{ $p{name} } );
428 114         191 push @{$self->{paused_compiles}}, $c;
  114         313  
429 114         329 $self->{current_compile} = $c->{ $p{block_type} }{ $p{name} };
430 114         647 $self->{current_compile}->{in_named_block} = {block_type => $p{block_type}, name => $p{name}};
431             }
432              
433             sub end_named_block
434             {
435 113     113 1 206 my $self = shift;
436              
437 113         304 delete $self->{current_compile}->{in_named_block};
438 113         173 $self->{current_compile} = pop @{$self->{paused_compiles}};
  113         273  
439 113         258 $self->{current_compile}{in_main}++;
440             }
441              
442             sub substitution
443             {
444 387     387 1 620 my $self = shift;
445 387         1635 my %p = @_;
446              
447 387         801 my $text = $p{substitution};
448              
449             # This is a comment tag if all lines of text contain only whitespace
450             # or start with whitespace and a comment marker, e.g.
451             #
452             # <%
453             # #
454             # # foo
455             # %>
456             #
457 387         1147 my @lines = split(/\n/, $text);
458 387 100       743 unless (grep { /^\s*[^\s\#]/ } @lines) {
  394         1866  
459 4         13 $self->{current_compile}{last_body_code_type} = 'substitution';
460 4         12 return;
461             }
462              
463 383 100 66     1873 if ( ( exists $p{escape} && defined $p{escape} ) ||
      100        
464 361         1084 @{ $self->{default_escape_flags} }
465             )
466             {
467 29         43 my @flags;
468 29 100       63 if ( defined $p{escape} )
469             {
470 22         52 $p{escape} =~ s/\s+$//;
471              
472 22 100       134 if ( $p{escape} =~ /$old_escape_re/ )
473             {
474 14         38 @flags = split //, $p{escape};
475             }
476             else
477             {
478 8         31 @flags = split /\s*,\s*/, $p{escape};
479             }
480             }
481              
482             # is there any way to check the flags for validity and still
483             # allow them to be dynamically set from components?
484              
485 22         79 unshift @flags, @{ $self->default_escape_flags }
486 29 100       58 unless grep { $_ eq 'n' } @flags;
  28         74  
487              
488 29         49 my %seen;
489             my $flags =
490             ( join ', ',
491 32 100       128 map { $seen{$_}++ ? () : "'$_'" }
492 29         42 grep { $_ ne 'n' } @flags
  39         80  
493             );
494              
495 29 100       104 $text = "(map {; \$m->interp->apply_escapes(\$_, $flags) } ($text))"
496             if $flags;
497             }
498              
499 383         601 my $code;
500              
501             # Make sure to allow lists within <% %> tags.
502             #
503 383 100       1035 if ($self->enable_autoflush) {
504 375         867 $code = "\$m->print( $text );\n";
505             } else {
506             # more efficient output form when autoflush is disabled. only
507             # output defined bits, which is what $m->print does internally
508             # as well. use 'if defined' for maximum efficiency; grep
509             # creates a list.
510 8         24 $code = "for ( $text ) { \$\$_outbuf .= \$_ if defined }\n";
511             }
512              
513 383 100       952 eval { $self->postprocess_perl->(\$code) } if $self->postprocess_perl;
  3         7  
514 383 50       786 compiler_error $@ if $@;
515              
516 383         955 $self->_add_body_code($code);
517              
518 383         1214 $self->{current_compile}{last_body_code_type} = 'substitution';
519             }
520              
521             sub component_call
522             {
523 216     216 1 375 my $self = shift;
524 216         666 my %p = @_;
525              
526 216         1220 my ($prespace, $call, $postspace) = ($p{call} =~ /(\s*)(.*)(\s*)/s);
527 216 100       863 if ( $call =~ m,^[\w/.],)
528             {
529 203         498 my $comma = index($call, ',');
530 203 100       481 $comma = length $call if $comma == -1;
531 203         969 (my $comp = substr($call, 0, $comma)) =~ s/\s+$//;
532 203         682 $call = "'$comp'" . substr($call, $comma);
533             }
534 216         584 my $code = "\$m->comp( $prespace $call $postspace \n); ";
535 216 50       731 eval { $self->postprocess_perl->(\$code) } if $self->postprocess_perl;
  0         0  
536 216 50       525 compiler_error $@ if $@;
537              
538 216         617 $self->_add_body_code($code);
539              
540 216         665 $self->{current_compile}{last_body_code_type} = 'component_call';
541             }
542              
543             sub component_content_call
544             {
545 39     39 1 73 my $self = shift;
546 39         75 my $c = $self->{current_compile};
547 39         119 my %p = @_;
548              
549 39         70 my $call = $p{call};
550 39         82 for ($call) { s/^\s+//; s/\s+$//; }
  39         162  
  39         204  
551 39         65 push @{ $c->{comp_with_content_stack} }, $call;
  39         110  
552              
553 39         72 my $code = "\$m->comp( { content => sub {\n";
554 39         152 $code .= $self->_set_buffer();
555              
556 39 50       108 eval { $self->postprocess_perl->(\$code) } if $self->postprocess_perl;
  0         0  
557 39 50       93 compiler_error $@ if $@;
558              
559 39         112 $self->_add_body_code($code);
560              
561 39         115 $c->{last_body_code_type} = 'component_content_call';
562             }
563              
564             sub component_content_call_end
565             {
566 39     39 1 63 my $self = shift;
567 39         67 my $c = $self->{current_compile};
568 39         122 my %p = @_;
569              
570             $self->lexer->throw_syntax_error("Found component with content ending tag but no beginning tag")
571 39 100       67 unless @{ $c->{comp_with_content_stack} };
  39         127  
572              
573 37         56 my $call = pop @{ $c->{comp_with_content_stack} };
  37         87  
574 37         67 my $call_end = $p{call_end};
575 37         73 for ($call_end) { s/^\s+//; s/\s+$//; }
  37         68  
  37         80  
576              
577 37         58 my $comp = undef;
578 37 100       155 if ( $call =~ m,^[\w/.],)
579             {
580 33         83 my $comma = index($call, ',');
581 33 100       91 $comma = length $call if $comma == -1;
582 33         104 ($comp = substr($call, 0, $comma)) =~ s/\s+$//;
583 33         115 $call = "'$comp'" . substr($call, $comma);
584             }
585 37 100       80 if ($call_end) {
586 7 100       27 if ($call_end !~ m,^[\w/.],) {
587 2         8 $self->lexer->throw_syntax_error("Cannot use an expression inside component with content ending tag; use a bare component name or instead");
588             }
589 5 100       17 if (!defined($comp)) {
590 1         19 $self->lexer->throw_syntax_error("Cannot match an expression as a component name; use instead");
591             }
592 4 100       10 if ($call_end ne $comp) {
593 1         10 $self->lexer->throw_syntax_error("Component name in ending tag ($call_end) does not match component name in beginning tag ($comp)");
594             }
595             }
596              
597 33         87 my $code = "} }, $call\n );\n";
598              
599 33 50       92 eval { $self->postprocess_perl->(\$code) } if $self->postprocess_perl;
  0         0  
600 33 50       74 compiler_error $@ if $@;
601              
602 33         1143 $self->_add_body_code($code);
603              
604 33         112 $c->{last_body_code_type} = 'component_content_call_end';
605             }
606              
607             sub perl_line
608             {
609 395     395 1 670 my $self = shift;
610 395         1381 my %p = @_;
611              
612 395         990 my $code = "$p{line}\n";
613              
614 395 100       977 eval { $self->postprocess_perl->(\$code) } if $self->postprocess_perl;
  1         4  
615 395 50       808 compiler_error $@ if $@;
616              
617 395         1063 $self->_add_body_code($code);
618              
619 395         1142 $self->{current_compile}{last_body_code_type} = 'perl_line';
620             }
621              
622             sub _add_body_code
623             {
624 2233     2233   3291 my $self = shift;
625              
626             # We know a perl-line is always _one_ line, so we know that the
627             # line numbers are going to match up as long as the first line in
628             # a series has a line number comment before it. Adding a comment
629             # can break certain constructs like qw() list that spans multiple
630             # perl-lines.
631 2233 100 66     4460 if ( $self->lexer->line_number &&
      100        
632             $self->{current_compile}{last_body_code_type} ne 'perl_line' &&
633             $self->use_source_line_numbers )
634             {
635 1926         3682 my $line = $self->lexer->line_number;
636 1926         3800 my $file = $self->_escape_filename( $self->lexer->name );
637 1926         6495 $self->{current_compile}{body} .= qq{#line $line "$file"\n};
638             }
639              
640 2233         7957 $self->{current_compile}{body} .= $_ foreach @_;
641             }
642              
643             sub _escape_filename
644             {
645 2133     2133   3111 my $self = shift;
646 2133         2790 my $file = shift;
647              
648 2133         4438 $file =~ s/\"//g;
649              
650 2133         3600 return $file;
651             }
652              
653             sub dump
654             {
655 0     0 0 0 my $self = shift;
656 0         0 my $c = $self->{current_compile};
657              
658 0         0 warn "Main component\n";
659              
660 0         0 $self->_dump_data( $c );
661              
662 0         0 foreach ( keys %{ $c->{def} } )
  0         0  
663             {
664 0         0 warn " Subcomponent $_\n";
665 0         0 $self->_dump_data( $c->{def}{$_}, ' ' );
666             }
667              
668 0         0 foreach ( keys %{ $c->{method} } )
  0         0  
669             {
670 0         0 warn " Methods $_\n";
671 0         0 $self->_dump_data( $c->{method}{$_}, ' ');
672             }
673             }
674              
675             sub _dump_data
676             {
677 0     0   0 my $self = shift;
678 0         0 my $data = shift;
679 0   0     0 my $indent = shift || '';
680              
681 0 0       0 if ( @{ $data->{args} } )
  0         0  
682             {
683 0         0 warn "$indent args\n";
684 0         0 foreach ( @{ $data->{args} } )
  0         0  
685             {
686 0         0 warn "$indent $_->{type}$_->{name}";
687 0 0       0 warn " => $_->{default}" if defined $_->{default};
688 0         0 warn "\n";
689             }
690             }
691              
692 0         0 warn "\n$indent body\n";
693 0         0 warn $data->{body}, "\n";
694             }
695              
696             sub _blocks
697             {
698 5566     5566   7564 my $self = shift;
699              
700 5566         6439 return @{ $self->{current_compile}{blocks}{ shift() } };
  5566         15786  
701             }
702              
703             sub HTML::Mason::Parser::new
704             {
705 0     0     die "The Parser module is no longer a part of HTML::Mason. Please see ".
706             "the Lexer and Compiler modules, its replacements.\n";
707             }
708              
709             1;
710              
711             __END__