Skip to content
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

feat: add Typescript v[4.9.5 ; 5.1.6] support #14

Merged
merged 2 commits into from Aug 4, 2023

Conversation

astahmer
Copy link
Contributor

related to: chakra-ui/panda#1008 (comment)

I got them all ! 6860 tests passed
Had to use some anys cause TS deprecated some methods but the update was mostly a painless process !
well played on the ts macro versions testing, this helped a lot.

please tell me if there's anything I can do to get this merged

Copy link
Owner

@wessberg wessberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there. Thanks so much for your contribution! I've left a few comments with some suggestions.

export function hasModifier(node: TS.Node | TS.Modifier[], modifier: TS.Modifier["kind"]): boolean {
const modifiers = Array.isArray(node) ? node : (node.modifiers as readonly TS.Modifier[] | undefined);
return modifiers != null && modifiers.some(m => m.kind === modifier);
export function hasModifier(node: TS.Node | TS.Modifier[], modifier: TS.Modifier["kind"], typescript: typeof TS): boolean {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer a much simpler implementation where we just check for the existence of an array of modifiers on the Node to avoid having to pass in a reference to the TypeScript object and using the new canHaveModifiers helper.

The existing implementation could simply be rewritten to this, which will work in TS5 as well:

/**
 * Returns true if the given Node has the given kind of Modifier
 */
export function hasModifier(node: TS.Node | TS.ModifierLike[], modifier: TS.Modifier["kind"]): boolean {
	const modifiers = Array.isArray(node) ? node : "modifiers" in node && Array.isArray(node.modifiers) ? (node.modifiers as readonly TS.ModifierLike[]) : undefined;
	return modifiers != null && modifiers.some(m => m.kind === modifier);
}

package.json Show resolved Hide resolved
super({
message,
environment,
node: typescript.factory?.createEmptyStatement() ?? (typescript as any as (typeof TS)["factory"]).createEmptyStatement()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is definitely me being nitpicky, but I'd prefer casting to unknown over any, and maybe a cleaner cast would be: typescript.factory?.createEmptyStatement() ?? (typescript as unknown as TS.NodeFactory).createEmptyStatement() instead :)

@@ -21,8 +21,8 @@ export function getDotPathFromNode<T extends TS.Node>(options: EvaluatorOptions<
return SUPER_SYMBOL;
} else if (typescript.isParenthesizedExpression(node)) {
return getDotPathFromNode({...options, node: node.expression});
} else if (typescript.isTypeAssertionExpression?.(node) || (!("isTypeAssertionExpression" in typescript) && (typescript as typeof TS).isTypeAssertion(node))) {
return getDotPathFromNode({...options, node: node.expression});
} else if (typescript.isTypeAssertionExpression?.(node) || (!("isTypeAssertionExpression" in typescript) && (typescript as any).isTypeAssertion(node))) {
Copy link
Owner

@wessberg wessberg Aug 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If instead of the any cast here, we write it like this...:

// ...
else if (
		rest.typescript.isTypeAssertionExpression?.(node) ||
		(!("isTypeAssertionExpression" in rest.typescript) && (rest.typescript as {isTypeAssertion: typeof TS.isTypeAssertionExpression}).isTypeAssertion(node))
	)

...

} else if (typescript.isTypeAssertionExpression?.(node) || (!("isTypeAssertionExpression" in typescript) && (typescript as typeof TS).isTypeAssertion(node))) {
return getDotPathFromNode({...options, node: node.expression});
} else if (typescript.isTypeAssertionExpression?.(node) || (!("isTypeAssertionExpression" in typescript) && (typescript as any).isTypeAssertion(node))) {
return getDotPathFromNode({...options, node: (node as any as TS.TypeAssertion).expression});
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...Then we won't have to do the cast here and can't just keep it as node.expression, as TypeScript will understand that node is a TypeAssertionExpression.

return expressionContainsSuperKeyword(expression.expression, typescript);
}
else {
else if (typescript.isTypeAssertionExpression?.(expression) || (!("isTypeAssertionExpression" in typescript) && (typescript as any).isTypeAssertion(expression))) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same feedback as above - we can write this like this instead:

else if (typescript.isTypeAssertionExpression?.(expression) || (!("isTypeAssertionExpression" in typescript) && (typescript as {isTypeAssertion: typeof TS.isTypeAssertionExpression}).isTypeAssertion(expression))) {
		return expressionContainsSuperKeyword(expression.expression, typescript);
}

That way we won't have to do the expression as TS.TypeAssertion cast

}
else {
else if (typescript.isTypeAssertionExpression?.(expression) || (!("isTypeAssertionExpression" in typescript) && (typescript as any).isTypeAssertion(expression))) {
return expressionContainsSuperKeyword((expression as TS.TypeAssertion).expression, typescript);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above

return getInnerNode(node.expression, typescript);
}
else {
else if (typescript.isTypeAssertionExpression?.(node) || (!("isTypeAssertionExpression" in typescript) && (typescript as any).isTypeAssertion(node))) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same feedback as the other two places where we check for a TypeAssertionExpression.

Copy link
Owner

@wessberg wessberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks a lot!

@wessberg wessberg merged commit f7ade86 into wessberg:master Aug 4, 2023
@astahmer
Copy link
Contributor Author

astahmer commented Aug 4, 2023

thanks for the valuable feedback, this is indeed way better now !
I'm not sure why but I couldn't run pnpm test locally anymore ? it just hang, I tried restarting my mac & closing everything but without success. I pushed it to see if it was going to work on CI but I just realized there's no CI action being run on push ?
Screenshot 2023-08-04 at 11 35 08

@wessberg
Copy link
Owner

wessberg commented Aug 4, 2023

They're running just fine here on GH Actions.

Did you perform an additional pnpm i after pulling in the latest changes from master before running pnpm test?

@astahmer
Copy link
Contributor Author

astahmer commented Aug 4, 2023

oh oh, couldnt find them
I think I did ? anyway it's fine they're still green

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants