Class: Mirah::AST::MethodDefinition
- Defined in:
- lib/mirah/ast/method.rb,
lib/mirah/compiler/method.rb
Direct Known Subclasses
ConstructorDefinition, JsniMethodDefinition, StaticMethodDefinition
Instance Attribute Summary collapse
-
#abstract ⇒ Object
Returns the value of attribute abstract.
-
#defining_class ⇒ Object
Returns the value of attribute defining_class.
-
#exceptions ⇒ Object
TODO change return_type to a child if we remove the ‘returns’ macro.
-
#return_type ⇒ Object
TODO change return_type to a child if we remove the ‘returns’ macro.
-
#visibility ⇒ Object
Returns the value of attribute visibility.
Attributes included from Scope
Attributes included from Annotated
Attributes inherited from Node
#children, #inferred_type, #newline, #parent, #position
Instance Method Summary collapse
- #abstract? ⇒ Boolean
- #compile(compiler, expression) ⇒ Object
- #infer(typer, expression) ⇒ Object
-
#initialize(parent, line_number, name, annotations = [], &block) ⇒ MethodDefinition
constructor
A new instance of MethodDefinition.
- #name ⇒ Object
- #resolve_if(typer) ⇒ Object
- #static? ⇒ Boolean
Methods included from Binding
#binding_type, #binding_type=, #has_binding?
Methods included from ClassScoped
Methods included from Scoped
Methods included from Named
#string_value, #to_s, #validate_name
Methods included from Annotated
Methods inherited from Node
#<<, ===, #[], #[]=, #_dump, _load, #_set_parent, child, child_name, #child_nodes, #each, #empty?, #expr?, #inferred_type!, #initialize_copy, #insert, #inspect, #inspect_children, #line_number, #log, #precompile, #resolved!, #resolved?, #simple_name, #string_value, #temp, #to_s, #top_level?, #validate_child, #validate_children
Constructor Details
#initialize(parent, line_number, name, annotations = [], &block) ⇒ MethodDefinition
Returns a new instance of MethodDefinition.
226 227 228 229 230 231 |
# File 'lib/mirah/ast/method.rb', line 226 def initialize(parent, line_number, name, annotations=[], &block) @annotations = annotations super(parent, line_number, &block) self.name = name @visibility = (class_scope && class_scope.current_access_level) || :public end |
Instance Attribute Details
#abstract ⇒ Object
Returns the value of attribute abstract.
224 225 226 |
# File 'lib/mirah/ast/method.rb', line 224 def abstract @abstract end |
#defining_class ⇒ Object
Returns the value of attribute defining_class.
222 223 224 |
# File 'lib/mirah/ast/method.rb', line 222 def defining_class @defining_class end |
#exceptions ⇒ Object
TODO change return_type to a child if we remove the ‘returns’ macro.
220 221 222 |
# File 'lib/mirah/ast/method.rb', line 220 def exceptions @exceptions end |
#return_type ⇒ Object
TODO change return_type to a child if we remove the ‘returns’ macro.
220 221 222 |
# File 'lib/mirah/ast/method.rb', line 220 def return_type @return_type end |
#visibility ⇒ Object
Returns the value of attribute visibility.
223 224 225 |
# File 'lib/mirah/ast/method.rb', line 223 def visibility @visibility end |
Instance Method Details
#abstract? ⇒ Boolean
324 325 326 |
# File 'lib/mirah/ast/method.rb', line 324 def abstract? @abstract || InterfaceDeclaration === class_scope end |
#compile(compiler, expression) ⇒ Object
28 29 30 31 32 33 |
# File 'lib/mirah/compiler/method.rb', line 28 def compile(compiler, expression) # TODO: what does it mean for a method to be an expression? compiler.define_method(self) rescue Exception => ex raise Mirah::InternalCompilerError.wrap(ex, self) end |
#infer(typer, expression) ⇒ Object
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
# File 'lib/mirah/ast/method.rb', line 237 def infer(typer, expression) resolve_if(typer) do @defining_class ||= begin static_scope.self_node = :self static_scope.self_type = if static? scope.static_scope.self_type. else scope.static_scope.self_type end end @annotations.each {|a| a.infer(typer, true)} if @annotations typer.infer(arguments, true) if @return_type if @return_type.kind_of?(UnquotedValue) @return_type = @return_type.node @return_type.parent = self else @return_type.parent = self end signature[:return] = @return_type.type_reference(typer) end if @exceptions signature[:throws] = @exceptions.map {|e| e.type_reference(typer)} end typer.infer_signature(self) forced_type = signature[:return] body_is_expression = (forced_type != typer.no_type) inferred_type = body ? typer.infer(body, body_is_expression) : typer.no_type if inferred_type && arguments.inferred_type.all? actual_type = if forced_type forced_type else inferred_type end if actual_type.kind_of? Mirah::AST::InlineCode raise Mirah::Typer::InferenceError.new("Method %s has the same signature as macro of the same name." % name,self) end if actual_type.unreachable? actual_type = typer.no_type end if !abstract? && forced_type != typer.no_type && !actual_type.is_parent(inferred_type) raise Mirah::Typer::InferenceError.new( "Inferred return type %s is incompatible with declared %s" % [inferred_type, actual_type], self) end signature[:return] = actual_type end end end |
#name ⇒ Object
233 234 235 |
# File 'lib/mirah/ast/method.rb', line 233 def name super end |
#resolve_if(typer) ⇒ Object
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 |
# File 'lib/mirah/ast/method.rb', line 295 def resolve_if(typer) super(typer) do actual_type = type = yield argument_types = arguments.inferred_type # If we know the return type go ahead and tell the typer # even if we can't infer the body yet. type ||= signature[:return] if argument_types && argument_types.all? if type argument_types ||= [Mirah::AST.error_type] if type.error? typer.learn_method_type(defining_class, name, argument_types, type, signature[:throws]) # learn the other overloads as well args_for_opt = [] if arguments.args arguments.args.each do |arg| if OptionalArgument === arg arg_types_for_opt = args_for_opt.map do |arg_for_opt| arg_for_opt.infer(typer, true) end typer.learn_method_type(defining_class, name, arg_types_for_opt, type, signature[:throws]) end args_for_opt << arg end end end actual_type end end |
#static? ⇒ Boolean
328 329 330 |
# File 'lib/mirah/ast/method.rb', line 328 def static? scope.static_scope.self_type. end |