/
dsl_handler_methods.rb
96 lines (80 loc) · 2.92 KB
/
dsl_handler_methods.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# frozen_string_literal: true
module YARD
module Handlers
module Ruby
module DSLHandlerMethods
include CodeObjects
include Parser
IGNORE_METHODS = Hash[*%w(alias alias_method autoload attr attr_accessor
attr_reader attr_writer extend include module_function public private
protected private_constant private_class_method public_class_method).
map {|n| [n, true] }.flatten]
def handle_comments
return if IGNORE_METHODS[caller_method]
@docstring = statement.comments || ""
@docstring = @docstring.join("\n") if @docstring.is_a?(Array)
attaching = false
if @docstring =~ /^@!?macro\s+\[[^\]]*attach/
register_docstring(nil)
@docstring = ""
attaching = true
end
macro = find_attached_macro
if macro
txt = macro.expand([caller_method, *call_params], statement.source)
@docstring += "\n" + txt
# macro may have a directive
return register_docstring(nil) if !attaching && txt.match(/^\s*@!/)
elsif !statement.comments_hash_flag && !implicit_docstring?
return register_docstring(nil)
end
# ignore DSL definitions if @method/@attribute directive is used
if @docstring =~ /^@!?(method|attribute)\b/
return register_docstring(nil)
end
register MethodObject.new(namespace, method_name, scope) do |o|
o.signature = method_signature
end
end
def register_docstring(object, docstring = @docstring, stmt = statement)
super
end
private
def implicit_docstring?
tags = %w(method attribute overload visibility scope return)
tags.any? {|tag| @docstring =~ /^@!?#{tag}\b/ }
end
def method_name
name = call_params.first || ""
if name =~ /^#{CodeObjects::METHODNAMEMATCH}$/
name
else
raise UndocumentableError, "method, missing name"
end
end
def method_signature
"def #{method_name}"
end
def find_attached_macro
Registry.all(:macro).each do |macro|
next unless macro.method_object
next unless macro_name_matches(macro)
(namespace.inheritance_tree(true) + [P('Object')]).each do |obj|
return macro if obj == macro.method_object.namespace
end
end
nil
end
# @return [Boolean] whether caller method matches a macro or
# its alias names.
def macro_name_matches(macro)
objs = [macro.method_object]
if objs.first.type != :proxy && objs.first.respond_to?(:aliases)
objs.concat(objs.first.aliases)
end
objs.any? {|obj| obj.name.to_s == caller_method.to_s }
end
end
end
end
end