Skip to content

Instantly share code, notes, and snippets.

@hanachin
Last active September 1, 2017 07:10
Show Gist options
  • Save hanachin/deafd221e0f667ffb60f5d68241669f9 to your computer and use it in GitHub Desktop.
Save hanachin/deafd221e0f667ffb60f5d68241669f9 to your computer and use it in GitHub Desktop.
るりまのdoctreeからsyntax errorやrequireがないっぽいの探す
# Usage:
# % cd ~/.bitclust/rubydoc
# % ruby rurema_missing_require.rb
# % tree error_codes
# % vi error_codes/path/to/yml
require 'bitclust'
require 'fileutils'
require 'yaml'
class RuremaSourceCodeLinter
def initialize
umap = BitClust::URLMapper.new({})
@compiler = BitClust::RDCompiler.new(umap, 1, force: true)
@codes = []
def_list
def_emlist
stub_method_signature
end
def lint(src, &block)
@codes.clear
@compiler.compile(src)
@codes.reject! {|c| desc?(c) }
@codes.select!(&block)
@codes
end
private
def def_list
codes = @codes
@compiler.define_singleton_method(:list) do
lines = unindent_block(canonicalize(@f.break(/\A\S/)))
while lines.last.empty?
lines.pop
end
out = StringIO.new
lines.each do |line|
out.puts line
end
codes << out.string
end
end
def def_emlist
codes = @codes
@compiler.define_singleton_method(:emlist) do
@f.gets # discard "//emlist{"
out = StringIO.new
@f.until_terminator(%r<\A//\}>) do |line|
out.puts line.rstrip
end
codes << out.string
end
end
def stub_method_signature
@compiler.define_singleton_method(:method_signature) do |_sig_line, _first|
# stub
end
end
def desc?(s)
s.include?('[[m:') ||
s.include?('[[c:') ||
s.include?('[[ref:') ||
s.bytesize.to_f / s.size > 2
end
end
linter = RuremaSourceCodeLinter.new
error_rds = []
Dir["refm/**/*"].each do |rd|
next if rd.include?('/capi/')
next if rd.include?('/_builtin/')
next if File.directory?(rd)
src = File.read(rd)
begin
error_codes = linter.lint(src) do |s|
!s.include?('require')
end
next if error_codes.empty?
FileUtils.mkdir_p(File.dirname(File.join('error_codes', rd)))
File.write(File.join('error_codes', rd + '.yml'), error_codes.to_yaml)
rescue
$stderr.puts $!.message
error_rds << rd
end
end
File.write('error_rds.yml', error_rds.to_yaml) unless error_rds.empty?
require 'bitclust'
require 'fileutils'
require 'yaml'
umap = BitClust::URLMapper.new({})
compiler = BitClust::RDCompiler.new(umap, 1, {force: true})
list = []
compiler.define_singleton_method(:list) do
lines = unindent_block(canonicalize(@f.break(/\A\S/)))
while lines.last.empty?
lines.pop
end
out = StringIO.new
lines.each do |line|
out.puts line
end
list << out.string
end
emlist = []
compiler.define_singleton_method(:emlist) do
@f.gets # discard "//emlist{"
out = StringIO.new
@f.until_terminator(%r<\A//\}>) do |line|
out.puts line.rstrip
end
emlist << out.string
end
compiler.define_singleton_method(:method_signature) do |_sig_line, _first|
# stub
end
error_rds = []
def beautify_source(src)
ret = src.gsub(/(?<!\d)\.{3,}(?!-?\d)/, 'foo')
lines = ret.lines
lines.each_with_index do |l, index|
while (l.start_with?('# => ') && lines[index + 1]&.start_with?(' ')) || (l.start_with?('#=> ') && lines[index + 1]&.start_with?(' ')) || (l.start_with?('=> ') && lines[index + 1]&.start_with?(' '))
lines.delete_at(index + 1)
end
if l.start_with?('=> ')
lines[index] = '# ' + l
end
end
ret = lines.join("\n")
ret
end
Dir["refm/**/*"].each do |rd|
next if File.directory?(rd)
src = File.read(rd)
begin
compiler.compile(src)
syntax_error = (list + emlist).reject { |l|
begin
RubyVM::InstructionSequence.compile(beautify_source(l))
true
rescue SyntaxError
if l.include?('[[m:') || l.include?('[[c:') || l.lines.any? {|l| l.start_with?('$ ') }
true
else
false
end
end
}
unless syntax_error.empty?
FileUtils.mkdir_p(File.dirname(File.join('syntax_error', rd)))
File.write(File.join('syntax_error', rd + '.yml'), syntax_error.to_yaml)
end
rescue
$stderr.puts $!.message
error_rds << rd
ensure
list = []
emlist = []
end
end
File.write('error_rds.yml', error_rds.to_yaml) unless error_rds.empty?
@hanachin
Copy link
Author

hanachin commented Sep 1, 2017

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