diff --git a/bench.rb b/bench.rb index afd20ad9..c8e81eae 100755 --- a/bench.rb +++ b/bench.rb @@ -10,7 +10,8 @@ puts RUBY_DESCRIPTION a = Example::Page.new.call -Example::Page.compile +# Example::Page.compile +# Example::LayoutComponent.compile b = Example::Page.new.call raise unless a == b diff --git a/fixtures/page.rb b/fixtures/page.rb index 859bd913..a2adc25e 100644 --- a/fixtures/page.rb +++ b/fixtures/page.rb @@ -3,28 +3,30 @@ module Example class Page < Phlex::View def template - h1 { "Hi" } + render LayoutComponent.new do + h1 { "Hi" } - table id: "test", class: "a b c d e f g" do - tr do - td id: "test", class: "a b c d e f g" do - span { "Hi" } - end + table id: "test", class: "a b c d e f g" do + tr do + td id: "test", class: "a b c d e f g" do + span { "Hi" } + end - td id: "test", class: "a b c d e f g" do - span { "Hi" } - end + td id: "test", class: "a b c d e f g" do + span { "Hi" } + end - td id: "test", class: "a b c d e f g" do - span { "Hi" } - end + td id: "test", class: "a b c d e f g" do + span { "Hi" } + end - td id: "test", class: "a b c d e f g" do - span { "Hi" } - end + td id: "test", class: "a b c d e f g" do + span { "Hi" } + end - td id: "test", class: "a b c d e f g" do - span { "Hi" } + td id: "test", class: "a b c d e f g" do + span { "Hi" } + end end end end diff --git a/lib/phlex/compiler.rb b/lib/phlex/compiler.rb index ec3322c0..a4943937 100644 --- a/lib/phlex/compiler.rb +++ b/lib/phlex/compiler.rb @@ -6,6 +6,8 @@ def initialize(view) @view = view end + attr_accessor :scope + def inspect "#{self.class.name} for #{@view.name} view class" end @@ -26,9 +28,25 @@ def redefined?(method_name) end def redefine(method, line:) - print method - print "\n\n" - @view.class_eval(method, file, line) + string = the_scope + method + (";end" * scope.size) + + print string + puts + puts + + + eval(string) + + # Module.class_eval(string, file, line) + end + + def the_scope + scope.map do |scope| + case scope + in SyntaxTree::ModuleDeclaration then "module #{scope.constant.constant.value};" + in SyntaxTree::ClassDeclaration then "class #{scope.constant.constant.value};" + end + end.join end def line diff --git a/lib/phlex/compiler/visitors/file.rb b/lib/phlex/compiler/visitors/file.rb index f1a953b4..eaafd9de 100644 --- a/lib/phlex/compiler/visitors/file.rb +++ b/lib/phlex/compiler/visitors/file.rb @@ -2,12 +2,28 @@ module Phlex::Compiler::Visitors class File < Base + def initialize(compiler) + @scope = [] + super + end + visit_method def visit_class(node) + @scope.push node + if node.location.start_line == @compiler.line + @compiler.scope = @scope View.new(@compiler).visit_all(node.child_nodes) else super end + + @scope.pop + end + + visit_method def visit_module(node) + @scope.push(node) + super + @scope.pop end end end diff --git a/lib/phlex/compiler/visitors/stable_scope.rb b/lib/phlex/compiler/visitors/stable_scope.rb index 7d21c829..8142d43d 100644 --- a/lib/phlex/compiler/visitors/stable_scope.rb +++ b/lib/phlex/compiler/visitors/stable_scope.rb @@ -18,4 +18,11 @@ def visit_brace_block(node) def visit_do_block(node) nil end + + def visit_method_add_block(node) + node = Phlex::Compiler::Nodes::MethodAddBlock.new(node) + if node.method_call.name == :render + visit(node.content) + end + end end diff --git a/lib/phlex/compiler/visitors/view_method.rb b/lib/phlex/compiler/visitors/view_method.rb index 7945dbe2..73708833 100644 --- a/lib/phlex/compiler/visitors/view_method.rb +++ b/lib/phlex/compiler/visitors/view_method.rb @@ -19,6 +19,8 @@ def optimized_something? if optimizer.call @optimized_something = true end + + super end visit_method def visit_vcall(node)