-
Notifications
You must be signed in to change notification settings - Fork 10
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
refactor codeAsInSource to not require command + fix nbJs bug fixes #163
refactor codeAsInSource to not require command + fix nbJs bug fixes #163
Conversation
From a quick look at the docs, it looks like this new approach is actually working 🎊 And if there would appear any edge cases, it is trivial to fix most of them by adding code in either There is a list of all node kinds here but I don't even know what half of them means or what code looks like that produces them. So I'm leaning towards letting our users find out for us in the future which more ones actually require handling 🤣 I will go over all existing nimib uses I can find though, so I might still find new edge cases. Other than checking that, this PR is basically done implementation-wise. :o That was easier than I thought just a week ago 😎 |
Good job! I guess there are a few lines of code that can be removed before merging? |
It depends on if you want to keep the old |
Ok, I have hit some trouble... It was too good to be true 🙃 It has to do with templates and the fact that they transform the AST into template foo() =
nbCode:
nb.renderPlans["nbText"] = @["mdOutputToHtml"] then it will have a different AST compared with a "raw" nbCode:
nb.renderPlans["nbText"] = @["mdOutputToHtml"]
In the "raw" untyped version, we will get the position of I am not sure how to solve this at the moment, and this is mostly for my own memory before going to bed. Options:
|
Very interesting anyway. With this notes little by little I can hopefully understand more about this stuff. It seems the problem is in this Open Choice nodes. Is it possibile to just skip those and consider the first node that is not open choice? Or do we have cases where the open choice node would be the correct pick? |
Another option, if we just go over all nodes and take the minimum of lineinfo? |
It's not really the openChoice node that is the problem, even if it was just a sym we would have the same problem as the The search for the minimum could work :o we just have to make sure we don't get AST from somewhere else as well. Then we could get weird behaviors. |
in the lineinfo object there is also the filename, right? we could use that to make sure we take the minimum conditioned on the correct file (if we actually are able to know which is the right one...) |
and I guess if we have a StmtList we might need only to go over all nodes in the first statement, I guess statements should not be mixed up... actually there is the case of Call above, let's say all children of first node? to be honest not sure if I know what I am talking about, the above is mostly coming from your examples above... :D |
Regarding lineinfo, how do we know which filte of the correct one? A majority vote? (That would be in favour of the l file with longer code) And even if we get the correct file, if we use nnCode inside a template, the template will have a lower line number than the call to it. But if we assume the file is correct, your idea is quite similar to what we are already doing. With the adddition of checking all childs of all nodes except nnkStmtList. And taking the minimum. I will try this out when I get some time :) thanks for the ideas! 😁 |
Not sure if it works but we could probably use as source of truth the file set through Line 26 in ad0e44b
|
That is a good idea, most of the time the code we read will be from the end-user and not the libraries (why would they show their code :P). 😄 |
One problem with this idea: we don't have access to |
Ah right this is compile time! |
I haven't looked everywhere but this passes all tests so we might not need to know the actual file. The only time we get problems is if someone tries to do this: template foo(body: untyped) =
nbCode:
echo "This line will be the one found"
body but I'm not really sure why one would do something like that either. |
I have now gone over the majority of the nimib code I could find and found one minor bug. But I think this is ready a merge after I clean up the code tomorrow. Please have a look yourself and see if you can find any edge cases. Otherwise we'll tag a new release in the weekend. |
ok, looks good thanks, I will review this (possibly later this evenining). I think this PR also fixes #167 and #164 and we should mention that in the title. also not sure if there is anything to document here, at the very least we should add some changelog lines, and I guess also bump version, since after this is merged we should release a new 0.3.x |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a question because I gotta ask and a suggestion for an uncorrelated fix ;)
other than that looks good for me, thanks!
nimib.nimble
Outdated
@@ -1,6 +1,6 @@ | |||
# Package | |||
|
|||
version = "0.3.4" | |||
version = "0.3.5" | |||
author = "Pietro Peterlongo" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw, just noticed this but you need to add your name here!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh :o
line*: int | ||
column*: int | ||
|
||
proc `<`*(p1, p2: Pos): bool = | ||
(p1.line, p1.column) < (p2.line, p2.column) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am guessing since you checked on quite a few examples it is not something that happens often or possibly ever, but I gotta ask. is it possible we end comparing positions from two different files? should we check that this does not happen and put an assert? and in case it happens? I guess we should only compare stuff that comes from same file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is totally possible that we compare from two different files. I'll add an assert with a prompt to open an issue if it ever happens. 👍
if you want after this you can merge and release! |
Thank you :D I will let this sit for the night and merge and release it first thing tomorrow :) |
During the night I was thinking about the assert filename thing. Maybe a warning is better? If it happens to someone in a harmless way we might not want make nimib useless... not sure about this either though (an assert feels correct) |
The only scenario where it's harmless is if it's on the exact same line in both files (or on adjacent whitespace lines), so I wouldn't exactly say that there are any realistic harmless cases. So I think it's better that we shout at them and investigates it rather than a silent bug (I rarely reas hints and warnings 🙊) |
Ok, it's also harmless if the line number in the incorrect file is larger than the correct file. But that's just a 50% probability. The other 50% of the times you would get an undefined behavior that depend on how you structure another file. Imagine this scenario: you write and check your nbCode output and it's correct and you never expect to have to update it again. Sometime in the future you refactor the incorrect file and trigger the bug. But if you don't explicitly check the nimib document (why would you, it was correct and you haven't changed it), this bug would silently creep into your document. |
ok, let's keep the assert. but this implicitly means that we do NOT expect to have code from different files, otherwise we should have a way to deal with that and not run in the assertion error. what could be the logic we use? first node is authority for filename (and we compare only with nodes with same filename) unless we explicitly override? do you think it could make sense to test again with the assert the different documents? or to try and actively create a case where we do expect to have different filenames? I am not entirely sure this can indeed happen, never tried... also, should it be a doAssert so that it still checks in release mode? |
The case when we run into trouble is when we have in file A a template with a nbCode which both inputs the body it gets as input, but also a piece of code of it's own: template foo(body: untyped) =
nbCode:
body # code from file B
echo "Hello world" # file A And then in file B: foo:
echo "Code from file B" Except for this kind of use-case, I don't currently see any way for the assert to be triggered. And what would be the correct code to show in this case? Of course we would like to combine the code from both files ideally. But what if the template is defined in file B instead, then we want to comine two different code blocks from the same file. And how we would differentiate between those is even harder. So until we have a solution for these problems, I would say any usecase which triggers the assert is unsupported by codeAsInSource and should use codeFromAst instead. Giving the nodes authority based on order makes no sense as it depend on the order you put the statements in I can run through all the nimib documents and check so they don't assert 👍 If I recall correctly, asserts are only removed in danger mode. Release mode previously removed them but I think it was changed quite a while ago. But I'll change it to doAssert just in case 👍 |
I have improved the error message now and tested it against all the nimib documents. And no assertions were raised. |
the more I think about it, the more complex it looks. :) |
Yes exactly, this is an improvement to the current. Merging and releasing now. Let's rerun the CI over on the nimibook repo when it's done! |
This aims to solve #134 by changing the way nimib tries to find the start of a code block. This is mostly due to solving a bug that stopped us from getting the accurate start position.
TODO:
lineInfo
to get the file. Currently, we only havenb.source
with the current file, but we need to handle this case:B.nim
is the main file in this case, but the source is inA.nim
. I'm thinking about adding anb.sources: Table[string, string]
so that we can at least cache the files that we open.This also fixes #167 and #164 by adding a check so nimib doesn't compile an empty nim file if no nbJs was used. And the temporary js file created now has a unique name for each file, so parallel builds should be safer now.