Module: Sourcify::Proc::Scanner::Extensions

Included in:
Sourcify::Proc::Scanner
Defined in:
lib/sourcify/proc/scanner/extensions.rb

Defined Under Namespace

Classes: Escape

Constant Summary collapse

RUBY_PARSER =
RubyParser.new

Instance Method Summary collapse

Instance Method Details

#codified_tokensObject



135
136
137
# File 'lib/sourcify/proc/scanner/extensions.rb', line 135

def codified_tokens
  @tokens.map(&:last).join
end

#construct_result_codeObject



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/sourcify/proc/scanner/extensions.rb', line 119

def construct_result_code
  code = <<-SOURCIFIED_HEREDOKIE.strip
    proc #{codified_tokens}
  SOURCIFIED_HEREDOKIE

  begin
    if safe_eval(code) && @body_matcher.call(code)
      @results << code
      raise Escape if @stop_on_newline or @lineno != 1
      reset_attributes
    end
  rescue Exception
    raise if $!.is_a?(Escape)
  end
end

#data_frag(range) ⇒ Object



26
27
28
# File 'lib/sourcify/proc/scanner/extensions.rb', line 26

def data_frag(range)
  @data[range].pack('c*')
end

#decrement_counter(key) ⇒ Object



98
99
100
101
102
# File 'lib/sourcify/proc/scanner/extensions.rb', line 98

def decrement_counter(key)
  return unless (counter = this_counter(key)).started?
  counter.decrement
  construct_result_code if counter.balanced?
end

#fix_counter_false_start(key) ⇒ Object



104
105
106
107
108
109
# File 'lib/sourcify/proc/scanner/extensions.rb', line 104

def fix_counter_false_start(key)
  return unless this_counter(key).just_started?
  return unless really_false_started?
  reset_attributes
  @tokens, @false_start_backup = @false_start_backup.dup, nil if @false_start_backup
end

#increment_counter(key, count = 1) ⇒ Object



88
89
90
91
92
93
94
95
96
# File 'lib/sourcify/proc/scanner/extensions.rb', line 88

def increment_counter(key, count = 1)
  return if other_counter(key).started?
  unless (counter = this_counter(key)).started?
    return if (@rejecting_block = codified_tokens !~ @start_pattern)
    @false_start_backup = @tokens.dup if key == :brace
    offset_attributes
  end
  counter.increment(count)
end

#increment_linenoObject



81
82
83
84
85
86
# File 'lib/sourcify/proc/scanner/extensions.rb', line 81

def increment_lineno
  @lineno += 1
  if @stop_on_newline || !@results.empty? || (@results.empty? && @rejecting_block)
    raise Escape
  end
end

#offset_attributesObject



155
156
157
158
159
160
161
162
# File 'lib/sourcify/proc/scanner/extensions.rb', line 155

def offset_attributes
  @lineno = 1 # Fixing JRuby's lineno bug (see http://jira.codehaus.org/browse/JRUBY-5014)
  unless @tokens.empty?
    last = @tokens[-1]
    @tokens.clear
    @tokens << last
  end
end

#other_counter(type) ⇒ Object



111
112
113
# File 'lib/sourcify/proc/scanner/extensions.rb', line 111

def other_counter(type)
  {:do_end => @brace_counter, :brace => @do_end_counter}[type]
end

#preceded_with?(*args) ⇒ Boolean

Returns:

  • (Boolean)


73
74
75
76
77
78
79
# File 'lib/sourcify/proc/scanner/extensions.rb', line 73

def preceded_with?(*args)
  begin
    prev_token = @tokens[-1][0] == :space ? @tokens[-2] : @tokens[-1]
    !([args].flatten & prev_token).empty?
  rescue
  end
end

#process(data, opts = {}) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/sourcify/proc/scanner/extensions.rb', line 13

def process(data, opts={})
  begin
    @start_pattern = opts[:start_pattern] || /.*/
    @body_matcher = opts[:body_matcher] || lambda{|_| true }
    @stop_on_newline = opts[:stop_on_newline]
    @results, @data = [], data.unpack("c*")
    reset_attributes
    execute!
  rescue Escape
    @results
  end
end

#push(key, ts, te) ⇒ Object



30
31
32
# File 'lib/sourcify/proc/scanner/extensions.rb', line 30

def push(key, ts, te)
  @tokens << [key, data_frag(ts .. te.pred)]
end

#push_comment(ts, te) ⇒ Object



43
44
45
46
47
48
49
50
# File 'lib/sourcify/proc/scanner/extensions.rb', line 43

def push_comment(ts, te)
  data = data_frag(ts .. te.pred)
  @comment ||= Comment.new
  @comment << data
  return true unless @comment.closed?
  @tokens << [:comment, @comment.to_s]
  @comment = nil
end

#push_dstring(ts, te) ⇒ Object



34
35
36
37
38
39
40
41
# File 'lib/sourcify/proc/scanner/extensions.rb', line 34

def push_dstring(ts, te)
  data = data_frag(ts .. te.pred)
  @dstring ||= DString.new(data[%r{^("|`|/|%(?:Q|W|r|x|)(?:\W|_))},1])
  @dstring << data
  return true unless @dstring.closed?
  @tokens << [:dstring, @dstring.to_s]
  @dstring = nil
end

#push_heredoc(ts, te) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
# File 'lib/sourcify/proc/scanner/extensions.rb', line 52

def push_heredoc(ts, te)
  data = data_frag(ts .. te.pred)
  unless @heredoc
    indented, tag = data.match(/\<\<(\-?)['"]?(\w+)['"]?$/)[1..3]
    @heredoc = Heredoc.new(tag, !indented.empty?)
  end
  @heredoc << data
  return true unless @heredoc.closed?(data_frag(te .. te))
  @tokens << [:heredoc, @heredoc.to_s]
  @heredoc = nil
end

#push_label(ts, te) ⇒ Object



64
65
66
67
68
69
70
71
# File 'lib/sourcify/proc/scanner/extensions.rb', line 64

def push_label(ts, te)
  # NOTE: 1.9.* supports label key, which RubyParser cannot handle, thus
  # conversion is needed.
  data = data_frag(ts .. te.pred)
  @tokens << [:symbol, data.sub(/^(.*)\:$/, ':\1')]
  @tokens << [:space, ' ']
  @tokens << [:assoc, '=>']
end

#really_false_started?Boolean

Returns:

  • (Boolean)


148
149
150
151
152
153
# File 'lib/sourcify/proc/scanner/extensions.rb', line 148

def really_false_started?
  safe_eval(<<-SOURCIFIED_HEREDOKIE.strip
      #{codified_tokens} 1}
    SOURCIFIED_HEREDOKIE
  ) && true
end

#reset_attributesObject



139
140
141
142
143
144
145
146
# File 'lib/sourcify/proc/scanner/extensions.rb', line 139

def reset_attributes
  @tokens = []
  @lineno = 1
  @heredoc, @dstring, @comment = nil
  @do_end_counter = DoEndBlockCounter.new
  @brace_counter = BraceBlockCounter.new
  @rejecting_block = false
end

#safe_eval(string) ⇒ Object



164
165
166
# File 'lib/sourcify/proc/scanner/extensions.rb', line 164

def safe_eval(string)
  Parser::Converter.to_sexp(string)
end

#this_counter(type) ⇒ Object



115
116
117
# File 'lib/sourcify/proc/scanner/extensions.rb', line 115

def this_counter(type)
  {:brace => @brace_counter, :do_end => @do_end_counter}[type]
end