Class: Contrast::Agent::Assess::Policy::Propagator::Prepend

Inherits:
Base
  • Object
show all
Defined in:
lib/contrast/agent/assess/policy/propagator/prepend.rb

Overview

Propagation that results in all the tags of the source being applied to the beginning of the target. The target’s preexisting tags are shifted to account for this.

Class Method Summary collapse

Methods inherited from Base

find_source, tracked_value?

Class Method Details

.propagate(propagation_node, preshift, target) ⇒ Object

For the source, prepend its tags to the target. It’s basically the opposite of append. :-P

propagation action required by this method.

Parameters:



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/contrast/agent/assess/policy/propagator/prepend.rb', line 21

def propagate propagation_node, preshift, target
  return unless (properties = Contrast::Agent::Assess::Tracker.properties!(target))

  sources = propagation_node.sources
  # source1 is the copy of the thing being prepended to
  source1 = find_source(sources[0], preshift)

  # source2 is the copy of the thing being prepended
  source2 = sources[1] ? find_source(sources[1], preshift) : source1

  original_start_index = target.rindex(source1) || 0
  # if the object and the return are the same length just copy the
  # tags from the object(since nothing from args was added to
  # return)
  if source1.length == target.length
    properties.copy_from(source1, target, 0, propagation_node.untags)
  else
    # find original in the target, copy tags to the new position in target
    properties.copy_from(source1, target, original_start_index, propagation_node.untags)
    # then we add the tags from the thing prepended to the start
    # of the target
    start = 0
    while start < original_start_index
      properties.copy_from(source2, target, start, propagation_node.untags)
      start += source2.length
      next unless start > original_start_index

      properties.tags_at(start - source2.length).each do |tag|
        tag.update_end(original_start_index)
      end
    end
  end
  # and finally merge the tags if any overlap.
  properties.cleanup_tags
end