Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
Checking mergeability… Don't worry, you can still create the pull request.
  • 8 commits
  • 18 files changed
  • 0 commit comments
  • 1 contributor
View
10 bin/mirahp
@@ -6,4 +6,12 @@ rescue LoadError
require 'mirah'
end
-puts Duby.parse(*ARGV).inspect
+asts = Duby.parse(*ARGV)
+if asts.size == 1
+ puts asts[0].inspect
+else
+ asts.each do |ast|
+ next if Duby::AST::ErrorNode === ast
+ puts "#{ast.filename}:", ast.inspect, ""
+ end
+end
View
2  examples/edb.mirah
@@ -1,3 +1,3 @@
-def_edb :render, 'test.edb'
+def_edb render, 'test.edb'
@message = "Hello"
puts render
View
142 lib/mirah.rb
@@ -2,6 +2,7 @@
require 'rbconfig'
require 'mirah/transform'
require 'mirah/ast'
+require 'mirah/threads'
require 'mirah/typer'
require 'mirah/compiler'
require 'mirah/env'
@@ -15,6 +16,11 @@
require 'mirah/jvm/typer'
Dir[File.dirname(__FILE__) + "/mirah/plugin/*"].each {|file| require "#{file}" if file =~ /\.rb$/}
require 'jruby'
+require 'jruby/synchronized'
+
+class Duby::AST::Node
+ include JRuby::Synchronized
+end
module Duby
def self.run(*args)
@@ -66,7 +72,23 @@ def self.print_error(message, position)
end
class CompilationState
- attr_accessor :verbose, :destination
+ attr_accessor :verbose, :destination, :builtins_initialized
+ attr_reader :executor, :mutex, :main_thread
+
+ def initialize
+ @executor = Duby::Threads::Executor.new
+ @mutex = Mutex.new
+ @main_thread = Thread.current
+ end
+
+ def log(message)
+ # TODO allow filtering which logs to show.
+ if verbose
+ @mutex.synchronize {
+ puts message
+ }
+ end
+ end
end
end
@@ -78,7 +100,7 @@ def initialize(parent, class_map)
super(parent)
@class_map = class_map
end
-
+
def findClass(name)
if @class_map[name]
bytes = @class_map[name].to_java_bytes
@@ -151,22 +173,7 @@ def compile(*args)
end
def generate(args, &block)
- process_flags!(args)
-
- # collect all ASTs from all files
- all_nodes = []
- expand_files(args).each do |duby_file|
- if duby_file == '-e'
- @filename = '-e'
- next
- elsif @filename == '-e'
- all_nodes << parse('-e', duby_file)
- else
- all_nodes << parse(duby_file)
- end
- @filename = nil
- exit 1 if @error
- end
+ all_nodes = parse(*args)
# enter all ASTs into inference engine
infer_asts(all_nodes)
@@ -179,36 +186,42 @@ def generate(args, &block)
def parse(*args)
process_flags!(args)
- @filename = args.shift
- if @filename
- if @filename == '-e'
- @filename = 'DashE'
- src = args[0]
- else
- src = File.read(@filename)
- end
- else
+ files = expand_files(args)
+ if files.empty?
print_help
exit(1)
end
- begin
- ast = Duby::AST.parse_ruby(src, @filename)
- # rescue org.jrubyparser.lexer.SyntaxException => ex
- # Duby.print_error(ex.message, ex.position)
- # raise ex if @state.verbose
- end
- @transformer = Duby::Transform::Transformer.new(@state)
- Java::MirahImpl::Builtin.initialize_builtins(@transformer)
- @transformer.filename = @filename
- ast = @transformer.transform(ast, nil)
- @transformer.errors.each do |ex|
- Duby.print_error(ex.message, ex.position)
- raise ex.cause || ex if @state.verbose
+
+ # collect all ASTs from all files
+ all_nodes = @state.executor.each(files) do |pair|
+ filename, src = pair
+ begin
+ ast = Duby::AST.parse_ruby(src, filename)
+ # rescue org.jrubyparser.lexer.SyntaxException => ex
+ # Duby.print_error(ex.message, ex.position)
+ # raise ex if @state.verbose
+ end
+ transformer = Duby::Transform::Transformer.new(@state)
+ @state.mutex.synchronize {
+ @state.builtins_initialized ||= begin
+ Java::MirahImpl::Builtin.initialize_builtins(transformer)
+ true
+ end
+ }
+ transformer.filename = filename
+ ast = transformer.transform(ast, nil)
+ @state.mutex.synchronize {
+ transformer.errors.each do |ex|
+ Duby.print_error(ex.message, ex.position)
+ raise ex.cause || ex if @state.verbose
+ end
+ }
+ @error ||= transformer.errors.size > 0
+ ast
end
- @error = @transformer.errors.size > 0
- ast
+ all_nodes
end
def infer_asts(asts)
@@ -242,9 +255,11 @@ def compile_ast(ast, &block)
compiler.generate(&block)
rescue Exception => ex
if ex.respond_to? :node
- Duby.print_error(ex.message, ex.node.position)
- puts ex.backtrace if @state.verbose
- exit 1
+ @state.mutex.synchronize {
+ Duby.print_error(ex.message, ex.node.position)
+ @state.log(ex.backtrace)
+ }
+ @error = true
else
raise ex
end
@@ -314,23 +329,54 @@ def print_help
def expand_files(files)
expanded = []
+ dash_e = false
files.each do |filename|
- if File.directory?(filename)
+ if dash_e
+ expanded << ['DashE', filename]
+ dash_e = false
+ elsif filename == '-e'
+ dash_e = true
+ next
+ elsif File.directory?(filename)
Dir[File.join(filename, '*')].each do |child|
if File.directory?(child)
files << child
elsif child =~ /\.(duby|mirah)$/
- expanded << child
+ expanded << [child, File.read(child)]
end
end
else
- expanded << filename
+ expanded << [filename, File.read(filename)]
end
end
expanded
end
end
+module JRuby::Synchronized
+ def respond_to?(*args)
+ m = Object.instance_method(:respond_to?)
+ begin
+ m.bind(self).call(*args)
+ rescue java.lang.NullPointerException
+ nil
+ end
+ end
+end
+
+class Array
+ alias join_unsynchronized join
+ def join(*args)
+ map{|x| x.to_s}.join_unsynchronized(*args)
+ end
+
+ alias to_s_unsynchronized to_s
+
+ def to_s
+ map{|x| x.to_s}.to_s_unsynchronized
+ end
+end
+
Mirah = Duby
if __FILE__ == $0
View
4 lib/mirah/ast/class.rb
@@ -93,8 +93,8 @@ def infer(typer)
@superclass = superclass_node.type_reference(typer) if superclass_node
@annotations.each {|a| a.infer(typer)} 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.define_type(self, name, superclass, @interfaces) do |self_type|
+ static_scope.self_type = self_type
typer.infer(body) if body
end
end
View
5 lib/mirah/ast/intrinsics.rb
@@ -214,9 +214,6 @@ def infer(typer)
extension_name,
typer.transformer.state)
- # restore the self type since we're sharing a type factory
- typer.known_types['self'] = self_type
-
arg_types = argument_types
macro = self_type.add_compiled_macro(klass, name, arg_types)
if arguments[-1].kind_of?(BlockArgument) && arguments[-1].optional?
@@ -255,7 +252,7 @@ def build_and_load_extension(parent, name, state)
new_factory = orig_factory.dup
Duby::AST.type_factory = new_factory
ast = build_ast(name, parent, transformer)
- puts ast.inspect if state.verbose
+ state.log(ast.inspect)
classes = compile_ast(name, ast, transformer)
loader = DubyClassLoader.new(
JRuby.runtime.jruby_class_loader, classes)
View
12 lib/mirah/ast/method.rb
@@ -1,3 +1,4 @@
+require 'jruby/synchronized'
module Duby::AST
class Arguments < Node
child :required
@@ -202,6 +203,7 @@ def initialize(parent, line_number, name, annotations=[], &block)
@annotations = annotations
super(parent, line_number, &block)
@name = name
+ signature.extend JRuby::Synchronized if signature
@visibility = (class_scope && class_scope.current_access_level) || :public
end
@@ -285,7 +287,15 @@ def abstract?
end
def static?
- scope.static_scope.self_type.meta?
+ type = scope.static_scope.self_type
+ # type should never be nil, but it can be in tests
+ type && type.meta?
+ end
+
+ alias :set_signature_unsynchronized :signature=
+ def signature=(signature)
+ signature.extend JRuby::Synchronized if signature
+ set_signature_unsynchronized(signature)
end
end
View
3  lib/mirah/ast/scope.rb
@@ -1,3 +1,5 @@
+require 'jruby/synchronized'
+
module Duby
module AST
module Scoped
@@ -40,6 +42,7 @@ def class_scope
class StaticScope
java_import 'java.util.LinkedHashMap'
+ include JRuby::Synchronized
attr_reader :parent
attr_writer :self_type, :self_node, :package
View
13 lib/mirah/ast/structure.rb
@@ -8,7 +8,6 @@ def initialize(parent, line_number, &block)
def infer(typer)
unless @inferred_type
@typer ||= typer
- @self_type ||= typer.self_type
if children.size == 0
@inferred_type = typer.no_type
else
@@ -27,12 +26,7 @@ def infer(typer)
def <<(node)
super
- if @typer
- orig_self = @typer.self_type
- @typer.known_types['self'] = @self_type
- @typer.infer(node)
- @typer.known_types['self'] = orig_self
- end
+ @typer.infer(node) if @typer
self
end
end
@@ -57,7 +51,7 @@ class ScopedBody < Body
include Scoped
def infer(typer)
- static_scope.self_type ||= typer.self_type
+ static_scope.self_type ||= scope.static_scope.self_type
super
end
@@ -200,9 +194,8 @@ def initialize(parent, line_number, &block)
def infer(typer)
resolve_if(typer) do
- typer.set_filename(self, filename)
@defining_class ||= begin
- static_scope.self_type = typer.self_type
+ static_scope.self_type = typer.declare_main_type(self, filename)
end
typer.infer(body)
end
View
6 lib/mirah/jvm/compiler.rb
@@ -122,11 +122,11 @@ def define_method(node)
push_jump_scope(node) do
base_define_method(node, true) do |method, arg_types|
return if @class.interface?
-
- log "Starting new #{node.static? ? 'static ' : ''}method #{node.name}(#{arg_types})"
+ type_names = arg_types.map{|t| t.full_name}.join(', ')
+ log "Starting new #{node.static? ? 'static ' : ''}method #{node.name}(#{type_names})"
args = node.arguments.args
method_body(method, args, node, node.signature[:return])
- log "Method #{node.name}(#{arg_types}) complete!"
+ log "Method #{node.name}(#{type_names}) complete!"
end
end
end
View
18 lib/mirah/jvm/typer.rb
@@ -1,4 +1,5 @@
require 'mirah/typer'
+require 'mirah/threads'
require 'mirah/jvm/types'
require 'mirah/jvm/types/factory'
@@ -17,13 +18,13 @@ def initialize(transformer)
end
@known_types = @factory.known_types
@known_types['dynamic'] = DynamicType.new
- @errors = []
+ @errors = Duby::Threads::SynchronizedArray.new
end
- def set_filename(scope, filename)
+ def declare_main_type(scope, filename)
classname = Duby::Compiler::JVM.classname_from_filename(filename)
main_class = @factory.declare_type(scope, classname)
- @known_types['self'] = main_class.meta
+ main_class.meta
end
def type_reference(scope, name, array=false, meta=false)
@@ -95,13 +96,14 @@ def infer_signature(method_def)
return_type = sig_args.delete(:return)
exceptions = sig_args.delete(:throws)
args = method_def.arguments.args || []
- static = method_def.kind_of? Duby::AST::StaticMethodDefinition
+ static = method_def.static?
+ klass = method_def.defining_class.unmeta
if sig_args.size != args.size
# If the superclass declares one method with the same name and
# same number of arguments, assume we're overriding it.
found = nil
ambiguous = false
- classes = [self_type.superclass] + self_type.interfaces
+ classes = [klass.superclass] + klass.interfaces
while classes.size > 0
cls = classes.pop
if static
@@ -132,9 +134,9 @@ def infer_signature(method_def)
arg_types = args.map do |arg|
signature[arg.name.intern]
end
- method = self_type.find_method(
- self_type, method_def.name, arg_types, false)
- interfaces = self_type.interfaces.dup
+ method = klass.find_method(
+ klass, method_def.name, arg_types, false)
+ interfaces = klass.interfaces.dup
until method || interfaces.empty?
interface = interfaces.pop
method = interface.find_method(
View
6 lib/mirah/jvm/types.rb
@@ -29,8 +29,12 @@ def initialize(mirror_or_name)
end
def full_name
+ asm_type.class_name
+ end
+
+ def asm_type
desc = BiteScript::Signature.class_id(self)
- BiteScript::ASM::Type.get_type(desc).class_name
+ BiteScript::ASM::Type.get_type(desc)
end
def jvm_type
View
12 lib/mirah/jvm/types/extensions.rb
@@ -1,5 +1,9 @@
require 'delegate'
+class BiteScript::ASM::MethodMirror
+ alias parameter_types argument_types
+end
+
module Duby::JVM::Types
class ExtendedType < DelegateClass(Type)
def initialize(*args)
@@ -47,21 +51,23 @@ def java_static_method(name, *types)
end
def declared_instance_methods(name=nil)
- __combine_methods(__getobj__.declared_instance_methods)
+ __combine_methods(__getobj__.declared_instance_methods, name)
end
def declared_class_methods(name=nil)
- __combine_methods(__getobj__.declared_class_methods)
+ __combine_methods(__getobj__.declared_class_methods, name)
end
- def __combine_methods(basic_methods)
+ def __combine_methods(basic_methods, name)
methods = {}
basic_methods.each do |method|
+ next unless name.nil? || method.name == name
key = [method.name, method.parameter_types, method.return_type]
methods[key] = method
end
@static_includes.each do |type|
type.declared_class_methods.each do |method|
+ next unless name.nil? || method.name == name
key = [method.name, method.parameter_types, method.return_type]
methods[key] ||= method
end
View
6 lib/mirah/jvm/types/factory.rb
@@ -1,6 +1,10 @@
require 'jruby'
+require 'mirah/threads'
+
module Duby::JVM::Types
class TypeFactory
+ include JRuby::Synchronized
+
BASIC_TYPES = {
"boolean" => Boolean,
"byte" => Byte,
@@ -28,7 +32,7 @@ class TypeFactory
attr_accessor :package
attr_reader :known_types
- class ParanoidHash < Hash
+ class ParanoidHash < Duby::Threads::SynchronizedHash
def []=(k, v)
raise ArgumentError, "Can't store nil for key #{k.inspect}" if v.nil?
super(k, v)
View
26 lib/mirah/jvm/types/methods.rb
@@ -65,6 +65,10 @@ def abstract?
def exceptions
[]
end
+
+ def parameter_types
+ @parameter_types ||= @argument_types.map {|t| t.asm_type}
+ end
end
class JavaCallable
@@ -156,8 +160,11 @@ def abstract?
def void?
return_type = @member.return_type
return true if return_type.nil?
- if return_type.respond_to?(:descriptor) && return_type.descriptor == 'V'
- return true
+ begin
+ if return_type.respond_to?(:descriptor) && return_type.descriptor == 'V'
+ return true
+ end
+ rescue java.lang.NullPointerException
end
false
end
@@ -395,13 +402,16 @@ def constructor(*types)
rescue => ex
log(ex.message)
end
- raise NameError, "No constructor #{name}(#{types.join ', '})"
+ raise NameError, "No constructor #{name}(#{types.map{|t| t.full_name}.join ', '})"
end
def java_method(name, *types)
intrinsic = intrinsics[name][types]
return intrinsic if intrinsic
- jvm_types = types.map {|type| type.jvm_type}
+ jvm_types = types.map do |type|
+ raise NameError, "jvm_type" unless type.respond_to?(:jvm_type)
+ type.jvm_type
+ end
return JavaDynamicMethod.new(name, *jvm_types) if dynamic?
@@ -428,7 +438,7 @@ def java_method(name, *types)
rescue => ex
log(ex.message)
end
- raise NameError, "No method #{self.name}.#{name}(#{types.join ', '})"
+ raise NameError, "No method #{self.name}.#{name}(#{types.map{|t| t.full_name}.join ', '})"
end
def declared_instance_methods(name=nil)
@@ -493,7 +503,7 @@ def java_method(name, *types)
return method if method
intrinsic = intrinsics[name][types]
return intrinsic if intrinsic
- raise NameError, "No method #{self.name}.#{name}(#{types.join ', '})"
+ raise NameError, "No method #{self.name}.#{name}(#{types.map{|x|x.full_name}.join ', '})"
end
def java_static_method(name, *types)
@@ -501,13 +511,13 @@ def java_static_method(name, *types)
return method if method
intrinsic = meta.intrinsics[name][types]
return intrinsic if intrinsic
- raise NameError, "No method #{self.name}.#{name}(#{types.join ', '})"
+ raise NameError, "No method #{self.name}.#{name}(#{types.map{|x|x.full_name}.join ', '})"
end
def constructor(*types)
constructor = constructors.find {|c| c.argument_types == types}
return constructor if constructor
- raise NameError, "No constructor #{name}(#{types.join ', '})"
+ raise NameError, "No constructor #{name}(#{types.map{|x|x.full_name}.join ', '})"
end
def declared_instance_methods(name=nil)
View
5 lib/mirah/plugin/java.rb
@@ -40,10 +40,11 @@ def method_type(typer, target_type, name, parameter_types)
end
end
+ type_names = parameter_types.map{|t| t.full_name}
if result
- log "Method type for \"#{name}\" #{parameter_types} on #{target_type} = #{result}"
+ log "Method type for #{name}(#{type_names}) on #{target_type} = #{result}"
else
- log "Method type for \"#{name}\" #{parameter_types} on #{target_type} not found"
+ log "Method type for #{name}(#{type_names}) on #{target_type} not found"
end
result
View
65 lib/mirah/threads.rb
@@ -0,0 +1,65 @@
+require 'jruby/synchronized'
+require 'thread'
+
+module Duby
+ module Threads
+ class SynchronizedArray < Array
+ include JRuby::Synchronized
+ end
+
+ class SynchronizedHash < Hash
+ include JRuby::Synchronized
+ end
+
+ class Executor
+ java_import 'java.util.concurrent.Executors'
+
+ def initialize(executor=nil)
+ @executor = executor ||
+ Executors.new_cached_thread_pool(DaemonThreadFactory.new)
+ end
+
+ class DaemonThreadFactory
+ java_import 'java.util.concurrent.ThreadFactory'
+ java_import 'java.lang.Thread'
+ include ThreadFactory
+
+ def newThread(runnable)
+ thread = Thread.new(runnable)
+ thread.setDaemon(true)
+ thread
+ end
+ end
+
+ class MirahTask
+ java_import 'java.util.concurrent.Callable'
+ include Callable
+
+ def initialize(factory=nil, &block)
+ @factory = factory || Duby::AST.type_factory
+ @block = block
+ end
+
+ def call
+ Duby::AST.type_factory = @factory
+ @block.call
+ end
+ end
+
+ def each(list)
+ tasks = list.map do |x|
+ MirahTask.new do
+ yield x
+ end
+ end
+ futures = @executor.invoke_all(tasks)
+ futures.map {|x| x.get}
+ end
+
+ def execute(&block)
+ each([nil], &block)[0]
+ end
+ end
+
+ end
+end
View
66 lib/mirah/typer.rb
@@ -1,5 +1,6 @@
require 'mirah/ast'
require 'mirah/transform'
+require 'mirah/threads'
module Duby
module Typer
@@ -29,28 +30,28 @@ def to_s
end
end
+ # This class is not threadsafe and should only be used in tests.
+ # Subclasses must override the declare_main_type method.
class Simple < BaseTyper
attr_accessor :known_types, :errors, :last_chance
- def initialize(self_type)
- @known_types = {}
+ def initialize(main_type_name)
+ @known_types = Duby::Threads::SynchronizedHash.new
- @known_types["self"] = type_reference(nil, self_type)
+ @main_type = type_reference(nil, main_type_name)
@known_types["fixnum"] = type_reference(nil, "fixnum")
@known_types["float"] = type_reference(nil, "float")
@known_types["string"] = type_reference(nil, "string")
@known_types["boolean"] = type_reference(nil, "boolean")
- @errors = []
+ @errors = Duby::Threads::SynchronizedArray.new
end
def name
"Simple"
end
- def set_filename(scope, name); end
-
- def self_type
- known_types["self"]
+ def declare_main_type(scope, filename)
+ @main_type
end
def default_type
@@ -99,10 +100,7 @@ def define_type(scope, name, superclass, interfaces)
log "New type defined: '#{name}' < '#{superclass}'"
result = type_definition(scope, name, superclass, interfaces)
- # TODO Get rid of known_types["self"]
- old_self, known_types["self"] = known_types["self"], result
- yield
- known_types["self"] = old_self
+ yield(result)
result
end
@@ -119,20 +117,12 @@ def local_type(scope, name)
type
end
- def local_types
- @local_types ||= {}
- end
-
- def local_type_hash(scope)
- local_types[scope] ||= {}
- end
-
def field_types
- @field_types ||= {}
+ @field_types ||= Duby::Threads::SynchronizedHash.new
end
def field_type_hash(cls)
- field_types[cls] ||= {}
+ field_types[cls] ||= Duby::Threads::SynchronizedHash.new
end
def static_field_types
@@ -173,7 +163,8 @@ def static_field_type(cls, name)
end
def learn_method_type(target_type, name, parameter_types, type, exceptions)
- log "Learned method #{name} (#{parameter_types}) on #{target_type} = #{type}"
+ type_names = parameter_types.map{|t| t.full_name}.join(', ')
+ log "Learned method #{name}(#{type_names}) on #{target_type} = #{type}"
get_method_type_hash(target_type, name, parameter_types)[:type] = known_types[type] || type
@@ -197,8 +188,9 @@ def method_type(target_type, name, parameter_types)
end
+ type_names = parameter_types.map{|t| t.full_name}.join(', ')
if !simple_type
- log "Method type for \"#{name}\" #{parameter_types} on #{target_type} not found."
+ log "Method type for \"#{name}\" #{type_names} on #{target_type} not found."
# allow plugins a go if we're in the inference phase
simple_type = plugins do |plugin|
@@ -209,10 +201,10 @@ def method_type(target_type, name, parameter_types)
return nil unless simple_type
if constructor
- log "Method type for \"#{name}\" #{parameter_types} on #{target_type} = #{target_type}"
+ log "Method type for #{name}(#{type_names}) on #{target_type} = #{target_type}"
target_type.unmeta
else
- log "Method type for \"#{name}\" #{parameter_types} on #{target_type} = #{simple_type}"
+ log "Method type for #{name}(#{type_names}) on #{target_type} = #{simple_type}"
simple_type
end
end
@@ -253,17 +245,20 @@ def cycle(count)
end
def method_types
- @method_types ||= {}
+ @method_types ||= Duby::Threads::SynchronizedHash.new
end
def get_method_type_hash(target_type, name, parameter_types)
- method_types[target_type] ||= {}
- method_types[target_type][name] ||= {}
- method_types[target_type][name][parameter_types.size] ||= {}
+ method_types[target_type] ||= Duby::Threads::SynchronizedHash.new
+ method_types[target_type][name] ||= Duby::Threads::SynchronizedHash.new
+ method_types[target_type][name][parameter_types.size] ||= Duby::Threads::SynchronizedHash.new
current = method_types[target_type][name][parameter_types.size]
- parameter_types.each {|type| current[type] ||= {}; current = current[type]}
+ parameter_types.each do |type|
+ current[type] ||= Duby::Threads::SynchronizedHash.new
+ current = current[type]
+ end
current
end
@@ -277,7 +272,7 @@ def type_definition(scope, name, superclass, interfaces)
end
def deferred_nodes
- @deferred_nodes ||= {}
+ @deferred_nodes ||= Duby::Threads::SynchronizedHash.new
end
def infer(node)
@@ -316,7 +311,7 @@ def defer(node, error_message=nil)
return if deferred_nodes.include? node
log "Deferring inference for #{node}"
- deferred_nodes[node] = self_type
+ deferred_nodes[node] = true
end
end
@@ -328,9 +323,8 @@ def resolve(raise = false)
retried = false
cycle(count) do |i|
old_deferred = @deferred_nodes
- @deferred_nodes = {}
+ @deferred_nodes = Duby::Threads::SynchronizedHash.new
old_deferred.each do |node, saved_type|
- known_types["self"] = saved_type
type = infer(node)
log "[Cycle #{i}]: Inferred type for #{node}: #{type || 'FAILED'}"
@@ -386,7 +380,7 @@ def resolve(raise = false)
end
def self.typer_plugins
- @typer_plugins ||= []
+ @typer_plugins ||= Duby::Threads::SynchronizedArray.new
end
end
View
26 test/test_typer.rb
@@ -67,9 +67,9 @@ def test_signature
if def_foo =~ /self/
- type = typer.self_type.meta
+ type = typer.type_reference(nil, :bar, false, true)
else
- type = typer.self_type
+ type = typer.type_reference(nil, :bar, false, false)
end
assert_equal(typer.null_type, typer.method_type(type, 'foo', [typer.string_type]))
@@ -113,8 +113,10 @@ def test_call
ast.infer(typer)
ast = ast.body
- assert_equal(typer.float_type, typer.method_type(typer.self_type, "bar", [typer.fixnum_type, typer.string_type]))
- assert_equal(typer.float_type, typer.method_type(typer.self_type, "baz", []))
+ self_type = typer.type_reference(nil, :bar)
+
+ assert_equal(typer.float_type, typer.method_type(self_type, "bar", [typer.fixnum_type, typer.string_type]))
+ assert_equal(typer.float_type, typer.method_type(self_type, "baz", []))
assert_equal(typer.float_type, ast.children[0].inferred_type)
assert_equal(typer.float_type, ast.children[1].inferred_type)
@@ -125,16 +127,18 @@ def test_call
ast.infer(typer)
ast = ast.body
- assert_equal(typer.default_type, typer.method_type(typer.self_type, "baz", []))
- assert_equal(typer.float_type, typer.method_type(typer.self_type, "bar", [typer.fixnum_type, typer.string_type]))
+ self_type = typer.type_reference(nil, :bar)
+
+ assert_equal(typer.default_type, typer.method_type(self_type, "baz", []))
+ assert_equal(typer.float_type, typer.method_type(self_type, "bar", [typer.fixnum_type, typer.string_type]))
assert_equal(typer.default_type, ast.children[0].inferred_type)
assert_equal(typer.float_type, ast.children[1].inferred_type)
# allow resolution to run
assert_nothing_raised {typer.resolve}
- assert_equal(typer.float_type, typer.method_type(typer.self_type, "baz", []))
- assert_equal(typer.float_type, typer.method_type(typer.self_type, "bar", [typer.fixnum_type, typer.string_type]))
+ assert_equal(typer.float_type, typer.method_type(self_type, "baz", []))
+ assert_equal(typer.float_type, typer.method_type(self_type, "bar", [typer.fixnum_type, typer.string_type]))
assert_equal(typer.float_type, ast.children[0].inferred_type)
assert_equal(typer.float_type, ast.children[1].inferred_type)
@@ -145,8 +149,10 @@ def test_call
ast.infer(typer)
ast = ast.body
- assert_equal(typer.default_type, typer.method_type(typer.self_type, "baz", []))
- assert_equal(typer.float_type, typer.method_type(typer.self_type, "bar", [typer.fixnum_type, typer.string_type]))
+ self_type = typer.type_reference(nil, :bar)
+
+ assert_equal(typer.default_type, typer.method_type(self_type, "baz", []))
+ assert_equal(typer.float_type, typer.method_type(self_type, "bar", [typer.fixnum_type, typer.string_type]))
assert_equal(typer.default_type, ast.children[0].inferred_type)
assert_equal(typer.float_type, ast.children[1].inferred_type)

No commit comments for this range

Something went wrong with that request. Please try again.