-
Notifications
You must be signed in to change notification settings - Fork 650
Bring back SourceFile.EndOfFileToken
#1257
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
base: main
Are you sure you want to change the base?
Conversation
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.
tbh, I don't know how to assess if this is a correct change or not
if len(p.reparseList) > 0 { | ||
nodes = append(nodes, p.reparseList...) | ||
p.reparseList = nil | ||
end = p.nodePos() |
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'm not entirely sure if this dance with end
is fully correct here. It seems to me that end
for the statement list should get shifted if some reparsed nodes were pushed to it - otherwise some weird data mismatches would occur and the code would have to, likely, handle them in a special way. cc @sandersn
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.
At first I thought you were wrong but after I tried replacing the mutation with a a panic I see you are right. I think it's the best option but it still might cause some weirdness when getTokenAtPosition should return an EOF. However, the reparsed nodes are marked as such and should be skipped by that code.
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.
end
should be a real location, so I would very much assume that we don't need to do anything here. The end of file token should always come after the statement list, and IIRC any reparsed nodes would have to as well, and so nothing special needs to happen?
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.
Yeah, all of that makes sense and matches my expectations. I believe one of the previous iterations was not correct because it computed end
before the reparsed nodes on the eof were handled. That's why I have changed the parseListIndex
's return type - so I could get control over the assigned end
position.
I've just done this because it intuitively made sense but I have not fully verified why the previous version of this code I had have not worked. And because of that, I just want the reviewers to be extra cautious here - even though I think this makes sense :)
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 actually more confused as to why we need to append reparseList
at all. I thought that was an internal detail of the reparser?
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.
Hm, I guess that's where it sticks its statements, so.
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.
In other words, I think what you've written here is actually all correct.
Or at least, at worst maybe this position should just be the old end before the EOF.
+ export default _default; | ||
+ export type default = string | number; |
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.
Hm, this looks like a syntax error. Curious whether or not this is a quick fix. What should have happened here is that the type was renamed to _default
too. But, that wouldn't be in the parser, but the declaration transform.
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'll look into it. Btw. this doesn't correctly generate a unique identifier in Strada (:
// @allowJs: true
// @checkJs: true
// @target: es5
// @outDir: ./out
// @declaration: true
export const _default = class {}
export default 12;
/**
* @typedef {string | number} default
*/
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.
Playground Link is what I was testing; putting your code into that also seems to work?
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.
In my sample, there is an explicit _default
exported and the merged default export is assigned a _default
name too. Both of those should refer to different identifiers/exports
==== /foo.js (3 errors) ==== | ||
/** @import * as f from "./foo" with */ | ||
+ ~~~~~~~ | ||
+!!! error TS2306: File '/foo.js' is not a module. |
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.
Weird, but we also have other follow-on errors anyway.
+++ new.jsDeclarationsFunctionPrototypeStatic.errors.txt | ||
@@= skipped -0, +0 lines =@@ | ||
-<no content> | ||
+source.js(1,1): error TS2309: An export assignment cannot be used in a module with other exported elements. |
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.
This seems preexisting; the reparsed code triggers some other errors about addtional exports.
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.
yep. I need to get back to the PR that fixes these now that declaration emit is done, and I'm done adding (most) JS features.
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.
Still reviewing baselines, but here are some out of order comments.
@@ -49,6 +49,9 @@ func getTokenAtPosition( | |||
left := 0 | |||
|
|||
testNode := func(node *ast.Node) int { | |||
if node.Kind == ast.KindEndOfFile { | |||
return 0 |
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.
how does this translate from the code in services/utilities.ts? I don't see a specific EOF case in that code so I assume it's simplified from it in some way.
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.
This is a good question. It's an indirect port of the EOF case checked by nodeContainsPosition
. The related code in Corsa is rewritten sligthly so it's not easy to see this. There is a chance this second nodeContainsPosition
call might have to be ported too... but, so far, I have not found a need for it (at least not in the case of EOF):
// first element whose start position is before the input and whose end position is after or equal to the input
if (nodeContainsPosition(children[middle], start, end)) {
if (children[middle - 1]) {
// we want the _first_ element that contains the position, so left-recur if the prior node also contains the position
if (nodeContainsPosition(children[middle - 1])) {
return Comparison.GreaterThan;
}
}
return Comparison.EqualTo;
}
if len(p.reparseList) > 0 { | ||
nodes = append(nodes, p.reparseList...) | ||
p.reparseList = nil | ||
end = p.nodePos() |
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.
At first I thought you were wrong but after I tried replacing the mutation with a a panic I see you are right. I think it's the best option but it still might cause some weirdness when getTokenAtPosition should return an EOF. However, the reparsed nodes are marked as such and should be skipped by that code.
@@ -102,6 +106,9 @@ func (p *Parser) reparseUnhosted(tag *ast.Node, parent *ast.Node, jsDoc *ast.Nod | |||
case ast.KindJSDocImportTag: | |||
importTag := tag.AsJSDocImportTag() | |||
importClause := importTag.ImportClause | |||
if importClause == nil { |
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 think ModuleSpecifier is actually the critical property to require non-nil, although an import tag that imports no identifiers is pointless, so keep checking importClause for nil too.
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'm not sure if I understand correctly. Have you meant I should adjust it to this?
if importClause == nil || importTag.ModuleSpecifier == nil {
break
}
@@ -1,3 +1,39 @@ | |||
〚Positions: [729, 730]〛 | |||
【TS: SourceFile [0, 9772)】 | |||
《Go: EndOfFileToken [9770, 9772)》 |
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.
@andrewbranch I don't know how to read these baselines, but this could be the difference in GetTokenAtPosition that I was worried about.
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.
Later: no, there's no jsdoc at the end; this is just a difference in GetTokenAtPosition or something similar between Strada and Corsa. Based on my reading of the diff--still not an expert--it looks like it is incorrect and Strada is correct.
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.
Requesting changes based on my previous comments, since this batch is just guesses for why diffs have happened.
@@ -1,3 +1,39 @@ | |||
〚Positions: [729, 730]〛 | |||
【TS: SourceFile [0, 9772)】 | |||
《Go: EndOfFileToken [9770, 9772)》 |
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.
Later: no, there's no jsdoc at the end; this is just a difference in GetTokenAtPosition or something similar between Strada and Corsa. Based on my reading of the diff--still not an expert--it looks like it is incorrect and Strada is correct.
+!!! error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. |
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.
this error seems more accurate than the Strada one, although it's missing the suggestion to use a mapped type.
+>(barts, tidus, noctis) => "cecil" : (barts: { fantasy: any; }, tidus: { heroes: any; }, noctis: { heroes: any; } & { fantasy: any; }) => "cecil" |
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.
this diff is because the type annotation is now a contextual type, not a type annotation that attaches to the arrow
+ ~~~~~~~~~~~~~~~~~~ | ||
+!!! error TS1141: String literal expected. |
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 don't know why this parse error is different, but it's not related to this PR
+++ new.jsDeclarationsFunctionPrototypeStatic.errors.txt | ||
@@= skipped -0, +0 lines =@@ | ||
-<no content> | ||
+source.js(1,1): error TS2309: An export assignment cannot be used in a module with other exported elements. |
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.
yep. I need to get back to the PR that fixes these now that declaration emit is done, and I'm done adding (most) JS features.
No description provided.