Class: Ember::Template::Program

Inherits:
Object
  • Object
show all
Defined in:
lib/ember/template.rb

Overview

:nodoc:

Defined Under Namespace

Classes: Statement

Instance Method Summary collapse

Constructor Details

#initialize(result_variable, continue_result) ⇒ Program

Transforms this program into Ruby code which uses the given variable name as the evaluation buffer.

If continue_result is true, the evaluation buffer is reused if it already exists in the rendering context.



435
436
437
438
439
# File 'lib/ember/template.rb', line 435

def initialize result_variable, continue_result
  @result_variable = result_variable
  @continue_result = continue_result
  @source_lines = [] # each line is composed of multiple statements
end

Instance Method Details

#compileObject

Transforms this program into executable Ruby source code.



529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
# File 'lib/ember/template.rb', line 529

def compile
  '(%s %s []; %s; %s.join)' % [
    @result_variable,
    @continue_result ? '||=' : '=',

    @source_lines.map do |source_line|
      compiled_line = []
      combine_prev = false

      source_line.each do |stmt|
        is_code = stmt.type == :code
        is_expr = stmt.type == :expr

        if is_code
          compiled_line << stmt.value
          combine_prev = false

        else
          code =
            if is_expr
              " << (#{stmt.value.strip})"
            else
              " << #{stmt.value.inspect}"
            end

          if combine_prev
            compiled_line.last << code
          else
            compiled_line << @result_variable.to_s + code
          end

          combine_prev = true
        end
      end

      compiled_line.join('; ')

    end.join("\n"),

    @result_variable,
  ]
end

#emit_code(value) ⇒ Object

Schedules the given Ruby code to be evaluated when this program is run.



484
485
486
# File 'lib/ember/template.rb', line 484

def emit_code value
  statement :code, value
end

#emit_endObject

Inserts an <% end %> directive before the oldest non-whitespace statement possible.

Preceding lines that only emit whitespace are skipped.



502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
# File 'lib/ember/template.rb', line 502

def emit_end
  ending  = Statement.new(:code, :end)
  current = insertion_point

  can_skip_line = lambda do |line|
    line.empty? ||
    line.all? {|stmt| stmt.type == :text && stmt.value =~ /\A\s*\z/ }
  end

  if can_skip_line[current]
    target = current

    # skip past empty whitespace in previous lines
    @source_lines.reverse_each do |line|
      break unless can_skip_line[line]
      target = line
    end

    target.unshift ending
  else
    current.push ending
  end
end

#emit_expr(value) ⇒ Object

Schedules the given Ruby code to be evaluated and inserted into the evaluation buffer when this program is run.



492
493
494
# File 'lib/ember/template.rb', line 492

def emit_expr value
  statement :expr, value
end

#emit_text(value) ⇒ Object

Schedules the given text to be inserted verbatim into the evaluation buffer when this program is run.



468
469
470
471
472
473
474
475
476
477
478
# File 'lib/ember/template.rb', line 468

def emit_text value
  # don't bother emitting empty strings
  return if value.empty?

  # combine adjacent statements to reduce code size
  if prev = insertion_point.last and prev.type == :text
    prev.value << value
  else
    statement :text, value
  end
end

#empty?Boolean

Returns true if there are no source lines in this program.

Returns:

  • (Boolean)


444
445
446
# File 'lib/ember/template.rb', line 444

def empty?
  @source_lines.empty?
end

#new_lineObject

Begins a new line in the program’s source code.



451
452
453
# File 'lib/ember/template.rb', line 451

def new_line
  @source_lines << []
end

#new_line?Boolean

Returns true if a new (blank) line is ready in the program’s source code.

Returns:

  • (Boolean)


459
460
461
462
# File 'lib/ember/template.rb', line 459

def new_line?
  ary = insertion_point
  ary.empty? || ary.all? {|stmt| stmt.type == :code }
end