Class: Duby::AST::MethodDefinition

Inherits:
Node show all
Includes:
Named, Scope
Defined in:
lib/duby/compiler.rb,
lib/duby/ast/method.rb

Direct Known Subclasses

StaticMethodDefinition

Instance Attribute Summary collapse

Attributes included from Named

#name

Attributes inherited from Node

#children, #inferred_type, #newline, #parent, #position

Instance Method Summary collapse

Methods included from Named

#to_s

Methods inherited from Node

#[], #each, #expr?, #inspect, #line_number, #log, #precompile, #resolve_if, #resolved!, #resolved?, #simple_name, #temp, #to_s

Constructor Details

#initialize(parent, line_number, name, &block) ⇒ MethodDefinition

Returns a new instance of MethodDefinition.



110
111
112
113
114
# File 'lib/duby/ast/method.rb', line 110

def initialize(parent, line_number, name, &block)
  super(parent, line_number, &block)
  @signature, @arguments, @body = children
  @name = name
end

Instance Attribute Details

#argumentsObject

Returns the value of attribute arguments.



108
109
110
# File 'lib/duby/ast/method.rb', line 108

def arguments
  @arguments
end

#bodyObject

Returns the value of attribute body.



108
109
110
# File 'lib/duby/ast/method.rb', line 108

def body
  @body
end

#defining_classObject

Returns the value of attribute defining_class.



108
109
110
# File 'lib/duby/ast/method.rb', line 108

def defining_class
  @defining_class
end

#signatureObject

Returns the value of attribute signature.



108
109
110
# File 'lib/duby/ast/method.rb', line 108

def signature
  @signature
end

Instance Method Details

#abstract?Boolean

Returns:



165
166
167
168
169
170
171
# File 'lib/duby/ast/method.rb', line 165

def abstract?
  node = parent
  while node && !node.kind_of?(Scope)
    node = node.parent
  end
  InterfaceDeclaration === node
end

#compile(compiler, expression) ⇒ Object



103
104
105
106
# File 'lib/duby/compiler.rb', line 103

def compile(compiler, expression)
  # TODO: what does it mean for a method to be an expression?
  compiler.define_method(name, signature, arguments, body, static?)
end

#infer(typer) ⇒ Object



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
# File 'lib/duby/ast/method.rb', line 116

def infer(typer)
  @defining_class ||= typer.self_type
  typer.infer(arguments)
  typer.infer_signature(self)
  forced_type = signature[:return]
  inferred_type = body ? typer.infer(body) : typer.no_type
    
  if !inferred_type
    typer.defer(self)
  else
    actual_type = if forced_type.nil?
      inferred_type
    else
      forced_type
    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 Duby::Typer::InferenceError.new(
          "Inferred return type %s is incompatible with declared %s" %
          [inferred_type, actual_type], self)
    end

    @inferred_type = typer.learn_method_type(defining_class, name, arguments.inferred_type, actual_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)
          end
          typer.learn_method_type(defining_class, name, arg_types_for_opt, actual_type, signature[:throws])
        end
        args_for_opt << arg
      end
    end

    signature[:return] = @inferred_type
  end
    
  @inferred_type
end

#static?Boolean

Returns:



173
174
175
# File 'lib/duby/ast/method.rb', line 173

def static?
  false
end