Class: Mirah::AST::StaticScope

Inherits:
Object
  • Object
show all
Includes:
Scope
Defined in:
lib/mirah/ast/scope.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(node, scoper, parent = nil) ⇒ StaticScope

Returns a new instance of StaticScope.



30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/mirah/ast/scope.rb', line 30

def initialize(node, scoper, parent=nil)
  @scope_node = node
  @vars = {}
  @var_types = {}
  @parent = parent
  @children = {}
  @imports = {}
  @search_packages = []
  @shadowed = {}
  @scoper = scoper
  @temps = Hash.new {|h,k| h[k] = -1}
  @package_block = nil
end

Instance Attribute Details

#parentObject

Returns the value of attribute parent.



27
28
29
# File 'lib/mirah/ast/scope.rb', line 27

def parent
  @parent
end

#self_nodeObject



162
163
164
165
166
167
# File 'lib/mirah/ast/scope.rb', line 162

def self_node
  if @self_node.nil? && parent
    @self_node = parent.self_node
  end
  @self_node
end

#self_typeObject



155
156
157
158
159
160
# File 'lib/mirah/ast/scope.rb', line 155

def self_type
  if @self_type.nil? && parent
    @self_type = parent.self_type
  end
  @self_type
end

Instance Method Details

#<<(name) ⇒ Object



76
77
78
# File 'lib/mirah/ast/scope.rb', line 76

def <<(name)
  @vars[name] = true
end

#add_child(scope) ⇒ Object



135
136
137
# File 'lib/mirah/ast/scope.rb', line 135

def add_child(scope)
  @children[scope] = true
end

#binding_typeObject



169
170
171
172
173
174
175
# File 'lib/mirah/ast/scope.rb', line 169

def binding_type
  if parent
    parent.binding_type
  else
    @binding_type
  end
end

#binding_type=(type) ⇒ Object Also known as: binding_type_set



177
178
179
180
181
182
183
# File 'lib/mirah/ast/scope.rb', line 177

def binding_type=(type)
  if parent
    parent.binding_type = type
  else
    @binding_type = type
  end
end

#captured?(name) ⇒ Boolean

Returns:

  • (Boolean)


117
118
119
120
121
122
123
124
125
# File 'lib/mirah/ast/scope.rb', line 117

def captured?(name)
  if !include?(name, false)
    return false
  elsif parent && parent.include?(name)
    return true
  else
    return children.any? {|child| child.include?(name, false)}
  end
end

#capturedLocalsObject



92
93
94
# File 'lib/mirah/ast/scope.rb', line 92

def capturedLocals
  locals.select {|name| self.captured?(name)}
end

#childrenObject



131
132
133
# File 'lib/mirah/ast/scope.rb', line 131

def children
  @children.keys
end

#contextObject



44
45
46
# File 'lib/mirah/ast/scope.rb', line 44

def context
  @scope_node
end

#fetch_imports(map) ⇒ Object



206
207
208
209
210
211
# File 'lib/mirah/ast/scope.rb', line 206

def fetch_imports(map)
  parent_scope = outer_scope
  parent_scope.fetch_imports(map) if parent_scope

  map.update(@imports)
end

#fetch_packages(list) ⇒ Object



213
214
215
216
217
218
# File 'lib/mirah/ast/scope.rb', line 213

def fetch_packages(list)
  parent_scope = outer_scope
  parent_scope.fetch_packages(list) if parent_scope

  list.concat(@search_packages)
end

#has_binding?Boolean

Returns:

  • (Boolean)


186
187
188
# File 'lib/mirah/ast/scope.rb', line 186

def has_binding?
  @binding_type != nil || (parent && parent.has_binding?)
end

#import(full_name, short_name) ⇒ Object



235
236
237
238
239
240
241
242
243
244
# File 'lib/mirah/ast/scope.rb', line 235

def import(full_name, short_name)
  return if full_name == short_name
  if short_name == '*'
    @search_packages << full_name.sub(/\.\*$/, '')
    @cached_packages = nil
  else
    @imports[short_name] = full_name
    @cached_imports = nil
  end
end

#importsObject



220
221
222
# File 'lib/mirah/ast/scope.rb', line 220

def imports
  @cached_imports ||= fetch_imports({})
end

#include?(name, include_parent = true) ⇒ Boolean

Returns:

  • (Boolean)


112
113
114
115
# File 'lib/mirah/ast/scope.rb', line 112

def include?(name, include_parent=true)
  @vars.include?(name) ||
      (include_parent && parent && parent.include?(name))
end

#inspectObject



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/mirah/ast/scope.rb', line 53

def inspect
  result = "#<StaticScope\n  node=#{@scope_node.inspect}\n  "
  result << "parent=#{@parent}\n  " if @parent
  result << "vars=#{locals.inspect}\n  " if @vars.size > 0
  result << "shadowed=#{@shadowed.keys.inspect}\n  " if @shadowed.size > 0
  result << "captured=#{capturedLocals.inspect}\n  " if capturedLocals.size > 0
  result << "temps=#{@temps.keys.inspect}\n  " if @temps.size > 0
  result << "package=#{@package}\n  " if @package
  result << "imports=#{@imports.inspect}\n  " if @imports.size > 0
  result << "search=#{@search_packages.inspect}\n  " if @search_packages.size > 0
  result << "self=#{@self_node.inspect}\n  " if @self_node
  if @self_type
    result << "self_type=#{@self_type}"
    if @self_type.isResolved
      result << " (#{@self_type.resolve.full_name})"
    end
    result << "\n  "
  end
  result << ">"
end

#isCaptured(name) ⇒ Object



127
128
129
# File 'lib/mirah/ast/scope.rb', line 127

def isCaptured(name)
  self.captured?(name)
end

#local_type(name, position = nil) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
# File 'lib/mirah/ast/scope.rb', line 100

def local_type(name, position=nil)
  @var_types[name] ||= begin
    type = LocalFuture.new(name, position)
    type.onUpdate {|_, resolved| self << name unless resolved.isError}
    if parent && !shadowed?(name)
      # TODO what if a var of the same name is later declared in the parent scope?
      type.parent_set(parent.local_type(name, position))
    end
    type
  end
end

#localsObject



88
89
90
# File 'lib/mirah/ast/scope.rb', line 88

def locals
  @vars.keys
end

#on_package_change(&block) ⇒ Object



202
203
204
# File 'lib/mirah/ast/scope.rb', line 202

def on_package_change(&block)
  @package_block = block
end

#outer_scopeObject



149
150
151
152
153
# File 'lib/mirah/ast/scope.rb', line 149

def outer_scope
  node = @scope_node
  return nil if node.nil? || node.parent.nil?
  @scoper.getScope(node)
end

#packageObject



190
191
192
# File 'lib/mirah/ast/scope.rb', line 190

def package
  @package || (outer_scope && outer_scope.package)
end

#package=(package) ⇒ Object

Raises:

  • (ArgumentError)


194
195
196
197
198
199
200
# File 'lib/mirah/ast/scope.rb', line 194

def package=(package)
  raise ArgumentError, "Package already set to #{@package.inspect}" if @package
  @package = package
  if @package_block
    @package_block.call
  end
end

#package_set(package) ⇒ Object



254
255
256
# File 'lib/mirah/ast/scope.rb', line 254

def package_set(package)
  self.package = package
end

#parent_set(scope) ⇒ Object



251
252
253
# File 'lib/mirah/ast/scope.rb', line 251

def parent_set(scope)
  self.parent = scope
end

#remove_child(scope) ⇒ Object



139
140
141
# File 'lib/mirah/ast/scope.rb', line 139

def remove_child(scope)
  @children.delete(scope)
end

#resetDefaultSelfNodeObject



257
258
259
# File 'lib/mirah/ast/scope.rb', line 257

def resetDefaultSelfNode
  self.self_node = :self
end

#search_packagesObject



224
225
226
# File 'lib/mirah/ast/scope.rb', line 224

def search_packages
  @cached_packages ||= fetch_packages([])
end

#selfTypeObject



245
246
247
# File 'lib/mirah/ast/scope.rb', line 245

def selfType
  self_type
end

#selfType_set(type) ⇒ Object

Should this be resolved?



248
249
250
# File 'lib/mirah/ast/scope.rb', line 248

def selfType_set(type)
  self.self_type = type
end

#shadow(name) ⇒ Object



80
81
82
# File 'lib/mirah/ast/scope.rb', line 80

def shadow(name)
  @shadowed[name] = @vars[name] = true
end

#shadowed?(name) ⇒ Boolean

Returns:

  • (Boolean)


84
85
86
# File 'lib/mirah/ast/scope.rb', line 84

def shadowed?(name)
  @shadowed[name]
end

#staticImport(type) ⇒ Object



228
229
230
231
232
233
# File 'lib/mirah/ast/scope.rb', line 228

def staticImport(type)
  future = BaseTypeFuture.new(self_type.position)
  extended = self_type.resolve.include(type.resolve)
  future.resolved(extended)
  self.self_type = future
end

#temp(name = "tmp") ⇒ Object



96
97
98
# File 'lib/mirah/ast/scope.rb', line 96

def temp(name="tmp")
  "#{name}$#{@temps[name] += 1}"
end

#to_sObject



48
49
50
51
# File 'lib/mirah/ast/scope.rb', line 48

def to_s
  #"#<StaticScope node=#{@scope_node.to_s}>"
  inspect
end

#toStringObject



74
# File 'lib/mirah/ast/scope.rb', line 74

def toString; inspect; end