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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
class NameMap
MAP = {
'`' => 'backtick',
'+' => 'plus',
'-' => 'minus',
'+@' => 'uplus',
'-@' => 'uminus',
'*' => 'multiply',
'/' => 'divide',
'%' => 'modulo',
'<<' => {'Integer' => 'left_shift',
'IO' => 'output',
:default => 'append' },
'>>' => 'right_shift',
'<' => 'lt',
'<=' => 'lte',
'>' => 'gt',
'>=' => 'gte',
'=' => 'assignment',
'==' => 'equal_value',
'===' => 'case_compare',
'<=>' => 'comparison',
'[]' => 'element_reference',
'[]=' => 'element_set',
'**' => 'exponent',
'!' => 'not',
'~' => {'Integer' => 'complement',
:default => 'match' },
'!=' => 'not_equal',
'!~' => 'not_match',
'=~' => 'match',
'&' => {'Integer' => 'bit_and',
'Array' => 'intersection',
'Set' => 'intersection',
:default => 'and' },
'|' => {'Integer' => 'bit_or',
'Array' => 'union',
'Set' => 'union',
:default => 'or' },
'^' => {'Integer' => 'bit_xor',
'Set' => 'exclusion',
:default => 'xor' },
}
EXCLUDED = %w[
MSpecScript
MkSpec
MSpecOption
MSpecOptions
NameMap
SpecVersion
]
def initialize(filter = false)
@seen = {}
@filter = filter
end
def exception?(name)
return false unless c = class_or_module(name)
c == Errno or c.ancestors.include? Exception
end
def class_or_module(c)
const = Object.const_get(c, false)
filtered = @filter && EXCLUDED.include?(const.name)
return const if Module === const and !filtered
rescue NameError
end
def namespace(mod, const)
return const.to_s if mod.nil? or %w[Object Class Module].include? mod
"#{mod}::#{const}"
end
def map(hash, constants, mod = nil)
@seen = {} unless mod
constants.each do |const|
name = namespace mod, const
m = class_or_module name
next unless m and !@seen[m]
@seen[m] = true
ms = m.methods(false).map { |x| x.to_s }
hash["#{name}."] = ms.sort unless ms.empty?
ms = m.public_instance_methods(false) +
m.protected_instance_methods(false)
ms.map! { |x| x.to_s }
hash["#{name}#"] = ms.sort unless ms.empty?
map hash, m.constants(false), name
end
hash
end
def dir_name(c, base)
return File.join(base, 'exception') if exception? c
c.split('::').inject(base) do |dir, name|
name.gsub!(/Class/, '') unless name == 'Class'
File.join dir, name.downcase
end
end
def file_name(m, c)
if MAP.key?(m)
mapping = MAP[m]
if mapping.is_a?(Hash)
name = mapping[c.split('::').last] || mapping.fetch(:default)
else
name = mapping
end
else
name = m.gsub(/[?!=]/, '')
end
"#{name}_spec.rb"
end
end
|