Class: Duby::AST::ClassDefinition

Inherits:
Node
  • Object
show all
Includes:
Annotated, Named, Scope
Defined in:
lib/duby/compiler.rb,
lib/duby/ast/class.rb

Direct Known Subclasses

ClosureDefinition, InterfaceDeclaration

Instance Attribute Summary collapse

Attributes included from Scope

#static_scope

Attributes included from Named

#name

Attributes included from Annotated

#annotations

Attributes inherited from Node

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

Instance Method Summary collapse

Methods included from Named

#to_s

Methods included from Annotated

#annotation

Methods inherited from Node

#<<, ===, #[], #_set_parent, child, child_name, #each, #empty?, #expr?, #initialize_copy, #insert, #inspect, #line_number, #log, #precompile, #resolve_if, #resolved!, #resolved?, #simple_name, #temp, #to_s

Constructor Details

#initialize(parent, position, name, annotations = [], &block) ⇒ ClassDefinition

Returns a new instance of ClassDefinition.



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/duby/ast/class.rb', line 11

def initialize(parent, position, name, annotations=[], &block)
  @annotations = annotations
  @interfaces = []
  @name = name
  if Duby::AST.type_factory.respond_to? :declare_type
    Duby::AST.type_factory.declare_type(self)
  end
  # We need somewhere to collect nodes that get appended during
  # the transform phase.
  @extra_body = Body.new(self, position)
  super(parent, position, &block)
  if body
    @extra_body.insert(0, body)
  end
  self.body = @extra_body
end

Instance Attribute Details

#interfacesObject

Returns the value of attribute interfaces.



6
7
8
# File 'lib/duby/ast/class.rb', line 6

def interfaces
  @interfaces
end

Instance Method Details

#_define_method(klass, position, name, type, args) ⇒ Object



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

def _define_method(klass, position, name, type, args)
  klass.new(nil, position, name) do |method|
    signature = {:return => type}
    if Arguments === args[0]
      args_node = args[0]
      args_node.parent = method
    else
      args_node = Arguments.new(method, position) do |args_node|
        arg_list = args.map do |arg_name, arg_type, arg_position|
          signature[arg_name.intern] = arg_type
          arg_position ||= position
          RequiredArgument.new(args_node, arg_position, arg_name)
        end
        [arg_list, nil, nil, nil]
      end
    end
    [
      signature,
      args_node,
      if block_given?
        yield(method)
      end
    ]
  end
end

#append_node(node) ⇒ Object



28
29
30
31
# File 'lib/duby/ast/class.rb', line 28

def append_node(node)
  @extra_body << node
  node
end

#compile(compiler, expression) ⇒ Object



219
220
221
# File 'lib/duby/compiler.rb', line 219

def compile(compiler, expression)
  compiler.define_class(self, expression)
end

#declare_field(position, name, type) ⇒ Object



78
79
80
81
82
# File 'lib/duby/ast/class.rb', line 78

def declare_field(position, name, type)
  field = FieldDeclaration.new(nil, position || self.position, name)
  field.type = type.dup
  append_node(field)
end

#define_constructor(position, *args, &block) ⇒ Object



47
48
49
50
# File 'lib/duby/ast/class.rb', line 47

def define_constructor(position, *args, &block)
  append_node(_define_method(
      ConstructorDefinition, position, 'initialize', nil, args, &block))
end

#define_inner_class(position, name, &block) ⇒ Object



33
34
35
36
# File 'lib/duby/ast/class.rb', line 33

def define_inner_class(position, name, &block)
  name = "#{self.name}$#{name}"
  append_node ClassDefinition.new(nil, position, name, &block)
end

#define_method(position, name, type, *args) ⇒ Object



38
39
40
# File 'lib/duby/ast/class.rb', line 38

def define_method(position, name, type, *args)
  append_node(_define_method(MethodDefinition, position, name, type, args))
end

#define_static_method(position, name, type, *args) ⇒ Object



42
43
44
45
# File 'lib/duby/ast/class.rb', line 42

def define_static_method(position, name, type, *args)
  append_node(
      _define_method(StaticMethodDefinition, position, name, type, args))
end

#implements(*types) ⇒ Object

Raises:

  • (ArgumentError)


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

def implements(*types)
  raise ArgumentError if types.any? {|x| x.nil?}
  @interfaces.concat types
end

#infer(typer) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/duby/ast/class.rb', line 84

def infer(typer)
  unless resolved?
    @inferred_type ||= typer.define_type(name, superclass, @interfaces) do
      if body
        typer.infer(body)
      else
        typer.no_type
      end
    end
    if @inferred_type
      resolved!
    else
      typer.defer(self)
    end
  end

  @inferred_type
end