starscope 1.3.3 → 1.4.0

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,25 +1,24 @@
1
1
  module Starscope::Exportable
2
-
3
- CTAGS_DEFAULT_PATH='tags'
4
- CSCOPE_DEFAULT_PATH='cscope.out'
2
+ CTAGS_DEFAULT_PATH = 'tags'
3
+ CSCOPE_DEFAULT_PATH = 'cscope.out'
5
4
 
6
5
  class UnknownExportFormatError < StandardError; end
7
6
 
8
- def export(format, path=nil)
7
+ def export(format, path = nil)
9
8
  case format
10
9
  when :ctags
11
10
  path ||= CTAGS_DEFAULT_PATH
12
11
  when :cscope
13
12
  path ||= CSCOPE_DEFAULT_PATH
14
13
  else
15
- raise UnknownExportFormatError
14
+ fail UnknownExportFormatError
16
15
  end
17
16
 
18
17
  @output.normal("Exporting to '#{path}' in format '#{format}'...")
19
18
  File.open(path, 'w') do |file|
20
19
  export_to(format, file)
21
20
  end
22
- @output.normal("Export complete.")
21
+ @output.normal('Export complete.')
23
22
  end
24
23
 
25
24
  def export_to(format, io)
@@ -29,7 +28,7 @@ module Starscope::Exportable
29
28
  when :cscope
30
29
  export_cscope(io)
31
30
  else
32
- raise UnknownExportFormatError
31
+ fail UnknownExportFormatError
33
32
  end
34
33
  end
35
34
 
@@ -44,7 +43,7 @@ module Starscope::Exportable
44
43
  !_TAG_PROGRAM_URL https://github.com/eapache/starscope //
45
44
  !_TAG_PROGRAM_VERSION #{Starscope::VERSION} //
46
45
  END
47
- defs = (@tables[:defs] || {}).sort_by {|x| x[:name][-1].to_s}
46
+ defs = (@tables[:defs] || {}).sort_by { |x| x[:name][-1].to_s }
48
47
  defs.each do |record|
49
48
  file.puts ctag_line(record, @meta[:files][record[:file]])
50
49
  end
@@ -55,7 +54,7 @@ END
55
54
  ret = "#{rec[:name][-1]}\t#{rec[:file]}\t/^#{line}$/"
56
55
 
57
56
  ext = ctag_ext_tags(rec, file)
58
- if not ext.empty?
57
+ unless ext.empty?
59
58
  ret << ";\""
60
59
  ext.sort.each do |k, v|
61
60
  ret << "\t#{k}:#{v}"
@@ -71,12 +70,12 @@ END
71
70
  # these extensions are documented at http://ctags.sourceforge.net/FORMAT
72
71
  case rec[:type]
73
72
  when :func
74
- tag["kind"] = "f"
73
+ tag['kind'] = 'f'
75
74
  when :module, :class
76
- tag["kind"] = "c"
75
+ tag['kind'] = 'c'
77
76
  end
78
77
 
79
- tag["language"] = file[:lang]
78
+ tag['language'] = file[:lang]
80
79
 
81
80
  tag
82
81
  end
@@ -91,9 +90,9 @@ END
91
90
 
92
91
  # ftp://ftp.eeng.dcu.ie/pub/ee454/cygwin/usr/share/doc/mlcscope-14.1.8/html/cscope.html
93
92
  def export_cscope(file)
94
- buf = ""
93
+ buf = ''
95
94
  files = []
96
- db_by_line().each do |filename, lines|
95
+ db_by_line.each do |filename, lines|
97
96
  next if lines.empty?
98
97
 
99
98
  buf << "\t@#{filename}\n\n"
@@ -107,9 +106,8 @@ END
107
106
  next if toks.empty?
108
107
 
109
108
  prev = 0
110
- buf << line_no.to_s << " "
109
+ buf << line_no.to_s << ' '
111
110
  toks.each do |offset, record|
112
-
113
111
  next if offset < prev # this probably indicates an extractor bug
114
112
 
115
113
  # Don't export nested functions, cscope barfs on them since C doesn't
@@ -128,7 +126,6 @@ END
128
126
 
129
127
  buf << cscope_output(line, prev, offset, record)
130
128
  prev = offset + record[:key].length
131
-
132
129
  end
133
130
  buf << cscope_plaintext(line, prev, line.length) << "\n\n"
134
131
  end
@@ -144,19 +141,19 @@ END
144
141
  file.print(buf)
145
142
 
146
143
  file.print("#{@meta[:paths].length}\n")
147
- @meta[:paths].each {|p| file.print("#{p}\n")}
144
+ @meta[:paths].each { |p| file.print("#{p}\n") }
148
145
  file.print("0\n")
149
146
  file.print("#{files.length}\n")
150
- buf = ""
151
- files.each {|f| buf << f + "\n"}
147
+ buf = ''
148
+ files.each { |f| buf << f + "\n" }
152
149
  file.print("#{buf.length}\n#{buf}")
153
150
  end
154
151
 
155
- def db_by_line()
152
+ def db_by_line
156
153
  db = {}
157
154
  @tables.each do |tbl, records|
158
155
  records.each do |record|
159
- next if not record[:line_no]
156
+ next unless record[:line_no]
160
157
  record[:tbl] = tbl
161
158
  db[record[:file]] ||= {}
162
159
  db[record[:file]][record[:line_no]] ||= []
@@ -176,7 +173,7 @@ END
176
173
  index = record[:col] || line.index(key)
177
174
 
178
175
  while index && !valid_index?(line, index, key)
179
- index = line.index(key, index+1)
176
+ index = line.index(key, index + 1)
180
177
  end
181
178
 
182
179
  next if index.nil?
@@ -197,7 +194,7 @@ END
197
194
  end
198
195
 
199
196
  def cscope_output(line, prev, offset, record)
200
- buf = ""
197
+ buf = ''
201
198
  buf << CSCOPE_GLOBAL_HACK_STOP if record[:type] == :func && record[:tbl] == :defs
202
199
 
203
200
  record[:name][0...-1].each do |key|
@@ -207,11 +204,11 @@ END
207
204
 
208
205
  index = line.index(key, prev)
209
206
 
210
- while index && index+key.length < offset && !valid_index?(line, index, key)
211
- index = line.index(key, index+1)
207
+ while index && index + key.length < offset && !valid_index?(line, index, key)
208
+ index = line.index(key, index + 1)
212
209
  end
213
210
 
214
- if index && index+key.length < offset
211
+ if index && index + key.length < offset
215
212
  buf << cscope_plaintext(line, prev, index) << "\n"
216
213
  buf << "#{key}\n"
217
214
  prev = index + key.length
@@ -231,12 +228,12 @@ END
231
228
  def valid_index?(line, index, key)
232
229
  # index is valid if the key exists at it, and the prev/next chars are not word characters
233
230
  ((line[index, key.length] == key) &&
234
- (index == 0 || line[index-1] !~ /\w/) &&
235
- (index+key.length == line.length || line[index+key.length] !~ /\w/))
231
+ (index == 0 || line[index - 1] !~ /\w/) &&
232
+ (index + key.length == line.length || line[index + key.length] !~ /\w/))
236
233
  end
237
234
 
238
235
  def cscope_plaintext(line, start, stop)
239
- ret = line.slice(start, stop-start)
236
+ ret = line.slice(start, stop - start)
240
237
  ret.lstrip! if start == 0
241
238
  ret.rstrip! if stop == line.length
242
239
  ret.gsub(/\s+/, ' ')
@@ -250,33 +247,33 @@ END
250
247
  when :end
251
248
  case rec[:type]
252
249
  when :func
253
- ret = "}"
250
+ ret = '}'
254
251
  else
255
- return ""
252
+ return ''
256
253
  end
257
254
  when :file
258
- ret = "@"
255
+ ret = '@'
259
256
  when :defs
260
257
  case rec[:type]
261
258
  when :func
262
- ret = "$"
259
+ ret = '$'
263
260
  when :class, :module
264
- ret = "c"
261
+ ret = 'c'
265
262
  when :type
266
- ret = "t"
263
+ ret = 't'
267
264
  else
268
- ret = "g"
265
+ ret = 'g'
269
266
  end
270
267
  when :calls
271
- ret = "`"
268
+ ret = '`'
272
269
  when :requires
273
270
  ret = "~\""
274
271
  when :imports
275
- ret = "~<"
272
+ ret = '~<'
276
273
  when :assigns
277
- ret = "="
274
+ ret = '='
278
275
  else
279
- return ""
276
+ return ''
280
277
  end
281
278
 
282
279
  "\t" + ret
@@ -0,0 +1,22 @@
1
+ class Starscope::FragmentExtractor
2
+ def initialize(lang, frags)
3
+ @child = Starscope::Lang.const_get(lang)
4
+ @frags = frags
5
+ end
6
+
7
+ def extract(path, text)
8
+ text = @frags.map { |f| f.delete(:frag).strip }.join("\n")
9
+
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
14
+
15
+ # TODO: translate metadata?
16
+ extractor_metadata
17
+ end
18
+
19
+ def name
20
+ @child.name
21
+ end
22
+ end
@@ -0,0 +1,45 @@
1
+ module Starscope::Lang
2
+ module ERB
3
+ VERSION = 1
4
+
5
+ ERB_START = /<%(?:-|={1,4})?/
6
+ ERB_END = /-?%>/
7
+
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
17
+
18
+ if multiline
19
+ term = line.index(ERB_END)
20
+ if term
21
+ yield FRAGMENT, :Ruby, :frag => line[0...term], :line_no => line_no
22
+ line = line[term + 1..-1]
23
+ multiline = false
24
+ else
25
+ yield FRAGMENT, :Ruby, :frag => line, :line_no => line_no
26
+ end
27
+ end
28
+
29
+ unless multiline
30
+ line.scan(/#{ERB_START}(.*?)#{ERB_END}/) do |match|
31
+ yield FRAGMENT, :Ruby, :frag => match[0], :line_no => line_no
32
+ end
33
+
34
+ line.gsub!(/<%.*?%>/, '')
35
+
36
+ match = /#{ERB_START}(.*)$/.match(line)
37
+ if match
38
+ yield FRAGMENT, :Ruby, :frag => match[1], :line_no => line_no
39
+ multiline = true
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -6,42 +6,39 @@ module Starscope::Lang
6
6
  END_OF_BLOCK = /^\s*\}\s*$/
7
7
  END_OF_GROUP = /^\s*\)\s*$/
8
8
  STRING_LITERAL = /".+?"/
9
- BUILTIN_FUNCS = ['new', 'make', 'len', 'close', 'copy', 'delete',
10
- 'int', 'int8', 'int16', 'int32', 'int64',
11
- 'uint', 'uint8', 'uint16', 'uint32', 'uint64',
12
- 'string', 'byte']
13
- CONTROL_KEYS = ['if', 'for', 'switch', 'case']
9
+ BUILTIN_FUNCS = %w(new make len close copy delete int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 string byte)
10
+ CONTROL_KEYS = %w(if for switch case)
14
11
 
15
12
  def self.match_file(name)
16
- name.end_with?(".go")
13
+ name.end_with?('.go')
17
14
  end
18
15
 
19
- def self.extract(file, &block)
16
+ def self.extract(path, contents, &block)
20
17
  stack = []
21
18
  scope = []
22
- File.readlines(file).each_with_index do |line, line_no|
19
+ contents.lines.each_with_index do |line, line_no|
23
20
  line_no += 1 # zero-index to one-index
24
21
 
25
22
  # strip single-line comments like // foo
26
- match = /\/\//.match(line)
23
+ match = %r{//}.match(line)
27
24
  line = match.pre_match if match
28
25
  # strip single-line comments like foo /* foo */ foo
29
- match = /\/\*.*\*\//.match(line)
26
+ match = %r{/\*.*\*/}.match(line)
30
27
  line = match.pre_match + match.post_match if match
31
28
  # strip end-of-line comment starters like foo /* foo \n
32
- match = /\/\*/.match(line)
29
+ match = %r{/\*}.match(line)
33
30
  line = match.pre_match if match
34
31
  ends_with_comment = !match.nil?
35
32
 
36
33
  # if we're in a block comment, wait for it to end
37
34
  if stack[-1] == :comment
38
- match = /\*\/(.*)/.match(line)
35
+ match = %r{\*/(.*)}.match(line)
39
36
  next unless match
40
37
  line = match[1]
41
38
  stack.pop
42
39
  end
43
40
 
44
- if stack[-1] != :import && !line.start_with?("import")
41
+ if stack[-1] != :import && !line.start_with?('import')
45
42
  # strip string literals like "foo" unless they're part of an import
46
43
  pos = 0
47
44
  while match = STRING_LITERAL.match(line[pos..-1])
@@ -58,21 +55,21 @@ module Starscope::Lang
58
55
  when END_OF_BLOCK
59
56
  end_block(line_no, scope, stack, &block)
60
57
  when /(.+)\s+\w+/
61
- parse_def($1, line_no, scope, &block)
58
+ parse_def(Regexp.last_match(1), line_no, scope, &block)
62
59
  end
63
60
  when :interface
64
61
  case line
65
62
  when END_OF_BLOCK
66
63
  end_block(line_no, scope, stack, &block)
67
64
  when /(\w+)\(.*\)\s+/
68
- yield :defs, scope + [$1], :line_no => line_no
65
+ yield :defs, scope + [Regexp.last_match(1)], :line_no => line_no
69
66
  end
70
67
  when :def
71
68
  case line
72
69
  when END_OF_GROUP
73
70
  stack.pop
74
71
  when /(.+)\s*=.*/
75
- parse_def($1, line_no, scope, &block)
72
+ parse_def(Regexp.last_match(1), line_no, scope, &block)
76
73
  parse_call(line, line_no, scope, &block)
77
74
  else
78
75
  parse_def(line, line_no, scope, &block)
@@ -82,13 +79,13 @@ module Starscope::Lang
82
79
  when END_OF_GROUP
83
80
  stack.pop
84
81
  when /"(.+)"/
85
- name = $1.split('/')
82
+ name = Regexp.last_match(1).split('/')
86
83
  yield :imports, name, :line_no => line_no
87
84
  end
88
85
  when :func
89
86
  case line
90
87
  when /^\}/
91
- yield :end, "}", :line_no => line_no, :type => :func
88
+ yield :end, '}', :line_no => line_no, :type => :func
92
89
  stack.pop
93
90
  else
94
91
  parse_new_line(line, line_no, scope, stack, &block)
@@ -99,9 +96,7 @@ module Starscope::Lang
99
96
 
100
97
  # if the line looks like "foo /* foo" then we enter the comment state
101
98
  # after parsing the usable part of the line
102
- if ends_with_comment
103
- stack.push(:comment)
104
- end
99
+ stack.push(:comment) if ends_with_comment
105
100
  end
106
101
  end
107
102
 
@@ -109,44 +104,44 @@ module Starscope::Lang
109
104
  def self.parse_new_line(line, line_no, scope, stack, &block)
110
105
  case line
111
106
  when /^func\s+(\w+)\(/
112
- yield :defs, scope + [$1], :line_no => line_no, :type => :func
107
+ yield :defs, scope + [Regexp.last_match(1)], :line_no => line_no, :type => :func
113
108
  stack.push(:func)
114
109
  when /^func\s+\(\w+\s+\*?(\w+)\)\s*(\w+)\(/
115
- yield :defs, scope + [$1, $2], :line_no => line_no, :type => :func
110
+ yield :defs, scope + [Regexp.last_match(1), Regexp.last_match(2)], :line_no => line_no, :type => :func
116
111
  stack.push(:func)
117
112
  when /^package\s+(\w+)/
118
- scope.push($1)
113
+ scope.push(Regexp.last_match(1))
119
114
  yield :defs, scope, :line_no => line_no, :type => :package
120
115
  when /^type\s+(\w+)\s+struct\s*\{/
121
- scope.push($1)
116
+ scope.push(Regexp.last_match(1))
122
117
  stack.push(:struct)
123
118
  yield :defs, scope, :line_no => line_no, :type => :class
124
119
  when /^type\s+(\w+)\s+interface\s*\{/
125
- scope.push($1)
120
+ scope.push(Regexp.last_match(1))
126
121
  stack.push(:interface)
127
122
  yield :defs, scope, :line_no => line_no, :type => :class
128
123
  when /^type\s+(\w+)/
129
- yield :defs, scope + [$1], :line_no => line_no, :type => :type
124
+ yield :defs, scope + [Regexp.last_match(1)], :line_no => line_no, :type => :type
130
125
  when /^import\s+"(.+)"/
131
- name = $1.split('/')
126
+ name = Regexp.last_match(1).split('/')
132
127
  yield :imports, name, :line_no => line_no
133
128
  when /^import\s+\(/
134
129
  stack.push(:import)
135
130
  when /^var\s+\(/
136
131
  stack.push(:def)
137
132
  when /^var\s+(\w+)\s/
138
- yield :defs, scope + [$1], :line_no => line_no
133
+ yield :defs, scope + [Regexp.last_match(1)], :line_no => line_no
139
134
  parse_call(line, line_no, scope, &block)
140
135
  when /^const\s+\(/
141
136
  stack.push(:def)
142
137
  when /^const\s+(\w+)\s/
143
- yield :defs, scope + [$1], :line_no => line_no
138
+ yield :defs, scope + [Regexp.last_match(1)], :line_no => line_no
144
139
  parse_call(line, line_no, scope, &block)
145
140
  when /^\s+(.*?) :?=[^=]/
146
- $1.split(' ').each do |var|
141
+ Regexp.last_match(1).split(' ').each do |var|
147
142
  next if CONTROL_KEYS.include?(var)
148
143
  name = var.delete(',').split('.')
149
- next if name[0] == "_" # assigning to _ is a discard in golang
144
+ next if name[0] == '_' # assigning to _ is a discard in golang
150
145
  if name.length == 1
151
146
  yield :assigns, scope + [name[0]], :line_no => line_no
152
147
  else
@@ -161,7 +156,7 @@ module Starscope::Lang
161
156
 
162
157
  def self.parse_call(line, line_no, scope)
163
158
  line.scan(FUNC_CALL) do |match|
164
- name = match[0].split('.').select {|chunk| not chunk.empty?}
159
+ name = match[0].split('.').select { |chunk| !chunk.empty? }
165
160
  if name.length == 1
166
161
  next if name[0] == 'func'
167
162
  if BUILTIN_FUNCS.include?(name[0])
@@ -178,23 +173,23 @@ module Starscope::Lang
178
173
  def self.parse_def(line, line_no, scope)
179
174
  # if it doesn't start with a valid identifier character, it's probably
180
175
  # part of a multi-line literal and we should skip it
181
- return if not line =~ /^\s*[[:alpha:]_]/
176
+ return unless line =~ /^\s*[[:alpha:]_]/
182
177
 
183
178
  line.split.each do |var|
184
179
  yield :defs, scope + [var.delete(',')], :line_no => line_no
185
- break if not var.end_with?(',')
180
+ break unless var.end_with?(',')
186
181
  end
187
182
  end
188
183
 
189
184
  def self.end_block(line_no, scope, stack)
190
- yield :end, scope + ["}"], :line_no => line_no, :type => :class
185
+ yield :end, scope + ['}'], :line_no => line_no, :type => :class
191
186
  stack.pop
192
187
  scope.pop
193
188
  end
194
189
 
195
190
  def self.find_end_of_string(line, start)
196
191
  escape = false
197
- (start+1...line.length).each do |i|
192
+ (start + 1...line.length).each do |i|
198
193
  if escape
199
194
  escape = false
200
195
  elsif line[i].chr == '\\'
@@ -204,7 +199,7 @@ module Starscope::Lang
204
199
  end
205
200
  end
206
201
 
207
- return line.length
202
+ line.length
208
203
  end
209
204
  end
210
205
  end