-
Notifications
You must be signed in to change notification settings - Fork 696
fix(1632): erase const enums after inlining #1639
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
798d12b
to
c5a62a9
Compare
441cca9
to
ded3fa0
Compare
...ference/submodule/compiler/blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.js.diff
Outdated
Show resolved
Hide resolved
testdata/baselines/reference/submodule/compiler/constEnumErrors.js.diff
Outdated
Show resolved
Hide resolved
testdata/baselines/reference/submodule/conformance/constEnum4.js.diff
Outdated
Show resolved
Hide resolved
testdata/baselines/reference/submodule/conformance/constEnum4.js
Outdated
Show resolved
Hide resolved
...baselines/reference/submodule/compiler/elidedEmbeddedStatementsReplacedWithSemicolon.js.diff
Outdated
Show resolved
Hide resolved
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.
So, this seems probably right but will defer to @weswigham 😄
@jakebailey ok, thanks |
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 was unsure if we wanted this behavior back and didn't just wanna make const enum
s always preserved, since that's what we were doing before we re-added inlining, but I suppose since vscode reported it, they'd like the runtime source elision behavior back, too. Tbh, preserveConstEnums
should at least be the default nowadays, but that's a change for another PR.
We also need to elide namespace
declarations containing exclusively const enum
s and/or types (preserveConstEnums
dependent) for the same reasons you'd want the const enum
s elided. See the missing shouldEmitModuleDeclaration
call from the original ts.ts
source. ast.GetModuleInstanceState
is already ported, so it shouldn't be too bad.
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 good - some last comments on comment preservation, since we're working with NotEmittedStatement
s which explicitly exist to copy those.
return nil | ||
} | ||
if ast.IsNotEmittedStatement(updated) { | ||
return visitor.Factory.NewEmptyStatement() |
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 needs to copy position/comment emit node information from updated
- NotEmittedStatement
s are injected into the tree explicitly to preserve that kind of thing, so failing to copy it here unintentionally drops it.
Though, why is this needed at all, actually? Is it just so follow-on transforms can see an EmptyStatement
instead of a NotEmittedStatement
and react appropriately? It might be better to not perform a remapping on transform like this, and instead use a ast.IsEmptyStatementLike
helper that includes both EmptyStatement
and NotEmittedStatement
. Either one of the two strategies to preserve comment information should be fine, though (either copying that info here or dropping the remapping entirely and updating downstream transforms/printers to handle NotEmittedStatement
s like EmptyStatement
s).
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 comment still needs to be addressed - this remapping drops comments and location information.
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.
@weswigham Thanks for pointing that out. The main issue is using remapping to handle cases related to embedded statements
// ts
if (true)
const enum E1 { A = 1 }
else
const enum E2 { A = 1 }
// js
if (true)
;
else
;
typescript-go/internal/printer/printer.go
Lines 3163 to 3174 in 9347366
func (p *Printer) emitEmptyStatement(node *ast.EmptyStatement, isEmbeddedStatement bool) { | |
state := p.enterNode(node.AsNode()) | |
// While most trailing semicolons are possibly insignificant, an embedded "empty" | |
// statement is significant and cannot be elided by a trailing-semicolon-omitting writer. | |
if isEmbeddedStatement { | |
p.writePunctuation(";") | |
} else { | |
p.writeTrailingSemicolon() | |
} | |
p.exitNode(node.AsNode(), state) | |
} |
Strada
uses this helper to wrap all embedded statements
It might be an option to extend
typescript-go/internal/printer/printer.go
Lines 3430 to 3432 in 9347366
func (p *Printer) emitNotEmittedStatement(node *ast.NotEmittedStatement) { | |
p.exitNode(node.AsNode(), p.enterNode(node.AsNode())) | |
} |
for cases involving embedded statements.
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, you can use the transform hook to automatically do the thing the embedded statement helper is doing like you are here (probably - we're moving the remapping from node construction later a step to the generic visitor base, so it's possible a transform could witness the difference before returning; but transforms don't usually inspect what the node factory returns anyway), you definitely just need the corsa equivalents of the setTextRange+setOriginal calls.
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.
@weswigham I was thinking about the following options:
- Extend
emitEmbeddedStatement
to emit a;
forNotEmittedStatement
, since it currently feels more like an alias used only at runtime
typescript-go/internal/printer/printer.go
Lines 3895 to 3899 in 9347366
if node.Kind == ast.KindEmptyStatement { | |
p.emitEmptyStatement(node.AsEmptyStatement(), true /*isEmbeddedStatement*/) | |
} else { | |
p.emitStatement(node) | |
} |
- Add handling logic to runtimesyntax so that when a
NotEmittedStatement
appears inside anEmbeddedStatement
, anEmptyStatement
is emitted instead.
Fixes #1632