diff options
Diffstat (limited to 'actionview/lib/action_view/dependency_tracker.rb')
-rw-r--r-- | actionview/lib/action_view/dependency_tracker.rb | 61 |
1 files changed, 46 insertions, 15 deletions
diff --git a/actionview/lib/action_view/dependency_tracker.rb b/actionview/lib/action_view/dependency_tracker.rb index e34bdd4a46..7716955fd9 100644 --- a/actionview/lib/action_view/dependency_tracker.rb +++ b/actionview/lib/action_view/dependency_tracker.rb @@ -1,16 +1,18 @@ -require 'thread_safe' +require 'concurrent' +require 'action_view/path_set' module ActionView class DependencyTracker # :nodoc: - @trackers = ThreadSafe::Cache.new + @trackers = Concurrent::Map.new - def self.find_dependencies(name, template) + def self.find_dependencies(name, template, view_paths = nil) tracker = @trackers[template.handler] + return [] unless tracker.present? - if tracker.present? - tracker.call(name, template) + if tracker.respond_to?(:supports_view_paths?) && tracker.supports_view_paths? + tracker.call(name, template, view_paths) else - [] + tracker.call(name, template) end end @@ -76,12 +78,22 @@ module ActionView (?:#{STRING}|#{VARIABLE_OR_METHOD_CHAIN}) # finally, the dependency name of interest /xm - def self.call(name, template) - new(name, template).dependencies + LAYOUT_DEPENDENCY = /\A + (?:\s*\(?\s*) # optional opening paren surrounded by spaces + (?:.*?#{LAYOUT_HASH_KEY}) # check if the line has layout key declaration + (?:#{STRING}|#{VARIABLE_OR_METHOD_CHAIN}) # finally, the dependency name of interest + /xm + + def self.supports_view_paths? # :nodoc: + true + end + + def self.call(name, template, view_paths = nil) + new(name, template, view_paths).dependencies end - def initialize(name, template) - @name, @template = name, template + def initialize(name, template, view_paths = nil) + @name, @template, @view_paths = name, template, view_paths end def dependencies @@ -106,15 +118,20 @@ module ActionView render_calls = source.split(/\brender\b/).drop(1) render_calls.each do |arguments| - arguments.scan(RENDER_ARGUMENTS) do - add_dynamic_dependency(render_dependencies, Regexp.last_match[:dynamic]) - add_static_dependency(render_dependencies, Regexp.last_match[:static]) - end + add_dependencies(render_dependencies, arguments, LAYOUT_DEPENDENCY) + add_dependencies(render_dependencies, arguments, RENDER_ARGUMENTS) end render_dependencies.uniq end + def add_dependencies(render_dependencies, arguments, pattern) + arguments.scan(pattern) do + add_dynamic_dependency(render_dependencies, Regexp.last_match[:dynamic]) + add_static_dependency(render_dependencies, Regexp.last_match[:static]) + end + end + def add_dynamic_dependency(dependencies, dependency) if dependency dependencies << "#{dependency.pluralize}/#{dependency.singularize}" @@ -131,8 +148,22 @@ module ActionView end end + def resolve_directories(wildcard_dependencies) + return [] unless @view_paths + + wildcard_dependencies.each_with_object([]) do |query, templates| + @view_paths.find_all_with_query(query).each do |template| + templates << "#{File.dirname(query)}/#{File.basename(template).split('.').first}" + end + end + end + def explicit_dependencies - source.scan(EXPLICIT_DEPENDENCY).flatten.uniq + dependencies = source.scan(EXPLICIT_DEPENDENCY).flatten.uniq + + wildcards, explicits = dependencies.partition { |dependency| dependency[-1] == '*' } + + (explicits + resolve_directories(wildcards)).uniq end end |