i18n-tools 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/core_ext/hash/iterate_nested.rb +35 -0
- data/lib/core_ext/hash/slice.rb +20 -0
- data/lib/core_ext/hash/sorted_yaml_style.rb +17 -0
- data/lib/core_ext/hash/symbolize_keys.rb +14 -0
- data/lib/core_ext/module/attribute_accessors.rb +48 -0
- data/lib/core_ext/object/deep_clone.rb +5 -0
- data/lib/core_ext/object/instance_variables.rb +9 -0
- data/lib/core_ext/object/meta_class.rb +5 -0
- data/lib/core_ext/object/tap.rb +6 -0
- data/lib/i18n/backend/simple_storage.rb +119 -0
- data/lib/i18n/commands/keys.rb +84 -0
- data/lib/i18n/exceptions/key_exists.rb +9 -0
- data/lib/i18n/index.rb +33 -0
- data/lib/i18n/index/base.rb +38 -0
- data/lib/i18n/index/file.rb +55 -0
- data/lib/i18n/index/format.rb +49 -0
- data/lib/i18n/index/key.rb +45 -0
- data/lib/i18n/index/occurence.rb +18 -0
- data/lib/i18n/index/simple.rb +69 -0
- data/lib/i18n/index/simple/data.rb +34 -0
- data/lib/i18n/index/simple/storage.rb +79 -0
- data/lib/i18n/ripper2ruby.rb +7 -0
- data/lib/i18n/ripper2ruby/translate_args_list.rb +89 -0
- data/lib/i18n/ripper2ruby/translate_call.rb +66 -0
- data/lib/i18n/translation_properties.rb +38 -0
- data/test/all.rb +1 -1
- data/test/core_ext/hash_iterate_nested.rb +31 -0
- data/test/fixtures/all.rb.src +106 -0
- data/test/fixtures/config.yml +3 -0
- data/test/fixtures/locale/de.yml +4 -0
- data/test/fixtures/locale/en.yml +4 -0
- data/test/fixtures/source_1.rb +2 -1
- data/test/fixtures/translate/double_key.rb +32 -0
- data/test/fixtures/translate/double_scope.rb +32 -0
- data/test/fixtures/translate/single_key.rb +10 -0
- data/test/fixtures/translate/single_scope.rb +32 -0
- data/test/i18n/backend/simple_storage_test.rb +81 -0
- data/test/i18n/backend/translation_properties_test.rb +33 -0
- data/test/i18n/index/all.rb +1 -0
- data/test/i18n/index/args_replace_test.rb +218 -0
- data/test/i18n/index/calls_replace_test.rb +67 -0
- data/test/i18n/index/commands_test.rb +75 -0
- data/test/i18n/index/key_test.rb +32 -0
- data/test/i18n/index/simple_test.rb +67 -0
- data/test/i18n/ripper2ruby/translate_call_test.rb +98 -0
- data/test/test_helper.rb +66 -9
- metadata +49 -32
- data/MIT-LICENSE +0 -20
- data/README.textile +0 -1
- data/bin/i18n-keys +0 -6
- data/lib/ansi.rb +0 -19
- data/lib/i18n/keys.rb +0 -51
- data/lib/i18n/keys/commands.rb +0 -53
- data/lib/i18n/keys/formatter.rb +0 -39
- data/lib/i18n/keys/index.rb +0 -209
- data/lib/i18n/keys/occurence.rb +0 -120
- data/lib/i18n/parser/erb_parser.rb +0 -54
- data/lib/i18n/parser/ruby_parser.rb +0 -93
- data/test/commands_test.rb +0 -1
- data/test/erb_parser_test.rb +0 -31
- data/test/index_test.rb +0 -135
- data/test/keys_test.rb +0 -75
- data/test/occurence_test.rb +0 -130
- data/test/ruby_parser_test.rb +0 -54
data/lib/i18n/keys/formatter.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
module I18n
|
2
|
-
module Keys
|
3
|
-
class Index
|
4
|
-
module Formatter
|
5
|
-
module Setup
|
6
|
-
def setup(target)
|
7
|
-
(class << target; self; end).send(:include, self)
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
module Stdin
|
12
|
-
extend Setup
|
13
|
-
|
14
|
-
def build(*args)
|
15
|
-
puts "building index \"#{name}\"" if I18n::Keys.verbose?
|
16
|
-
super
|
17
|
-
puts "\nfound #{occurences.size} occurences of #{keys.size} keys in #{files.size} files" if I18n::Keys.verbose?
|
18
|
-
end
|
19
|
-
|
20
|
-
def save
|
21
|
-
puts "saving index \"#{name}\"" if I18n::Keys.verbose?
|
22
|
-
super
|
23
|
-
end
|
24
|
-
|
25
|
-
def parse(file)
|
26
|
-
# puts " parsing #{file}" if I18n::Keys.verbose?
|
27
|
-
putc '.' if I18n::Keys.verbose?
|
28
|
-
super
|
29
|
-
end
|
30
|
-
|
31
|
-
# def each(*keys)
|
32
|
-
# puts "iterating occurences of: #{keys.map { |key| key.to_sym.inspect }.join(', ')}" if I18n::Keys.verbose?
|
33
|
-
# super
|
34
|
-
# end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
data/lib/i18n/keys/index.rb
DELETED
@@ -1,209 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
require File.dirname(__FILE__) + '/formatter'
|
3
|
-
require File.dirname(__FILE__) + '/occurence'
|
4
|
-
|
5
|
-
# Keys.index(:default, :pattern => '/**/*.{rb,erb}').each(:foo, :bar) { |occurence| ... }
|
6
|
-
#
|
7
|
-
# when the :index name is not given it creates the index on the fly but won't save it
|
8
|
-
# when the :index name is true it uses :default as an index name
|
9
|
-
#
|
10
|
-
# when an index with the given name does not exist it builds and saves an index
|
11
|
-
# when an index with the given name exists and the given pattern does not match
|
12
|
-
# the index's pattern it issues a warning and rebuilds the index
|
13
|
-
#
|
14
|
-
# when no keys are given, occurences of all keys will be iterated
|
15
|
-
# when keys are given, only occurences of the given keys will be iterated
|
16
|
-
|
17
|
-
module I18n
|
18
|
-
module Keys
|
19
|
-
class Index
|
20
|
-
include Enumerable
|
21
|
-
|
22
|
-
@@formatter = Formatter::Stdin
|
23
|
-
@@default_pattern = '/**/*.{rb,erb}'
|
24
|
-
|
25
|
-
class << self
|
26
|
-
def load_or_create_or_init(*args)
|
27
|
-
options = args.last.is_a?(Hash) ? args.pop : {}
|
28
|
-
name = TrueClass === args.first ? :default : args.first
|
29
|
-
index = name ? load_or_create(name, options) : new(name, options)
|
30
|
-
index
|
31
|
-
end
|
32
|
-
|
33
|
-
def load_or_create(*args)
|
34
|
-
options = args.last.is_a?(Hash) ? args.pop : {}
|
35
|
-
name = args.first || :default
|
36
|
-
exists?(name) ? load(name) : create(name, options)
|
37
|
-
end
|
38
|
-
|
39
|
-
def create(*args)
|
40
|
-
index = new(*args)
|
41
|
-
index.update
|
42
|
-
index
|
43
|
-
end
|
44
|
-
|
45
|
-
def load(name)
|
46
|
-
File.open(filename(name), 'r') { |f| Marshal.load(f) } if exists?
|
47
|
-
end
|
48
|
-
|
49
|
-
def mk_dir
|
50
|
-
FileUtils.mkdir_p(store_dir) unless exists?
|
51
|
-
end
|
52
|
-
|
53
|
-
def exists?(name = nil)
|
54
|
-
name ? File.exists?(filename(name)) : File.exists?(store_dir)
|
55
|
-
end
|
56
|
-
|
57
|
-
def delete(name)
|
58
|
-
new(name).delete
|
59
|
-
end
|
60
|
-
|
61
|
-
def delete_all
|
62
|
-
FileUtils.rm_r(store_dir) if exists? rescue Errno::ENOENT
|
63
|
-
end
|
64
|
-
|
65
|
-
def filename(name)
|
66
|
-
store_dir + "/#{name.to_s}.marshal"
|
67
|
-
end
|
68
|
-
|
69
|
-
def store_dir
|
70
|
-
File.expand_path(Keys.meta_dir + '/indizes')
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
attr_reader :name
|
75
|
-
|
76
|
-
[:keys, :occurences, :by_key].each do |name|
|
77
|
-
class_eval <<-code
|
78
|
-
def #{name} # def key
|
79
|
-
build unless built? # build unless built?
|
80
|
-
@#{name} # @key
|
81
|
-
end # end
|
82
|
-
code
|
83
|
-
end
|
84
|
-
|
85
|
-
def initialize(*args)
|
86
|
-
options = args.last.is_a?(Hash) ? args.pop : {}
|
87
|
-
@name = args.first || :default
|
88
|
-
@pattern = options[:pattern] || @@default_pattern
|
89
|
-
reset!
|
90
|
-
@@formatter.setup(self) if @@formatter
|
91
|
-
end
|
92
|
-
|
93
|
-
def reset!
|
94
|
-
@built = false
|
95
|
-
@keys = []
|
96
|
-
@occurences = []
|
97
|
-
@by_key = {}
|
98
|
-
end
|
99
|
-
|
100
|
-
def built?
|
101
|
-
@built
|
102
|
-
end
|
103
|
-
|
104
|
-
def build(options = {})
|
105
|
-
@occurences = find_occurences(options)
|
106
|
-
@occurences.each do |occurence|
|
107
|
-
@keys << occurence.key
|
108
|
-
(@by_key[occurence.key] ||= []) << occurence
|
109
|
-
end
|
110
|
-
@built = true
|
111
|
-
end
|
112
|
-
|
113
|
-
def exists?
|
114
|
-
File.exists?(filename)
|
115
|
-
end
|
116
|
-
|
117
|
-
def save
|
118
|
-
self.class.mk_dir
|
119
|
-
File.open(filename, 'w+') { |f| Marshal.dump(self, f) }
|
120
|
-
end
|
121
|
-
|
122
|
-
def update(options = {})
|
123
|
-
reset!
|
124
|
-
build(options)
|
125
|
-
save
|
126
|
-
end
|
127
|
-
|
128
|
-
def delete
|
129
|
-
FileUtils.rm(filename) if exists? rescue Errno::ENOENT
|
130
|
-
end
|
131
|
-
|
132
|
-
def filename
|
133
|
-
self.class.filename(name)
|
134
|
-
end
|
135
|
-
|
136
|
-
def files
|
137
|
-
Dir[Keys.root + pattern]
|
138
|
-
end
|
139
|
-
|
140
|
-
def pattern
|
141
|
-
@pattern ||= config['pattern'] || @@default_pattern
|
142
|
-
end
|
143
|
-
|
144
|
-
def config
|
145
|
-
@config ||= Keys.config['indices'][name] || { }
|
146
|
-
end
|
147
|
-
|
148
|
-
def each(*keys)
|
149
|
-
patterns = key_patterns(keys)
|
150
|
-
occurences.each { |occurence| yield(occurence) if key_matches?(occurence.key, patterns) }
|
151
|
-
end
|
152
|
-
|
153
|
-
def inject(memo, *keys)
|
154
|
-
each(*keys) { |occurence| yield(memo, occurence) }
|
155
|
-
memo
|
156
|
-
end
|
157
|
-
|
158
|
-
def replace!(occurence, replacement)
|
159
|
-
occurence.replace!(replacement)
|
160
|
-
save if exists?
|
161
|
-
end
|
162
|
-
|
163
|
-
def marshal_dump
|
164
|
-
keys = :name, :pattern, :keys, :occurences, :by_key
|
165
|
-
keys.inject({ :built => built? }) { |result, key| result[key] = send(key); result }
|
166
|
-
end
|
167
|
-
|
168
|
-
def marshal_load(data)
|
169
|
-
keys = :name, :pattern, :keys, :occurences, :by_key, :built
|
170
|
-
keys.each { |key| instance_variable_set(:"@#{key}", data[key]) }
|
171
|
-
end
|
172
|
-
|
173
|
-
protected
|
174
|
-
|
175
|
-
def find_occurences(options)
|
176
|
-
files.inject([]) do |result, file|
|
177
|
-
code = parse(file) || Sexp.new
|
178
|
-
code.find_by_type(:call).select { |call| call[2] == :t }.inject(result) do |result, node|
|
179
|
-
node.each_key_node { |key| result << Occurence.from_sexp(key, file) }
|
180
|
-
result
|
181
|
-
end
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
def key_matches?(subject, key_patterns)
|
186
|
-
key_patterns.empty? || key_patterns.any? do |key, pattern|
|
187
|
-
subject.to_sym == key || subject.to_s =~ pattern
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
def key_patterns(keys)
|
192
|
-
keys.inject({}) { |result, key| result[key] = key_pattern(key); result }
|
193
|
-
end
|
194
|
-
|
195
|
-
def key_pattern(key)
|
196
|
-
key = key.to_s.dup
|
197
|
-
match_end = key.gsub!(/\*$/, '') ? '' : '$'
|
198
|
-
pattern = Regexp.escape("#{key}")
|
199
|
-
/^#{pattern}#{match_end}/
|
200
|
-
end
|
201
|
-
|
202
|
-
def parse(file)
|
203
|
-
source = File.read(file)
|
204
|
-
source = ErbParser.new.to_ruby(source) if File.extname(file) == '.erb'
|
205
|
-
RubyParser.new.parse(source)
|
206
|
-
end
|
207
|
-
end
|
208
|
-
end
|
209
|
-
end
|
data/lib/i18n/keys/occurence.rb
DELETED
@@ -1,120 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../../ansi'
|
2
|
-
|
3
|
-
module I18n
|
4
|
-
module Keys
|
5
|
-
class Occurence
|
6
|
-
include Ansi
|
7
|
-
|
8
|
-
@@context_lines = 2
|
9
|
-
|
10
|
-
class << self
|
11
|
-
def context_lines
|
12
|
-
@@context_lines
|
13
|
-
end
|
14
|
-
|
15
|
-
def context_lines=(num)
|
16
|
-
@@context_lines = num
|
17
|
-
end
|
18
|
-
|
19
|
-
def from_sexp(sexp, file = nil)
|
20
|
-
new(sexp[1], file || sexp.file, sexp.source_start_pos, sexp.source_end_pos)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
attr_reader :key, :file, :start_pos, :end_pos
|
25
|
-
|
26
|
-
def initialize(key, file, start_pos, end_pos)
|
27
|
-
@key = key.to_sym
|
28
|
-
@file = file
|
29
|
-
@start_pos = start_pos
|
30
|
-
@end_pos = end_pos
|
31
|
-
end
|
32
|
-
|
33
|
-
def replace!(replacement)
|
34
|
-
replacement = replacement.to_sym.inspect
|
35
|
-
content = content_head + replacement + content_tail
|
36
|
-
@key = replacement.to_sym
|
37
|
-
self.length = replacement.to_s.length
|
38
|
-
File.open(file, 'w+') { |f| f.write(content) }
|
39
|
-
@position, @lines, @context = nil, nil, nil
|
40
|
-
end
|
41
|
-
|
42
|
-
def content
|
43
|
-
lines.join
|
44
|
-
end
|
45
|
-
|
46
|
-
def lines
|
47
|
-
@lines ||= File.open(file, 'r') { |f| f.readlines }
|
48
|
-
end
|
49
|
-
|
50
|
-
def line(highlight = false)
|
51
|
-
line = lines[line_num - 1].dup
|
52
|
-
highlight ? line_head + ansi_format(original_key, [:red, :bold]) + line_tail : line
|
53
|
-
end
|
54
|
-
|
55
|
-
def line_num
|
56
|
-
position[0]
|
57
|
-
end
|
58
|
-
|
59
|
-
def column
|
60
|
-
position[1]
|
61
|
-
end
|
62
|
-
|
63
|
-
def length
|
64
|
-
end_pos - start_pos + 1
|
65
|
-
end
|
66
|
-
|
67
|
-
def length=(length)
|
68
|
-
@length = length
|
69
|
-
@end_pos = start_pos + length - 1
|
70
|
-
end
|
71
|
-
|
72
|
-
def original_key
|
73
|
-
line[column - 1, length]
|
74
|
-
end
|
75
|
-
|
76
|
-
def content_head
|
77
|
-
content[0..(start_pos - 1)].to_s
|
78
|
-
end
|
79
|
-
|
80
|
-
def content_tail
|
81
|
-
content[(end_pos + 1)..-1].to_s
|
82
|
-
end
|
83
|
-
|
84
|
-
def line_head
|
85
|
-
line[0..(column - 2)].to_s
|
86
|
-
end
|
87
|
-
|
88
|
-
def line_tail
|
89
|
-
line[(column + length - 1)..-1].to_s
|
90
|
-
end
|
91
|
-
|
92
|
-
def context
|
93
|
-
@context ||=
|
94
|
-
lines[line_num - self.class.context_lines - 1, self.class.context_lines].join +
|
95
|
-
line(true) + lines[line_num, self.class.context_lines].join
|
96
|
-
end
|
97
|
-
|
98
|
-
def to_s
|
99
|
-
"#{key}: #{file} [#{line_num}/#{column}]"
|
100
|
-
end
|
101
|
-
|
102
|
-
def ==(other)
|
103
|
-
key == other.key and start_pos == other.start_pos and end_pos == other.end_pos
|
104
|
-
end
|
105
|
-
|
106
|
-
def position
|
107
|
-
@position ||= begin
|
108
|
-
line_num, col = 1, 1
|
109
|
-
lines.inject(0) do |sum, line|
|
110
|
-
break if sum + line.length > start_pos
|
111
|
-
line_num += 1
|
112
|
-
col = start_pos - sum - line.length + 1
|
113
|
-
sum += line.length
|
114
|
-
end
|
115
|
-
[line_num, col]
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
@@ -1,54 +0,0 @@
|
|
1
|
-
# replaces html and erb tags with whitespace so that we can parse the result
|
2
|
-
# as pure ruby preserving the exact positions of tokens in the original erb
|
3
|
-
# source code
|
4
|
-
|
5
|
-
require 'erb'
|
6
|
-
$KCODE = 'u'
|
7
|
-
|
8
|
-
class String
|
9
|
-
def to_whitespace
|
10
|
-
gsub(/[^\s;]/, ' ')
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
module I18n
|
15
|
-
class ErbParser
|
16
|
-
class Scanner < ERB::Compiler::Scanner
|
17
|
-
def scan
|
18
|
-
stag_reg = /(.*?)(^[ \t]*<%%|<%=|<%#|<%-|<%|\z)/m
|
19
|
-
etag_reg = /(.*?)(%%>|\-%>|%>|\z)/m
|
20
|
-
scanner = StringScanner.new(@src)
|
21
|
-
while !scanner.eos?
|
22
|
-
scanner.scan(@stag ? etag_reg : stag_reg)
|
23
|
-
yield(scanner[1]) unless scanner[1].nil?
|
24
|
-
yield(scanner[2]) unless scanner[2].nil?
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
ERB::Compiler::Scanner.regist_scanner(Scanner, nil, false)
|
29
|
-
|
30
|
-
def to_ruby(source)
|
31
|
-
result = ''
|
32
|
-
comment = false
|
33
|
-
scanner = ERB::Compiler.new(nil).make_scanner(source)
|
34
|
-
scanner.scan do |token|
|
35
|
-
comment = true if token == '<%#'
|
36
|
-
if scanner.stag.nil?
|
37
|
-
result << token.to_whitespace
|
38
|
-
scanner.stag = token if ['<%', '<%-', '<%=', '<%#'].include?(token)
|
39
|
-
elsif ['%>', '-%>'].include?(token)
|
40
|
-
result << token.gsub(/>/, ';').to_whitespace
|
41
|
-
scanner.stag = nil
|
42
|
-
else
|
43
|
-
result << (comment ? token.to_whitespace : token) # so, this is the ruby code, then
|
44
|
-
comment = false
|
45
|
-
end
|
46
|
-
end
|
47
|
-
result
|
48
|
-
end
|
49
|
-
|
50
|
-
def content_dump(string)
|
51
|
-
string.split("\n").map { |s| s.to_whitespace }.join("\n")
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
@@ -1,93 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'sexp_processor'
|
3
|
-
require 'ruby_parser'
|
4
|
-
|
5
|
-
# monkey patch galore, adds the ability to inspect the original source code
|
6
|
-
# that a :lit or :str sexp was parsed from
|
7
|
-
|
8
|
-
Sexp.class_eval do
|
9
|
-
attr_accessor :full_source, :source_start_pos, :source_end_pos
|
10
|
-
|
11
|
-
def value
|
12
|
-
self[1]
|
13
|
-
end
|
14
|
-
|
15
|
-
def source_range
|
16
|
-
source_start_pos..source_end_pos if source_start_pos && source_end_pos
|
17
|
-
end
|
18
|
-
|
19
|
-
def source
|
20
|
-
full_source[source_range] if full_source && source_range
|
21
|
-
end
|
22
|
-
|
23
|
-
def find_by_type(type)
|
24
|
-
nodes = []
|
25
|
-
nodes << self if self.first == type
|
26
|
-
each_of_type(type) { |node| nodes << node }
|
27
|
-
nodes
|
28
|
-
end
|
29
|
-
|
30
|
-
def each_key_node(&block)
|
31
|
-
each do |element|
|
32
|
-
next unless Sexp === element
|
33
|
-
element.each_key_node(&block)
|
34
|
-
block.call(element) if element.is_key_node?
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def is_key_node?
|
39
|
-
first == :str || first == :lit && self[1].is_a?(Symbol)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
RubyLexer.class_eval do
|
44
|
-
attr_accessor :source_start_pos, :source_end_pos
|
45
|
-
|
46
|
-
def reset_source_positions!
|
47
|
-
self.source_start_pos, self.source_end_pos = nil, nil, nil
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
module I18n
|
52
|
-
class RubyParser < RubyParser
|
53
|
-
def s(*args)
|
54
|
-
result = super
|
55
|
-
|
56
|
-
result.full_source = lexer.src.string.dup
|
57
|
-
result.source_start_pos = lexer.source_start_pos
|
58
|
-
result.source_end_pos = lexer.source_end_pos || lexer.src.pos
|
59
|
-
lexer.reset_source_positions!
|
60
|
-
|
61
|
-
result
|
62
|
-
end
|
63
|
-
|
64
|
-
# :tSYMBOL
|
65
|
-
def _reduce_380(val, _values, result)
|
66
|
-
lexer.source_start_pos = lexer.src.pos - lexer.yacc_value.size - 1
|
67
|
-
lexer.source_end_pos = lexer.src.pos - 1
|
68
|
-
super
|
69
|
-
end
|
70
|
-
|
71
|
-
# :tSTRING
|
72
|
-
def _reduce_386(val, _values, result)
|
73
|
-
lexer.source_start_pos = lexer.src.pos - lexer.yacc_value.size - 2
|
74
|
-
lexer.source_end_pos = lexer.src.pos - 1
|
75
|
-
super
|
76
|
-
end
|
77
|
-
|
78
|
-
# :tSYMBEG
|
79
|
-
def _reduce_403(val, _values, result)
|
80
|
-
lexer.source_start_pos = lexer.src.pos - lexer.yacc_value.size - 2
|
81
|
-
super
|
82
|
-
end
|
83
|
-
|
84
|
-
def _reduce_418(val, _values, result)
|
85
|
-
result = super
|
86
|
-
result.source_start_pos = val[1].source_start_pos
|
87
|
-
result.source_end_pos = val[1].source_end_pos
|
88
|
-
result.full_source = val[1].full_source
|
89
|
-
result
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|