Closed jackc closed 9 years ago
Yes, thanks for the feedback. It’s true that gen needs a compilable project – first it needs valid syntax to get an AST, and in turn it needs semantic validity to evaluate types.
What was the text of the error in your case? I wonder if we might communicate it better.
There have been suggestions in the past that there may be scenarios where gen can proceed even in the absence of correct code, but I haven’t been convinced. Basically, too heuristic (non-deterministic) for my taste, but deserves more thinking.
You can duplicate the problem by deleting a gen generated file that is used by the rest of the package.
jack@edi:~/dev/go/src/github.com/jackc/jchat/backend$ rm user_signal.go
jack@edi:~/dev/go/src/github.com/jackc/jchat/backend$ gen
repository.go:33:23: undeclared name: UserSignal
exit status 1
Yeah. Correct but a usability problem. Not sure what can be done, ideas?
Maybe just an explanation with the error message. It's reasonable to require a compilable project, it's just not immediately obvious that that is the problem.
Maybe something like "Project must be compilable to generate code" before the line number of the compile error.
@jackc I may have a way forward here. https://groups.google.com/d/msg/golang-nuts/0uA0E1kf0Y4/chNYS6gYk3oJ
That would be pretty cool.
I hit this problem too. I had some nicely working generated code. Then something broke and I very rapidly got cornered. Things snowballed. I had to throw away work to recover it.
The cryptic error messages made it worse. We could improve the messages, but the deeper problem remains.
Code generation tools should never get you into a situation where you are forced to go backwards. This is a serious problem for 'gen' because people will typically give up immediately and stop using it, instead of persevering. That would be a shame.
@rickb777 Entirely right. It’s a usability problem, but also kind of fundamental to the nature of codegen. Good news is the types package (appears to) give us some tolerance that will cover a decent percentage of the frustrating situations. Let’s see if I can push my attempt this weekend.
One thought: it's nice that gen doesn't need lots of command line options. But perhaps when things go wrong, some verbose mode would be valuable.
One more thought: an easy trap to fall into is generating code containing a syntax error. This is hard to correct if you have lots of generated files. Version control comes to the rescue if you're lucky or if you planned for this, but maybe a way is needed to revert a particular change somehow, so as to get unstuck in such cases.
(Just thinking out loud.)
Yes, syntactic problems are hard. If we can’t parse it, we can know very little, so correctness or safety go out the window.
However, in type-checking case, we can retain certain guarantees while other semantic errors are present. That’s my current approach. I’ll offer a command-line flag to override certain classes of errors.
In the case of syntactic failure, we might consider falling back to really crude string matching to get out of a jam. Would also be a command-line flag. But yuck.
How about parsing into AST, generating the new types in their files, parsing those, and THEN pass it all off to the type checker.
@dgnorton The typewriters need type information to do their thing. Type checking happens before code generation.
I’ve just pushed a bunch of experimental changes to allow gen to tolerate a class of type-check errors. Here are some docs: http://clipperhouse.github.io/gen/force/
Would appreciate your testing it out and letting me know what you think. @rickb777 @jackc @dgnorton
The -f flag does solve the original problem I had. +1
It seems that gen will not if the current package is not compilable. This caused me some confusion as I was refactoring some hand-duplicated code to use gen. I first tried it with one type and it worked. So then I deleted all my hand implementations and added the annotations to generate them.
But now gen would fail with what looks like a compile error that my types I wanted to generate were not found (because the rest of my original package depended on what I now wanted gen to generate for me). Confusing to be told that it is failing because Foo is not defined when gen is supposed to generate Foo.
Finally I figured out that gen must be parsing the Go code to read out the annotations and that was what was failing.
It'd be nice to get an error message that gen needs a compilable project before it can generate code instead of just getting what looks like a Go build error.
On the bright side, overall gen is easy to use and extend. Even with this I was able to refactor my hand-duplicated code to use gen (including a custom typewriter) in about an hour and a half.