Class: YARD::CodeObjects::Proxy

Inherits:
Object
  • Object
show all
Defined in:
lib/yard/code_objects/proxy.rb

Overview

The Proxy class is a way to lazily resolve code objects in cases where the object may not yet exist. A proxy simply stores an unresolved path until a method is called on the object, at which point it does a lookup using Registry.resolve. If the object is not found, a warning is raised and ProxyMethodError might be raised.

Examples:

Creates a Proxy to the String class from a module

# When the String class is parsed this method will
# begin to act like the String ClassObject.
Proxy.new(mymoduleobj, "String")

See Also:

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(namespace, name, type = nil) ⇒ Proxy

Creates a new Proxy

Raises:

  • (ArgumentError)

    if namespace is not a NamespaceObject

[View source]

34
35
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
82
# File 'lib/yard/code_objects/proxy.rb', line 34

def initialize(namespace, name, type = nil)
  namespace = Registry.root if !namespace || namespace == :root

  if name =~ /^#{NSEPQ}/
    namespace = Registry.root
    name = name[2..-1]
  end

  if name =~ PROXY_MATCH
    @orignamespace = namespace
    @origname = name
    @imethod = true if name.include? ISEP
    namespace = Proxy.new(namespace, $`) unless $`.empty?
    name = $1
  else
    @orignamespace = nil
    @origname = nil
    @imethod = nil
  end

  @name = name.to_sym
  @namespace = namespace
  @obj = nil
  @imethod ||= nil
  self.type = type

  if @namespace.is_a?(ConstantObject)
    unless @namespace.value =~ /\A#{NAMESPACEMATCH}\Z/
      raise Parser::UndocumentableError, "constant mapping for " +
        "#{@origname} (type=#{type.inspect})"
    end

    @origname = nil # forget these for a constant
    @orignamespace = nil
    @namespace = Proxy.new(@namespace.namespace, @namespace.value)
  end

  unless @namespace.is_a?(NamespaceObject) || @namespace.is_a?(Proxy)
    raise ArgumentError, "Invalid namespace object: #{namespace}"
  end

  # If the name begins with "::" (like "::String")
  # this is definitely a root level object, so
  # remove the namespace and attach it to the root
  if @name =~ /^#{NSEPQ}/
    @name.gsub!(/^#{NSEPQ}/, '')
    @namespace = Registry.root
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args, &block) ⇒ Object

Dispatches the method to the resolved object.

Raises:

[View source]

178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/yard/code_objects/proxy.rb', line 178

def method_missing(meth, *args, &block)
  if to_obj
    to_obj.__send__(meth, *args, &block)
  else
    log.warn "Load Order / Name Resolution Problem on #{path}:\n" \
             "-\n" \
             "Something is trying to call #{meth} on object #{path} before it has been recognized.\n" \
             "This error usually means that you need to modify the order in which you parse files\n" \
             "so that #{path} is parsed before methods or other objects attempt to access it.\n" \
             "-\n" \
             "YARD will recover from this error and continue to parse but you *may* have problems\n" \
             "with your generated documentation. You should probably fix this.\n" \
             "-\n"
    begin
      super
    rescue NoMethodError
      raise ProxyMethodError, "Proxy cannot call method ##{meth} on object '#{path}'"
    end
  end
end

Instance Attribute Details

#namespaceObject (readonly) Also known as: parent

Returns the value of attribute namespace.


27
28
29
# File 'lib/yard/code_objects/proxy.rb', line 27

def namespace
  @namespace
end

Class Method Details

.===(other) ⇒ Object

[View source]

25
# File 'lib/yard/code_objects/proxy.rb', line 25

def self.===(other) other.is_a?(self) end

Instance Method Details

#<=>(other) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

118
119
120
121
122
123
124
# File 'lib/yard/code_objects/proxy.rb', line 118

def <=>(other)
  if other.respond_to? :path
    path <=> other.path
  else
    false
  end
end

#===(other) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

113
114
115
# File 'lib/yard/code_objects/proxy.rb', line 113

def ===(other)
  to_obj ? to_obj === other : self.class <= other.class
end

#classClass

Returns the class name of the object the proxy is mimicking, if resolved. Otherwise returns Proxy.

Returns:

  • (Class)

    the resolved object’s class or Proxy

[View source]

142
143
144
# File 'lib/yard/code_objects/proxy.rb', line 142

def class
  to_obj ? to_obj.class : Proxy
end

#equal?(other) ⇒ Boolean Also known as: ==

Returns:

  • (Boolean)
[View source]

127
128
129
130
131
132
133
# File 'lib/yard/code_objects/proxy.rb', line 127

def equal?(other)
  if other.respond_to? :path
    path == other.path
  else
    false
  end
end

#hashInteger

Returns the object’s hash value (for equality checking).

Returns:

  • (Integer)

    the object’s hash value (for equality checking)

[View source]

137
# File 'lib/yard/code_objects/proxy.rb', line 137

def hash; path.hash end

#inspectString

Returns a text representation of the Proxy

Returns:

  • (String)

    the object’s #inspect method or P(OBJECTPATH)

[View source]

91
92
93
# File 'lib/yard/code_objects/proxy.rb', line 91

def inspect
  to_obj ? to_obj.inspect : "P(#{path})"
end

#instance_of?(klass) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

161
162
163
# File 'lib/yard/code_objects/proxy.rb', line 161

def instance_of?(klass)
  self.class == klass
end

#is_a?(klass) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

108
109
110
# File 'lib/yard/code_objects/proxy.rb', line 108

def is_a?(klass)
  to_obj ? to_obj.is_a?(klass) : self.class <= klass
end

#kind_of?(klass) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

166
167
168
# File 'lib/yard/code_objects/proxy.rb', line 166

def kind_of?(klass)
  self.class <= klass
end

#name(prefix = false) ⇒ Symbol, String

The name of the object

Parameters:

  • prefix (Boolean) (defaults to: false)

    whether to show a prefix. Implement this in a subclass to define how the prefix is showed.

Returns:

  • (Symbol)

    if prefix is false, the symbolized name

  • (String)

    if prefix is true, prefix + the name as a String. This must be implemented by the subclass.

[View source]

85
86
87
# File 'lib/yard/code_objects/proxy.rb', line 85

def name(prefix = false)
  prefix ? "#{@imethod && ISEP}#{@name}" : @name
end

#pathString Also known as: to_s, to_str, title

If the proxy resolves to an object, returns its path, otherwise guesses at the correct path using the original namespace and name.

Returns:

  • (String)

    the assumed path of the proxy (or the real path of the resolved object)

[View source]

100
101
102
# File 'lib/yard/code_objects/proxy.rb', line 100

def path
  to_obj ? to_obj.path : proxy_path
end

#respond_to?(meth, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

171
172
173
# File 'lib/yard/code_objects/proxy.rb', line 171

def respond_to?(meth, include_private = false)
  to_obj ? to_obj.respond_to?(meth, include_private) : super
end

#root?Boolean

This class is never a root object

Returns:

  • (Boolean)
[View source]

200
# File 'lib/yard/code_objects/proxy.rb', line 200

def root?; false end

#typeSymbol

Returns the type of the proxy. If it cannot be resolved at the time of the call, it will either return the inferred proxy type (see #type=) or :proxy

Returns:

  • (Symbol)

    the Proxy’s type

See Also:

[View source]

151
152
153
# File 'lib/yard/code_objects/proxy.rb', line 151

def type
  to_obj ? to_obj.type : @type || :proxy
end

#type=(type) ⇒ void

This method returns an undefined value.

Allows a parser to infer the type of the proxy by its path.

Parameters:

  • type (#to_sym)

    the proxy’s inferred type

[View source]

158
# File 'lib/yard/code_objects/proxy.rb', line 158

def type=(type) @type = type ? type.to_sym : nil end