Class: Mirah::AST::ClassDefinition

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

Direct Known Subclasses

ClosureDefinition, InterfaceDeclaration

Instance Attribute Summary collapse

Attributes included from Scope

#static_scope, #type_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 Scoped

#containing_scope, #scope

Methods included from Named

#string_value, #to_s, #validate_name

Methods included from Annotated

#annotation

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, #resolve_if, #resolved!, #resolved?, #simple_name, #string_value, #temp, #to_s, #validate_child, #validate_children

Constructor Details

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

Returns a new instance of ClassDefinition.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/mirah/ast/class.rb', line 32

def initialize(parent, position, name, annotations=[], &block)
  @abstract = false
  @annotations = annotations
  @interfaces = []
  @interface_nodes = []
  self.name = name
  self.parent = parent
  if Mirah::AST.type_factory.respond_to? :define_type
    Mirah::AST.type_factory.define_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

#abstractObject

Returns the value of attribute abstract.



25
26
27
# File 'lib/mirah/ast/class.rb', line 25

def abstract
  @abstract
end

#current_access_levelObject

Returns the value of attribute current_access_level.



24
25
26
# File 'lib/mirah/ast/class.rb', line 24

def current_access_level
  @current_access_level
end

#interfacesObject

Returns the value of attribute interfaces.



23
24
25
# File 'lib/mirah/ast/class.rb', line 23

def interfaces
  @interfaces
end

#superclassObject

Returns the value of attribute superclass.



30
31
32
# File 'lib/mirah/ast/class.rb', line 30

def superclass
  @superclass
end

Instance Method Details

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



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

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



52
53
54
55
# File 'lib/mirah/ast/class.rb', line 52

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

#compile(compiler, expression) ⇒ Object



19
20
21
22
23
# File 'lib/mirah/compiler/class.rb', line 19

def compile(compiler, expression)
  compiler.define_class(self, expression)
rescue Exception => ex
  raise Mirah::InternalCompilerError.wrap(ex, self)
end

#declare_field(position, name, type) ⇒ Object



97
98
99
100
101
# File 'lib/mirah/ast/class.rb', line 97

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



66
67
68
69
# File 'lib/mirah/ast/class.rb', line 66

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

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



57
58
59
# File 'lib/mirah/ast/class.rb', line 57

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

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



61
62
63
64
# File 'lib/mirah/ast/class.rb', line 61

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

#implements(*types) ⇒ Object

Raises:

  • (ArgumentError)


115
116
117
118
119
120
121
122
123
124
# File 'lib/mirah/ast/class.rb', line 115

def implements(*types)
  raise ArgumentError if types.any? {|x| x.nil?}
  types.each do |type|
    if Mirah::AST::TypeReference === type
      @interfaces << type
    else
      @interface_nodes << type
    end
  end
end

#infer(typer, expression) ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
# File 'lib/mirah/ast/class.rb', line 103

def infer(typer, expression)
  resolve_if(typer) do
    @superclass = superclass_node.type_reference(typer) if superclass_node
    @annotations.each {|a| a.infer(typer, true)} if @annotations
    @interfaces.concat(@interface_nodes.map{|n| n.type_reference(typer)})
    typer.define_type(self, name, superclass, @interfaces) do
      static_scope.self_type = typer.self_type
      typer.infer(body, false) if body
    end
  end
end

#top_level?Boolean

Returns:



126
127
128
# File 'lib/mirah/ast/class.rb', line 126

def top_level?
  true
end