actionwebservice 0.6.2 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +21 -0
- data/README +50 -6
- data/Rakefile +9 -9
- data/TODO +6 -6
- data/lib/action_web_service.rb +4 -3
- data/lib/action_web_service/api.rb +248 -1
- data/lib/action_web_service/casting.rb +111 -0
- data/lib/action_web_service/client/soap_client.rb +17 -33
- data/lib/action_web_service/client/xmlrpc_client.rb +10 -34
- data/lib/action_web_service/container/delegated_container.rb +1 -1
- data/lib/action_web_service/dispatcher/abstract.rb +52 -72
- data/lib/action_web_service/dispatcher/action_controller_dispatcher.rb +71 -55
- data/lib/action_web_service/protocol/abstract.rb +82 -3
- data/lib/action_web_service/protocol/discovery.rb +2 -2
- data/lib/action_web_service/protocol/soap_protocol.rb +95 -22
- data/lib/action_web_service/protocol/soap_protocol/marshaler.rb +197 -0
- data/lib/action_web_service/protocol/xmlrpc_protocol.rb +56 -24
- data/lib/action_web_service/scaffolding.rb +237 -0
- data/lib/action_web_service/struct.rb +17 -4
- data/lib/action_web_service/support/signature_types.rb +194 -0
- data/lib/action_web_service/templates/scaffolds/layout.rhtml +65 -0
- data/lib/action_web_service/templates/scaffolds/methods.rhtml +6 -0
- data/lib/action_web_service/templates/scaffolds/parameters.rhtml +28 -0
- data/lib/action_web_service/templates/scaffolds/result.rhtml +30 -0
- data/lib/action_web_service/test_invoke.rb +23 -42
- data/test/abstract_dispatcher.rb +102 -48
- data/test/abstract_unit.rb +1 -1
- data/test/api_test.rb +40 -7
- data/test/casting_test.rb +82 -0
- data/test/client_soap_test.rb +3 -0
- data/test/client_xmlrpc_test.rb +5 -1
- data/test/dispatcher_action_controller_soap_test.rb +9 -12
- data/test/dispatcher_action_controller_xmlrpc_test.rb +1 -11
- data/test/run +1 -0
- data/test/scaffolded_controller_test.rb +67 -0
- data/test/struct_test.rb +33 -21
- data/test/test_invoke_test.rb +1 -1
- metadata +18 -31
- data/lib/action_web_service/api/base.rb +0 -135
- data/lib/action_web_service/vendor/ws.rb +0 -4
- data/lib/action_web_service/vendor/ws/common.rb +0 -8
- data/lib/action_web_service/vendor/ws/encoding.rb +0 -3
- data/lib/action_web_service/vendor/ws/encoding/abstract.rb +0 -26
- data/lib/action_web_service/vendor/ws/encoding/soap_rpc_encoding.rb +0 -90
- data/lib/action_web_service/vendor/ws/encoding/xmlrpc_encoding.rb +0 -53
- data/lib/action_web_service/vendor/ws/marshaling.rb +0 -3
- data/lib/action_web_service/vendor/ws/marshaling/abstract.rb +0 -17
- data/lib/action_web_service/vendor/ws/marshaling/soap_marshaling.rb +0 -277
- data/lib/action_web_service/vendor/ws/marshaling/xmlrpc_marshaling.rb +0 -116
- data/lib/action_web_service/vendor/ws/types.rb +0 -165
- data/test/ws/abstract_encoding.rb +0 -68
- data/test/ws/abstract_unit.rb +0 -13
- data/test/ws/gencov +0 -3
- data/test/ws/run +0 -5
- data/test/ws/soap_marshaling_test.rb +0 -91
- data/test/ws/soap_rpc_encoding_test.rb +0 -47
- data/test/ws/types_test.rb +0 -43
- data/test/ws/xmlrpc_encoding_test.rb +0 -34
data/CHANGELOG
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
*0.7.0* (19th April, 2005)
|
2
|
+
|
3
|
+
* When casting structured types, don't try to send obj.name= unless obj responds to it, causes casting to be less likely to fail for XML-RPC
|
4
|
+
|
5
|
+
* Add scaffolding via ActionController::Base.web_service_scaffold for quick testing using a web browser
|
6
|
+
|
7
|
+
* ActionWebService::API::Base#api_methods now returns a hash containing ActionWebService::API::Method objects instead of hashes. However, ActionWebService::API::Method defines a #[]() backwards compatibility method so any existing code utilizing this will still work.
|
8
|
+
|
9
|
+
* The :layered dispatching mode can now be used with SOAP as well, allowing you to support SOAP and XML-RPC clients for APIs like the metaWeblog API
|
10
|
+
|
11
|
+
* Remove ActiveRecordSoapMarshallable workaround, see #912 for details
|
12
|
+
|
13
|
+
* Generalize casting code to be used by both SOAP and XML-RPC (previously, it was only XML-RPC)
|
14
|
+
|
15
|
+
* Ensure return value is properly cast as well, fixes XML-RPC interoperability with Ecto and possibly other clients
|
16
|
+
|
17
|
+
* Include backtraces in 500 error responses for failed request parsing, and remove "rescue nil" statements obscuring real errors for XML-RPC
|
18
|
+
|
19
|
+
* Perform casting of struct members even if the structure is already of the correct type, so that the type we specify for the struct member is always the type of the value seen by the API implementation
|
20
|
+
|
21
|
+
|
1
22
|
*0.6.2* (27th March, 2005)
|
2
23
|
|
3
24
|
* Allow method declarations for direct dispatching to declare parameters as well. We treat an arity of < 0 or > 0 as an indication that we should send through parameters. Closes #939.
|
data/README
CHANGED
@@ -162,11 +162,10 @@ This mode is similar to _delegated_ mode, in that multiple web service objects
|
|
162
162
|
can be attached to one controller, however, all protocol requests are sent to a
|
163
163
|
single endpoint.
|
164
164
|
|
165
|
-
|
166
|
-
|
167
|
-
|
165
|
+
Use this mode when you want to share code between XML-RPC and SOAP clients,
|
166
|
+
for APIs where the XML-RPC method names have prefixes. An example of such
|
167
|
+
a method name would be <tt>blogger.newPost</tt>.
|
168
168
|
|
169
|
-
The _prefix_ can be any word, followed by a period.
|
170
169
|
|
171
170
|
==== Layered dispatching example
|
172
171
|
|
@@ -192,11 +191,56 @@ The _prefix_ can be any word, followed by a period.
|
|
192
191
|
end
|
193
192
|
|
194
193
|
|
195
|
-
For this example,
|
196
|
-
<tt>mt.getCategories</tt> will be
|
194
|
+
For this example, an XML-RPC call for a method with a name like
|
195
|
+
<tt>mt.getCategories</tt> will be sent to the <tt>getCategories</tt>
|
197
196
|
method on the <tt>:mt</tt> service.
|
198
197
|
|
199
198
|
|
199
|
+
== Testing your APIs
|
200
|
+
|
201
|
+
|
202
|
+
=== Functional testing
|
203
|
+
|
204
|
+
You can perform testing of your APIs by creating a functional test for the
|
205
|
+
controller dispatching the API, and calling #invoke in the test case to
|
206
|
+
perform the invocation.
|
207
|
+
|
208
|
+
Example:
|
209
|
+
|
210
|
+
class PersonApiControllerTest < Test::Unit::TestCase
|
211
|
+
def setup
|
212
|
+
@controller = PersonController.new
|
213
|
+
@request = ActionController::TestRequest.new
|
214
|
+
@response = ActionController::TestResponse.new
|
215
|
+
end
|
216
|
+
|
217
|
+
def test_add
|
218
|
+
result = invoke :remove, 1
|
219
|
+
assert_equal true, result
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
This example invokes the API method <tt>test</tt>, defined on
|
224
|
+
the PersonController, and returns the result.
|
225
|
+
|
226
|
+
|
227
|
+
=== Scaffolding
|
228
|
+
|
229
|
+
You can also test your APIs with a web browser by attaching scaffolding
|
230
|
+
to the controller.
|
231
|
+
|
232
|
+
Example:
|
233
|
+
|
234
|
+
class PersonController
|
235
|
+
web_service_scaffold :invocation
|
236
|
+
end
|
237
|
+
|
238
|
+
This creates an action named <tt>invocation</tt> on the PersonController.
|
239
|
+
|
240
|
+
Navigating to this action lets you select the method to invoke, supply the parameters,
|
241
|
+
and view the result of the invocation.
|
242
|
+
|
243
|
+
|
200
244
|
== Using the client support
|
201
245
|
|
202
246
|
Action Web Service includes client classes that can use the same API
|
data/Rakefile
CHANGED
@@ -9,7 +9,7 @@ require 'fileutils'
|
|
9
9
|
|
10
10
|
PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
|
11
11
|
PKG_NAME = 'actionwebservice'
|
12
|
-
PKG_VERSION = '0.
|
12
|
+
PKG_VERSION = '0.7.0' + PKG_BUILD
|
13
13
|
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
14
14
|
PKG_DESTINATION = ENV["RAILS_PKG_DESTINATION"] || "../#{PKG_NAME}"
|
15
15
|
|
@@ -25,7 +25,7 @@ task :default => [ :test ]
|
|
25
25
|
# Run the unit tests
|
26
26
|
Rake::TestTask.new { |t|
|
27
27
|
t.libs << "test"
|
28
|
-
t.test_files = Dir['test/*_test.rb']
|
28
|
+
t.test_files = Dir['test/*_test.rb']
|
29
29
|
t.verbose = true
|
30
30
|
}
|
31
31
|
|
@@ -62,9 +62,9 @@ spec = Gem::Specification.new do |s|
|
|
62
62
|
s.rubyforge_project = "aws"
|
63
63
|
s.homepage = "http://www.rubyonrails.org"
|
64
64
|
|
65
|
-
s.add_dependency('actionpack', '= 1.
|
66
|
-
s.add_dependency('activerecord', '= 1.
|
67
|
-
s.add_dependency('activesupport', '= 1.0.
|
65
|
+
s.add_dependency('actionpack', '= 1.8.0' + PKG_BUILD)
|
66
|
+
s.add_dependency('activerecord', '= 1.10.0' + PKG_BUILD)
|
67
|
+
s.add_dependency('activesupport', '= 1.0.4' + PKG_BUILD)
|
68
68
|
|
69
69
|
s.has_rdoc = true
|
70
70
|
s.requirements << 'none'
|
@@ -86,14 +86,14 @@ end
|
|
86
86
|
# Publish beta gem
|
87
87
|
desc "Publish the API documentation"
|
88
88
|
task :pgem => [:package] do
|
89
|
-
Rake::SshFilePublisher.new("davidhh@
|
90
|
-
`ssh davidhh@
|
89
|
+
Rake::SshFilePublisher.new("davidhh@wrath.rubyonrails.com", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
|
90
|
+
`ssh davidhh@wrath.rubyonrails.com './gemupdate.sh'`
|
91
91
|
end
|
92
92
|
|
93
93
|
# Publish documentation
|
94
94
|
desc "Publish the API documentation"
|
95
95
|
task :pdoc => [:rdoc] do
|
96
|
-
Rake::SshDirPublisher.new("davidhh@
|
96
|
+
Rake::SshDirPublisher.new("davidhh@wrath.rubyonrails.com", "public_html/aws", "doc").upload
|
97
97
|
end
|
98
98
|
|
99
99
|
|
@@ -264,4 +264,4 @@ task :release => [:package] do
|
|
264
264
|
first_file = false
|
265
265
|
end
|
266
266
|
end
|
267
|
-
end
|
267
|
+
end
|
data/TODO
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
= 0.7.0
|
2
|
-
- WS Dynamic Scaffolding
|
3
|
-
- WS Scaffolding Generators
|
4
|
-
|
5
1
|
= 0.8.0
|
6
|
-
-
|
2
|
+
- Allow locking down a controller to only accept messages for a particular protocol.
|
3
|
+
This will allow us to generate fully conformant error messages in cases where we
|
4
|
+
currently fudge it if we don't know the protocol.
|
5
|
+
|
6
|
+
- Allow AWS user to participate in typecasting, so they can centralize workarounds
|
7
|
+
for buggy input in one place
|
7
8
|
|
8
9
|
= Refactoring
|
9
|
-
- Port dispatcher tests to use test_invoke
|
10
10
|
- Don't have clean way to go from SOAP Class object to the xsd:NAME type
|
11
11
|
string -- NaHi possibly looking at remedying this situation
|
data/lib/action_web_service.rb
CHANGED
@@ -35,17 +35,17 @@ end
|
|
35
35
|
$:.unshift(File.dirname(__FILE__) + "/action_web_service/vendor/")
|
36
36
|
|
37
37
|
require 'action_web_service/support/class_inheritable_options'
|
38
|
-
require 'action_web_service/
|
39
|
-
|
38
|
+
require 'action_web_service/support/signature_types'
|
40
39
|
require 'action_web_service/base'
|
41
40
|
require 'action_web_service/client'
|
42
41
|
require 'action_web_service/invocation'
|
43
42
|
require 'action_web_service/api'
|
43
|
+
require 'action_web_service/casting'
|
44
44
|
require 'action_web_service/struct'
|
45
45
|
require 'action_web_service/container'
|
46
46
|
require 'action_web_service/protocol'
|
47
|
-
require 'action_web_service/struct'
|
48
47
|
require 'action_web_service/dispatcher'
|
48
|
+
require 'action_web_service/scaffolding'
|
49
49
|
|
50
50
|
ActionWebService::Base.class_eval do
|
51
51
|
include ActionWebService::Container::Direct
|
@@ -61,4 +61,5 @@ ActionController::Base.class_eval do
|
|
61
61
|
include ActionWebService::Container::ActionController
|
62
62
|
include ActionWebService::Dispatcher
|
63
63
|
include ActionWebService::Dispatcher::ActionController
|
64
|
+
include ActionWebService::Scaffolding
|
64
65
|
end
|
@@ -1 +1,248 @@
|
|
1
|
-
|
1
|
+
module ActionWebService # :nodoc:
|
2
|
+
module API # :nodoc:
|
3
|
+
# A web service API class specifies the methods that will be available for
|
4
|
+
# invocation for an API. It also contains metadata such as the method type
|
5
|
+
# signature hints.
|
6
|
+
#
|
7
|
+
# It is not intended to be instantiated.
|
8
|
+
#
|
9
|
+
# It is attached to web service implementation classes like
|
10
|
+
# ActionWebService::Base and ActionController::Base derivatives by using
|
11
|
+
# ClassMethods#web_service_api.
|
12
|
+
class Base
|
13
|
+
# Whether to transform the public API method names into camel-cased names
|
14
|
+
class_inheritable_option :inflect_names, true
|
15
|
+
|
16
|
+
# Whether to allow ActiveRecord::Base models in <tt>:expects</tt>.
|
17
|
+
# The default is +false+, you should be aware of the security implications
|
18
|
+
# of allowing this, and ensure that you don't allow remote callers to
|
19
|
+
# easily overwrite data they should not have access to.
|
20
|
+
class_inheritable_option :allow_active_record_expects, false
|
21
|
+
|
22
|
+
# If present, the name of a method to call when the remote caller
|
23
|
+
# tried to call a nonexistent method. Semantically equivalent to
|
24
|
+
# +method_missing+.
|
25
|
+
class_inheritable_option :default_api_method
|
26
|
+
|
27
|
+
# Disallow instantiation
|
28
|
+
private_class_method :new, :allocate
|
29
|
+
|
30
|
+
class << self
|
31
|
+
include ActionWebService::SignatureTypes
|
32
|
+
|
33
|
+
# API methods have a +name+, which must be the Ruby method name to use when
|
34
|
+
# performing the invocation on the web service object.
|
35
|
+
#
|
36
|
+
# The signatures for the method input parameters and return value can
|
37
|
+
# by specified in +options+.
|
38
|
+
#
|
39
|
+
# A signature is an array of one or more parameter specifiers.
|
40
|
+
# A parameter specifier can be one of the following:
|
41
|
+
#
|
42
|
+
# * A symbol or string of representing one of the Action Web Service base types.
|
43
|
+
# See ActionWebService::Signature for a canonical list of the base types.
|
44
|
+
# * The Class object of the parameter type
|
45
|
+
# * A single-element Array containing one of the two preceding items. This
|
46
|
+
# will cause Action Web Service to treat the parameter at that position
|
47
|
+
# as an array containing only values of the given type.
|
48
|
+
# * A Hash containing as key the name of the parameter, and as value
|
49
|
+
# one of the three preceding items
|
50
|
+
#
|
51
|
+
# If no method input parameter or method return value signatures are given,
|
52
|
+
# the method is assumed to take no parameters and/or return no values of
|
53
|
+
# interest, and any values that are received by the server will be
|
54
|
+
# discarded and ignored.
|
55
|
+
#
|
56
|
+
# Valid options:
|
57
|
+
# [<tt>:expects</tt>] Signature for the method input parameters
|
58
|
+
# [<tt>:returns</tt>] Signature for the method return value
|
59
|
+
# [<tt>:expects_and_returns</tt>] Signature for both input parameters and return value
|
60
|
+
def api_method(name, options={})
|
61
|
+
unless options.is_a?(Hash)
|
62
|
+
raise(ActionWebServiceError, "Expected a Hash for options")
|
63
|
+
end
|
64
|
+
validate_options([:expects, :returns, :expects_and_returns], options.keys)
|
65
|
+
if options[:expects_and_returns]
|
66
|
+
expects = options[:expects_and_returns]
|
67
|
+
returns = options[:expects_and_returns]
|
68
|
+
else
|
69
|
+
expects = options[:expects]
|
70
|
+
returns = options[:returns]
|
71
|
+
end
|
72
|
+
expects = canonical_signature(expects)
|
73
|
+
returns = canonical_signature(returns)
|
74
|
+
if expects
|
75
|
+
expects.each do |type|
|
76
|
+
type = type.element_type if type.is_a?(ArrayType)
|
77
|
+
if type.type_class.ancestors.include?(ActiveRecord::Base) && !allow_active_record_expects
|
78
|
+
raise(ActionWebServiceError, "ActiveRecord model classes not allowed in :expects")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
name = name.to_sym
|
83
|
+
public_name = public_api_method_name(name)
|
84
|
+
method = Method.new(name, public_name, expects, returns)
|
85
|
+
write_inheritable_hash("api_methods", name => method)
|
86
|
+
write_inheritable_hash("api_public_method_names", public_name => name)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Whether the given method name is a service method on this API
|
90
|
+
def has_api_method?(name)
|
91
|
+
api_methods.has_key?(name)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Whether the given public method name has a corresponding service method
|
95
|
+
# on this API
|
96
|
+
def has_public_api_method?(public_name)
|
97
|
+
api_public_method_names.has_key?(public_name)
|
98
|
+
end
|
99
|
+
|
100
|
+
# The corresponding public method name for the given service method name
|
101
|
+
def public_api_method_name(name)
|
102
|
+
if inflect_names
|
103
|
+
name.to_s.camelize
|
104
|
+
else
|
105
|
+
name.to_s
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# The corresponding service method name for the given public method name
|
110
|
+
def api_method_name(public_name)
|
111
|
+
api_public_method_names[public_name]
|
112
|
+
end
|
113
|
+
|
114
|
+
# A Hash containing all service methods on this API, and their
|
115
|
+
# associated metadata.
|
116
|
+
def api_methods
|
117
|
+
read_inheritable_attribute("api_methods") || {}
|
118
|
+
end
|
119
|
+
|
120
|
+
# The Method instance for the given public API method name, if any
|
121
|
+
def public_api_method_instance(public_method_name)
|
122
|
+
api_method_instance(api_method_name(public_method_name))
|
123
|
+
end
|
124
|
+
|
125
|
+
# The Method instance for the given API method name, if any
|
126
|
+
def api_method_instance(method_name)
|
127
|
+
api_methods[method_name]
|
128
|
+
end
|
129
|
+
|
130
|
+
# The Method instance for the default API method, if any
|
131
|
+
def default_api_method_instance
|
132
|
+
return nil unless name = default_api_method
|
133
|
+
instance = read_inheritable_attribute("default_api_method_instance")
|
134
|
+
if instance && instance.name == name
|
135
|
+
return instance
|
136
|
+
end
|
137
|
+
instance = Method.new(name, public_api_method_name(name), nil, nil)
|
138
|
+
write_inheritable_attribute("default_api_method_instance", instance)
|
139
|
+
instance
|
140
|
+
end
|
141
|
+
|
142
|
+
private
|
143
|
+
def api_public_method_names
|
144
|
+
read_inheritable_attribute("api_public_method_names") || {}
|
145
|
+
end
|
146
|
+
|
147
|
+
def validate_options(valid_option_keys, supplied_option_keys)
|
148
|
+
unknown_option_keys = supplied_option_keys - valid_option_keys
|
149
|
+
unless unknown_option_keys.empty?
|
150
|
+
raise(ActionWebServiceError, "Unknown options: #{unknown_option_keys}")
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
# Represents an API method and its associated metadata, and provides functionality
|
157
|
+
# to assist in commonly performed API method tasks.
|
158
|
+
class Method
|
159
|
+
attr :name
|
160
|
+
attr :public_name
|
161
|
+
attr :expects
|
162
|
+
attr :returns
|
163
|
+
|
164
|
+
def initialize(name, public_name, expects, returns)
|
165
|
+
@name = name
|
166
|
+
@public_name = public_name
|
167
|
+
@expects = expects
|
168
|
+
@returns = returns
|
169
|
+
@caster = ActionWebService::Casting::BaseCaster.new(self)
|
170
|
+
end
|
171
|
+
|
172
|
+
# The list of parameter names for this method
|
173
|
+
def param_names
|
174
|
+
return [] unless @expects
|
175
|
+
@expects.map{ |type| type.name }
|
176
|
+
end
|
177
|
+
|
178
|
+
# Casts a set of Ruby values into the expected Ruby values
|
179
|
+
def cast_expects(params)
|
180
|
+
@caster.cast_expects(params)
|
181
|
+
end
|
182
|
+
|
183
|
+
# Cast a Ruby return value into the expected Ruby value
|
184
|
+
def cast_returns(return_value)
|
185
|
+
@caster.cast_returns(return_value)
|
186
|
+
end
|
187
|
+
|
188
|
+
# Returns the index of the first expected parameter
|
189
|
+
# with the given name
|
190
|
+
def expects_index_of(param_name)
|
191
|
+
return -1 if @expects.nil?
|
192
|
+
(0..(@expects.length-1)).each do |i|
|
193
|
+
return i if @expects[i].name.to_s == param_name.to_s
|
194
|
+
end
|
195
|
+
-1
|
196
|
+
end
|
197
|
+
|
198
|
+
# Returns a hash keyed by parameter name for the given
|
199
|
+
# parameter list
|
200
|
+
def expects_to_hash(params)
|
201
|
+
return {} if @expects.nil?
|
202
|
+
h = {}
|
203
|
+
@expects.zip(params){ |type, param| h[type.name] = param }
|
204
|
+
h
|
205
|
+
end
|
206
|
+
|
207
|
+
# Backwards compatibility with previous API
|
208
|
+
def [](sig_type)
|
209
|
+
case sig_type
|
210
|
+
when :expects
|
211
|
+
@expects.map{|x| compat_signature_entry(x)}
|
212
|
+
when :returns
|
213
|
+
@returns.map{|x| compat_signature_entry(x)}
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
# String representation of this method
|
218
|
+
def to_s
|
219
|
+
fqn = ""
|
220
|
+
fqn << (@returns ? (friendly_param(@returns[0], false) + " ") : "void ")
|
221
|
+
fqn << "#{@public_name}("
|
222
|
+
fqn << @expects.map{ |p| friendly_param(p) }.join(", ") if @expects
|
223
|
+
fqn << ")"
|
224
|
+
fqn
|
225
|
+
end
|
226
|
+
|
227
|
+
private
|
228
|
+
def compat_signature_entry(entry)
|
229
|
+
if entry.array?
|
230
|
+
[compat_signature_entry(entry.element_type)]
|
231
|
+
else
|
232
|
+
if entry.spec.is_a?(Hash)
|
233
|
+
{entry.spec.keys.first => entry.type_class}
|
234
|
+
else
|
235
|
+
entry.type_class
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
def friendly_param(type, show_name=true)
|
241
|
+
name = type.name.to_s
|
242
|
+
type_type = type.array?? type.element_type.type.to_s : type.type.to_s
|
243
|
+
str = type.array?? (type_type + '[]') : type_type
|
244
|
+
show_name ? (str + " " + name) : str
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|