actionview 6.0.0.beta1 → 6.0.1.rc1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionview might be problematic. Click here for more details.

Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +90 -3
  3. data/README.rdoc +3 -1
  4. data/lib/action_view.rb +2 -1
  5. data/lib/action_view/base.rb +107 -10
  6. data/lib/action_view/cache_expiry.rb +54 -0
  7. data/lib/action_view/context.rb +0 -5
  8. data/lib/action_view/digestor.rb +8 -17
  9. data/lib/action_view/gem_version.rb +2 -2
  10. data/lib/action_view/helpers/asset_tag_helper.rb +5 -5
  11. data/lib/action_view/helpers/cache_helper.rb +5 -5
  12. data/lib/action_view/helpers/csp_helper.rb +4 -2
  13. data/lib/action_view/helpers/form_helper.rb +2 -2
  14. data/lib/action_view/helpers/form_options_helper.rb +4 -3
  15. data/lib/action_view/helpers/form_tag_helper.rb +5 -2
  16. data/lib/action_view/helpers/output_safety_helper.rb +1 -1
  17. data/lib/action_view/helpers/rendering_helper.rb +6 -4
  18. data/lib/action_view/helpers/sanitize_helper.rb +10 -16
  19. data/lib/action_view/helpers/tag_helper.rb +1 -1
  20. data/lib/action_view/helpers/tags/base.rb +1 -1
  21. data/lib/action_view/helpers/translation_helper.rb +3 -3
  22. data/lib/action_view/helpers/url_helper.rb +2 -2
  23. data/lib/action_view/layouts.rb +5 -5
  24. data/lib/action_view/lookup_context.rb +69 -27
  25. data/lib/action_view/path_set.rb +5 -10
  26. data/lib/action_view/railtie.rb +9 -4
  27. data/lib/action_view/renderer/abstract_renderer.rb +56 -3
  28. data/lib/action_view/renderer/partial_renderer.rb +66 -55
  29. data/lib/action_view/renderer/partial_renderer/collection_caching.rb +27 -20
  30. data/lib/action_view/renderer/renderer.rb +16 -4
  31. data/lib/action_view/renderer/streaming_template_renderer.rb +4 -4
  32. data/lib/action_view/renderer/template_renderer.rb +24 -18
  33. data/lib/action_view/rendering.rb +46 -27
  34. data/lib/action_view/template.rb +84 -69
  35. data/lib/action_view/template/error.rb +21 -1
  36. data/lib/action_view/template/handlers.rb +27 -1
  37. data/lib/action_view/template/handlers/builder.rb +2 -2
  38. data/lib/action_view/template/handlers/erb.rb +5 -5
  39. data/lib/action_view/template/handlers/erb/erubi.rb +7 -3
  40. data/lib/action_view/template/handlers/html.rb +1 -1
  41. data/lib/action_view/template/handlers/raw.rb +2 -2
  42. data/lib/action_view/template/html.rb +14 -5
  43. data/lib/action_view/template/inline.rb +22 -0
  44. data/lib/action_view/template/raw_file.rb +28 -0
  45. data/lib/action_view/template/resolver.rb +80 -117
  46. data/lib/action_view/template/sources.rb +13 -0
  47. data/lib/action_view/template/sources/file.rb +17 -0
  48. data/lib/action_view/template/text.rb +5 -3
  49. data/lib/action_view/testing/resolvers.rb +33 -20
  50. data/lib/action_view/unbound_template.rb +32 -0
  51. data/lib/action_view/view_paths.rb +25 -1
  52. data/lib/assets/compiled/rails-ujs.js +21 -12
  53. metadata +25 -16
@@ -19,10 +19,14 @@ module ActionView
19
19
 
20
20
  # Main render entry point shared by Action View and Action Controller.
21
21
  def render(context, options)
22
+ render_to_object(context, options).body
23
+ end
24
+
25
+ def render_to_object(context, options) # :nodoc:
22
26
  if options.key?(:partial)
23
- render_partial(context, options)
27
+ render_partial_to_object(context, options)
24
28
  else
25
- render_template(context, options)
29
+ render_template_to_object(context, options)
26
30
  end
27
31
  end
28
32
 
@@ -41,16 +45,24 @@ module ActionView
41
45
 
42
46
  # Direct access to template rendering.
43
47
  def render_template(context, options) #:nodoc:
44
- TemplateRenderer.new(@lookup_context).render(context, options)
48
+ render_template_to_object(context, options).body
45
49
  end
46
50
 
47
51
  # Direct access to partial rendering.
48
52
  def render_partial(context, options, &block) #:nodoc:
49
- PartialRenderer.new(@lookup_context).render(context, options, block)
53
+ render_partial_to_object(context, options, &block).body
50
54
  end
51
55
 
52
56
  def cache_hits # :nodoc:
53
57
  @cache_hits ||= {}
54
58
  end
59
+
60
+ def render_template_to_object(context, options) #:nodoc:
61
+ TemplateRenderer.new(@lookup_context).render(context, options)
62
+ end
63
+
64
+ def render_partial_to_object(context, options, &block) #:nodoc:
65
+ PartialRenderer.new(@lookup_context).render(context, options, block)
66
+ end
55
67
  end
56
68
  end
@@ -34,7 +34,7 @@ module ActionView
34
34
  return unless logger
35
35
 
36
36
  message = +"\n#{exception.class} (#{exception.message}):\n"
37
- message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code)
37
+ message << exception.annotated_source_code.to_s if exception.respond_to?(:annotated_source_code)
38
38
  message << " " << exception.backtrace.join("\n ")
39
39
  logger.fatal("#{message}\n\n")
40
40
  end
@@ -43,14 +43,14 @@ module ActionView
43
43
  # For streaming, instead of rendering a given a template, we return a Body
44
44
  # object that responds to each. This object is initialized with a block
45
45
  # that knows how to render the template.
46
- def render_template(template, layout_name = nil, locals = {}) #:nodoc:
47
- return [super] unless layout_name && template.supports_streaming?
46
+ def render_template(view, template, layout_name = nil, locals = {}) #:nodoc:
47
+ return [super.body] unless layout_name && template.supports_streaming?
48
48
 
49
49
  locals ||= {}
50
50
  layout = layout_name && find_layout(layout_name, locals.keys, [formats.first])
51
51
 
52
52
  Body.new do |buffer|
53
- delayed_render(buffer, template, layout, @view, locals)
53
+ delayed_render(buffer, template, layout, view, locals)
54
54
  end
55
55
  end
56
56
 
@@ -5,15 +5,12 @@ require "active_support/core_ext/object/try"
5
5
  module ActionView
6
6
  class TemplateRenderer < AbstractRenderer #:nodoc:
7
7
  def render(context, options)
8
- @view = context
9
8
  @details = extract_details(options)
10
9
  template = determine_template(options)
11
10
 
12
- prepend_formats(template.formats)
11
+ prepend_formats(template.format)
13
12
 
14
- @lookup_context.rendered_format ||= (template.formats.first || formats.first)
15
-
16
- render_template(template, options[:layout], options[:locals])
13
+ render_template(context, template, options[:layout], options[:locals] || {})
17
14
  end
18
15
 
19
16
  private
@@ -29,15 +26,25 @@ module ActionView
29
26
  elsif options.key?(:html)
30
27
  Template::HTML.new(options[:html], formats.first)
31
28
  elsif options.key?(:file)
32
- with_fallbacks { find_file(options[:file], nil, false, keys, @details) }
29
+ if File.exist?(options[:file])
30
+ Template::RawFile.new(options[:file])
31
+ else
32
+ ActiveSupport::Deprecation.warn "render file: should be given the absolute path to a file"
33
+ @lookup_context.with_fallbacks.find_template(options[:file], nil, false, keys, @details)
34
+ end
33
35
  elsif options.key?(:inline)
34
36
  handler = Template.handler_for_extension(options[:type] || "erb")
35
- Template.new(options[:inline], "inline template", handler, locals: keys)
37
+ format = if handler.respond_to?(:default_format)
38
+ handler.default_format
39
+ else
40
+ @lookup_context.formats.first
41
+ end
42
+ Template::Inline.new(options[:inline], "inline template", handler, locals: keys, format: format)
36
43
  elsif options.key?(:template)
37
44
  if options[:template].respond_to?(:render)
38
45
  options[:template]
39
46
  else
40
- find_template(options[:template], options[:prefixes], false, keys, @details)
47
+ @lookup_context.find_template(options[:template], options[:prefixes], false, keys, @details)
41
48
  end
42
49
  else
43
50
  raise ArgumentError, "You invoked render but did not give any of :partial, :template, :inline, :file, :plain, :html or :body option."
@@ -46,27 +53,25 @@ module ActionView
46
53
 
47
54
  # Renders the given template. A string representing the layout can be
48
55
  # supplied as well.
49
- def render_template(template, layout_name = nil, locals = nil)
50
- view, locals = @view, locals || {}
51
-
52
- render_with_layout(layout_name, locals) do |layout|
56
+ def render_template(view, template, layout_name, locals)
57
+ render_with_layout(view, template, layout_name, locals) do |layout|
53
58
  instrument(:template, identifier: template.identifier, layout: layout.try(:virtual_path)) do
54
59
  template.render(view, locals) { |*name| view._layout_for(*name) }
55
60
  end
56
61
  end
57
62
  end
58
63
 
59
- def render_with_layout(path, locals)
64
+ def render_with_layout(view, template, path, locals)
60
65
  layout = path && find_layout(path, locals.keys, [formats.first])
61
66
  content = yield(layout)
62
67
 
63
- if layout
64
- view = @view
68
+ body = if layout
65
69
  view.view_flow.set(:layout, content)
66
70
  layout.render(view, locals) { |*name| view._layout_for(*name) }
67
71
  else
68
72
  content
69
73
  end
74
+ build_rendered_template(body, template, layout)
70
75
  end
71
76
 
72
77
  # This is the method which actually finds the layout using details in the lookup
@@ -84,16 +89,17 @@ module ActionView
84
89
  when String
85
90
  begin
86
91
  if layout.start_with?("/")
87
- with_fallbacks { find_template(layout, nil, false, [], details) }
92
+ ActiveSupport::Deprecation.warn "Rendering layouts from an absolute path is deprecated."
93
+ @lookup_context.with_fallbacks.find_template(layout, nil, false, [], details)
88
94
  else
89
- find_template(layout, nil, false, [], details)
95
+ @lookup_context.find_template(layout, nil, false, [], details)
90
96
  end
91
97
  rescue ActionView::MissingTemplate
92
98
  all_details = @details.merge(formats: @lookup_context.default_formats)
93
99
  raise unless template_exists?(layout, nil, false, [], all_details)
94
100
  end
95
101
  when Proc
96
- resolve_layout(layout.call(formats), keys, formats)
102
+ resolve_layout(layout.call(@lookup_context, formats), keys, formats)
97
103
  else
98
104
  layout
99
105
  end
@@ -26,6 +26,13 @@ module ActionView
26
26
  extend ActiveSupport::Concern
27
27
  include ActionView::ViewPaths
28
28
 
29
+ attr_reader :rendered_format
30
+
31
+ def initialize
32
+ @rendered_format = nil
33
+ super
34
+ end
35
+
29
36
  # Overwrite process to setup I18n proxy.
30
37
  def process(*) #:nodoc:
31
38
  old_config, I18n.config = I18n.config, I18nProxy.new(I18n.config, lookup_context)
@@ -35,30 +42,40 @@ module ActionView
35
42
  end
36
43
 
37
44
  module ClassMethods
38
- def view_context_class
39
- @view_context_class ||= begin
40
- supports_path = supports_path?
41
- routes = respond_to?(:_routes) && _routes
42
- helpers = respond_to?(:_helpers) && _helpers
43
-
44
- Class.new(ActionView::Base) do
45
- if routes
46
- include routes.url_helpers(supports_path)
47
- include routes.mounted_helpers
48
- end
49
-
50
- if helpers
51
- include helpers
52
- end
45
+ def _routes
46
+ end
47
+
48
+ def _helpers
49
+ end
50
+
51
+ def build_view_context_class(klass, supports_path, routes, helpers)
52
+ Class.new(klass) do
53
+ if routes
54
+ include routes.url_helpers(supports_path)
55
+ include routes.mounted_helpers
56
+ end
57
+
58
+ if helpers
59
+ include helpers
53
60
  end
54
61
  end
55
62
  end
56
- end
57
63
 
58
- attr_internal_writer :view_context_class
64
+ def view_context_class
65
+ klass = ActionView::LookupContext::DetailsKey.view_context_class(ActionView::Base)
66
+
67
+ @view_context_class ||= build_view_context_class(klass, supports_path?, _routes, _helpers)
68
+
69
+ if klass.changed?(@view_context_class)
70
+ @view_context_class = build_view_context_class(klass, supports_path?, _routes, _helpers)
71
+ end
72
+
73
+ @view_context_class
74
+ end
75
+ end
59
76
 
60
77
  def view_context_class
61
- @_view_context_class ||= self.class.view_context_class
78
+ self.class.view_context_class
62
79
  end
63
80
 
64
81
  # An instance of a view class. The default view class is ActionView::Base.
@@ -72,11 +89,12 @@ module ActionView
72
89
  #
73
90
  # Override this method in a module to change the default behavior.
74
91
  def view_context
75
- view_context_class.new(view_renderer, view_assigns, self)
92
+ view_context_class.new(lookup_context, view_assigns, self)
76
93
  end
77
94
 
78
95
  # Returns an object that is able to render templates.
79
96
  def view_renderer # :nodoc:
97
+ # Lifespan: Per controller
80
98
  @_view_renderer ||= ActionView::Renderer.new(lookup_context)
81
99
  end
82
100
 
@@ -85,10 +103,6 @@ module ActionView
85
103
  _render_template(options)
86
104
  end
87
105
 
88
- def rendered_format
89
- Template::Types[lookup_context.rendered_format]
90
- end
91
-
92
106
  private
93
107
 
94
108
  # Find and render a template based on the options given.
@@ -98,17 +112,22 @@ module ActionView
98
112
  context = view_context
99
113
 
100
114
  context.assign assigns if assigns
101
- lookup_context.rendered_format = nil if options[:formats]
102
115
  lookup_context.variants = variant if variant
103
116
 
104
- view_renderer.render(context, options)
117
+ rendered_template = context.in_rendering_context(options) do |renderer|
118
+ renderer.render_to_object(context, options)
119
+ end
120
+
121
+ rendered_format = rendered_template.format || lookup_context.formats.first
122
+ @rendered_format = Template::Types[rendered_format]
123
+
124
+ rendered_template.body
105
125
  end
106
126
 
107
127
  # Assign the rendered format to look up context.
108
128
  def _process_format(format)
109
129
  super
110
- lookup_context.formats = [format.to_sym]
111
- lookup_context.rendered_format = lookup_context.formats.first
130
+ lookup_context.formats = [format.to_sym] if format.to_sym
112
131
  end
113
132
 
114
133
  # Normalize args by converting render "foo" to render :action => "foo" and
@@ -2,14 +2,22 @@
2
2
 
3
3
  require "active_support/core_ext/object/try"
4
4
  require "active_support/core_ext/kernel/singleton_class"
5
+ require "active_support/deprecation"
5
6
  require "thread"
7
+ require "delegate"
6
8
 
7
9
  module ActionView
8
10
  # = Action View Template
9
11
  class Template
10
12
  extend ActiveSupport::Autoload
11
13
 
12
- mattr_accessor :finalize_compiled_template_methods, default: true
14
+ def self.finalize_compiled_template_methods
15
+ ActiveSupport::Deprecation.warn "ActionView::Template.finalize_compiled_template_methods is deprecated and has no effect"
16
+ end
17
+
18
+ def self.finalize_compiled_template_methods=(_)
19
+ ActiveSupport::Deprecation.warn "ActionView::Template.finalize_compiled_template_methods= is deprecated and has no effect"
20
+ end
13
21
 
14
22
  # === Encodings in ActionView::Template
15
23
  #
@@ -105,44 +113,60 @@ module ActionView
105
113
 
106
114
  eager_autoload do
107
115
  autoload :Error
116
+ autoload :RawFile
108
117
  autoload :Handlers
109
118
  autoload :HTML
119
+ autoload :Inline
120
+ autoload :Sources
110
121
  autoload :Text
111
122
  autoload :Types
112
123
  end
113
124
 
114
125
  extend Template::Handlers
115
126
 
116
- attr_accessor :locals, :formats, :variants, :virtual_path
117
-
118
- attr_reader :source, :identifier, :handler, :original_encoding, :updated_at
127
+ attr_reader :identifier, :handler, :original_encoding, :updated_at
128
+ attr_reader :variable, :format, :variant, :locals, :virtual_path
119
129
 
120
- # This finalizer is needed (and exactly with a proc inside another proc)
121
- # otherwise templates leak in development.
122
- Finalizer = proc do |method_name, mod| # :nodoc:
123
- proc do
124
- mod.module_eval do
125
- remove_possible_method method_name
126
- end
130
+ def initialize(source, identifier, handler, format: nil, variant: nil, locals: nil, virtual_path: nil, updated_at: nil)
131
+ unless locals
132
+ ActiveSupport::Deprecation.warn "ActionView::Template#initialize requires a locals parameter"
133
+ locals = []
127
134
  end
128
- end
129
-
130
- def initialize(source, identifier, handler, details)
131
- format = details[:format] || (handler.default_format if handler.respond_to?(:default_format))
132
135
 
133
136
  @source = source
134
137
  @identifier = identifier
135
138
  @handler = handler
136
139
  @compiled = false
137
- @original_encoding = nil
138
- @locals = details[:locals] || []
139
- @virtual_path = details[:virtual_path]
140
- @updated_at = details[:updated_at] || Time.now
141
- @formats = Array(format).map { |f| f.respond_to?(:ref) ? f.ref : f }
142
- @variants = [details[:variant]]
140
+ @locals = locals
141
+ @virtual_path = virtual_path
142
+
143
+ @variable = if @virtual_path
144
+ base = @virtual_path[-1] == "/" ? "" : ::File.basename(@virtual_path)
145
+ base =~ /\A_?(.*?)(?:\.\w+)*\z/
146
+ $1.to_sym
147
+ end
148
+
149
+ if updated_at
150
+ ActiveSupport::Deprecation.warn "ActionView::Template#updated_at is deprecated"
151
+ @updated_at = updated_at
152
+ else
153
+ @updated_at = Time.now
154
+ end
155
+ @format = format
156
+ @variant = variant
143
157
  @compile_mutex = Mutex.new
144
158
  end
145
159
 
160
+ deprecate :original_encoding
161
+ deprecate :updated_at
162
+ deprecate def virtual_path=(_); end
163
+ deprecate def locals=(_); end
164
+ deprecate def formats=(_); end
165
+ deprecate def formats; Array(format); end
166
+ deprecate def variants=(_); end
167
+ deprecate def variants; [variant]; end
168
+ deprecate def refresh(_); self; end
169
+
146
170
  # Returns whether the underlying handler supports streaming. If so,
147
171
  # a streaming buffer *may* be passed when it starts rendering.
148
172
  def supports_streaming?
@@ -155,40 +179,29 @@ module ActionView
155
179
  # This method is instrumented as "!render_template.action_view". Notice that
156
180
  # we use a bang in this instrumentation because you don't want to
157
181
  # consume this in production. This is only slow if it's being listened to.
158
- def render(view, locals, buffer = nil, &block)
182
+ def render(view, locals, buffer = ActionView::OutputBuffer.new, &block)
159
183
  instrument_render_template do
160
184
  compile!(view)
161
- view.send(method_name, locals, buffer, &block)
185
+ view._run(method_name, self, locals, buffer, &block)
162
186
  end
163
187
  rescue => e
164
188
  handle_render_error(view, e)
165
189
  end
166
190
 
167
191
  def type
168
- @type ||= Types[@formats.first] if @formats.first
192
+ @type ||= Types[format]
169
193
  end
170
194
 
171
- # Receives a view object and return a template similar to self by using @virtual_path.
172
- #
173
- # This method is useful if you have a template object but it does not contain its source
174
- # anymore since it was already compiled. In such cases, all you need to do is to call
175
- # refresh passing in the view object.
176
- #
177
- # Notice this method raises an error if the template to be refreshed does not have a
178
- # virtual path set (true just for inline templates).
179
- def refresh(view)
180
- raise "A template needs to have a virtual path in order to be refreshed" unless @virtual_path
181
- lookup = view.lookup_context
182
- pieces = @virtual_path.split("/")
183
- name = pieces.pop
184
- partial = !!name.sub!(/^_/, "")
185
- lookup.disable_cache do
186
- lookup.find_template(name, [ pieces.join("/") ], partial, @locals)
187
- end
195
+ def short_identifier
196
+ @short_identifier ||= defined?(Rails.root) ? identifier.sub("#{Rails.root}/", "") : identifier
188
197
  end
189
198
 
190
199
  def inspect
191
- @inspect ||= defined?(Rails.root) ? identifier.sub("#{Rails.root}/", "") : identifier
200
+ "#<#{self.class.name} #{short_identifier} locals=#{@locals.inspect}>"
201
+ end
202
+
203
+ def source
204
+ @source.to_s
192
205
  end
193
206
 
194
207
  # This method is responsible for properly setting the encoding of the
@@ -202,7 +215,9 @@ module ActionView
202
215
  # before passing the source on to the template engine, leaving a
203
216
  # blank line in its stead.
204
217
  def encode!
205
- return unless source.encoding == Encoding::BINARY
218
+ source = self.source
219
+
220
+ return source unless source.encoding == Encoding::BINARY
206
221
 
207
222
  # Look for # encoding: *. If we find one, we'll encode the
208
223
  # String in that encoding, otherwise, we'll use the
@@ -240,11 +255,11 @@ module ActionView
240
255
  # to ensure that references to the template object can be marshalled as well. This means forgoing
241
256
  # the marshalling of the compiler mutex and instantiating that again on unmarshalling.
242
257
  def marshal_dump # :nodoc:
243
- [ @source, @identifier, @handler, @compiled, @original_encoding, @locals, @virtual_path, @updated_at, @formats, @variants ]
258
+ [ @source, @identifier, @handler, @compiled, @locals, @virtual_path, @updated_at, @format, @variant ]
244
259
  end
245
260
 
246
261
  def marshal_load(array) # :nodoc:
247
- @source, @identifier, @handler, @compiled, @original_encoding, @locals, @virtual_path, @updated_at, @formats, @variants = *array
262
+ @source, @identifier, @handler, @compiled, @locals, @virtual_path, @updated_at, @format, @variant = *array
248
263
  @compile_mutex = Mutex.new
249
264
  end
250
265
 
@@ -264,23 +279,25 @@ module ActionView
264
279
  # re-compilation
265
280
  return if @compiled
266
281
 
267
- if view.is_a?(ActionView::CompiledTemplates)
268
- mod = ActionView::CompiledTemplates
269
- else
270
- mod = view.singleton_class
271
- end
282
+ mod = view.compiled_method_container
272
283
 
273
284
  instrument("!compile_template") do
274
285
  compile(mod)
275
286
  end
276
287
 
277
- # Just discard the source if we have a virtual path. This
278
- # means we can get the template back.
279
- @source = nil if @virtual_path
280
288
  @compiled = true
281
289
  end
282
290
  end
283
291
 
292
+ class LegacyTemplate < DelegateClass(Template) # :nodoc:
293
+ attr_reader :source
294
+
295
+ def initialize(template, source)
296
+ super(template)
297
+ @source = source
298
+ end
299
+ end
300
+
284
301
  # Among other things, this method is responsible for properly setting
285
302
  # the encoding of the compiled template.
286
303
  #
@@ -294,16 +311,15 @@ module ActionView
294
311
  # In general, this means that templates will be UTF-8 inside of Rails,
295
312
  # regardless of the original source encoding.
296
313
  def compile(mod)
297
- encode!
298
- code = @handler.call(self)
314
+ source = encode!
315
+ code = @handler.call(self, source)
299
316
 
300
317
  # Make sure that the resulting String to be eval'd is in the
301
318
  # encoding of the code
319
+ original_source = source
302
320
  source = +<<-end_src
303
321
  def #{method_name}(local_assigns, output_buffer)
304
- _old_virtual_path, @virtual_path = @virtual_path, #{@virtual_path.inspect};_old_output_buffer = @output_buffer;#{locals_code};#{code}
305
- ensure
306
- @virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer
322
+ @virtual_path = #{@virtual_path.inspect};#{locals_code};#{code}
307
323
  end
308
324
  end_src
309
325
 
@@ -318,12 +334,16 @@ module ActionView
318
334
  # handler is valid in the default_internal. This is for handlers
319
335
  # that handle encoding but screw up
320
336
  unless source.valid_encoding?
321
- raise WrongEncodingError.new(@source, Encoding.default_internal)
337
+ raise WrongEncodingError.new(source, Encoding.default_internal)
322
338
  end
323
339
 
324
- mod.module_eval(source, identifier, 0)
325
- if finalize_compiled_template_methods
326
- ObjectSpace.define_finalizer(self, Finalizer[method_name, mod])
340
+ begin
341
+ mod.module_eval(source, identifier, 0)
342
+ rescue SyntaxError
343
+ # Account for when code in the template is not syntactically valid; e.g. if we're using
344
+ # ERB and the user writes <%= foo( %>, attempting to call a helper `foo` and interpolate
345
+ # the result into the template, but missing an end parenthesis.
346
+ raise SyntaxErrorInTemplate.new(self, original_source)
327
347
  end
328
348
  end
329
349
 
@@ -332,12 +352,7 @@ module ActionView
332
352
  e.sub_template_of(self)
333
353
  raise e
334
354
  else
335
- template = self
336
- unless template.source
337
- template = refresh(view)
338
- template.encode!
339
- end
340
- raise Template::Error.new(template)
355
+ raise Template::Error.new(self)
341
356
  end
342
357
  end
343
358
 
@@ -360,7 +375,7 @@ module ActionView
360
375
  end
361
376
 
362
377
  def identifier_method_name
363
- inspect.tr("^a-z_", "_")
378
+ short_identifier.tr("^a-z_", "_")
364
379
  end
365
380
 
366
381
  def instrument(action, &block) # :doc: