-
Notifications
You must be signed in to change notification settings - Fork 9
chore: Introduce CTHelpers in ts-transformers serving imported symbols. #1892
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
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.
1 issue found across 17 files
Prompt for AI agents (all 1 issues)
Understand the root cause of the following 1 issues and fix them.
<file name="packages/ts-transformers/src/core/ct-helpers.ts">
<violation number="1" location="packages/ts-transformers/src/core/ct-helpers.ts:102">
`getCTHelpersIdentifier` should compare the string literal’s text, not its quoted source, so helpers added with single quotes are still detected.</violation>
</file>
React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.
| ): string { | ||
| // Throw when this symbol name is already in use | ||
| // for some reason. | ||
| if (source.indexOf(CT_HELPERS_IDENTIFIER) !== -1) { |
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 this is reasonable... just noticing it'll reject even on something like // TODO: include __ctHelpers or // note: we omit __ctHelpers or whatever. i can't really think of an important use case where this is a problem so i'm good with this as-is, mentioning for your consideration
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 guess this also means it's not valid for users to manually write import * as __ctHelpers from commontools 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.
Right, we could use ts API to create a unique name, or use the existence of any * import for commontools rather than a new one, though that works less well with the sourceline preservation I think, could try that too
| name: string, | ||
| ): ts.PropertyAccessExpression { | ||
| if (!this.sourceHasHelpers()) { | ||
| throw new Error("Source file does not contain helpers."); |
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 consider making this error message more suggestive, eg "Source file does not contain helpers. Did you mean to include /// <cts-enable />?
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 occurs if the transformers filtering have failed, so it's on our end, not an author's
| name: string, | ||
| ): ts.QualifiedName { | ||
| if (!this.sourceHasHelpers()) { | ||
| throw new Error("Source file does not contain helpers."); |
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.
same q here re error message potentially being more explicit
| return `/${id}${filename}`; | ||
| } | ||
|
|
||
| function isCTSEnabled(line: string) { |
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.
unused (i think you moved it elsewhere)
| @@ -1,31 +1,5 @@ | |||
| import ts from "typescript"; | |||
| import { | |||
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.
very nice simplifications here and throughout!
|
|
||
| // Helper type extending CallExpression with | ||
| // truthy typeArguments. | ||
| interface ToSchemaNode extends ts.CallExpression { |
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.
cool thank you this is nicer
| const jsonSchemaIdentifier = context.imports.getIdentifier( | ||
| context, | ||
| { module: "commontools", name: "JSONSchema" }, | ||
| const jsonSchemaName = context.ctHelpers.getHelperQualified( |
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 had to ask claude for some help understanding the reason for getHelperQualified here. ultimately it suggests that something like the following comment might be helpful, slash, is this in fact the correct understanding?
"// Use getHelperQualified() for type positions (satisfies, type references)
// vs getHelperExpr() for value positions (function calls, property access)"
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 due to that's what the SatisfiesExpression needs, as its a const statement, and when we use the expression form, it's for identifiers which could represent values or functions etc. -- TBD on what other Node forms we'll need to offers
| detectCallKind, | ||
| isEventHandlerJsxAttribute, | ||
| } from "../ast/mod.ts"; | ||
| import { OpaqueRefHelperName, rewriteExpression } from "./opaque-ref/mod.ts"; |
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 was this previously an unused import? i'd thought typescript would have complained about that
| @@ -1,6 +1,6 @@ | |||
| import ts from "typescript"; | |||
|
|
|||
| import type { Emitter, OpaqueRefHelperName } from "../types.ts"; | |||
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.
same q here, previously unused?
|
one general DX question... since the runner is where we do the pretransform, is there any nice way to warn users if they seem to be trying to use the transformers outside of the runner? eg if a user has /// in their source file but they try to run the transformers pipeline without sending it through the runner, is there any nice way we can indicate to them that that's probably their issue? the only idea i had would be to check in each transformer's filter() function, which is pretty ugly and requires us, transformer authors, to remember to do that for each new transformer sub-class, so i don't love it. otherwise i guess they'll just get typescript compiler errors about missing the injected functions? |
|
one other general DX question... if a user manually imports derive from commontools, and then uses it - will there be two differently qualified versions of derive in the JS that the AMD loader generates? it's probably fine right? |
|
this looks really great! thank you so much for figuring this out and continuing to make everything in this part of the codebase so much nicer. |
54a70dc to
03aa134
Compare
Yes, exactly! |
Yeah it's tricky, ts-transformers is a part of the compilation step which also must have been preprocessed with runner-specific information. Two-pass compiling makes this nicer, at the cost of 50% slower compiles, but definite room for improvement here |
e79728e to
d93c319
Compare
As a part of the "pretransform" step, we replace the CTS enable directive with a wildcard import for "commontools" module that is used when injecting new functionality via transformations. Remove unused imports from various patterns that are now injected by the transformers.
d93c319 to
22a9a0d
Compare
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.
yet another big improvement thank you
As a part of the "pretransform" step, we replace the CTS enable directive with a wildcard import for "commontools" module that is used when injecting new functionality via transformations.
Summary by cubic
Introduced a pretransform that replaces the CTS directive with import * as __ctHelpers from "commontools", and added CTHelpers so transformers access helpers reliably without custom import management. This simplifies helper resolution and runs before TypeScript binding to avoid symbol issues.
Refactors
Migration