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.58';
7 30     30   176 use strict;
  30         129  
  30         754  
8 30     30   135 use warnings;
  30         54  
  30         783  
9 30     30   11669 use Data::Dumper;
  30         149324  
  30         1972  
10 30     30   9678 use HTML::Mason::Component::FileBased;
  30         91  
  30         800  
11 30     30   9033 use HTML::Mason::Component::Subcomponent;
  30         72  
  30         934  
12 30     30   184 use HTML::Mason::Exceptions( abbr => [qw(param_error compiler_error syntax_error)] );
  30         56  
  30         188  
13 30     30   9518 use HTML::Mason::Lexer;
  30         72  
  30         985  
14 30     30   239 use HTML::Mason::Tools qw(checksum);
  30         52  
  30         1551  
15 30     30   167 use Params::Validate qw(:all);
  30         60  
  30         4965  
16             Params::Validate::validation_options( on_fail => sub { param_error join '', @_ } );
17              
18 30     30   199 use Class::Container;
  30         62  
  30         597  
19 30     30   131 use base qw(Class::Container);
  30         59  
  30         7067  
20              
21             BEGIN
22             {
23 30     30   774 __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         1241 __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       524 if (defined($DB::sub)) {
68 0         0 *IN_PERL_DB = sub () { 1 };
69             } else {
70 30         1067 *IN_PERL_DB = sub () { 0 };
71             }
72             }
73              
74             use HTML::Mason::MethodMaker
75 30         230 ( 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   185 );
  30         55  
86              
87             my $old_escape_re = qr/^[hnu]+$/;
88              
89             sub new
90             {
91 391     391 1 170488 my $class = shift;
92 391         1874 my $self = $class->SUPER::new(@_);
93              
94             $self->default_escape_flags( $self->{default_escape_flags} )
95 391 50       98638 if defined $self->{default_escape_flags};
96              
97             # Verify the validity of the global names
98 391         673 $self->allow_globals( @{$self->{allow_globals}} );
  391         1647  
99              
100             # Compute object_id once, on the assumption that all of compiler's
101             # and lexer's parameters are read-only.
102 391         1255 $self->compute_object_id;
103            
104 391         1269 return $self;
105             }
106              
107             sub compute_object_id
108             {
109 391     391 0 699 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         1302 my $spec = $self->validation_spec;
115             my @id_keys =
116 6648   66     18448 ( grep { ! exists $spec->{$_}{isa} && ! exists $spec->{$_}{can} }
117 391         4931 grep { $_ ne 'container' } keys %$spec );
  7039         10841  
118              
119 391         1280 my @vals = ('HTML::Mason::VERSION', $HTML::Mason::VERSION);
120 391         2746 foreach my $k ( sort @id_keys ) {
121 6257         9824 push @vals, $k, $self->{$k};
122             }
123 391         3300 my $dumped_vals = Data::Dumper->new(\@vals)->Indent(0)->Sortkeys(1)->Dump;
124 391         57188 $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 29 my $self = shift;
133 12         33 my @globals = @_;
134              
135 12 50       27 if ( my @bad = grep { ! /^[\$@%]/ } @globals )
  12         80  
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         21  
  12         78  
  12         26  
141 12         28 return @{ $self->{allow_globals} };
  12         34  
142             }
143              
144             sub allow_globals
145             {
146 922     922 1 1647 my $self = shift;
147              
148 922 100       2247 if (@_)
149             {
150 5         18 $self->{allow_globals} = [];
151 5 50 33     48 return if @_ == 1 and not defined $_[0]; # @_ is (undef)
152 5         36 $self->add_allowed_globals(@_);
153             }
154              
155 922         1281 return @{ $self->{allow_globals} };
  922         4060  
156             }
157              
158             sub default_escape_flags
159             {
160 413     413 1 819 my $self = shift;
161              
162 413 100       1149 return $self->{default_escape_flags} unless @_;
163              
164 391         733 my $flags = shift;
165              
166 391 50       1078 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       1058 unless ( ref $flags )
174             {
175 4 50       26 if ( $flags =~ /^[hu]+$/ )
176             {
177 4         15 $self->{default_escape_flags} = [ split //, $flags ];
178             }
179             else
180             {
181 0         0 $self->{default_escape_flags} = [ $flags ];
182             }
183             }
184              
185 391         948 return $self->{default_escape_flags};
186             }
187              
188             sub compile
189             {
190 547     547 1 1047 my $self = shift;
191 547         18817 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       4841 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         1606 local $self->{current_compile} = {};
200            
201             # Useful for implementing features that affect both main body and methods/subcomps
202 547         1226 local $self->{main_compile} = $self->{current_compile};
203              
204             # So we're re-entrant in subcomps
205 547         1272 local $self->{paused_compiles} = [];
206              
207 547         1233 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       1889 if ($self->preprocess)
212             {
213 1         2 eval { $self->preprocess->( $src ) };
  1         4  
214 1 50       25 compiler_error "Error during custom preprocess step: $@" if $@;
215             }
216              
217 547         1529 $self->lexer->lex( comp_source => $src, name => $p{name}, compiler => $self );
218              
219 530 100       2850 return $self->compiled_component( exists($p{fh}) ? (fh => $p{fh}) : () );
220             }
221              
222             sub start_component
223             {
224 547     547 1 931 my $self = shift;
225 547         983 my $c = $self->{current_compile};
226              
227 547         1196 $c->{in_main} = 1;
228              
229 547         1015 $c->{in_block} = undef;
230              
231 547         1475 $self->_init_comp_data($c);
232             }
233              
234             sub _init_comp_data
235             {
236 661     661   991 my $self = shift;
237 661         958 my $data = shift;
238              
239 661         1378 $data->{body} = '';
240 661         1207 $data->{last_body_code_type} = '';
241              
242 661         1392 foreach ( qw( def method ) )
243             {
244 1322         3029 $data->{$_} = {};
245             }
246              
247 661         1381 $data->{args} = [];
248 661         1802 $data->{flags} = {};
249 661         1395 $data->{attr} = {};
250              
251 661         1324 $data->{comp_with_content_stack} = [];
252              
253 661         1375 foreach ( qw( cleanup filter init once shared ) )
254             {
255 3305         7020 $data->{blocks}{$_} = [];
256             }
257             }
258              
259             sub end_component
260             {
261 547     547 1 914 my $self = shift;
262 547         979 my $c = $self->{current_compile};
263              
264             $self->lexer->throw_syntax_error("Not enough component-with-content ending tags found")
265 547 100       820 if @{ $c->{comp_with_content_stack} };
  547         1789  
266             }
267              
268             sub start_block
269             {
270 265     265 1 450 my $self = shift;
271 265         467 my $c = $self->{current_compile};
272 265         800 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     1046 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       661 if $c->{in_block};
279              
280 265         787 $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 393 my $self = shift;
288 163         320 my $c = $self->{current_compile};
289 163         566 my %p = @_;
290              
291 163 100       291 eval { $self->postprocess_perl->( \$p{block} ) if $self->postprocess_perl };
  163         539  
292 163 50       416 compiler_error $@ if $@;
293              
294 163         419 my $method = "$p{block_type}_block";
295 163 100       1053 return $self->$method(%p) if $self->can($method);
296              
297 129         283 my $comment = '';
298 129 50 33     361 if ( $self->lexer->line_number && $self->use_source_line_numbers )
299             {
300 129         323 my $line = $self->lexer->line_number;
301 129         364 my $file = $self->_escape_filename( $self->lexer->name );
302 129         487 $comment = qq{#line $line "$file"\n};
303             }
304              
305 129         249 push @{ $self->{current_compile}{blocks}{ $p{block_type} } }, "$comment$p{block}";
  129         705  
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 67 my $self = shift;
316 34         94 my %p = @_;
317              
318 34         124 $self->_add_body_code( $p{block} );
319              
320 34         128 $self->{current_compile}{last_body_code_type} = 'perl_block';
321             }
322              
323             sub text
324             {
325 1133     1133 1 3932 my ($self, %p) = @_;
326 1133 100       3140 my $tref = ref($p{text}) ? $p{text} : \$p{text}; # Allow a reference
327              
328 1133 100       3021 eval { $self->postprocess_text->($tref) } if $self->postprocess_text;
  5         11  
329 1133 50       2198 compiler_error $@ if $@;
330              
331 1133         2684 $$tref =~ s,([\'\\]),\\$1,g;
332              
333 1133 100       2688 if ($self->enable_autoflush) {
334 1115         2619 $self->_add_body_code("\$m->print( '", $$tref, "' );\n");
335             } else {
336 18         39 $self->_add_body_code("\$\$_outbuf .= '", $$tref, "';\n");
337             }
338              
339 1133         3511 $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         9 $self->text(text => \$p{block});
347             }
348              
349             sub end_block
350             {
351 263     263 1 482 my $self = shift;
352 263         457 my $c = $self->{current_compile};
353 263         707 my %p = @_;
354              
355             $self->lexer->throw_syntax_error("End of $p{block_type} encountered while in $c->{in_block} block")
356 263 50       753 unless $c->{in_block} eq $p{block_type};
357              
358 263         902 $c->{in_block} = undef;
359             }
360              
361             sub variable_declaration
362             {
363 85     85 1 147 my $self = shift;
364 85         381 my %p = @_;
365              
366             $self->lexer->throw_syntax_error("variable_declaration called inside a $p{block_type} block")
367 85 50       275 unless $p{block_type} eq 'args';
368              
369 85         199 my $arg = "$p{type}$p{name}";
370              
371             $self->lexer->throw_syntax_error("$arg already defined")
372 85 50       120 if grep { "$_->{type}$_->{name}" eq $arg } @{ $self->{current_compile}{args} };
  56         156  
  85         269  
373              
374 85         303 push @{ $self->{current_compile}{args} }, { type => $p{type},
375             name => $p{name},
376             default => $p{default},
377 85         138 line => $self->lexer->line_number,
378             file => $self->lexer->name,
379             };
380             }
381              
382             sub key_value_pair
383             {
384 62     62 1 100 my $self = shift;
385 62         287 my %p = @_;
386              
387             compiler_error "key_value_pair called inside a $p{block_type} block"
388 62 50 66     265 unless $p{block_type} eq 'flags' || $p{block_type} eq 'attr';
389              
390 62 100       159 my $type = $p{block_type} eq 'flags' ? 'flag' : 'attribute';
391             $self->lexer->throw_syntax_error("$p{key} $type already defined")
392 62 50       204 if exists $self->{current_compile}{ $p{block_type} }{ $p{key} };
393              
394             $self->{current_compile}{ $p{block_type} }{ $p{key} } = $p{value}
395 62         271 }
396              
397             sub start_named_block
398             {
399 119     119 1 210 my $self = shift;
400 119         322 my $c = $self->{current_compile};
401 119         400 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       312 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       435 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       407 if exists $c->{$p{block_type}}{ $p{name} };
    100          
417            
418             # Error if def and method defined with same name
419 115 100       386 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       319 if exists $c->{$other_type}{ $p{name} };
423              
424 114         191 $c->{in_main}--;
425              
426 114         366 $c->{ $p{block_type} }{ $p{name} } = {};
427 114         393 $self->_init_comp_data( $c->{ $p{block_type} }{ $p{name} } );
428 114         170 push @{$self->{paused_compiles}}, $c;
  114         258  
429 114         293 $self->{current_compile} = $c->{ $p{block_type} }{ $p{name} };
430 114         547 $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 200 my $self = shift;
436              
437 113         303 delete $self->{current_compile}->{in_named_block};
438 113         168 $self->{current_compile} = pop @{$self->{paused_compiles}};
  113         279  
439 113         257 $self->{current_compile}{in_main}++;
440             }
441              
442             sub substitution
443             {
444 387     387 1 654 my $self = shift;
445 387         1470 my %p = @_;
446              
447 387         802 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         1297 my @lines = split(/\n/, $text);
458 387 100       792 unless (grep { /^\s*[^\s\#]/ } @lines) {
  394         1866  
459 4         8 $self->{current_compile}{last_body_code_type} = 'substitution';
460 4         10 return;
461             }
462              
463 383 100 66     1761 if ( ( exists $p{escape} && defined $p{escape} ) ||
      100        
464 361         1155 @{ $self->{default_escape_flags} }
465             )
466             {
467 29         40 my @flags;
468 29 100       63 if ( defined $p{escape} )
469             {
470 22         64 $p{escape} =~ s/\s+$//;
471              
472 22 100       135 if ( $p{escape} =~ /$old_escape_re/ )
473             {
474 14         34 @flags = split //, $p{escape};
475             }
476             else
477             {
478 8         30 @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         51 unshift @flags, @{ $self->default_escape_flags }
486 29 100       79 unless grep { $_ eq 'n' } @flags;
  28         78  
487              
488 29         44 my %seen;
489             my $flags =
490             ( join ', ',
491 32 100       123 map { $seen{$_}++ ? () : "'$_'" }
492 29         48 grep { $_ ne 'n' } @flags
  39         75  
493             );
494              
495 29 100       104 $text = "(map {; \$m->interp->apply_escapes(\$_, $flags) } ($text))"
496             if $flags;
497             }
498              
499 383         620 my $code;
500              
501             # Make sure to allow lists within <% %> tags.
502             #
503 383 100       1106 if ($self->enable_autoflush) {
504 375         902 $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         21 $code = "for ( $text ) { \$\$_outbuf .= \$_ if defined }\n";
511             }
512              
513 383 100       1006 eval { $self->postprocess_perl->(\$code) } if $self->postprocess_perl;
  3         7  
514 383 50       808 compiler_error $@ if $@;
515              
516 383         940 $self->_add_body_code($code);
517              
518 383         1163 $self->{current_compile}{last_body_code_type} = 'substitution';
519             }
520              
521             sub component_call
522             {
523 216     216 1 398 my $self = shift;
524 216         779 my %p = @_;
525              
526 216         1527 my ($prespace, $call, $postspace) = ($p{call} =~ /(\s*)(.*)(\s*)/s);
527 216 100       944 if ( $call =~ m,^[\w/.],)
528             {
529 203         531 my $comma = index($call, ',');
530 203 100       514 $comma = length $call if $comma == -1;
531 203         1055 (my $comp = substr($call, 0, $comma)) =~ s/\s+$//;
532 203         746 $call = "'$comp'" . substr($call, $comma);
533             }
534 216         659 my $code = "\$m->comp( $prespace $call $postspace \n); ";
535 216 50       772 eval { $self->postprocess_perl->(\$code) } if $self->postprocess_perl;
  0         0  
536 216 50       560 compiler_error $@ if $@;
537              
538 216         732 $self->_add_body_code($code);
539              
540 216         683 $self->{current_compile}{last_body_code_type} = 'component_call';
541             }
542              
543             sub component_content_call
544             {
545 39     39 1 76 my $self = shift;
546 39         77 my $c = $self->{current_compile};
547 39         102 my %p = @_;
548              
549 39         67 my $call = $p{call};
550 39         73 for ($call) { s/^\s+//; s/\s+$//; }
  39         129  
  39         178  
551 39         64 push @{ $c->{comp_with_content_stack} }, $call;
  39         106  
552              
553 39         75 my $code = "\$m->comp( { content => sub {\n";
554 39         131 $code .= $self->_set_buffer();
555              
556 39 50       110 eval { $self->postprocess_perl->(\$code) } if $self->postprocess_perl;
  0         0  
557 39 50       95 compiler_error $@ if $@;
558              
559 39         114 $self->_add_body_code($code);
560              
561 39         113 $c->{last_body_code_type} = 'component_content_call';
562             }
563              
564             sub component_content_call_end
565             {
566 39     39 1 59 my $self = shift;
567 39         74 my $c = $self->{current_compile};
568 39         96 my %p = @_;
569              
570             $self->lexer->throw_syntax_error("Found component with content ending tag but no beginning tag")
571 39 100       55 unless @{ $c->{comp_with_content_stack} };
  39         109  
572              
573 37         54 my $call = pop @{ $c->{comp_with_content_stack} };
  37         98  
574 37         55 my $call_end = $p{call_end};
575 37         78 for ($call_end) { s/^\s+//; s/\s+$//; }
  37         67  
  37         72  
576              
577 37         60 my $comp = undef;
578 37 100       121 if ( $call =~ m,^[\w/.],)
579             {
580 33         71 my $comma = index($call, ',');
581 33 100       90 $comma = length $call if $comma == -1;
582 33         95 ($comp = substr($call, 0, $comma)) =~ s/\s+$//;
583 33         110 $call = "'$comp'" . substr($call, $comma);
584             }
585 37 100       72 if ($call_end) {
586 7 100       21 if ($call_end !~ m,^[\w/.],) {
587 2         6 $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       15 if (!defined($comp)) {
590 1         5 $self->lexer->throw_syntax_error("Cannot match an expression as a component name; use instead");
591             }
592 4 100       9 if ($call_end ne $comp) {
593 1         4 $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         74 my $code = "} }, $call\n );\n";
598              
599 33 50       82 eval { $self->postprocess_perl->(\$code) } if $self->postprocess_perl;
  0         0  
600 33 50       74 compiler_error $@ if $@;
601              
602 33         79 $self->_add_body_code($code);
603              
604 33         90 $c->{last_body_code_type} = 'component_content_call_end';
605             }
606              
607             sub perl_line
608             {
609 395     395 1 603 my $self = shift;
610 395         1369 my %p = @_;
611              
612 395         981 my $code = "$p{line}\n";
613              
614 395 100       1056 eval { $self->postprocess_perl->(\$code) } if $self->postprocess_perl;
  1         4  
615 395 50       828 compiler_error $@ if $@;
616              
617 395         1007 $self->_add_body_code($code);
618              
619 395         1108 $self->{current_compile}{last_body_code_type} = 'perl_line';
620             }
621              
622             sub _add_body_code
623             {
624 2233     2233   3313 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     4543 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         3820 my $line = $self->lexer->line_number;
636 1926         3988 my $file = $self->_escape_filename( $self->lexer->name );
637 1926         6701 $self->{current_compile}{body} .= qq{#line $line "$file"\n};
638             }
639              
640 2233         8039 $self->{current_compile}{body} .= $_ foreach @_;
641             }
642              
643             sub _escape_filename
644             {
645 2133     2133   3046 my $self = shift;
646 2133         2887 my $file = shift;
647              
648 2133         4082 $file =~ s/\"//g;
649              
650 2133         3869 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   7618 my $self = shift;
699              
700 5566         6170 return @{ $self->{current_compile}{blocks}{ shift() } };
  5566         16248  
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__