Module: BitClust::SimpleSearcher

Includes:
NameUtils
Defined in:
lib/bitclust/simplesearcher.rb

Overview

Tiny search engine for BitClust server. Note: loads all the entries onto memory, so first search will be slow.

Constant Summary

Constants included from NameUtils

NameUtils::CHAR_TO_MARK, NameUtils::CHAR_TO_NAME, NameUtils::CLASS_NAME_RE, NameUtils::CLASS_PATH_RE, NameUtils::CONST_PATH_RE, NameUtils::CONST_RE, NameUtils::GVAR_RE, NameUtils::LIBNAME_RE, NameUtils::MARK_TO_CHAR, NameUtils::MARK_TO_NAME, NameUtils::METHOD_NAME_RE, NameUtils::METHOD_SPEC_RE, NameUtils::MID, NameUtils::NAME_TO_CHAR, NameUtils::NAME_TO_MARK, NameUtils::TYPEMARK_RE

Class Method Summary collapse

Methods included from NameUtils

build_method_id, classid2name, classname2id, classname?, decodeid, decodename_fs, decodename_url, display_typemark, encodeid, encodename_fs, encodename_rdocurl, encodename_url, functionname?, gvarname?, html_filename, libid2name, libname2id, libname?, method_spec?, methodid2classid, methodid2libid, methodid2mname, methodid2specparts, methodid2specstring, methodid2typechar, methodid2typemark, methodid2typename, methodname?, split_method_id, split_method_spec, typechar2mark, typechar2name, typechar?, typemark2char, typemark2name, typemark?, typename2char, typename2mark, typename?

Class Method Details

.find_class(db, cname) ⇒ Object



37
38
39
# File 'lib/bitclust/simplesearcher.rb', line 37

def find_class(db, cname)
  db.classes.find_all{|c| /\b#{Regexp.escape(cname)}\w*\z/ =~ c.name }
end

.find_class_method(db, cname, type, mname) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/bitclust/simplesearcher.rb', line 41

def find_class_method(db, cname, type, mname)
  ret = [] #: Array[MethodEntry]
  db.classes.each{|c|
    if /\b#{Regexp.escape(cname)}/ =~ c.name
      ret += c.methods.find_all{|m|
        m.names.any?{|n| /\A#{Regexp.escape(mname)}/ =~ n }
      }
    end
  }
  ret
end

.find_methods(db, mname) ⇒ Object



53
54
55
56
57
# File 'lib/bitclust/simplesearcher.rb', line 53

def find_methods(db, mname)
  db.methods.find_all{|m|
    m.names.any?{|n| /\A#{Regexp.escape(mname)}/ =~ n }
  }
end

.find_special_vars(db, mname) ⇒ Object



59
60
61
62
63
# File 'lib/bitclust/simplesearcher.rb', line 59

def find_special_vars(db, mname)
  db.get_class('Kernel').special_variables.find_all{|m|
    m.names.any?{|n| /\A#{Regexp.escape(mname)}/ =~ n }
  }
end

.parse_method_spec_pattern(pat) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/bitclust/simplesearcher.rb', line 70

def parse_method_spec_pattern(pat)
  if /\s/ =~ pat
    return parse_method_spec_pattern0(pat)
  end
  return pat, nil, nil if /\A[A-Z]\w*\z/ =~ pat
  return nil, '$', $1  if /\$(\S*)/ =~ pat
  # bitclust#250: "?." is an alternate spelling of the module-function
  # separator ".#" (Ruby >=4.0 docs display it that way since #277; see
  # NameUtils.display_typemark). Accept it here regardless of which
  # Ruby version the query is about -- this is query *input*, not
  # display, so both notations are always accepted. "?" is added to the
  # same reversed-pattern alternative that already matches "#." and ",."
  # (a marker character immediately followed by ".", read in the
  # reversed pattern), so "?." matches the same way "#." already does.
  _m, _t, _c = pat.reverse.split(/(::|[\#,]\.|\.[\#,\?]|[\#\.\,])/, 2)
  _m || raise
  c = _c.reverse if _c
  t = _t.tr(',?', '##').sub(/\#\./, '.#') if _t
  m = _m.reverse
  return c, t, m
end

.parse_method_spec_pattern0(pat) ⇒ Object



92
93
94
95
96
97
# File 'lib/bitclust/simplesearcher.rb', line 92

def parse_method_spec_pattern0(pat)
  # @type var q: Array[String]
  q = _ = pat.scan(/\S+/)[0..1]
  q = q.reverse unless /\A[A-Z]/ =~ q[0]
  return q[0], nil, q[1]
end

.search_pattern(db, pat) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/bitclust/simplesearcher.rb', line 13

def search_pattern(db, pat)
  pat = to_pattern(pat)
  return [] if pat.empty? or /\A\s+\z/ =~ pat
  cname, type, mname = parse_method_spec_pattern(pat)
  # @type var cs: Array[ClassEntry]
  # @type var ms: Array[MethodEntry]
  cs = []; ms = []
  if cname and not cname.empty?
    if mname
      ms = find_class_method(db, cname, type, mname)
      cs += find_class(db, cname + '::' + mname) if /\A[A-Z]/ =~ mname
    else
      cs = find_class(db, cname)
    end
  elsif type == '$'
    ms = find_special_vars(db, mname || raise)
  else
    ms = find_methods(db, mname || raise)
  end
  ms = ms.sort_by{|e| [e.library.name, e.klass.name] }
  cs = cs.sort_by{|e| [e.library.name] }
  cs + ms
end

.to_pattern(pat) ⇒ Object



65
66
67
68
# File 'lib/bitclust/simplesearcher.rb', line 65

def to_pattern(pat)
  pat = pat.to_str
  pat = pat[/\A\s*(.*?)\s*\z/, 1] || raise
end