-
Notifications
You must be signed in to change notification settings - Fork 675
Accept and document jsdoc diffs, round 1 #1426
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.
Pull Request Overview
This PR documents and accepts 25 differences in JSDoc test outputs between the legacy TypeScript implementation (Strada) and the new native port (Corsa). The changes primarily reflect semantic differences in JavaScript handling, with many arising from the new reparsing strategy that gives JS exactly the same semantics as TypeScript.
- Accepts 25 test diffs by adding them to the submoduleAccepted.txt file
- Documents comprehensive semantic changes in CHANGES.md covering checker behavior, JSDoc types/tags, expandos, and CommonJS modules
- Includes differences discovered from compiling real-world JSDoc codebases like webpack and svelte
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
File | Description |
---|---|
testdata/submoduleAccepted.txt | Adds 25 conformance test diffs to the accepted changes list |
CHANGES.md | Extensive documentation of semantic differences between Strada and Corsa implementations |
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
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.
Mostly my comments are not about the text but about the actual differences themselves
CHANGES.md
Outdated
|
||
### JSDoc Tags | ||
|
||
1. `@type` tags no longer apply to function declarations, and now contextually type function expressions instead of applying directly. So this annotation no longer does anything: |
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 still really really think we should reconsider this and come up with some sort of way to do it
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.
The right way is to make a WholeType property for functions and check that if the function's Type and parameter types are nil, then only set WholeType in JS. It's possible but I'd put it even below constructor functions and maybe even Object.defineProperty expandos in importance, since contextual typing occurs in nearly all uses of it.
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.
Related sveltejs/svelte#16485 (comment)
CHANGES.md
Outdated
function sum(...ns) {} | ||
``` | ||
|
||
3. The postfix `=` type no longer adds `undefined` even when `strictNullChecks` is off: |
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.
Isn't this one just visual? Like, in a parameter position, missing vs undefined is not a real thing that matters.
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.
Pretty much. It shows up in the type baselines so I noted it.
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.
Right; who is the target of this doc? I had figured this was for end users to read when they find something that doesn't work, so this particular one seemed not enough to mention.
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.
Should this be "even when ... is on"
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.
No, it is supposed to add undefined when it is on. The Strada bug is that it adds it even when strict is off. I will make this note explain it better.
CHANGES.md
Outdated
|
||
### CommonJS | ||
|
||
1. Chained exports no longer 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.
Is this one a cleanup? Or just impossible?
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.
Simplification -- it's possible, but adds a bunch of code.
CHANGES.md
Outdated
|
||
This exports `x: undefined` not `x: typeof theRealExport`. | ||
|
||
3. Type info for `module` shows a property with name of the export instead of `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.
I'm not sure what this one means. Are you talking about hover? or something else?
module
, and exports
are different symbols entirely, right?
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's for hover, yes. module and exports are different symbols.
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.
Probably this is one we can avoid mentioning for end users. But the doc doesn't structure it like that of course so it's okay.
CHANGES.md
Outdated
|
||
results in `module: { singleIdentifier: any }` | ||
|
||
4. Property access on `require` no longer imports a single property from 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.
Why are we disallowing this one? I've definitely seen this before...
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 was extremely rare in the survey I did. And it would require significant hacking to the module exports resolution in the checker, too.
CHANGES.md
Outdated
const { x } = require("y") | ||
``` | ||
|
||
5. `Object.defineProperty` on `exports` no longer creates an export: |
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 have a feeling this one will bite us...
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 looks like a useful summary of where we are right now. A question, though:
A good number of the diffs are due to the reparsing strategy, which gives JS exactly the semantics of TS.
Should we be applying changes to https://github.com/microsoft/TypeScript/tree/tsgo-port to have a strada version with matching semantics for generating matching baselines? Seems like it'd be useful to have a JS version of the compiler that can report the same diagnostics (and maybe provide upgrade fixes? 6.0?).
``` | ||
|
||
In Strada, `cu` incorrectly narrows to `C` inside the `if` block, unlike with TS assertion syntax. | ||
In Corsa, the behaviour is the same between TS and JS. |
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.
...should we change this TS behavior? Seems like a bug, honestly. The presence of the cast doesn't make the truthiness check not present.
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 have trouble keeping the precise semantics of narrowing in my head, but if (cu.undeclaredProperty)
doesn't seem like a truthiness check compared to if (cu?.undeclaredProperty)
. I guess implicitly it is--"we are here without a crash, so cu
must exist". Also casts are often an escape hatch for when the compiler goes wrong, so maybe that's why that's here.
|
||
5. `@class` or `@constructor` does not make a function into a constructor function. | ||
|
||
Corsa ignores `@class` and `@constructor`. |
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.
We'd want it to emit the "convert to class declaration" quickfix on, anyway, right?
CHANGES.md
Outdated
They have no other semantics. | ||
|
||
|
||
2. A variadic type on a parameter no longer makes it a rest parameter. The parameter must use standard rest syntax. |
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 one might need some changes in declaration emit? Or not? ...number
still get changed to number[]
, which is.... still right, I think? Ah, whatever, mental note to check on it.
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; the emit changes for sum
but unless you ported the special-case check already, the correct emit is function sum(ns: number[])
and that's what the checker should give you if you're generating from a 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.
I checked and declaration emit does the right thing already.
I started adding precise differences for JS semantics to CHANGES.md. As you can see, I accepted 25 tests--and looked at around 40--before I got bored and switched to compiling well-known JSDoc codebases (webpack and svelte). The changes include a couple of diffs from Svelte as well.
I'm not 100% sure that this is worth generating. At some point we may instead want to declare legacy test bankruptcy, if people appear to be using JS features with no complaint. However, the first 2.5% of accepted tests probably has 25% of the semantics changes, so this list is at least worth reviewing by the team for surprises.
A good number of the diffs are due to the reparsing strategy, which gives JS exactly the semantics of TS. The rest are due to cut features, both whole features (eg type annotations on functions) and partial (eg use of
@class
to mark an otherwise-normal function as a constructor).