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 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
|
require 'java'
java_import org.jruby.ast.java_signature.PrimitiveTypeNode
java_import org.jruby.ast.java_signature.ArrayTypeNode
java_import org.jruby.parser.JavaSignatureParser
java_import java.io.ByteArrayInputStream
BYTE = PrimitiveTypeNode::BYTE
SHORT = PrimitiveTypeNode::SHORT
INT = PrimitiveTypeNode::INT
LONG = PrimitiveTypeNode::LONG
CHAR = PrimitiveTypeNode::CHAR
FLOAT = PrimitiveTypeNode::FLOAT
DOUBLE = PrimitiveTypeNode::DOUBLE
BOOLEAN = PrimitiveTypeNode::BOOLEAN
VOID = PrimitiveTypeNode::VOID
Override = java.lang.Override
class Object
def signature(string)
bytes = string.to_java.bytes
JavaSignatureParser.parse ByteArrayInputStream.new(bytes)
end
def arrayOf(a_type)
ArrayTypeNode.new(a_type)
end
end
class SimpleConstructorSignatureMatcher
attr_reader :errors
def initialize(*args)
@args, @errors = parse_args(*args), []
end
def parse_args(*args)
# FIXME: Error for other lengths
case args.length
when 2 then # name, params
[[], args[0], args[1], []]
when 3 then # modifiers, name, params
[args[0], args[1], args[2], []]
when 4 then # modifiers, name, params, throws
[args[0], args[1], args[2], args[3]]
end
end
def match_type?(ast_type, expected_type)
if expected_type.kind_of? Symbol
ast_type.to_s == expected_type.to_s
else
ast_type == expected_type
end
end
def match_parameters?(parameters, expected)
return false if parameters.size != expected.size
0.upto(parameters.size - 1) do |i|
return false unless match_type? parameters[i].get_type, expected[i]
end
true
end
def matches?(ast)
modifiers, name, parameters, throws = *@args
@errors << ['modifiers', ast.modifiers, modifiers] unless ast.modifiers.equals? modifiers
@errors << ['name', ast.name, name] unless ast.name == name
@errors << ['parameters', ast.parameters, parameters] unless match_parameters? ast.parameters, parameters
@errors << ['throws', ast.throws, throws] unless ast.throws.equals? throws
@errors.length == 0
end
def failure_message
@errors.inject('') do |memo, item|
memo += "#{item[0]}: "
# FIXME: Add nicer output when array mismatches
memo += "#{item[1].inspect} to equal #{item[2].inspect}\n"
memo
end
end
def negative_failure_message
@errors.inject('') do |memo, item|
memo += "#{item[0]}: "
# FIXME: Add nicer output when array mismatches
memo += "#{item[1].inspect} to not equal #{item[2].inspect}\n"
memo
end
end
end
class SimpleSignatureMatcher
attr_reader :errors
def initialize(*args)
@args, @errors = parse_args(*args), []
end
def parse_args(*args)
# FIXME: Error for other lengths
case args.length
when 3 then # return_type, name, params
[[], args[0], args[1], args[2], []]
when 4 then # modifiers, return_type, name, params
[args[0], args[1], args[2], args[3], []]
when 5 then # modifiers, return_type, name, params, throws
[args[0], args[1], args[2], args[3], args[4]]
end
end
def match_type?(ast_type, expected_type)
if expected_type.kind_of? Symbol
ast_type.to_s == expected_type.to_s
else
ast_type == expected_type
end
end
def match_parameters?(parameters, expected)
return false if parameters.size != expected.size
0.upto(parameters.size - 1) do |i|
return false unless match_type? parameters[i].get_type, expected[i]
end
true
end
def modifiers_match?(modifiers, expected_list)
modifiers.each_with_index do |modifier, i|
return false if modifier != expected_list[i]
end
true
end
def matches?(ast)
modifiers, return_type, name, parameters, throws = *@args
# Mildly brittle to depend on toString, but unlikely to change.
expected_modifiers = modifiers.map(&:to_s)
actual_modifiers = ast.modifiers.map(&:to_s)
@errors << ['modifiers', actual_modifiers, expected_modifiers] unless modifiers_match? actual_modifiers, expected_modifiers
@errors << ['return type', ast.return_type, return_type] unless match_type? ast.return_type.to_s, return_type.to_s
@errors << ['name', ast.name, name] unless ast.name == name
@errors << ['parameters', ast.parameters, parameters] unless match_parameters? ast.parameters, parameters
@errors << ['throws', ast.throws, throws] unless ast.throws.equals? throws
@errors.length == 0
end
def failure_message
@errors.inject('') do |memo, item|
memo += "#{item[0]}: "
# FIXME: Add nicer output when array mismatches
memo += "#{item[1].inspect} to equal #{item[2].inspect}\n"
memo
end
end
def negative_failure_message
@errors.inject('') do |memo, item|
memo += "#{item[0]}: "
# FIXME: Add nicer output when array mismatches
memo += "#{item[1].inspect} to not equal #{item[2].inspect}\n"
memo
end
end
end
class Object
def have_signature(*args)
SimpleSignatureMatcher.new(*args)
end
def have_constructor_signature(*args)
SimpleConstructorSignatureMatcher.new(*args)
end
end
|