Skip to content

Commit

Permalink
Raise type inferred from failed dispatch+privacy. IssueID: michaeledg…
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Edgar committed Jul 26, 2011
1 parent a172091 commit d42ed31
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 0 deletions.
7 changes: 7 additions & 0 deletions lib/laser/analysis/control_flow/constant_propagation.rb
Expand Up @@ -394,10 +394,17 @@ def raisability_for_templates(possible_dispatches, cartesian, ignore_privacy)
then Frequency::NEVER
else Frequency.for_samples(seen_private, seen_public)
end
if fails_privacy == Frequency::ALWAYS
raise_type = ClassRegistry['NoMethodError'].as_type
end
if fails_lookup > Frequency::NEVER
raise_type |= ClassRegistry['NoMethodError'].as_type
end
raised = Frequency.for_samples(seen_raise, seen_succeed)
raise_freq = [fails_privacy, raised, fails_lookup].max
else
raise_freq = Frequency::ALWAYS # no method!
raise_type = ClassRegistry['NoMethodError'].as_type
end
[raise_freq, raise_type]
end
Expand Down
2 changes: 2 additions & 0 deletions lib/laser/standard_library/bignum.rb
Expand Up @@ -74,6 +74,8 @@ def ===(num)
# pure: true
# builtin: true
# returns: Boolean
# num: Numeric
# raises: never
def >(num)
end
# pure: true
Expand Down
2 changes: 2 additions & 0 deletions lib/laser/standard_library/fixnum.rb
Expand Up @@ -73,6 +73,8 @@ def ===(num)
# pure: true
# builtin: true
# returns: Boolean
# num: Numeric
# raises: never
def >(num)
end
# pure: true
Expand Down
35 changes: 35 additions & 0 deletions spec/analysis_specs/control_flow_specs/raise_properties_spec.rb
Expand Up @@ -165,5 +165,40 @@ def silly(x)
[Types::FIXNUM],
Types::NILCLASS).should == Frequency::ALWAYS
end

it 'can infer a guaranteed NoMethodError from privacy violations' do
g = cfg <<-EOF
class RInfer5
def foo
end
private :foo
def bar
self.foo # error!
end
end
EOF
method = ClassRegistry['RInfer5'].instance_method('bar')
method.raise_frequency_for_types(
Utilities.type_for(ClassRegistry['RInfer5'])).should == Frequency::ALWAYS
end

it 'can infer a potential lookup failure when a successful one exists' do
g = cfg <<-EOF
class RInfer6
def bar
if gets.size > 0
x = 'hello'
else
x = 5
end
x.intern # error sometimes
end
end
EOF
method = ClassRegistry['RInfer6'].instance_method('bar')
method.raise_frequency_for_types(
Utilities.type_for(ClassRegistry['RInfer6'])).should == Frequency::MAYBE
end
end

Expand Up @@ -146,4 +146,41 @@ def silly(x)
[Types::FIXNUM],
Types::NILCLASS).should equal_type(ClassRegistry['NoMethodError'].as_type)
end

it 'can infer a guaranteed NoMethodError from privacy violations' do
g = cfg <<-EOF
class RTInfer5
def foo
end
private :foo
def bar
self.foo # error!
end
end
EOF
method = ClassRegistry['RTInfer5'].instance_method('bar')
method.raise_type_for_types(
Utilities.type_for(ClassRegistry['RTInfer5'])).should(
equal_type(ClassRegistry['NoMethodError'].as_type))
end

it 'can infer a potential lookup failure when a successful one exists' do
g = cfg <<-EOF
class RTInfer6
def bar
if gets.size > 0
x = 'hello'
else
x = 5
end
x.intern # error sometimes
end
end
EOF
method = ClassRegistry['RTInfer6'].instance_method('bar')
method.raise_type_for_types(
Utilities.type_for(ClassRegistry['RTInfer6'])).should(
equal_type(ClassRegistry['NoMethodError'].as_type))
end
end

0 comments on commit d42ed31

Please sign in to comment.