Permalink
Browse files

generators: optimize generated code a bit if only one concatenation i…

…s done

static_merger, dynamic_inliner: perform simple flattening
  • Loading branch information...
1 parent 94ee74a commit eb4570d5f91ee8219f73ad1fea4686c96ec680be @minad minad committed Aug 24, 2012
@@ -64,7 +64,7 @@ def on_multi(*exps)
result.concat(prev) if state == :single
end
- result
+ result.size == 2 ? result[1] : result
end
end
end
@@ -8,8 +8,7 @@ module Filters
#
# Compiles to:
#
- # [:multi,
- # [:static, "Hello World!"]]
+ # [:static, "Hello World!"]
#
# @api public
class StaticMerger < Filter
@@ -31,7 +30,7 @@ def on_multi(*exps)
end
end
- result
+ result.size == 2 ? result[1] : result
end
end
end
View
@@ -33,13 +33,7 @@ def on_newline
end
def on_capture(name, exp)
- if exp.first == :static
- "#{name} = #{exp.last.inspect}"
- elsif exp.first == :dynamic
- "#{name} = #{exp.last}"
- else
- options[:capture_generator].new(:buffer => name).call(exp)
- end
+ options[:capture_generator].new(:buffer => name).call(exp)
end
def on_static(text)
@@ -71,7 +65,7 @@ module Generators
# _buf = []
# _buf << "static"
# _buf << dynamic
- # _buf.join
+ # _buf
#
# @api public
class Array < Generator
@@ -85,8 +79,25 @@ def postamble
end
# Just like Array, but calls #join on the array.
+ #
+ # _buf = []
+ # _buf << "static"
+ # _buf << dynamic
+ # _buf.join
+ #
# @api public
class ArrayBuffer < Array
+ def call(exp)
+ case exp.first
+ when :static
+ "#{buffer} = #{exp.last.inspect}"
+ when :dynamic
+ "#{buffer} = (#{exp.last}).to_s"
+ else
+ super
+ end
+ end
+
def postamble
"#{buffer} = #{buffer}.join"
end
@@ -100,19 +111,23 @@ def postamble
# _buf
#
# @api public
- class StringBuffer < Array
+ class StringBuffer < ArrayBuffer
def preamble
"#{buffer} = ''"
end
+ def postamble
+ buffer
+ end
+
def on_dynamic(code)
concat("(#{code}).to_s")
end
end
# Implements a rails output buffer.
#
- # @output_buffer = ActionView::OutputBuffer
+ # @output_buffer = ActionView::SafeBuffer
# @output_buffer.safe_concat "static"
# @output_buffer.safe_concat dynamic.to_s
# @output_buffer
@@ -124,6 +139,10 @@ class RailsOutputBuffer < StringBuffer
# output_buffer is needed for Rails 3.1 Streaming support
:capture_generator => RailsOutputBuffer
+ def call(exp)
+ [preamble, compile(exp), postamble].join('; ')
+ end
+
def preamble
if options[:streaming] && options[:buffer] == '@output_buffer'
"#{buffer} = output_buffer || #{options[:buffer_class]}.new"
@@ -10,15 +10,15 @@
[:static, "Hello "],
[:static, "World\n "],
[:static, "Have a nice day"]
- ]).should.equal [:multi, [:dynamic, '"Hello World\n Have a nice day"']]
+ ]).should.equal [:dynamic, '"Hello World\n Have a nice day"']
end
it 'should compile several dynamics into dynamic' do
@filter.call([:multi,
[:dynamic, "@hello"],
[:dynamic, "@world"],
[:dynamic, "@yeah"]
- ]).should.equal [:multi, [:dynamic, '"#{@hello}#{@world}#{@yeah}"']]
+ ]).should.equal [:dynamic, '"#{@hello}#{@world}#{@yeah}"']
end
it 'should compile static and dynamic into dynamic' do
@@ -27,7 +27,7 @@
[:dynamic, "@world"],
[:dynamic, "@yeah"],
[:static, "Nice"]
- ]).should.equal [:multi, [:dynamic, '"Hello#{@world}#{@yeah}Nice"']]
+ ]).should.equal [:dynamic, '"Hello#{@world}#{@yeah}Nice"']
end
it 'should merge statics and dynamics around a code' do
@@ -45,18 +45,15 @@
end
it 'should keep codes intact' do
- exp = [:multi, [:code, 'foo']]
- @filter.call(exp).should.equal exp
+ @filter.call([:multi, [:code, 'foo']]).should.equal [:code, 'foo']
end
it 'should keep single statics intact' do
- exp = [:multi, [:static, 'foo']]
- @filter.call(exp).should.equal exp
+ @filter.call([:multi, [:static, 'foo']]).should.equal [:static, 'foo']
end
it 'should keep single dynamic intact' do
- exp = [:multi, [:dynamic, 'foo']]
- @filter.call(exp).should.equal exp
+ @filter.call([:multi, [:dynamic, 'foo']]).should.equal [:dynamic, 'foo']
end
it 'should inline inside multi' do
@@ -70,7 +67,7 @@
[:dynamic, "@world"]
]).should.equal [:multi,
[:dynamic, '"Hello #{@world}"'],
- [:multi, [:dynamic, '"Hello #{@world}"']],
+ [:dynamic, '"Hello #{@world}"'],
[:dynamic, '"Hello #{@world}"']
]
end
@@ -81,9 +78,7 @@
[:newline],
[:dynamic, "@world"],
[:newline]
- ]).should.equal [:multi,
- [:dynamic, ['"Hello \n"', '"#{@world}"', '""'].join("\\\n")]
- ]
+ ]).should.equal [:dynamic, ['"Hello \n"', '"#{@world}"', '""'].join("\\\n")]
end
it 'should compile static followed by newline' do
@@ -10,9 +10,7 @@
[:static, "Hello "],
[:static, "World, "],
[:static, "Good night"]
- ]).should.equal [:multi,
- [:static, "Hello World, Good night"]
- ]
+ ]).should.equal [:static, "Hello World, Good night"]
end
it 'should merge serveral statics around code' do
View
@@ -81,24 +81,33 @@ def on_code(s)
gen.call([:static, 'test']).should.equal '_buf = []; _buf << ("test"); _buf'
gen.call([:dynamic, 'test']).should.equal '_buf = []; _buf << (test); _buf'
gen.call([:code, 'test']).should.equal '_buf = []; test; _buf'
+
+ gen.call([:multi, [:static, 'a'], [:static, 'b']]).should.equal '_buf = []; _buf << ("a"); _buf << ("b"); _buf'
+ gen.call([:multi, [:static, 'a'], [:dynamic, 'b']]).should.equal '_buf = []; _buf << ("a"); _buf << (b); _buf'
end
end
describe Temple::Generators::ArrayBuffer do
it 'should compile simple expressions' do
gen = Temple::Generators::ArrayBuffer.new
- gen.call([:static, 'test']).should.equal '_buf = []; _buf << ("test"); _buf = _buf.join'
- gen.call([:dynamic, 'test']).should.equal '_buf = []; _buf << (test); _buf = _buf.join'
+ gen.call([:static, 'test']).should.equal '_buf = "test"'
+ gen.call([:dynamic, 'test']).should.equal '_buf = (test).to_s'
gen.call([:code, 'test']).should.equal '_buf = []; test; _buf = _buf.join'
+
+ gen.call([:multi, [:static, 'a'], [:static, 'b']]).should.equal '_buf = []; _buf << ("a"); _buf << ("b"); _buf = _buf.join'
+ gen.call([:multi, [:static, 'a'], [:dynamic, 'b']]).should.equal '_buf = []; _buf << ("a"); _buf << (b); _buf = _buf.join'
end
end
describe Temple::Generators::StringBuffer do
it 'should compile simple expressions' do
gen = Temple::Generators::StringBuffer.new
- gen.call([:static, 'test']).should.equal '_buf = \'\'; _buf << ("test"); _buf'
- gen.call([:dynamic, 'test']).should.equal '_buf = \'\'; _buf << ((test).to_s); _buf'
+ gen.call([:static, 'test']).should.equal '_buf = "test"'
+ gen.call([:dynamic, 'test']).should.equal '_buf = (test).to_s'
gen.call([:code, 'test']).should.equal '_buf = \'\'; test; _buf'
+
+ gen.call([:multi, [:static, 'a'], [:static, 'b']]).should.equal '_buf = \'\'; _buf << ("a"); _buf << ("b"); _buf'
+ gen.call([:multi, [:static, 'a'], [:dynamic, 'b']]).should.equal '_buf = \'\'; _buf << ("a"); _buf << ((b).to_s); _buf'
end
end

0 comments on commit eb4570d

Please sign in to comment.