Skip to content

Commit

Permalink
Compiler: Avoid showing duplicate entries as warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
bcardiff committed Apr 4, 2019
1 parent 4667ae2 commit 8a60d93
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 4 deletions.
72 changes: 72 additions & 0 deletions spec/compiler/codegen/warnings_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,78 @@ describe "Code gen: warnings" do
inject_primitives: false
end

it "informs warnings once per call site location (a)" do
warning_failures = warnings_result %(
class Foo
@[Deprecated("Do not use me")]
def m
end
def b
m
end
end
Foo.new.b
Foo.new.b
), inject_primitives: false

warning_failures.size.should eq(1)
end

it "informs warnings once per call site location (b)" do
warning_failures = warnings_result %(
class Foo
@[Deprecated("Do not use me")]
def m
end
end
Foo.new.m
Foo.new.m
), inject_primitives: false

warning_failures.size.should eq(2)
end

it "informs warnings once per yield" do
warning_failures = warnings_result %(
class Foo
@[Deprecated("Do not use me")]
def m
end
end
def twice
yield
yield
end
twice { Foo.new.m }
), inject_primitives: false

warning_failures.size.should eq(1)
end

it "informs warnings once per target type" do
warning_failures = warnings_result %(
class Foo(T)
@[Deprecated("Do not use me")]
def m
end
def b
m
end
end
Foo(Int32).new.b
Foo(Int64).new.b
), inject_primitives: false

warning_failures.size.should eq(2)
end

it "ignore deprecation excluded locations" do
with_tempfile("check_warnings_excludes") do |path|
FileUtils.mkdir_p File.join(path, "lib")
Expand Down
11 changes: 8 additions & 3 deletions spec/spec_helper.cr
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def assert_error(str, message, inject_primitives = true)
end
end

def assert_warning(code, message, inject_primitives = true)
def warnings_result(code, inject_primitives = true)
code = inject_primitives(code) if inject_primitives

output_filename = Crystal.tempfile("crystal-spec-output")
Expand All @@ -119,8 +119,13 @@ def assert_warning(code, message, inject_primitives = true)
compiler.prelude = "empty" # avoid issues in the current std lib
result = compiler.compile Compiler::Source.new("code.cr", code), output_filename

result.program.warning_failures.size.should eq(1)
result.program.warning_failures[0].should start_with(message)
result.program.warning_failures
end

def assert_warning(code, message, inject_primitives = true)
warning_failures = warnings_result(code, inject_primitives)
warning_failures.size.should eq(1)
warning_failures[0].should start_with(message)
end

def assert_macro(macro_args, macro_body, call_args, expected, expected_pragmas = nil, flags = nil)
Expand Down
11 changes: 10 additions & 1 deletion src/compiler/crystal/codegen/warnings.cr
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,26 @@ module Crystal
end

class CodeGenVisitor
@deprecated_methods_detected = Set(String).new

def check_call_to_deprecated_method(node : Call)
return unless @program.warnings.all?

if (ann = node.target_def.annotation(@program.deprecated_annotation)) &&
(deprecated_annotation = DeprecatedAnnotation.from(ann))
return if ignore_warning_due_to_location(node.location)
short_reference = node.target_def.short_reference
warning_key = node.location.try { |l| "#{short_reference} #{l}" }

# skip warning if the call site was already informed
# if there is no location information just inform it.
return if !warning_key || @deprecated_methods_detected.includes?(warning_key)
@deprecated_methods_detected.add(warning_key) if warning_key

message = deprecated_annotation.message
message = message ? " #{message}" : ""

full_message = node.warning "Deprecated #{node.target_def.short_reference}.#{message}"
full_message = node.warning "Deprecated #{short_reference}.#{message}"

@program.warning_failures << full_message
end
Expand Down

0 comments on commit 8a60d93

Please sign in to comment.