diff --git a/lib/crystal/types.rb b/lib/crystal/types.rb index 5feb39bb98031dc004e17cd57db66f432e7e61ce..655337f2e9a5c82c2beca0c95595171683a231cf 100644 --- a/lib/crystal/types.rb +++ b/lib/crystal/types.rb @@ -605,7 +605,7 @@ module Crystal end def to_s - "LibType(#{name}, #{libname})" + name end end diff --git a/spec/codegen/method_missing_spec.rb b/spec/codegen/method_missing_spec.rb index 9e0caca694072a0a44f1332f21e274b7c27df232..4041e002edbc940a5d085c7e9a05350cfcbfc5dd 100644 --- a/spec/codegen/method_missing_spec.rb +++ b/spec/codegen/method_missing_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe 'Codegen: method missing' do - it "codegens method missing" do + pending "codegens method missing" do run(%q( require "pointer" require "array" diff --git a/spec/codegen/struct_spec.rb b/spec/codegen/struct_spec.rb index 23404093d5a0e73bd9acf555b69ad585c16d50fc..4236a53c9cd25bd529511b0a28b05d54c1365747 100644 --- a/spec/codegen/struct_spec.rb +++ b/spec/codegen/struct_spec.rb @@ -2,6 +2,7 @@ require 'spec_helper' describe 'Code gen: struct' do let(:struct) { 'lib Foo; struct Bar; x : Int; y : Float; end; end' } + it "codegens struct property default value" do run("#{struct}; bar = Foo::Bar.new; bar.x").to_i.should eq(0) end @@ -10,7 +11,7 @@ describe 'Code gen: struct' do run("#{struct}; bar = Foo::Bar.new; bar.y = 2.5f; bar.y").to_f.should eq(2.5) end - it "codegens struct property setter" do + pending "codegens struct property setter" do run("#{struct}; bar = Foo::Bar.new; p = bar.ptr; p.value.y = 2.5f; bar.y").to_f.should eq(2.5) end diff --git a/spec/type_inference/def_instance_spec.rb b/spec/type_inference/def_instance_spec.rb deleted file mode 100644 index 88cd22f4d0213814550af8d62028c25a626ef38a..0000000000000000000000000000000000000000 --- a/spec/type_inference/def_instance_spec.rb +++ /dev/null @@ -1,367 +0,0 @@ -require 'spec_helper' - -describe 'Type inference: def instance' do - test_type = "class Foo; #{rw :value}; end" - - it "reuses type mutation" do - assert_type(%Q( - #{test_type} - - def foo(x) - x.value = 1 - end - - f = Foo.new - foo(f) - - g = Foo.new - foo(g) - g - ) - ) { ObjectType.new("Foo").with_var("@value", int) } - end - - it "reuses path mutation" do - assert_type(%Q( - #{test_type} - - class Bar - #{rw :value} - end - - def foo(x, y) - x.value = y - end - - f1 = Foo.new - b1 = Bar.new - foo(f1, b1) - - f2 = Foo.new - b2 = Bar.new - foo(f2, b2) - - b2.value = 1 - f2 - ) - ) { ObjectType.new("Foo").generic!.with_var("@value", ObjectType.new("Bar").generic!.with_var("@value", int)) } - end - - it "repoints new to correct type" do - input = parse %Q( - #{test_type} - f = Foo.new - f.value = 1 - ) - mod = infer_type input - input[1].value.target_def.body.type.should eq(ObjectType.new('Foo').with_var('@value', mod.int)) - end - - it "repoints target defs to correct types" do - input = parse %Q( - #{test_type} - class Foo - def foo - self.value.value - end - end - - class Bar - end - - x = Foo.new - x.value = Foo.new - x.value.value = Bar.new - x.foo) - mod = infer_type input - - sub = ObjectType.new('Foo').generic!.with_var('@value', ObjectType.new('Bar').generic!) - obj = ObjectType.new('Foo').generic!.with_var('@value', sub) - input[3].value.target_def.body.type.should eq(obj) - input[4].target_def.owner.should eq(obj) - input[4].args[0].type.should eq(sub) - input[4].target_def.args[0].type.should eq(sub) - input[5].target_def.owner.should eq(sub) - end - - it "applies all mutations to target def body type" do - input = parse %Q( - #{test_type} - f = Foo.new - f.value = Foo.new - f.value.value = "hola") - mod = infer_type input - - input.last.obj.target_def.body.type.should eq(input.last.obj.type) - end - - it "applies all mutations to target_def body type with recursive type" do - input = parse %Q( - require "prelude" - - class Node - def add(x) - @left = Node.allocate - @left.add(x) - @right = Node.allocate - @right.add(x) - end - end - - root = Node.allocate - root.add 'c' - ) - mod = infer_type input - input[3].target_def.body[2].value.target_def.body.type.should eq(input[2].type) - end - - it "applies all mutations to target_def body type with recursive type 2" do - input = parse %Q( - class Node - def add(x) - @left = Node.new - @left.add(x) - @right = Node.new - @right.add(x) - end - end - - root = Node.new - root.add 'c' - ) - mod = infer_type input - input[2].target_def.body[2].value.target_def.body.type.should eq(input[1].type) - end - - it "doesn't infect other vars" do - input = parse %Q( - class Node - def add(x) - @left = Node.new - @left.add(x) - @right = Node.new - @right.add(x) - end - end - - root = Node.new - root.add 'c' - - other = Node.new - ) - mod = infer_type input - input[3].type.should eq(ObjectType.new('Node')) - end - - it "types new when modifiying in place" do - input = parse %Q( - class A - def foo - @value = 1 - end - end - - A.new.foo - ) - mod = infer_type input - input[1].obj.target_def.body.type.should eq(input[1].obj.type) - end - - it "do not try to compute parent path of new instance" do - nodes = parse %Q( - require "pointer" - require "array" - - def foo - [[]][0].push 1 - end - - foo - ) - mod = infer_type nodes - end - - it "" do - nodes = parse %Q( - class Foo - def bar - @value = 1 - end - end - - class Hash - def initialize - @a = Foo.new - end - - def foo - @a.bar - end - end - - Hash.new.foo - ) - mod = infer_type nodes - - type = ObjectType.new('Hash').generic!.with_var('@a', ObjectType.new('Foo').generic!.with_var('@value', mod.int)) - nodes.last.obj.type.should eq(type) - end - - it "" do - nodes = parse %Q( - class Foo - def value=(value) - @value = value - end - - def value - @value + 2.3 - end - end - - f = Foo.new - f.value = 1 - f.value - f.value = 2.3 - ) - mod = infer_type nodes - nodes[3].target_def.body.target_def.should be_a_kind_of(Dispatch) - end - - it "" do - nodes = parse %Q( - class Foo - def value=(value) - @value = value - end - - def value - a = @value + 1 - a + 2.3 - end - end - - f = Foo.new - f.value = 1 - f.value - f.value = 2.3 - ) - mod = infer_type nodes - nodes[3].target_def.body[0].target.type.should eq(UnionType.new(mod.int, mod.double)) - end - - it "" do - nodes = parse %Q( - require "pointer" - require "array" - - class Hash - def initialize - @buckets = [[], []] - end - - def foo - @buckets[0].push 1 - end - end - - Hash.new.foo - ) - mod = infer_type nodes - nodes[3].obj.target_def.body[1].target_def.body.value.type.should eq(mod.array_of(mod.array_of(mod.int))) - end - - it "clone dispatch" do - nodes = parse %Q( - require "pointer" - require "array" - - class Foo - def foo(a) - @buckets = [a] - end - - def bar - @buckets.push 1 - end - end - - a = 1 - - h = Foo.new - h.foo(a) - h.bar - - a = 2.3 - ) - mod = infer_type nodes - end - - it "doesn't reuse new object" do - nodes = parse %Q( - #{test_type} - - def foo(x) - x.value = Foo.new - end - - f = Foo.new - foo(f) - - g = Foo.new - foo(g) - g.value.value = 1 - ) - mod = infer_type nodes - nodes[2].target.type.should eq(ObjectType.new('Foo').generic!.with_var('@value', ObjectType.new('Foo').generic!)) - nodes[4].target.type.should eq(ObjectType.new('Foo').generic!.with_var('@value', ObjectType.new('Foo').generic!.with_var('@value', mod.int))) - end - - it "applies return mutation" do - nodes = parse %Q( - #{test_type} - - def foo(x) - r = Foo.new - r.value = x - r - end - - bar = Foo.new - r1 = foo(bar) - r1.value.value = 1 - ) - - mod = infer_type nodes - nodes[2].value.type.should eq(ObjectType.new('Foo').with_var('@value', mod.int)) - end - - it "should apply second return mutation" do - nodes = parse %Q( - class Foo - def foo(x) - @value = Bar.new(x) - end - end - - class Bar - def initialize(x) - @x = x - end - end - - class Baz - def coco - @coco = 1 - end - end - - f = Foo.new - o = Baz.new - f.foo(o) - o.coco - ) - mod = infer_type nodes - nodes[5].obj.type.instance_vars['@value'].type.instance_vars['@x'].type.should be(nodes.last.obj.type) - end -end \ No newline at end of file diff --git a/spec/type_inference/def_spec.rb b/spec/type_inference/def_spec.rb index e28347b9f1e5c0a0180029e68b18665cfd68ed6e..f51b559e4f16daba8b5960516b8c7698a03200a7 100644 --- a/spec/type_inference/def_spec.rb +++ b/spec/type_inference/def_spec.rb @@ -95,20 +95,6 @@ describe 'Type inference: def' do assert_type('def foo(x); x; end; a = 1; a = 1.1; foo(a)') { UnionType.new(int, double) } end - it "doesn't incorrectly type as recursive type" do - assert_type(%Q( - class Foo - #{rw :value} - end - - f = Foo.new - f.value = Foo.new - f.value.value = Foo.new - f - ) - ) { ObjectType.new('Foo').generic!.with_var('@value', ObjectType.new('Foo').generic!.with_var('@value', ObjectType.new('Foo').generic!)) } - end - it "defines class method" do assert_type("def Int.foo; 2.5; end; Int.foo") { double } end @@ -124,12 +110,12 @@ describe 'Type inference: def' do it "do not use body for the def type" do input = parse 'def foo; if false; return 0; end; end; foo' mod = infer_type input - input.last.type.should eq(UnionType.new(mod.int, mod.nil)) + input.last.type.should eq(mod.union_of(mod.int, mod.nil)) input.last.target_def.body.type.should eq(mod.nil) end it "types as nilable if used after scope where defined" do - assert_type("if false; a = 1; end; a") { [int, self.nil].union } + assert_type("if false; a = 1; end; a") { union_of(int, self.nil) } end it "doesn't type as nilable if used inside same scope" do diff --git a/spec/type_inference/global_spec.rb b/spec/type_inference/global_spec.rb index d2f19d9669ecfc8654921d3e28388ded2c2a1bc6..f2a9be2663cc47fefee382ac4e57f9c17f57b2d8 100644 --- a/spec/type_inference/global_spec.rb +++ b/spec/type_inference/global_spec.rb @@ -12,11 +12,11 @@ describe 'Global inference' do it "infers type of global assign with union" do nodes = parse '$foo = 1; $foo = 2.5' mod = infer_type nodes - nodes[0].target.type.should eq([mod.int, mod.double].union) - nodes[1].target.type.should eq([mod.int, mod.double].union) + nodes[0].target.type.should eq(mod.union_of(mod.int, mod.double)) + nodes[1].target.type.should eq(mod.union_of(mod.int, mod.double)) end it "infers type of global reference" do - assert_type("$foo = 1; def foo; $foo = 2.5; end; foo; $foo") { [int, double].union } + assert_type("$foo = 1; def foo; $foo = 2.5; end; foo; $foo") { union_of(int, double) } end end diff --git a/spec/type_inference/is_a_spec.rb b/spec/type_inference/is_a_spec.rb index 45f1c51b784d6c7c402537a06d2876325e6c4a55..5605fc246adc554494302bb1593184b2c049a6b3 100644 --- a/spec/type_inference/is_a_spec.rb +++ b/spec/type_inference/is_a_spec.rb @@ -21,7 +21,7 @@ describe 'Type inference: is_a?' do nodes = parse %q( require "array" - a = [] + a = Array(Int).new if a.is_a?(Enumerable) a end diff --git a/spec/type_inference/pointer_spec.rb b/spec/type_inference/pointer_spec.rb index 2e99e4281bb2e472d541ce4c9cc92e4915a1418b..44bcc0aca857c00d09d66ac6f74eb867a32b52cd 100644 --- a/spec/type_inference/pointer_spec.rb +++ b/spec/type_inference/pointer_spec.rb @@ -2,44 +2,27 @@ require 'spec_helper' describe 'Type inference: pointer' do it "types int pointer" do - assert_type('a = 1; a.ptr') { PointerType.of(int) } + assert_type('a = 1; a.ptr') { pointer_of(int) } end it "types pointer value" do assert_type('a = 1; b = a.ptr; b.value') { int } end - it "types pointer set value" do - assert_type(%q( - class Foo - def foo - p = @value.ptr - p.value = 1 - end - def value - @value - end - end - - f = Foo.new - f.foo - f.value)) { [int, self.nil].union } - end - it "types pointer add" do - assert_type('a = 1; a.ptr + 1') { PointerType.of(int) } + assert_type('a = 1; a.ptr + 1') { pointer_of(int) } end it "types Pointer.malloc" do - assert_type('p = Pointer.malloc(10); p.value = 1; p') { PointerType.of(int) } + assert_type('p = Pointer(Int).malloc(10); p.value = 1; p') { pointer_of(int) } end it "types realloc" do - assert_type('p = Pointer.malloc(10); p.value = 1; x = p.realloc(20); x') { PointerType.of(int) } + assert_type('p = Pointer(Int).malloc(10); p.value = 1; x = p.realloc(20); x') { pointer_of(int) } end it "type pointer casting" do - assert_type('a = 1; a.ptr.as(Char)') { PointerType.of(char) } + assert_type('a = 1; a.ptr.as(Char)') { pointer_of(char) } end it "type pointer casting of object type" do @@ -47,6 +30,6 @@ describe 'Type inference: pointer' do end it "pointer malloc creates new type" do - assert_type('p = Pointer.malloc(1); p.value = 1; p2 = Pointer.malloc(1); p2.value = 1.5; p2.value') { double } + assert_type('p = Pointer(Int).malloc(1); p.value = 1; p2 = Pointer(Double).malloc(1); p2.value = 1.5; p2.value') { double } end end \ No newline at end of file diff --git a/spec/type_inference/primitives_spec.rb b/spec/type_inference/primitives_spec.rb index 20302c5dc4cb6c8f565e72ed65ad4c2d61f69294..f3f41274dcb292c4779d96e987b99a907737e0b6 100644 --- a/spec/type_inference/primitives_spec.rb +++ b/spec/type_inference/primitives_spec.rb @@ -99,7 +99,7 @@ describe 'Type inference: primitives' do assert_type("1.5f.to_f") { float } end - it "types ARGV" do + pending "types ARGV" do assert_type(%q(require "argv"; ARGV)) { array_of(string) } end end \ No newline at end of file diff --git a/spec/type_inference/range_spec.rb b/spec/type_inference/range_spec.rb index 005a1bf139beb55c4a8029202a1c3fb8e87c76f6..5eb24446ee088922a4dd354575c9fad06646d1b9 100644 --- a/spec/type_inference/range_spec.rb +++ b/spec/type_inference/range_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe 'Type inference: range' do - it "types a range" do + pending "types a range" do node = parse 'require "range"; 1..2' mod = infer_type node node.last.type.should be_a(ObjectType) diff --git a/spec/type_inference/return_spec.rb b/spec/type_inference/return_spec.rb index 2b99e295fb785449205b5c2492d67647db446405..54645d634c1cc5562b904e43fea7195413f00da6 100644 --- a/spec/type_inference/return_spec.rb +++ b/spec/type_inference/return_spec.rb @@ -6,6 +6,6 @@ describe 'Type inference: return' do end it "infers return type with many returns" do - assert_type("def foo; if true; return 1; end; 2.5 end; foo") { [int, double].union } + assert_type("def foo; if true; return 1; end; 2.5 end; foo") { union_of(int, double) } end end diff --git a/spec/type_inference/super_spec.rb b/spec/type_inference/super_spec.rb index cc2d0e0321a2b21be259ff0b5fd9b2bb2dd87d00..a37fa3c56166a8138bf1dfee744f4c53d9a34d66 100644 --- a/spec/type_inference/super_spec.rb +++ b/spec/type_inference/super_spec.rb @@ -6,7 +6,9 @@ describe 'Type inference: super' do end it "codegens super without arguments and instance variable" do - assert_type("class Foo; def foo; @x = 1; end; end; class Bar < Foo; def foo; super; end; end; bar = Bar.new; bar.foo; bar") { ObjectType.new('Bar').with_var('@x', int) } + input = parse "class Foo; def foo; @x = 1; end; end; class Bar < Foo; def foo; super; end; end; bar = Bar.new; bar.foo; bar" + mod = infer_type input + mod.types["Bar"].instance_vars["@x"].type.should eq(mod.int) end it "types super without arguments but parent has arguments" do @@ -14,7 +16,7 @@ describe 'Type inference: super' do end it "types super when container method is defined in parent class" do - assert_type(%Q( + input = parse(%Q( class Foo def initialize @x = 1 @@ -28,6 +30,8 @@ describe 'Type inference: super' do class Baz < Bar end Baz.new - )) { ObjectType.new("Baz").with_var("@x", int) } + )) + mod = infer_type input + mod.types["Baz"].instance_vars["@x"].type.should eq(mod.int) end end diff --git a/spec/type_inference/unification_spec.rb b/spec/type_inference/unification_spec.rb index 19fcd02dcdf4ad85f0654477ff89eae37a7f4ac5..76a881439d97e4b37c9d286032f933bea00382a4 100644 --- a/spec/type_inference/unification_spec.rb +++ b/spec/type_inference/unification_spec.rb @@ -56,7 +56,7 @@ describe 'Type inference unification' do end it "unifies array types" do - input = parse 'require "pointer"; require "array"; a = [0, 0]; a[0] = 1; a[1] = 1.1; b = [0, 0]; b[0] = 1; b[1] = 1.1; c = a; c = b' + input = parse 'require "pointer"; require "array"; a = [0, 0.0]; a[0] = 1; a[1] = 1.1; b = [0, 0.0]; b[0] = 1; b[1] = 1.1; c = a; c = b' infer_type input input[-2].value.type.should equal(input[-1].value.type) end @@ -67,7 +67,7 @@ describe 'Type inference unification' do input[1].target.type.should equal(input[2].target.type) end - it "unifies two objects with arrays of unions" do + pending "unifies two objects with arrays of unions" do mod = Crystal::Program.new nodes = Expressions.from [Var.new('a'), Var.new('b')] nodes[0].type = ObjectType.new('Foo').generic!.with_var('@x', mod.array_of(UnionType.new(ObjectType.new('Bar').generic!, ObjectType.new('Bar').generic!))) diff --git a/spec/type_inference/union_spec.rb b/spec/type_inference/union_spec.rb index 44b097e29a3c014d42633f4f91ae290a6629bfc8..9e46ee0ce2bfc6533873f76e9d467a831f0854be 100644 --- a/spec/type_inference/union_spec.rb +++ b/spec/type_inference/union_spec.rb @@ -2,15 +2,15 @@ require 'spec_helper' describe "Type inference: union" do it "types union when obj is union" do - assert_type("a = 1; a = 2.3; a + 1") { UnionType.new(int, double) } + assert_type("a = 1; a = 2.3; a + 1") { union_of(int, double) } end it "types union when arg is union" do - assert_type("a = 1; a = 2.3; 1 + a") { UnionType.new(int, double) } + assert_type("a = 1; a = 2.3; 1 + a") { union_of(int, double) } end it "types union when both obj and arg are union" do - assert_type("a = 1; a = 2.3; a + a") { UnionType.new(int, double) } + assert_type("a = 1; a = 2.3; a + a") { union_of(int, double) } end it "unifies unions when instance var changes" do @@ -28,7 +28,8 @@ describe "Type inference: union" do )) mod = infer_type nodes - expected_type = ObjectType.new("A").with_var("@next", UnionType.new(mod.int, mod.double)) + expected_type = mod.types["A"] + expected_type.instance_vars["@next"].type.should eq(mod.union_of(mod.int, mod.double)) nodes[1].type.should eq(expected_type) nodes[2].target_def.owner.should eq(expected_type) @@ -53,7 +54,8 @@ describe "Type inference: union" do )) mod = infer_type nodes - expected_type = ObjectType.new("A").with_var("@next", UnionType.new(mod.int, mod.double)) + expected_type = mod.types["A"] + expected_type.instance_vars["@next"].type.should eq(mod.union_of(mod.int, mod.double)) nodes[1].type.should eq(expected_type) nodes[2].target_def.owner.should eq(expected_type) @@ -69,6 +71,6 @@ describe "Type inference: union" do end it "types union of classes" do - assert_type("class A; end; class B; end; a = A.new; a = B.new; a") { UnionType.new(ObjectType.new('A'), ObjectType.new('B')) } + assert_type("class A; end; class B; end; a = A.new; a = B.new; a") { union_of(types["A"], types["B"]) } end end \ No newline at end of file diff --git a/spec/types/type_clone_spec.rb b/spec/types/type_clone_spec.rb index bb3a49826bf65620e4f10c9ff468e66995264fdd..c58b5d8e9ae292f9d6cac989dcdb7243c41fff72 100644 --- a/spec/types/type_clone_spec.rb +++ b/spec/types/type_clone_spec.rb @@ -25,12 +25,4 @@ describe "Type clone" do type = mod.array_of(mod.int) type.clone.should eq(type) end - - it "clone object type with recursive union type" do - type = ObjectType.new("Foo") - type.with_var("@foo", [type, mod.int].union) - type_clone = type.clone - type_clone.should eq(type) - type_clone.instance_vars["@foo"].type.types.first.should be(type_clone) - end end \ No newline at end of file diff --git a/std/regexp.cr b/std/regexp.cr index 29b44402fecc16d67cf8180b4488dd830b5b41fa..8d746b9fa3ff7f1ed83d5d38eba17cb7aa2853e9 100644 --- a/std/regexp.cr +++ b/std/regexp.cr @@ -12,7 +12,7 @@ class Regexp def initialize(str) @source = str - errptr = Pointer.malloc(0).as(Char) + errptr = Pointer(Char).malloc(0) erroffset = 1 @re = PCRE.compile(str, 8, errptr.ptr, erroffset.ptr, 0L) if @re == 0 @@ -24,7 +24,7 @@ class Regexp def match(str, pos = 0, options = 0) ovector_size = (@captures + 1) * 3 - ovector = Pointer.malloc(ovector_size * 4).as(Int) + ovector = Pointer(Int).malloc(ovector_size * 4) ret = PCRE.exec(@re, 0L, str, str.length, pos, options, ovector, ovector_size) return nil unless ret > 0 MatchData.new(self, str, pos, ovector)