class YARD::Parser::Ruby::TokenResolver
constant or identifier token.
the token and a possible {CodeObjects::Base} associated with the
Supports {#each} enumeration over a source’s tokens, yielding
def self.state_attr(*attrs)
def self.state_attr(*attrs) attrs.each do |attr| define_method(attr) { @states.last[attr.to_sym] } define_method("#{attr}=") {|v| @states.last[attr.to_sym] = v } protected attr, :"#{attr}=" end end
def each
- Example: Yielding code objects -
Other tags:
- Yieldparam: object - the fully qualified code
Yieldparam: token - the
def each @states = [] push_state @tokens.each do |token| yield_obj = false if skip_group && [:const, :ident, :op, :period].include?(token[0]) yield token, nil next else self.skip_group = false end case token[0] when :const lookup(token[0], token[1]) yield_obj = true self.last_sep = nil when :ident lookup(token[0], token[1]) yield_obj = true self.last_sep = nil when :op, :period self.last_sep = token[1] unless CodeObjects.types_for_separator(token[1]) self.object = nil self.last_sep = nil end when :lparen push_state when :rparen pop_state else self.object = nil end yield token, (yield_obj ? object : nil) if next_object self.object = next_object self.next_object = nil end self.skip_group = true if yield_obj && object.nil? end end
def initialize(source, namespace = Registry.root)
-
namespace
(CodeObjects::Base
) -- the object/namespace to resolve from -
source
(String
) -- the source code to tokenize
def initialize(source, namespace = Registry.root) @tokens = RubyParser.parse(source, '(tokenize)').tokens raise ParserSyntaxError if @tokens.empty? && !source.empty? @default_namespace = namespace end
def lookup(toktype, name)
def lookup(toktype, name) types = object_resolved_types return self.object = nil if types.empty? if toktype == :const types.any? do |type| prefix = type ? type.path : "" prefix += last_sep.to_s if separators.include?(last_sep.to_s) self.object = Registry.resolve(@default_namespace, "#{prefix}#{name}", true) end else # ident types.any? do |type| obj = Registry.resolve(type, name, true) if obj.nil? && name == "new" obj = Registry.resolve(object, "#initialize", true) self.next_object = object if obj.nil? end self.object = obj end end end
def object_resolved_types(obj = object)
def object_resolved_types(obj = object) return [obj] unless obj.is_a?(CodeObjects::MethodObject) resolved_types = [] tags = obj.tags(:return) tags += obj.tags(:overload).map {|o| o.tags(:return) }.flatten tags.each do |tag| next if tag.types.nil? tag.types.each do |type| type = type.sub(/<.+>/, '') if type == "self" resolved_types << obj.parent else type_obj = Registry.resolve(obj, type, true) resolved_types << type_obj if type_obj end end end resolved_types end
def pop_state
def pop_state @states.pop end
def push_state
def push_state @states.push :object => nil, :skip_group => false, :last_sep => nil end