Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: crystal-lang/crystal
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: a8783e211f39
Choose a base ref
...
head repository: crystal-lang/crystal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 60d9c4f46f55
Choose a head ref
  • 3 commits
  • 6 files changed
  • 1 contributor

Commits on Dec 30, 2016

  1. Let IO#skip raise if there aren't enough bytes

    Ary Borenszweig committed Dec 30, 2016
    Copy the full SHA
    a712c7e View commit details
  2. Add IO#skip_to_end

    Ary Borenszweig committed Dec 30, 2016
    Copy the full SHA
    5e9bf6e View commit details
  3. Let method_missing work with with ... yield. Fixes #1808

    Ary Borenszweig committed Dec 30, 2016
    Copy the full SHA
    60d9c4f View commit details
Showing with 77 additions and 6 deletions.
  1. +22 −0 spec/compiler/codegen/method_missing_spec.cr
  2. +19 −0 spec/compiler/semantic/method_missing_spec.cr
  3. +15 −0 spec/std/io/io_spec.cr
  4. +6 −0 src/compiler/crystal/semantic/call.cr
  5. +1 −3 src/http/content.cr
  6. +14 −3 src/io.cr
22 changes: 22 additions & 0 deletions spec/compiler/codegen/method_missing_spec.cr
Original file line number Diff line number Diff line change
@@ -408,4 +408,26 @@ describe "Code gen: method_missing" do
a.b(x: 1, y: 2)
)).to_i.should eq(3)
end

it "finds method_missing with 'with ... yield'" do
run(%(
class Foo
def initialize(@x : Int32)
end
macro method_missing(call)
@{{call.name.id}}
end
end
def bar
foo = Foo.new(10)
with foo yield
end
bar do
x
end
)).to_i.should eq(10)
end
end
19 changes: 19 additions & 0 deletions spec/compiler/semantic/method_missing_spec.cr
Original file line number Diff line number Diff line change
@@ -73,4 +73,23 @@ describe "Semantic: method_missing" do
),
"wrong method_missing expansion"
end

it "finds method_missing with 'with ... yield'" do
assert_type(%(
class Foo
macro method_missing(call)
1
end
end
def bar
foo = Foo.new
with foo yield
end
bar do
baz
end
)) { int32 }
end
end
15 changes: 15 additions & 0 deletions spec/std/io/io_spec.cr
Original file line number Diff line number Diff line change
@@ -477,6 +477,21 @@ describe IO do
io.skip(6)
io.gets_to_end.should eq("world")
end

it "skips but raises if not enough bytes" do
io = SimpleIOMemory.new
io << "hello"
expect_raises(IO::EOFError) do
io.skip(6)
end
end

it "skips to end" do
io = SimpleIOMemory.new
io << "hello"
io.skip_to_end
io.read_byte.should be_nil
end
end

describe "encoding" do
6 changes: 6 additions & 0 deletions src/compiler/crystal/semantic/call.cr
Original file line number Diff line number Diff line change
@@ -237,6 +237,12 @@ class Crystal::Call
defined_method_missing = owner.check_method_missing(signature, self)
if defined_method_missing
matches = owner.lookup_matches(signature)
elsif with_scope = @with_scope
defined_method_missing = with_scope.check_method_missing(signature, self)
if defined_method_missing
matches = with_scope.lookup_matches(signature)
@uses_with_scope = true
end
end
end

4 changes: 1 addition & 3 deletions src/http/content.cr
Original file line number Diff line number Diff line change
@@ -2,9 +2,7 @@ module HTTP
# :nodoc:
module Content
def close
buffer = uninitialized UInt8[1024]
while read(buffer.to_slice) > 0
end
skip_to_end
super
end
end
17 changes: 14 additions & 3 deletions src/io.cr
Original file line number Diff line number Diff line change
@@ -727,20 +727,31 @@ module IO
gets(*args, **options) || raise EOFError.new
end

# Reads and discards *bytes_count* bytes.
# Reads and discards exactly *bytes_count* bytes.
# Raises IO::EOFError if there aren't at least *bytes_count* bytes.
#
# ```
# io = IO::Memory.new "hello world"
# io.skip(6)
# io.gets # => "world"
# io.gets # => "world"
# io.skip(1) # raises IO::EOFError
# ```
def skip(bytes_count : Int) : Nil
buffer = uninitialized UInt8[1024]
while bytes_count > 0
read_count = read(buffer.to_slice[0, bytes_count])
raise IO::EOFError.new if read_count == 0

bytes_count -= read_count
end
nil
end

# Reads and discards bytes from `self` until there
# are no more bytes.
def skip_to_end : Nil
buffer = uninitialized UInt8[1024]
while read(buffer.to_slice) > 0
end
end

# Writes a single byte into this IO.