Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add restrictions to collection methods. Fixes #1764. Fixes #988 #2996

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion spec/std/hash_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,6 @@ describe "Hash" do

describe "select!" do
assert { {:a => 2, :b => 3}.select!(:b, :d).should eq({:b => 3}) }
assert { {:a => 2, :b => 3}.select!.should eq({} of Symbol => Int32) }
assert { {:a => 2, :b => 3}.select!(:b, :a).should eq({:a => 2, :b => 3}) }
assert { {:a => 2, :b => 3}.select!([:b, :a]).should eq({:a => 2, :b => 3}) }
it "does change currrent hash" do
Expand Down
96 changes: 4 additions & 92 deletions spec/std/set_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,9 @@ describe "Set" do

it "does |" do
set1 = Set{1, 2, 3}
set2 = Set{4, 2, 5, "3"}
set2 = Set{4, 2, 5, 9}
set3 = set1 | set2
set3.should eq(Set{1, 2, 3, 4, 5, "3"})
set3.should eq(Set{1, 2, 3, 4, 5, 9})
end

it "does -" do
Expand All @@ -135,125 +135,41 @@ describe "Set" do
set3.should eq(Set{1, 3, 5})
end

it "does -" do
set1 = Set{1, 2, 3, 4, 5}
set2 = Set{2, 4, 'a'}
set3 = set1 - set2
set3.should eq(Set{1, 3, 5})
end

it "does -" do
set1 = Set{1, 2, 3, 4, 'b'}
set2 = Set{2, 4, 5}
set3 = set1 - set2
set3.should eq(Set{1, 3, 'b'})
end

it "does -" do
set1 = Set{1, 2, 3, 4, 5}
set2 = [2, 4, 6]
set3 = set1 - set2
set3.should eq(Set{1, 3, 5})
end

it "does -" do
set1 = Set{1, 2, 3, 4, 5}
set2 = [2, 4, 'a']
set3 = set1 - set2
set3.should eq(Set{1, 3, 5})
end

it "does -" do
set1 = Set{1, 2, 3, 4, 'b'}
set2 = [2, 4, 5]
set3 = set1 - set2
set3.should eq(Set{1, 3, 'b'})
end

it "does ^" do
set1 = Set{1, 2, 3, 4, 5}
set2 = Set{2, 4, 6}
set3 = set1 ^ set2
set3.should eq(Set{1, 3, 5, 6})
end

it "does ^" do
set1 = Set{1, 2, 3, 4, 5}
set2 = Set{2, 4, 'a'}
set3 = set1 ^ set2
set3.should eq(Set{1, 3, 5, 'a'})
end

it "does ^" do
set1 = Set{1, 2, 3, 4, 'b'}
set2 = Set{2, 4, 5}
set3 = set1 ^ set2
set3.should eq(Set{1, 3, 5, 'b'})
end

it "does ^" do
set1 = Set{1, 2, 3, 4, 5}
set2 = [2, 4, 6]
set3 = set1 ^ set2
set3.should eq(Set{1, 3, 5, 6})
end

it "does ^" do
set1 = Set{1, 2, 3, 4, 5}
set2 = [2, 4, 'a']
set3 = set1 ^ set2
set3.should eq(Set{1, 3, 5, 'a'})
end

it "does ^" do
set1 = Set{1, 2, 3, 4, 'b'}
set2 = [2, 4, 5]
set3 = set1 ^ set2
set3.should eq(Set{1, 3, 5, 'b'})
end

it "does subtract" do
set1 = Set{1, 2, 3, 4, 5}
set2 = Set{2, 4, 6}
set1.subtract set2
set1.should eq(Set{1, 3, 5})
end

it "does subtract" do
set1 = Set{1, 2, 3, 4, 5}
set2 = Set{2, 4, 'a'}
set1.subtract set2
set1.should eq(Set{1, 3, 5})
end

it "does subtract" do
set1 = Set{1, 2, 3, 4, 'b'}
set2 = Set{2, 4, 5}
set1.subtract set2
set1.should eq(Set{1, 3, 'b'})
end

it "does subtract" do
set1 = Set{1, 2, 3, 4, 5}
set2 = [2, 4, 6]
set1.subtract set2
set1.should eq(Set{1, 3, 5})
end

it "does subtract" do
set1 = Set{1, 2, 3, 4, 5}
set2 = [2, 4, 'a']
set1.subtract set2
set1.should eq(Set{1, 3, 5})
end

it "does subtract" do
set1 = Set{1, 2, 3, 4, 'b'}
set2 = [2, 4, 5]
set1.subtract set2
set1.should eq(Set{1, 3, 'b'})
end

it "does to_a" do
Set{1, 2, 3}.to_a.should eq([1, 2, 3])
end
Expand Down Expand Up @@ -311,7 +227,6 @@ describe "Set" do
empty_set = Set(Int32).new

set.subset?(Set{1, 2, 3, 4}).should be_true
set.subset?(Set{1, 2, 3, "4"}).should be_true
set.subset?(Set{1, 2, 3}).should be_true
set.subset?(Set{1, 2}).should be_false
set.subset?(empty_set).should be_false
Expand All @@ -325,7 +240,6 @@ describe "Set" do
empty_set = Set(Int32).new

set.proper_subset?(Set{1, 2, 3, 4}).should be_true
set.proper_subset?(Set{1, 2, 3, "4"}).should be_true
set.proper_subset?(Set{1, 2, 3}).should be_false
set.proper_subset?(Set{1, 2}).should be_false
set.proper_subset?(empty_set).should be_false
Expand All @@ -335,12 +249,11 @@ describe "Set" do
end

it "check superset" do
set = Set{1, 2, "3"}
set = Set{1, 2, 33}
empty_set = Set(Int32).new

set.superset?(empty_set).should be_true
set.superset?(Set{1, 2}).should be_true
set.superset?(Set{1, 2, "3"}).should be_true
set.superset?(Set{1, 2, 3}).should be_false
set.superset?(Set{1, 2, 3, 4}).should be_false
set.superset?(Set{1, 4}).should be_false
Expand All @@ -349,12 +262,11 @@ describe "Set" do
end

it "check proper_superset" do
set = Set{1, 2, "3"}
set = Set{1, 2, 33}
empty_set = Set(Int32).new

set.proper_superset?(empty_set).should be_true
set.proper_superset?(Set{1, 2}).should be_true
set.proper_superset?(Set{1, 2, "3"}).should be_false
set.proper_superset?(Set{1, 2, 3}).should be_false
set.proper_superset?(Set{1, 2, 3, 4}).should be_false
set.proper_superset?(Set{1, 4}).should be_false
Expand Down
19 changes: 14 additions & 5 deletions src/array.cr
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ class Array(T)
# ```
#
# See also: `#uniq`.
def &(other : Array(U))
def &(other : Array(T))
return Array(T).new if self.empty? || other.empty?

hash = other.to_lookup_hash
Expand Down Expand Up @@ -272,7 +272,7 @@ class Array(T)
# ```
# [1, 2, 3] - [2, 1] # => [3]
# ```
def -(other : Array(U))
def -(other : Array(T))
ary = Array(T).new(Math.max(size - other.size, 0))
hash = other.to_lookup_hash
each do |obj|
Expand Down Expand Up @@ -663,7 +663,16 @@ class Array(T)
# ary # => ["a", "b", "c"]
# ```
def compact!
delete nil
found = false
reject! do |obj|
if obj.nil?
found = true
true
else
false
end
end
found
end

# Appends the elements of *other* to `self`, and returns `self`.
Expand Down Expand Up @@ -715,7 +724,7 @@ class Array(T)
# a.delete("b")
# a # => ["a", "c"]
# ```
def delete(obj)
def delete(obj : T)
reject! { |e| e == obj } != nil
end

Expand Down Expand Up @@ -1615,7 +1624,7 @@ class Array(T)
ReverseIterator.new(self)
end

def rindex(value)
def rindex(value : T)
rindex { |elem| elem == value }
end

Expand Down
2 changes: 1 addition & 1 deletion src/compiler/crystal/command.cr
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ class Crystal::Command

output_filename ||= original_output_filename
output_format ||= "text"
if !["text", "json"].includes?(output_format)
unless {"text", "json"}.includes?(output_format.not_nil!)
error "You have input an invalid format, only text and JSON are supported"
end

Expand Down
3 changes: 2 additions & 1 deletion src/compiler/crystal/syntax/parser.cr
Original file line number Diff line number Diff line change
Expand Up @@ -3168,7 +3168,8 @@ module Crystal
end

def check_valid_def_name
if {:is_a?, :as, :as?, :responds_to?, :nil?}.includes?(@token.value)
value = @token.value
if value.is_a?(Symbol) && {:is_a?, :as, :as?, :responds_to?, :nil?}.includes?(value)
raise "'#{@token.value}' is a pseudo-method and can't be redefined", @token
end
end
Expand Down
2 changes: 1 addition & 1 deletion src/deque.cr
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ class Deque(T)
# a.delete("b")
# a # => Deque{"a", "c"}
# ```
def delete(obj)
def delete(obj : T)
found = false
i = 0
while i < @size
Expand Down
6 changes: 3 additions & 3 deletions src/enumerable.cr
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ module Enumerable(T)
#
# [1, 2, 3, 4].count(3) #=> 1
#
def count(item)
def count(item : T)
count { |e| e == item }
end

Expand Down Expand Up @@ -327,7 +327,7 @@ module Enumerable(T)
# [1, 2, 3].includes?(2) #=> true
# [1, 2, 3].includes?(5) #=> false
#
def includes?(obj)
def includes?(obj : T)
any? { |e| e == obj }
end

Expand All @@ -348,7 +348,7 @@ module Enumerable(T)
# ["Alice", "Bob"].index("Alice") #=> 0
#
# Returns `nil` if *obj* is not in the collection.
def index(obj)
def index(obj : T)
index { |e| e == obj }
end

Expand Down
Loading