Class: Silhouette::MethodFinder

Inherits:
Syntax::Convertors::HTML
  • Object
show all
Defined in:
lib/silhouette/finder.rb

Defined Under Namespace

Classes: ClassPosition, MethodPosition

Constant Summary collapse

HAS_END =
%w!if begin while for until case unless!

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(tok) ⇒ MethodFinder

Returns a new instance of MethodFinder.



38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/silhouette/finder.rb', line 38

def initialize(tok)
  super
  @line_no = 1
  @inner_ends = 0
  @class_path = []
  @class_stack = []
  @modules = []
  @methods = []
  @method_stack = []
  @current_method = nil
  @html = ""
  @line_start = true
end

Instance Attribute Details

#methodsObject (readonly)

Returns the value of attribute methods.



52
53
54
# File 'lib/silhouette/finder.rb', line 52

def methods
  @methods
end

#modulesObject (readonly)

Returns the value of attribute modules.



52
53
54
# File 'lib/silhouette/finder.rb', line 52

def modules
  @modules
end

Instance Method Details

#find(text) ⇒ Object



119
120
121
122
123
# File 'lib/silhouette/finder.rb', line 119

def find(text)
  @tokenizer.tokenize(text) do |tok|
    process_token tok       
  end
end

#process_token(tok) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/silhouette/finder.rb', line 56

def process_token(tok)
  # p [tok, tok.group]
  case tok.group
  when :normal, :string, :constant
    nls = tok.count("\n")
    @line_no += nls
    @line_start = true if nls > 0
  when :class, :module
    # How to handle classes inside conditions? Don't count them.
    return unless @inner_ends == 0
    @class_path << tok.to_s
    klass = ClassPosition.new(@class_path.join("::"))
    klass.first_line = @line_no
    @modules << klass
    @class_stack << klass
    # puts "start class: #{@class_path.inspect}"
  when :method
    return unless @inner_ends == 0
    # Handle nested methods by just ignoring the nested ones.
    if @class_path.last == :def
      @inner_ends += 1
    else
      meth = MethodPosition.new(tok, @class_path.join("::"))
      meth.first_line = @line_no
      @methods << meth
      @method_stack << meth
      @class_path << :def
      # puts "start meth: #{@class_path.inspect}, #{tok}"
    end
  when :keyword
    if HAS_END.include?(tok.to_s) and @line_start
      @inner_ends += 1
      return
    elsif tok == "do"
      @inner_ends += 1
      return
    end
  
    if tok == "end"
      if @inner_ends == 0
        was_in = @class_path.pop
        if was_in == :def
          # puts "Done with method: #{@class_path.inspect}"
          @method_stack.last.last_line = @line_no
          @method_stack.pop
        else
          fin = @class_stack.pop
          if fin
            fin.last_line = @line_no
          end
        end
      else
        @inner_ends -= 1
        # puts "pending ends: #{@inner_ends}"
      end
    end
  end
  
  if tok.group != :normal
    @line_start = false
  end
end