starscope 1.5.3 → 1.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,22 +1,24 @@
1
- class Starscope::FragmentExtractor
2
- def initialize(lang, frags)
3
- @child = Starscope::Lang.const_get(lang)
4
- @frags = frags
5
- end
1
+ module Starscope
2
+ class FragmentExtractor
3
+ def initialize(lang, frags)
4
+ @child = Starscope::Lang.const_get(lang)
5
+ @frags = frags
6
+ end
6
7
 
7
- def extract(path, text)
8
- text = @frags.map { |f| f.delete(:frag).strip }.join("\n")
8
+ def extract(path, text)
9
+ text = @frags.map { |f| f.delete(:frag).strip }.join("\n")
9
10
 
10
- extractor_metadata = @child.extract(path, text) do |tbl, name, args|
11
- args.merge!(@frags[args[:line_no] - 1]) if args[:line_no]
12
- yield tbl, name, args
13
- end
11
+ extractor_metadata = @child.extract(path, text) do |tbl, name, args|
12
+ args.merge!(@frags[args[:line_no] - 1]) if args[:line_no]
13
+ yield tbl, name, args
14
+ end
14
15
 
15
- # TODO: translate metadata?
16
- extractor_metadata
17
- end
16
+ # TODO: translate metadata?
17
+ extractor_metadata
18
+ end
18
19
 
19
- def name
20
- @child.name
20
+ def name
21
+ @child.name
22
+ end
21
23
  end
22
24
  end
@@ -1,44 +1,46 @@
1
- module Starscope::Lang
2
- module ERB
3
- VERSION = 1
1
+ module Starscope
2
+ module Lang
3
+ module ERB
4
+ VERSION = 1
4
5
 
5
- ERB_START = /<%(?:-|={1,4})?/
6
- ERB_END = /-?%>/
6
+ ERB_START = /<%(?:-|={1,4})?/
7
+ ERB_END = /-?%>/
7
8
 
8
- def self.match_file(name)
9
- name.end_with?('.erb')
10
- end
11
-
12
- def self.extract(path, contents, &block)
13
- multiline = false # true when parsing a multiline <% ... %> block
14
-
15
- contents.lines.each_with_index do |line, line_no|
16
- line_no += 1 # zero-index to one-index
9
+ def self.match_file(name)
10
+ name.end_with?('.erb')
11
+ end
17
12
 
18
- if multiline
19
- term = line.index(ERB_END)
20
- if term
21
- yield Starscope::DB::FRAGMENT, :Ruby, frag: line[0...term], line_no: line_no
22
- line = line[term + 1..-1]
23
- multiline = false
24
- else
25
- yield Starscope::DB::FRAGMENT, :Ruby, frag: line, line_no: line_no
13
+ def self.extract(_path, contents)
14
+ multiline = false # true when parsing a multiline <% ... %> block
15
+
16
+ contents.lines.each_with_index do |line, line_no|
17
+ line_no += 1 # zero-index to one-index
18
+
19
+ if multiline
20
+ term = line.index(ERB_END)
21
+ if term
22
+ yield Starscope::DB::FRAGMENT, :Ruby, frag: line[0...term], line_no: line_no
23
+ line = line[term + 1..-1]
24
+ multiline = false
25
+ else
26
+ yield Starscope::DB::FRAGMENT, :Ruby, frag: line, line_no: line_no
27
+ end
26
28
  end
27
- end
28
29
 
29
- next if multiline
30
+ next if multiline
30
31
 
31
- line.scan(/#{ERB_START}(.*?)#{ERB_END}/) do |match|
32
- yield Starscope::DB::FRAGMENT, :Ruby, frag: match[0], line_no: line_no
33
- end
32
+ line.scan(/#{ERB_START}(.*?)#{ERB_END}/) do |match|
33
+ yield Starscope::DB::FRAGMENT, :Ruby, frag: match[0], line_no: line_no
34
+ end
34
35
 
35
- line.gsub!(/<%.*?%>/, '')
36
+ line.gsub!(/<%.*?%>/, '')
36
37
 
37
- match = /#{ERB_START}(.*)$/.match(line)
38
- next unless match
38
+ match = /#{ERB_START}(.*)$/.match(line)
39
+ next unless match
39
40
 
40
- yield Starscope::DB::FRAGMENT, :Ruby, frag: match[1], line_no: line_no
41
- multiline = true
41
+ yield Starscope::DB::FRAGMENT, :Ruby, frag: match[1], line_no: line_no
42
+ multiline = true
43
+ end
42
44
  end
43
45
  end
44
46
  end
@@ -1,206 +1,208 @@
1
- module Starscope::Lang
2
- module Golang
3
- VERSION = 1
1
+ module Starscope
2
+ module Lang
3
+ module Golang
4
+ VERSION = 1
4
5
 
5
- FUNC_CALL = /([\w\.]*?\w)\(/
6
- END_OF_BLOCK = /^\s*\}\s*$/
7
- END_OF_GROUP = /^\s*\)\s*$/
8
- STRING_LITERAL = /".+?"/
9
- BUILTIN_FUNCS = %w(new make len close copy delete int int8 int16 int32 int64
10
- uint uint8 uint16 uint32 uint64 string byte).freeze
11
- CONTROL_KEYS = %w(if for switch case).freeze
6
+ FUNC_CALL = /([\w\.]*?\w)\(/
7
+ END_OF_BLOCK = /^\s*\}\s*$/
8
+ END_OF_GROUP = /^\s*\)\s*$/
9
+ STRING_LITERAL = /".+?"/
10
+ BUILTIN_FUNCS = %w(new make len close copy delete int int8 int16 int32 int64
11
+ uint uint8 uint16 uint32 uint64 string byte).freeze
12
+ CONTROL_KEYS = %w(if for switch case).freeze
12
13
 
13
- def self.match_file(name)
14
- name.end_with?('.go')
15
- end
16
-
17
- def self.extract(path, contents, &block)
18
- stack = []
19
- scope = []
20
- contents.lines.each_with_index do |line, line_no|
21
- line_no += 1 # zero-index to one-index
22
-
23
- # strip single-line comments like // foo
24
- match = %r{//}.match(line)
25
- line = match.pre_match if match
26
- # strip single-line comments like foo /* foo */ foo
27
- match = %r{/\*.*\*/}.match(line)
28
- line = match.pre_match + match.post_match if match
29
- # strip end-of-line comment starters like foo /* foo \n
30
- match = %r{/\*}.match(line)
31
- line = match.pre_match if match
32
- ends_with_comment = !match.nil?
14
+ def self.match_file(name)
15
+ name.end_with?('.go')
16
+ end
33
17
 
34
- # if we're in a block comment, wait for it to end
35
- if stack[-1] == :comment
36
- match = %r{\*/(.*)}.match(line)
37
- next unless match
38
- line = match[1]
39
- stack.pop
40
- end
18
+ def self.extract(_path, contents, &block)
19
+ stack = []
20
+ scope = []
21
+ contents.lines.each_with_index do |line, line_no|
22
+ line_no += 1 # zero-index to one-index
41
23
 
42
- if stack[-1] != :import && !line.start_with?('import')
43
- # strip string literals like "foo" unless they're part of an import
44
- pos = 0
45
- while (match = STRING_LITERAL.match(line, pos))
46
- eos = find_end_of_string(line, match.begin(0))
47
- line = line[0..match.begin(0)] + line[eos..-1]
48
- pos = match.begin(0) + 2
49
- end
50
- end
24
+ # strip single-line comments like // foo
25
+ match = %r{//}.match(line)
26
+ line = match.pre_match if match
27
+ # strip single-line comments like foo /* foo */ foo
28
+ match = %r{/\*.*\*/}.match(line)
29
+ line = match.pre_match + match.post_match if match
30
+ # strip end-of-line comment starters like foo /* foo \n
31
+ match = %r{/\*}.match(line)
32
+ line = match.pre_match if match
33
+ ends_with_comment = !match.nil?
51
34
 
52
- # poor-man's parser
53
- case stack[-1]
54
- when :struct
55
- case line
56
- when END_OF_BLOCK
57
- end_block(line_no, scope, stack, &block)
58
- when /(.+)\s+\w+/
59
- parse_def(Regexp.last_match(1), line_no, scope, &block)
60
- end
61
- when :interface
62
- case line
63
- when END_OF_BLOCK
64
- end_block(line_no, scope, stack, &block)
65
- when /(\w+)\(.*\)\s+/
66
- yield :defs, scope + [Regexp.last_match(1)], line_no: line_no
67
- end
68
- when :def
69
- case line
70
- when END_OF_GROUP
35
+ # if we're in a block comment, wait for it to end
36
+ if stack[-1] == :comment
37
+ match = %r{\*/(.*)}.match(line)
38
+ next unless match
39
+ line = match[1]
71
40
  stack.pop
72
- when /(.+)\s*=.*/
73
- parse_def(Regexp.last_match(1), line_no, scope, &block)
74
- parse_call(line, line_no, scope, &block)
75
- else
76
- parse_def(line, line_no, scope, &block)
77
41
  end
78
- when :import
79
- case line
80
- when END_OF_GROUP
81
- stack.pop
82
- when /"(.+)"/
83
- name = Regexp.last_match(1).split('/')
84
- yield :imports, name, line_no: line_no
42
+
43
+ if stack[-1] != :import && !line.start_with?('import')
44
+ # strip string literals like "foo" unless they're part of an import
45
+ pos = 0
46
+ while (match = STRING_LITERAL.match(line, pos))
47
+ eos = find_end_of_string(line, match.begin(0))
48
+ line = line[0..match.begin(0)] + line[eos..-1]
49
+ pos = match.begin(0) + 2
50
+ end
85
51
  end
86
- when :func
87
- case line
88
- when /^\}/
89
- yield :end, '}', line_no: line_no, type: :func
90
- stack.pop
52
+
53
+ # poor-man's parser
54
+ case stack[-1]
55
+ when :struct
56
+ case line
57
+ when END_OF_BLOCK
58
+ end_block(line_no, scope, stack, &block)
59
+ when /(.+)\s+\w+/
60
+ parse_def(Regexp.last_match(1), line_no, scope, &block)
61
+ end
62
+ when :interface
63
+ case line
64
+ when END_OF_BLOCK
65
+ end_block(line_no, scope, stack, &block)
66
+ when /(\w+)\(.*\)\s+/
67
+ yield :defs, scope + [Regexp.last_match(1)], line_no: line_no
68
+ end
69
+ when :def
70
+ case line
71
+ when END_OF_GROUP
72
+ stack.pop
73
+ when /(.+)\s*=.*/
74
+ parse_def(Regexp.last_match(1), line_no, scope, &block)
75
+ parse_call(line, line_no, scope, &block)
76
+ else
77
+ parse_def(line, line_no, scope, &block)
78
+ end
79
+ when :import
80
+ case line
81
+ when END_OF_GROUP
82
+ stack.pop
83
+ when /"(.+)"/
84
+ name = Regexp.last_match(1).split('/')
85
+ yield :imports, name, line_no: line_no
86
+ end
87
+ when :func
88
+ case line
89
+ when /^\}/
90
+ yield :end, '}', line_no: line_no, type: :func
91
+ stack.pop
92
+ else
93
+ parse_new_line(line, line_no, scope, stack, &block)
94
+ end
91
95
  else
92
96
  parse_new_line(line, line_no, scope, stack, &block)
93
97
  end
94
- else
95
- parse_new_line(line, line_no, scope, stack, &block)
96
- end
97
98
 
98
- # if the line looks like "foo /* foo" then we enter the comment state
99
- # after parsing the usable part of the line
100
- stack.push(:comment) if ends_with_comment
99
+ # if the line looks like "foo /* foo" then we enter the comment state
100
+ # after parsing the usable part of the line
101
+ stack.push(:comment) if ends_with_comment
102
+ end
101
103
  end
102
- end
103
104
 
104
- # handles new lines (when not in the middle of an existing definition)
105
- def self.parse_new_line(line, line_no, scope, stack, &block)
106
- case line
107
- when /^func\s+(\w+)\(/
108
- yield :defs, scope + [Regexp.last_match(1)], line_no: line_no, type: :func
109
- stack.push(:func)
110
- when /^func\s+\(\w+\s+\*?(\w+)\)\s*(\w+)\(/
111
- yield :defs, scope + [Regexp.last_match(1), Regexp.last_match(2)], line_no: line_no, type: :func
112
- stack.push(:func)
113
- when /^package\s+(\w+)/
114
- scope.push(Regexp.last_match(1))
115
- yield :defs, scope, line_no: line_no, type: :package
116
- when /^type\s+(\w+)\s+struct\s*\{/
117
- scope.push(Regexp.last_match(1))
118
- stack.push(:struct)
119
- yield :defs, scope, line_no: line_no, type: :class
120
- when /^type\s+(\w+)\s+interface\s*\{/
121
- scope.push(Regexp.last_match(1))
122
- stack.push(:interface)
123
- yield :defs, scope, line_no: line_no, type: :class
124
- when /^type\s+(\w+)/
125
- yield :defs, scope + [Regexp.last_match(1)], line_no: line_no, type: :type
126
- when /^import\s+"(.+)"/
127
- name = Regexp.last_match(1).split('/')
128
- yield :imports, name, line_no: line_no
129
- when /^import\s+\(/
130
- stack.push(:import)
131
- when /^var\s+\(/
132
- stack.push(:def)
133
- when /^var\s+(\w+)\s/
134
- yield :defs, scope + [Regexp.last_match(1)], line_no: line_no
135
- parse_call(line, line_no, scope, &block)
136
- when /^const\s+\(/
137
- stack.push(:def)
138
- when /^const\s+(\w+)\s/
139
- yield :defs, scope + [Regexp.last_match(1)], line_no: line_no
140
- parse_call(line, line_no, scope, &block)
141
- when /^\s+(.*?) :?=[^=]/
142
- Regexp.last_match(1).split(' ').each do |var|
143
- next if CONTROL_KEYS.include?(var)
144
- name = var.delete(',').split('.')
145
- next if name[0] == '_' # assigning to _ is a discard in golang
146
- if name.length == 1
147
- yield :assigns, scope + [name[0]], line_no: line_no
148
- else
149
- yield :assigns, name, line_no: line_no
105
+ # handles new lines (when not in the middle of an existing definition)
106
+ def self.parse_new_line(line, line_no, scope, stack, &block)
107
+ case line
108
+ when /^func\s+(\w+)\(/
109
+ yield :defs, scope + [Regexp.last_match(1)], line_no: line_no, type: :func
110
+ stack.push(:func)
111
+ when /^func\s+\(\w+\s+\*?(\w+)\)\s*(\w+)\(/
112
+ yield :defs, scope + [Regexp.last_match(1), Regexp.last_match(2)], line_no: line_no, type: :func
113
+ stack.push(:func)
114
+ when /^package\s+(\w+)/
115
+ scope.push(Regexp.last_match(1))
116
+ yield :defs, scope, line_no: line_no, type: :package
117
+ when /^type\s+(\w+)\s+struct\s*\{/
118
+ scope.push(Regexp.last_match(1))
119
+ stack.push(:struct)
120
+ yield :defs, scope, line_no: line_no, type: :class
121
+ when /^type\s+(\w+)\s+interface\s*\{/
122
+ scope.push(Regexp.last_match(1))
123
+ stack.push(:interface)
124
+ yield :defs, scope, line_no: line_no, type: :class
125
+ when /^type\s+(\w+)/
126
+ yield :defs, scope + [Regexp.last_match(1)], line_no: line_no, type: :type
127
+ when /^import\s+"(.+)"/
128
+ name = Regexp.last_match(1).split('/')
129
+ yield :imports, name, line_no: line_no
130
+ when /^import\s+\(/
131
+ stack.push(:import)
132
+ when /^var\s+\(/
133
+ stack.push(:def)
134
+ when /^var\s+(\w+)\s/
135
+ yield :defs, scope + [Regexp.last_match(1)], line_no: line_no
136
+ parse_call(line, line_no, scope, &block)
137
+ when /^const\s+\(/
138
+ stack.push(:def)
139
+ when /^const\s+(\w+)\s/
140
+ yield :defs, scope + [Regexp.last_match(1)], line_no: line_no
141
+ parse_call(line, line_no, scope, &block)
142
+ when /^\s+(.*?) :?=[^=]/
143
+ Regexp.last_match(1).split(' ').each do |var|
144
+ next if CONTROL_KEYS.include?(var)
145
+ name = var.delete(',').split('.')
146
+ next if name[0] == '_' # assigning to _ is a discard in golang
147
+ if name.length == 1
148
+ yield :assigns, scope + [name[0]], line_no: line_no
149
+ else
150
+ yield :assigns, name, line_no: line_no
151
+ end
150
152
  end
153
+ parse_call(line, line_no, scope, &block)
154
+ else
155
+ parse_call(line, line_no, scope, &block)
151
156
  end
152
- parse_call(line, line_no, scope, &block)
153
- else
154
- parse_call(line, line_no, scope, &block)
155
157
  end
156
- end
157
158
 
158
- def self.parse_call(line, line_no, scope)
159
- line.scan(FUNC_CALL) do |match|
160
- name = match[0].split('.').select { |chunk| !chunk.empty? }
161
- if name.length == 1
162
- next if name[0] == 'func'
163
- if BUILTIN_FUNCS.include?(name[0])
164
- yield :calls, name[0], line_no: line_no
159
+ def self.parse_call(line, line_no, scope)
160
+ line.scan(FUNC_CALL) do |match|
161
+ name = match[0].split('.').select { |chunk| !chunk.empty? }
162
+ if name.length == 1
163
+ next if name[0] == 'func'
164
+ if BUILTIN_FUNCS.include?(name[0])
165
+ yield :calls, name[0], line_no: line_no
166
+ else
167
+ yield :calls, scope + [name[0]], line_no: line_no
168
+ end
165
169
  else
166
- yield :calls, scope + [name[0]], line_no: line_no
170
+ yield :calls, name, line_no: line_no
167
171
  end
168
- else
169
- yield :calls, name, line_no: line_no
170
172
  end
171
173
  end
172
- end
173
174
 
174
- def self.parse_def(line, line_no, scope)
175
- # if it doesn't start with a valid identifier character, it's probably
176
- # part of a multi-line literal and we should skip it
177
- return unless line =~ /^\s*[[:alpha:]_]/
175
+ def self.parse_def(line, line_no, scope)
176
+ # if it doesn't start with a valid identifier character, it's probably
177
+ # part of a multi-line literal and we should skip it
178
+ return unless line =~ /^\s*[[:alpha:]_]/
178
179
 
179
- line.split.each do |var|
180
- yield :defs, scope + [var.delete(',')], line_no: line_no
181
- break unless var.end_with?(',')
180
+ line.split.each do |var|
181
+ yield :defs, scope + [var.delete(',')], line_no: line_no
182
+ break unless var.end_with?(',')
183
+ end
182
184
  end
183
- end
184
185
 
185
- def self.end_block(line_no, scope, stack)
186
- yield :end, scope + ['}'], line_no: line_no, type: :class
187
- stack.pop
188
- scope.pop
189
- end
186
+ def self.end_block(line_no, scope, stack)
187
+ yield :end, scope + ['}'], line_no: line_no, type: :class
188
+ stack.pop
189
+ scope.pop
190
+ end
190
191
 
191
- def self.find_end_of_string(line, start)
192
- escape = false
193
- (start + 1...line.length).each do |i|
194
- if escape
195
- escape = false
196
- elsif line[i] == '\\'
197
- escape = true
198
- elsif line[i] == '"'
199
- return i
192
+ def self.find_end_of_string(line, start)
193
+ escape = false
194
+ (start + 1...line.length).each do |i|
195
+ if escape
196
+ escape = false
197
+ elsif line[i] == '\\'
198
+ escape = true
199
+ elsif line[i] == '"'
200
+ return i
201
+ end
200
202
  end
201
- end
202
203
 
203
- line.length
204
+ line.length
205
+ end
204
206
  end
205
207
  end
206
208
  end