Class: ActionView::Digestor

Inherits:
Object show all
Defined in:
actionview/lib/action_view/digestor.rb

Defined Under Namespace

Classes: Injected, Missing, Node, NullLogger, Partial

Constant Summary collapse

@@digest_mutex =
Mutex.new

Class Method Summary collapse

Class Method Details

.digest(name:, format: nil, finder:, dependencies: nil) ⇒ Object

Supported options:

  • name - Template name

  • format - Template format

  • finder - An instance of ActionView::LookupContext

  • dependencies - An array of dependent views


16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'actionview/lib/action_view/digestor.rb', line 16

def digest(name:, format: nil, finder:, dependencies: nil)
  if dependencies.nil? || dependencies.empty?
    cache_key = "#{name}.#{format}"
  else
    dependencies_suffix = dependencies.flatten.tap(&:compact!).join(".")
    cache_key = "#{name}.#{format}.#{dependencies_suffix}"
  end

  # this is a correctly done double-checked locking idiom
  # (Concurrent::Map's lookups have volatile semantics)
  finder.digest_cache[cache_key] || @@digest_mutex.synchronize do
    finder.digest_cache.fetch(cache_key) do # re-check under lock
      path = TemplatePath.parse(name)
      root = tree(path.to_s, finder, path.partial?)
      dependencies.each do |injected_dep|
        root.children << Injected.new(injected_dep, nil, nil)
      end if dependencies
      finder.digest_cache[cache_key] = root.digest(finder)
    end
  end
end

.loggerObject


38
39
40
# File 'actionview/lib/action_view/digestor.rb', line 38

def logger
  ActionView::Base.logger || NullLogger
end

.tree(name, finder, partial = false, seen = {}) ⇒ Object

Create a dependency tree for template named name.


43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'actionview/lib/action_view/digestor.rb', line 43

def tree(name, finder, partial = false, seen = {})
  logical_name = name.gsub(%r|/_|, "/")
  interpolated = name.include?("#")

  path = TemplatePath.parse(name)

  if !interpolated && (template = find_template(finder, path.name, [path.prefix], partial, []))
    if node = seen[template.identifier] # handle cycles in the tree
      node
    else
      node = seen[template.identifier] = Node.create(name, logical_name, template, partial)

      deps = DependencyTracker.find_dependencies(name, template, finder.view_paths)
      deps.uniq { |n| n.gsub(%r|/_|, "/") }.each do |dep_file|
        node.children << tree(dep_file, finder, true, seen)
      end
      node
    end
  else
    unless interpolated # Dynamic template partial names can never be tracked
      logger.error "  Couldn't find template for digesting: #{name}"
    end

    seen[name] ||= Missing.new(name, logical_name, nil)
  end
end