crystal-coverage
crystal-coverage copied to clipboard
Compile time error for nested expressions
My project does not compile using the coverage binary. I was able to reproduce the first problem with this code:
class Repro
@param = 1
CONST = 1
def call
chained.result(CONST * (@param + 1))
end
def chained
self
end
def result(param)
1
end
end
Which results in
Syntax error in src/repro.cr:6: unterminated call
chained.result(CONST * (@param + 1))
Looking at the generated code its obsious why:
def call
::Coverage[1, 2]; #<loc:"src/repro.cr",5,0>
chained.result(CONST * ( ::Coverage[1, 3]; #<loc:"src/repro.cr",5,0>
@param + 1
))
end
::Coverage[1, 1]; #<loc:"src/repro.cr",2,0>
CONST = 1
def call ::Coverage[1, 2]; #loc:"src/repro.cr",5,0 chained.result(CONST * ( ::Coverage[1, 3]; #loc:"src/repro.cr",5,0 @param + 1 )) end def chained ::Coverage[1, 4]; #loc:"src/repro.cr",9,0 self end def result(param) ::Coverage[1, 5]; #loc:"src/repro.cr",13,0 1 end end
</details>
Can even be boiled down to
class Repro
def call
(1 * (@param + 1))
end
end
which then is a
Syntax error in src/repro.cr:2: unexpected token: NEWLINE
def call
^
Generated code:
::Coverage[0, 0]; #loc:"spec/repro_spec.cr",3,0 describe("foo") do ::Coverage[0, 1]; #loc:"spec/repro_spec.cr",4,0 it("breaks") do ::Coverage[0, 2]; #loc:"spec/repro_spec.cr",5,0 Repro.new.call.should(eq(1)) end end
::Coverage.get_results(Coverage::Outputter::HtmlReport.new)
The original code it fails on for me is:
def latest(page : Int = 1)
published_at.lte(Time.now)
.published_at.desc_order
.limit(PER_PAGE)
.offset(PER_PAGE * (page - 1))
end
I won't fix; I have plans to integrate the covering system directly into Crystal compiler, which would makes pipelining way more easy since we won't produces half-baked code in between.
The only hiccups is I don't know when I will have time to implement it 😄
This PR from the Crystal compiler seems to fix this issue: https://github.com/crystal-lang/crystal/pull/11739