From d4ecaff8b839e7629090e238dd6bd5bff6c9e74c Mon Sep 17 00:00:00 2001 From: Dylan Thacker-Smith Date: Tue, 18 Mar 2014 17:38:43 -0400 Subject: [PATCH] Refactor to create tags with a parse class method instead of new. By moving parse out of the initializer, we can call super at the start of the initializers for subclasses, and avoid the nasty allocate hack. --- History.md | 1 + lib/liquid/block.rb | 2 +- lib/liquid/document.rb | 7 +++---- lib/liquid/tag.rb | 20 ++++++++++---------- lib/liquid/tags/assign.rb | 5 ++--- lib/liquid/tags/capture.rb | 5 ++--- lib/liquid/tags/case.rb | 5 ++--- lib/liquid/tags/cycle.rb | 4 ++-- lib/liquid/tags/decrement.rb | 5 ++--- lib/liquid/tags/for.rb | 4 ++-- lib/liquid/tags/if.rb | 4 ++-- lib/liquid/tags/include.rb | 6 +++--- lib/liquid/tags/increment.rb | 4 ++-- lib/liquid/tags/table_row.rb | 5 ++--- lib/liquid/template.rb | 2 +- performance/shopify/comment_form.rb | 6 +++--- performance/shopify/paginate.rb | 6 +++--- test/liquid/tags/standard_tag_test.rb | 2 +- 18 files changed, 44 insertions(+), 49 deletions(-) diff --git a/History.md b/History.md index 200b5eb9..d99f7cb1 100644 --- a/History.md +++ b/History.md @@ -3,6 +3,7 @@ ## 3.0.0 / not yet released / branch "master" * ... +* Tag#parse is called after initialize, which now takes options instead of tokens as the 3rd argument. See #321 [Dylan Thacker-Smith, dylanahsmith] * Raise `Liquid::ArgumentError` instead of `::ArgumentError` when filter has wrong number of arguments #309 [Bogdan Gusiev, bogdan] * Add a to_s default for liquid drops, see #306 [Adam Doeler, releod] * Add strip, lstrip, and rstrip to standard filters [Florian Weingarten, fw42] diff --git a/lib/liquid/block.rb b/lib/liquid/block.rb index 2acfe204..bcac5a84 100644 --- a/lib/liquid/block.rb +++ b/lib/liquid/block.rb @@ -31,7 +31,7 @@ module Liquid # fetch the tag from registered blocks if tag = Template.tags[$1] - new_tag = tag.new_with_options($1, $2, tokens, @options || {}) + new_tag = tag.parse($1, $2, tokens, @options) @blank &&= new_tag.blank? @nodelist << new_tag @children << new_tag diff --git a/lib/liquid/document.rb b/lib/liquid/document.rb index b802c859..1969a3af 100644 --- a/lib/liquid/document.rb +++ b/lib/liquid/document.rb @@ -1,9 +1,8 @@ module Liquid class Document < Block - # we don't need markup to open this block - def initialize(tokens, options = {}) - @options = options - parse(tokens) + def self.parse(tokens, options={}) + # we don't need markup to open this block + super(nil, nil, tokens, options) end # There isn't a real delimiter diff --git a/lib/liquid/tag.rb b/lib/liquid/tag.rb index 83dc7300..2daf0848 100644 --- a/lib/liquid/tag.rb +++ b/lib/liquid/tag.rb @@ -3,20 +3,20 @@ module Liquid attr_accessor :options attr_reader :nodelist, :warnings - def self.new_with_options(tag_name, markup, tokens, options) - # Forgive me Matz for I have sinned. I know this code is weird - # but it was necessary to maintain API compatibility. - new_tag = self.allocate - new_tag.options = options - new_tag.send(:initialize, tag_name, markup, tokens) - new_tag + class << self + def parse(tag_name, markup, tokens, options) + tag = new(tag_name, markup, options) + tag.parse(tokens) + tag + end + + private :new end - def initialize(tag_name, markup, tokens) + def initialize(tag_name, markup, options) @tag_name = tag_name @markup = markup - @options ||= {} # needs || because might be set before initialize - parse(tokens) + @options = options end def parse(tokens) diff --git a/lib/liquid/tags/assign.rb b/lib/liquid/tags/assign.rb index 4699a6a5..a3bc86f9 100644 --- a/lib/liquid/tags/assign.rb +++ b/lib/liquid/tags/assign.rb @@ -11,15 +11,14 @@ module Liquid class Assign < Tag Syntax = /(#{VariableSignature}+)\s*=\s*(.*)\s*/o - def initialize(tag_name, markup, tokens) + def initialize(tag_name, markup, options) + super if markup =~ Syntax @to = $1 @from = Variable.new($2) else raise SyntaxError.new options[:locale].t("errors.syntax.assign") end - - super end def render(context) diff --git a/lib/liquid/tags/capture.rb b/lib/liquid/tags/capture.rb index 34036be6..9acb22bd 100644 --- a/lib/liquid/tags/capture.rb +++ b/lib/liquid/tags/capture.rb @@ -14,14 +14,13 @@ module Liquid class Capture < Block Syntax = /(\w+)/ - def initialize(tag_name, markup, tokens) + def initialize(tag_name, markup, options) + super if markup =~ Syntax @to = $1 else raise SyntaxError.new(options[:locale].t("errors.syntax.capture")) end - - super end def render(context) diff --git a/lib/liquid/tags/case.rb b/lib/liquid/tags/case.rb index 2b7179fa..ed6e8069 100644 --- a/lib/liquid/tags/case.rb +++ b/lib/liquid/tags/case.rb @@ -3,7 +3,8 @@ module Liquid Syntax = /(#{QuotedFragment})/o WhenSyntax = /(#{QuotedFragment})(?:(?:\s+or\s+|\s*\,\s*)(#{QuotedFragment}.*))?/o - def initialize(tag_name, markup, tokens) + def initialize(tag_name, markup, options) + super @blocks = [] if markup =~ Syntax @@ -11,8 +12,6 @@ module Liquid else raise SyntaxError.new(options[:locale].t("errors.syntax.case")) end - - super end def nodelist diff --git a/lib/liquid/tags/cycle.rb b/lib/liquid/tags/cycle.rb index 02bca0bf..ed429951 100644 --- a/lib/liquid/tags/cycle.rb +++ b/lib/liquid/tags/cycle.rb @@ -15,7 +15,8 @@ module Liquid SimpleSyntax = /\A#{QuotedFragment}+/o NamedSyntax = /\A(#{QuotedFragment})\s*\:\s*(.*)/o - def initialize(tag_name, markup, tokens) + def initialize(tag_name, markup, options) + super case markup when NamedSyntax @variables = variables_from_string($2) @@ -26,7 +27,6 @@ module Liquid else raise SyntaxError.new(options[:locale].t("errors.syntax.cycle")) end - super end def render(context) diff --git a/lib/liquid/tags/decrement.rb b/lib/liquid/tags/decrement.rb index 217d96d4..e9b66065 100644 --- a/lib/liquid/tags/decrement.rb +++ b/lib/liquid/tags/decrement.rb @@ -19,10 +19,9 @@ module Liquid # Hello: -3 # class Decrement < Tag - def initialize(tag_name, markup, tokens) - @variable = markup.strip - + def initialize(tag_name, markup, options) super + @variable = markup.strip end def render(context) diff --git a/lib/liquid/tags/for.rb b/lib/liquid/tags/for.rb index 057658cd..3cd9e974 100644 --- a/lib/liquid/tags/for.rb +++ b/lib/liquid/tags/for.rb @@ -46,10 +46,10 @@ module Liquid class For < Block Syntax = /\A(#{VariableSegment}+)\s+in\s+(#{QuotedFragment}+)\s*(reversed)?/o - def initialize(tag_name, markup, tokens) + def initialize(tag_name, markup, options) + super parse_with_selected_parser(markup) @nodelist = @for_block = [] - super end def nodelist diff --git a/lib/liquid/tags/if.rb b/lib/liquid/tags/if.rb index e6175e80..ad48bb57 100644 --- a/lib/liquid/tags/if.rb +++ b/lib/liquid/tags/if.rb @@ -14,10 +14,10 @@ module Liquid ExpressionsAndOperators = /(?:\b(?:\s?and\s?|\s?or\s?)\b|(?:\s*(?!\b(?:\s?and\s?|\s?or\s?)\b)(?:#{QuotedFragment}|\S+)\s*)+)/o BOOLEAN_OPERATORS = %w(and or) - def initialize(tag_name, markup, tokens) + def initialize(tag_name, markup, options) + super @blocks = [] push_block('if', markup) - super end def nodelist diff --git a/lib/liquid/tags/include.rb b/lib/liquid/tags/include.rb index d439fff8..34b2b0b5 100644 --- a/lib/liquid/tags/include.rb +++ b/lib/liquid/tags/include.rb @@ -17,7 +17,9 @@ module Liquid class Include < Tag Syntax = /(#{QuotedFragment}+)(\s+(?:with|for)\s+(#{QuotedFragment}+))?/o - def initialize(tag_name, markup, tokens) + def initialize(tag_name, markup, options) + super + if markup =~ Syntax @template_name = $1 @@ -31,8 +33,6 @@ module Liquid else raise SyntaxError.new(options[:locale].t("errors.syntax.include")) end - - super end def parse(tokens) diff --git a/lib/liquid/tags/increment.rb b/lib/liquid/tags/increment.rb index 5540061d..251bd776 100644 --- a/lib/liquid/tags/increment.rb +++ b/lib/liquid/tags/increment.rb @@ -15,9 +15,9 @@ module Liquid # Hello: 2 # class Increment < Tag - def initialize(tag_name, markup, tokens) - @variable = markup.strip + def initialize(tag_name, markup, options) super + @variable = markup.strip end def render(context) diff --git a/lib/liquid/tags/table_row.rb b/lib/liquid/tags/table_row.rb index 8ceab444..771042da 100644 --- a/lib/liquid/tags/table_row.rb +++ b/lib/liquid/tags/table_row.rb @@ -2,7 +2,8 @@ module Liquid class TableRow < Block Syntax = /(\w+)\s+in\s+(#{QuotedFragment}+)/o - def initialize(tag_name, markup, tokens) + def initialize(tag_name, markup, options) + super if markup =~ Syntax @variable_name = $1 @collection_name = $2 @@ -13,8 +14,6 @@ module Liquid else raise SyntaxError.new(options[:locale].t("errors.syntax.table_row")) end - - super end def render(context) diff --git a/lib/liquid/template.rb b/lib/liquid/template.rb index 1f2bfd14..4ca7961a 100644 --- a/lib/liquid/template.rb +++ b/lib/liquid/template.rb @@ -72,7 +72,7 @@ module Liquid # Parse source code. # Returns self for easy chaining def parse(source, options = {}) - @root = Document.new(tokenize(source), DEFAULT_OPTIONS.merge(options)) + @root = Document.parse(tokenize(source), DEFAULT_OPTIONS.merge(options)) @warnings = nil self end diff --git a/performance/shopify/comment_form.rb b/performance/shopify/comment_form.rb index 2a62f660..30226dda 100644 --- a/performance/shopify/comment_form.rb +++ b/performance/shopify/comment_form.rb @@ -1,15 +1,15 @@ class CommentForm < Liquid::Block Syntax = /(#{Liquid::VariableSignature}+)/ - def initialize(tag_name, markup, tokens) + def initialize(tag_name, markup, options) + super + if markup =~ Syntax @variable_name = $1 @attributes = {} else raise SyntaxError.new("Syntax Error in 'comment_form' - Valid syntax: comment_form [article]") end - - super end def render(context) diff --git a/performance/shopify/paginate.rb b/performance/shopify/paginate.rb index a5b5c9f8..23c92c84 100644 --- a/performance/shopify/paginate.rb +++ b/performance/shopify/paginate.rb @@ -1,7 +1,9 @@ class Paginate < Liquid::Block Syntax = /(#{Liquid::QuotedFragment})\s*(by\s*(\d+))?/ - def initialize(tag_name, markup, tokens) + def initialize(tag_name, markup, options) + super + @nodelist = [] if markup =~ Syntax @@ -19,8 +21,6 @@ class Paginate < Liquid::Block else raise SyntaxError.new("Syntax Error in tag 'paginate' - Valid syntax: paginate [collection] by number") end - - super end def render(context) diff --git a/test/liquid/tags/standard_tag_test.rb b/test/liquid/tags/standard_tag_test.rb index ddd365f3..10cc5e32 100644 --- a/test/liquid/tags/standard_tag_test.rb +++ b/test/liquid/tags/standard_tag_test.rb @@ -4,7 +4,7 @@ class StandardTagTest < Test::Unit::TestCase include Liquid def test_tag - tag = Tag.new('tag', [], []) + tag = Tag.parse('tag', [], [], {}) assert_equal 'liquid::tag', tag.name assert_equal '', tag.render(Context.new) end