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: (code actions): add/from destructure #175

Merged
merged 66 commits into from
Oct 29, 2023
Merged

Conversation

Ilanaya
Copy link
Collaborator

@Ilanaya Ilanaya commented Sep 11, 2023

zardoy and others added 30 commits December 22, 2022 17:12
Copy link
Collaborator Author

@Ilanaya Ilanaya left a comment

Choose a reason for hiding this comment

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

It Looks like it is working!

@Ilanaya Ilanaya marked this pull request as ready for review October 6, 2023 22:06
Copy link
Owner

@zardoy zardoy left a comment

Choose a reason for hiding this comment

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

I think its good for its purpose.
didn't really look at the code, I think its fine. However, to destructure should also avoid name collisions eg:

const a = []
const b = {}
b.a

from destruct will result in broken code, a should be named as a2 e.g. a: a2

@Ilanaya
Copy link
Collaborator Author

Ilanaya commented Oct 13, 2023

I think its good for its purpose. didn't really look at the code, I think its fine. However, to destructure should also avoid name collisions eg:

const a = []
const b = {}
b.a

from destruct will result in broken code, a should be named as a2 e.g. a: a2

Given this code:

function fn(newVariable) {
  const something = newVariable.bar
}

Source file gonna contain this list of identifiers:
image

So if try getting unique name

 const uniqueAccessorName = tsFull.getUniqueName('bar', sourceFile as unknown as FullSourceFile)

It will always generate bar_1 because it treats .bar in access expression newVariable.bar as unique identifier.

Hope, this was a clear explanation :) For now I will drop support unique names in this case, or maybe there is some way to handle it?

@Ilanaya Ilanaya requested a review from zardoy October 13, 2023 20:05
@zardoy
Copy link
Owner

zardoy commented Oct 27, 2023

Thanks for clarifying, we need to remove any getUniqueName usage in favor of typeChecker.resolveName(name, <block body node>, SymbolFlags.Value, /*excludeGlobals*/ true) (needs full type checker) for checking for name collisions instead (I remember it was also used in extract type, thus need to use type SymbolFlag). Would be possible to make this?

@Ilanaya
Copy link
Collaborator Author

Ilanaya commented Oct 29, 2023

Thanks for clarifying, we need to remove any getUniqueName usage in favor of typeChecker.resolveName(name, <block body node>, SymbolFlags.Value, /*excludeGlobals*/ true) (needs full type checker) for checking for name collisions instead (I remember it was also used in extract type, thus need to use type SymbolFlag). Would be possible to make this?

Yeah, I'll replace it everywhere in the codebase in a separate PR if you approve the way I implemented this logic here.

@zardoy
Copy link
Owner

zardoy commented Oct 29, 2023

This is getting great! So excited to see it in repo, @Ilanaya is it ready to merge now?

@Ilanaya
Copy link
Collaborator Author

Ilanaya commented Oct 29, 2023

Yep, I think it is. I'll recheck it again soon and merge if u don't mind

@Ilanaya Ilanaya merged commit de548ee into develop Oct 29, 2023
1 check passed
@Ilanaya Ilanaya deleted the 167-to-from-destructure branch October 29, 2023 20:27
@zardoy
Copy link
Owner

zardoy commented Oct 30, 2023

@Ilanaya ok, I've got time to check how it works and I must admit there are some improvements needed:

  1. need to handle case if property is reserved (e.g. class or default might be pretty common):
const a = {
    default: 1,
}

a.default
// results in broken code:
const { class } = { // class is resorved token!
    class: 1,
}

class

If you use require in js file you will have a quickfix to convert the file to es modules eg:

module.exports.default = 5

will be converted to

const _default = 5
export { _default as default }

it just uses isIdentifierANonContextualKeyword: https://github.com/a-tarasyuk/typescript/blob/8dc7ee8c2b3eadcd4d1130afb9c3a9df927ef6a7/src/services/codefixes/convertToEsModule.ts#L165

  1. And also, have we ever discussed how we should handle index access? e.g.
const a = {
    a: 1,
}

a.a
a['b']
a['c-d']

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.

to destruct, from destruct
2 participants