Skip to content

Commit

Permalink
Refactor compiled source code into method
Browse files Browse the repository at this point in the history
Moves the part of `compile!` that compiles the template source into it's
own method. We need this for future work in improving exceptions for ERB
templates to pass to ErrorHighlight.

Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
  • Loading branch information
eileencodes and tenderlove committed Dec 12, 2022
1 parent a1367da commit 5026aba
Showing 1 changed file with 35 additions and 20 deletions.
55 changes: 35 additions & 20 deletions actionview/lib/action_view/template.rb
Expand Up @@ -317,19 +317,10 @@ def compile!(view)
end
end

# Among other things, this method is responsible for properly setting
# the encoding of the compiled template.
#
# If the template engine handles encodings, we send the encoded
# String to the engine without further processing. This allows
# the template engine to support additional mechanisms for
# specifying the encoding. For instance, ERB supports <%# encoding: %>
#
# Otherwise, after we figure out the correct encoding, we then
# encode the source into <tt>Encoding.default_internal</tt>.
# In general, this means that templates will be UTF-8 inside of Rails,
# regardless of the original source encoding.
def compile(mod)
# This method compiles the source of the template. The compilation of templates
# involves setting strict_locals! if applicable, encoding the template, and setting
# frozen string literal.
def compiled_source
strict_locals!
source = encode!
code = @handler.call(self, source)
Expand All @@ -343,7 +334,7 @@ def compile(mod)

# Make sure that the resulting String to be eval'd is in the
# encoding of the code
original_source = source
@original_source = source
source = +<<-end_src
def #{method_name}(#{method_arguments})
@virtual_path = #{@virtual_path.inspect};#{locals_code};#{code}
Expand All @@ -364,17 +355,33 @@ def #{method_name}(#{method_arguments})
raise WrongEncodingError.new(source, Encoding.default_internal)
end

if Template.frozen_string_literal
"# frozen_string_literal: true\n#{source}"
else
source
end
end

# Among other things, this method is responsible for properly setting
# the encoding of the compiled template.
#
# If the template engine handles encodings, we send the encoded
# String to the engine without further processing. This allows
# the template engine to support additional mechanisms for
# specifying the encoding. For instance, ERB supports <%# encoding: %>
#
# Otherwise, after we figure out the correct encoding, we then
# encode the source into <tt>Encoding.default_internal</tt>.
# In general, this means that templates will be UTF-8 inside of Rails,
# regardless of the original source encoding.
def compile(mod)
begin
if Template.frozen_string_literal
mod.module_eval("# frozen_string_literal: true\n#{source}", identifier, -1)
else
mod.module_eval(source, identifier, 0)
end
mod.module_eval(compiled_source, identifier, offset)
rescue SyntaxError
# Account for when code in the template is not syntactically valid; e.g. if we're using
# ERB and the user writes <%= foo( %>, attempting to call a helper `foo` and interpolate
# the result into the template, but missing an end parenthesis.
raise SyntaxErrorInTemplate.new(self, original_source)
raise SyntaxErrorInTemplate.new(self, @original_source)
end

return unless @strict_locals
Expand All @@ -398,6 +405,14 @@ def #{method_name}(#{method_arguments})
)
end

def offset
if Template.frozen_string_literal
-1
else
0
end
end

def handle_render_error(view, e)
if e.is_a?(Template::Error)
e.sub_template_of(self)
Expand Down

0 comments on commit 5026aba

Please sign in to comment.