I noticed that the crystal compiler does not validate unused code. IMHO, crystal should check the unused code, if I write a library, If I don't write a test that uses my code, the issue may not be found until someone includes the code in their project.
Example:
The following example compiles and runs:
class Foo
def bar
this_is_not_a_method_or_var
end
end
puts Foo.new
$ crystal run ./sample.cr
#<Foo:0x108335ff0>
It does not fail until you call the code that uses the invalid code.
class Foo
def bar
this_is_not_a_method_or_var
end
end
puts Foo.new.bar
$ crystal run ./sample.cr
puts Foo.new.bar
^~~
in script.cr:4: undefined local variable or method 'this_is_not_a_method_or_var'
this_is_not_a_method_or_var
^~~~~~~~~~~~~~~~~~~~~~~~~~~
This is a duplicate of some other issue, and there was a good reason for it (namely, checking all unused code would seriously slow down builds).
FWIW it's not any dead code, but just methods that are never called. If you can make a library with methods that never get called, your tests are screwed up anyway...
Similar to: #3801 (but this was for compiler sources, but it's the same issue)
I think a special flag --dead-code or crystal tool dead-code would be a good idea!
@jwaldrip - meaning: you're actually writing code you never run and you let your users test for the first time!!?? Makes no sense. Write tests. Or use them yourself. Why write code that is never used?
@ozra I think this is mostly about accidentally written dead code. Human is not ideal and can do mistakes. And we all are looking for a great software that can help to avoid those mistakes. This is what we love Crystal for :)
It does not fail until you call the code that uses the invalid code.
Please note that the error is coming at compile time, not execution time. Since you're using crystal run it might be confusing, but Crystal doesn't evaluate or validate code that is not invoked.
Now, in relation to testing, that is a complete different subject 馃槃
@veelenga - sometimes I wish I spent one more second thinking before writing ;-)
Code-coverage check feature!
Is this really for dead code, though? OP wrote:
f I write a library, If I don't write a test that uses my code, the issue may not be found until someone includes the code in their project.
which would imply that the code is very much not dead. Maybe zombie code, but not dead.
There are different scenarios.
The compiler right now is lazy in the sense that won't analyze that the method types unless there is an invocation. Because from the invocation the type of the arguments will be known and the type analysis can begin. This is something that could change. Maybe leading to have 3. as a consequence of the compiler/typing process or it could be added as a phase to check. But adding it as an additional phase will slow thing a bit more today since it will require to identify 1. first and check 3. from them.
I'd definitely vote for on demand static analysis, not bloating the regular compilation process.
This is the same as in Ruby: unused code is not checked, because it's not instantiated. If we want to change this it means we need to add mandatory types for method arguments, traits, interfaces, etc.
@veelenga Interesting issue, Can ameba help with this?
Most helpful comment
@ozra I think this is mostly about accidentally written dead code. Human is not ideal and can do mistakes. And we all are looking for a great software that can help to avoid those mistakes. This is what we love Crystal for :)