-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Crystal parser to_s
can produce invalid code
#5997
Comments
Yes, the shortcut |
@asterite I think this feature is really nice and the issues are not entirely unsolvable, nor are they serious enough to make it completely fail. For #3413 it'd be relatively easy to disallow ivars as default values and the problem is solved while still being able to set ivars from method arguments. For this issue here I'd suggest to disallow ivars as arguments that are actually a keyword (this would match with #5930 smoothly). This is a little confinement but still keeps the feature usable and productive, without many problems. At least none that I'm aware of. |
Oh, actually, we should just change how they are expanded. I tried it yesterday but got flooded with "invalid memory access" after doing the change and got demotivated. It will also solve a few other problems. The idea is to expand this: def foo(@var)
end to this: def foo(var __arg0)
@var = __arg0
end I'll try it later, I'll see if I can make it work. |
I think the fix could break some code if applied in every case (well it's not a big breaking however). def method(@var)
puts var #Works currently in crystal
end Should it be transposed to |
Changing the expansion is also a viable option. However, it makes it difficult to access the argument value as local variable. def foo(@var)
var.do_something # => undefined local variable or method 'var'
end This seems to be a high price compared to the alternative to simply disallow a few error-prone variable names. |
No, no, it's ok to change that behaviour: If you have a method |
@asterite I agree that class Foo
@value : Int32?
def set(@value : Int32)
pp typeof(value) # => Int32
pp typeof(@value) # => Int32 | Nil
end
end
Foo.new.set(4) But then the user can remove the |
Okay, sounds good. Accessing a ivar argument as local variable is probably a less-known feature anyway. The workaround is easy and more expressive. And avoids surprises as described in #4332. |
Context
Hello, I'm playing around with the Crystal::Visitor, Parser, AST node and so.
I'm trying to implement a coverage binary which enrich the code with coverage operations.
So far, I've made a proof of concept which is working is most of the cases (note: it's a PoC, the code is ugly) : https://github.com/anykeyh/crystal-coverage.
For that, I'm using the syntax visitor and crystal parser to regenerate code with additional instructions.
I'm also expanding all the relative
require
to generate one file only enriched with the coverage code. I assume the exported file can be passed tocrystal eval
operation.Example of code:
Same code enriched using the coverage binary:
Problem
Since I depend heavily on
to_s
of the nodes, I've noticed a case where the code outputted is not valid code:The AST
to_s
method will produceSince
select
is a reserved keyword, the code will not be evaluable. It obviously happens for any reserved keywords.How to reproduce
The text was updated successfully, but these errors were encountered: