require "../../spec_helper" describe "Semantic: new" do it "doesn't incorrectly redefines new for generic class" do assert_type(<<-CRYSTAL) { int32 } class Foo(T) def self.new 1 end end Foo(Int32).new CRYSTAL end it "evaluates initialize default value at the instance scope (1) (#731)" do assert_type(<<-CRYSTAL) { types["Foo"] } class Foo def initialize(@x = self) end def x @x end end Foo.new.x CRYSTAL end it "evaluates initialize default value at the instance scope (2) (#731)" do assert_type(<<-CRYSTAL) { char } class Foo def initialize(@x = self, @y = 'a') end def y @y end end Foo.new(y: 'b').y CRYSTAL end it "evaluates initialize default value at the instance scope (3) (#731)" do assert_type(<<-CRYSTAL) { int32 } class Foo @x : Int32 def initialize(@x = bar) yield 1, 2 end def x @x end def bar 1 end end foo = Foo.new do |x, y| end foo.x CRYSTAL end it "evaluates initialize default value at the instance scope (4) (#731)" do assert_type(<<-CRYSTAL) { int32 } class Foo @x : Int32 def initialize(@x = bar, &@block : ->) end def x @x end def bar 1 end end foo = Foo.new do end foo.x CRYSTAL end it "evaluates initialize default value at the instance scope (5) (#731)" do assert_type(<<-CRYSTAL, inject_primitives: true) { int32 } class Foo(R) @x : Int32 def initialize(@x = bar, &@block : -> R) end def bar 10 end def r @block.call end end Foo.new { 1 }.r CRYSTAL end it "evaluates initialize default value at the instance scope (6) (#731)" do assert_type(<<-CRYSTAL, inject_primitives: true) { int32 } class Foo(R) @x : Int32 def initialize(@x = bar, &@block : -> R) end def bar 10 end def r @block.call end end Foo(Int32).new { 1 }.r CRYSTAL end it "errors if using self call in default argument (1)" do assert_error <<-CRYSTAL, "instance variable '@caps' of My was not initialized directly in all of the 'initialize' methods, rendering it nilable. Indirect initialization is not supported." class My @name : String @caps : String def initialize(@name, caps = self.name) x = caps @caps = x end def name @name end end My.new("foo") CRYSTAL end it "errors if using self call in default argument (2)" do assert_error <<-CRYSTAL, "instance variable '@caps' of My was not initialized directly in all of the 'initialize' methods, rendering it nilable. Indirect initialization is not supported." class My @name : String @caps : String def initialize(@name, caps = self.name) @caps = caps end def name @name end end My.new("foo") CRYSTAL end it "errors if using self call in default argument (3)" do assert_error <<-CRYSTAL, "instance variable '@caps' of My was not initialized directly in all of the 'initialize' methods, rendering it nilable. Indirect initialization is not supported." class My @name : String @caps : String def initialize(@name, @caps = self.name) end def name @name end end My.new("foo") CRYSTAL end it "inherits initialize and new methods if doesn't define new (#3238)" do assert_type(<<-CRYSTAL) { types["Bar"] } class Foo(T) def initialize(x : Int32) end def self.new(x : Char) new(1) end end class Bar < Foo(Int32) end Bar.new('a') CRYSTAL end it "doesn't have default new for inherited class from generic type" do assert_error <<-CRYSTAL, "wrong number of arguments for 'Bar.new' (given 0, expected 1)" class Foo(T) def initialize(x : Int32) end end class Bar < Foo(Int32) end Bar.new CRYSTAL end it "uses correct receiver for `initialize` in namespaced generic classes (#4086)" do assert_type <<-CRYSTAL { char } class Foo class Baz(T) end module Bar class Baz(T) < Foo def initialize(x) end def foo 'a' end end end end Foo::Bar::Baz(Int32).new(1).foo CRYSTAL end end