Skip to content

Instantly share code, notes, and snippets.

@danlucraft
Created April 12, 2010 16:19
Show Gist options
  • Save danlucraft/363735 to your computer and use it in GitHub Desktop.
Save danlucraft/363735 to your computer and use it in GitHub Desktop.
Beginnings of a JVM native ctags library?
require 'yaml'
JAVA_YAML=<<YAML
- regex: "class\\s+(\\w+)"
capture: 1
type: id
- regex: "interface\\s+(\\w+)"
capture: 1
type: id
- regex: "(public|private).*\\s+(\\w+)\s*\\("
capture: 2
type: id
YAML
RUBY_YAML=<<YAML
- regex: "^[^#]*(class|module)\\s+(\\w+)"
capture: 2
type: id
- regex: "^[^#]*def (self\\.)(\\w+)"
capture: 2
type: id
- regex: "^[^#]*attr(_reader|_accessor|_writer)(.*)$"
capture: 2
type: id-list
- regex: "^[^#]*alias\s+:(\\w+)"
capture: 1
type: id
- regex: "^[^#]*alias_method\s+:(\\w+)"
capture: 1
type: id
YAML
class Declarations
DEFINITIONS = {
/\.rb$/ => YAML.load(RUBY_YAML),
/\.java$/ => YAML.load(JAVA_YAML)
}
def decls_for_file(path)
DEFINITIONS.each do |fn_re, decls|
if path =~ fn_re
return decls
end
end
nil
end
def match_in_file(path)
tags = []
begin
file = File.read(path)
if decls = decls_for_file(path)
decls.each do |decl|
file.each_line do |line|
if md = line.match(Regexp.new(decl["regex"]))
capture = md[decl["capture"]]
case decl["type"]
when "id"
tags << [capture, path, md[0]]
when "id-list"
tags += capture.scan(/\w+/).map {|id| [id, path, md[0]] }
end
end
end
end
end
tags
rescue
[]
end
end
def generate(files)
tags = []
files.each do |path|
tags += match_in_file(path)
end
tags.sort!
File.open("tags", "w") do |tags_file|
tags.each do |id, path, declaration|
tags_file.puts "#{id}\t#{path}\t#{declaration}"
end
end
end
end
files = Dir[ARGV[0]]
puts "#{files.length} files"
5.times do
s = Time.now
decl = Declarations.new
decl.generate(files)
puts "took #{Time.now - s}s"
end
#
# Timings for running against all Ruby and Java in the Redcar repository:
#
# ~/Redcar/redcar (master)
# $ ruby ~/Desktop/declarations.rb "**/*.{rb,java}"
# 917 files
# took 4.466576s
# took 4.694825s
# took 4.458402s
# took 4.87733s
# took 4.939915s
#
# ^C~/Redcar/redcar (master)
# $ jruby ~/Desktop/declarations.rb "**/*.{rb,java}"
# 917 files
# took 1.802s
# took 1.13s
# took 0.986s
# took 0.88s
# took 0.879s
#
#
# Timings for running against the entire Songkick.com Rails project:
#
#~/Redcar/redcar (master)
# $ ruby ~/Desktop/declarations.rb "/Users/danlucraft/Songkick/skweb/**/*.rb"
# 5330 files
# took 44.585956s
# took 31.532368s
# took 31.402265s
# took 31.702252s
# took 31.957006s
# ~/Redcar/redcar (master)
# $ jruby ~/Desktop/declarations.rb "/Users/danlucraft/Songkick/skweb/**/*.rb"
# 5330 files
# took 7.06s
# took 5.801s
# took 5.183s
# took 5.217s
# took 5.208s
@danlucraft
Copy link
Author

The language is kind of irrelevant as long as it runs on the jvm :) More important is whether this approach will work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment