Class: YARD::Handlers::Ruby::ClassConditionHandler

Inherits:
Base
  • Object
show all
Defined in:
lib/yard/handlers/ruby/class_condition_handler.rb

Overview

Matches if/unless conditions inside classes and attempts to process only one branch (by evaluating the condition if possible).

Examples:

A simple class conditional

class Foo
  if 0
    # This method is ignored
    def xyz; end
  end
end

Constant Summary

Constants included from CodeObjects

CodeObjects::BUILTIN_ALL, CodeObjects::BUILTIN_CLASSES, CodeObjects::BUILTIN_EXCEPTIONS, CodeObjects::BUILTIN_EXCEPTIONS_HASH, CodeObjects::BUILTIN_MODULES, CodeObjects::CONSTANTMATCH, CodeObjects::CONSTANTSTART, CodeObjects::CSEP, CodeObjects::CSEPQ, CodeObjects::ISEP, CodeObjects::ISEPQ, CodeObjects::METHODMATCH, CodeObjects::METHODNAMEMATCH, CodeObjects::NAMESPACEMATCH, CodeObjects::NSEP, CodeObjects::NSEPQ

Instance Method Summary collapse

Methods included from Parser::Ruby

#s

Methods included from CodeObjects::NamespaceMapper

#clear_separators, #default_separator, on_invalidate, #register_separator, #separators, #separators_for_type, #separators_match, #types_for_separator, #unregister_separator_by_type

Constructor Details

This class inherits a constructor from YARD::Handlers::Base

Instance Method Details

#parse_conditiontrue, ... (protected)

Parses the condition part of the if/unless statement

Returns:

  • (true, false, nil)

    true if the condition can be definitely parsed to true, false if not, and nil if the condition cannot be parsed with certainty (it’s dynamic)

[View source]

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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
# File 'lib/yard/handlers/ruby/class_condition_handler.rb', line 36

def parse_condition
  condition = nil

  # Right now we can handle very simple unary conditions like:
  #   if true
  #   if false
  #   if 0
  #   if 100 (not 0)
  #   if defined? SOME_CONSTANT
  #
  # The last case will do a lookup in the registry and then one
  # in the Ruby world (using eval).
  case statement.condition.type
  when :int
    condition = statement.condition[0] != "0"
  when :defined
    # defined? keyword used, let's see if we can look up the name
    # in the registry, then we'll try using Ruby's powers. eval() is not
    # *too* dangerous here since code is not actually executed.
    arg = statement.condition.first

    if arg.type == :var_ref
      name = arg.source
      obj = YARD::Registry.resolve(namespace, name, true)

      begin
        condition = true if obj || (name && Object.instance_eval("defined? #{name}"))
      rescue SyntaxError, NameError
        condition = false
      end
    end
  when :var_ref
    var = statement.condition[0]
    if var == s(:kw, "true")
      condition = true
    elsif var == s(:kw, "false")
      condition = false
    end
  end

  # Invert an unless condition
  if statement.type == :unless || statement.type == :unless_mod
    condition = !condition unless condition.nil?
  end
  condition
end

#parse_else_blockObject (protected)

[View source]

87
88
89
90
91
# File 'lib/yard/handlers/ruby/class_condition_handler.rb', line 87

def parse_else_block
  if statement.else_block
    parse_block(statement.else_block, :visibility => visibility)
  end
end

#parse_then_blockObject (protected)

[View source]

83
84
85
# File 'lib/yard/handlers/ruby/class_condition_handler.rb', line 83

def parse_then_block
  parse_block(statement.then_block, :visibility => visibility)
end

#processvoid

This method returns an undefined value.

Main processing callback

[View source]

16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/yard/handlers/ruby/class_condition_handler.rb', line 16

process do
  condition = parse_condition
  if condition.nil?
    # Parse both blocks if we're unsure of the condition
    parse_then_block
    parse_else_block
  elsif condition
    parse_then_block
  else
    parse_else_block
  end
end