-
Notifications
You must be signed in to change notification settings - Fork 878
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
[labs/analyzer] add mixin support #4147
base: main
Are you sure you want to change the base?
Conversation
🦋 Changeset detectedLatest commit: 0f47969 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
i've also tried to update all occurrences of seems to be what we do elsewhere in the codebase, but do correct me if im wrong edit: i've also dropped a test we had for static methods since it seems like it belongs in its own PR and was failing for unrelated reasons (think i lost some of the fixture code in merge). |
c14f07a
to
bffe865
Compare
fyi i've marked for review but i have some tests to write still there's also a comment or two i left myself which would be good to resolve first |
FYI i've also now updated gen-manifest to support mixins. i still need to update the goldens at some point, though. |
just did the minor changes @augustjk suggested (some package name updates) FYI |
}; | ||
}; | ||
|
||
const findSuperClassArgIndexFromHeritage = ( |
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.
Documentation on this function would be helpful since it's quite impressive what this function is doing, and it took me a while to understand it.
If I understand correctly, this function is finding which argument is the superClass. And it also is able to walk through the arguments.
Could this function be tricked to return the wrong super class with the following example:
const myMixin = (superClass, someArg) => {
// This other mixin takes `someArg` as its first argument.
class MyMixin extends someOtherMixin(someArg, superClass) {
...
}
}
In this case I think someArg
would be detected as the super class.
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 may be completely misunderstanding this function as well, but it may be worth adding an additional test case where a mixin applies some other mixin.
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.
you understood correctly i think
it'll basically recursively resolve your example:
- initially it'll have the expression
someOtherMixin(someArg, superClass)
and some possible names of['superClass', 'someArg']
- it'll then check if
someArg
is one of the possible names - it is so it'll return index
1
(because its[1]
of the possible names)
so you're right, it'll pick up someArg
as the class arg rather than superClass
not sure what we can do about that though 🤔
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.
Good catch here, this does seem wrong. I think in the isCallExpression
branch, rather than recursing into findSuperClassArgIndexFromHeritage()
, this function likely needs to try to look up / dereference the mixin that's being called and return the index of its own argument passed into the mixin's superclass argument; that will recurse until a mixin extends one of its arguments directly (iow, taking the isIdentifier
branch) rather than calling another mixin.
So in the example, we'd look up someOtherMixin
, it would have a superClassArgIdx
of 1
, and so we'd find the index of the superClass
argument, and search the current mixin's arg list for that name and return 0
.
As Justin said in the other comment, the name searches could be likely be done with symbol declaration identity, but that could be a separate change.
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 we might need to add something to the custom elements manifest here to identify which parameter of a mixin is the superclass.
We can do something internally to the analyzer in the mean time by just adding that to the model object.
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.
Some minor comments, but overall this is awesome! pre-approving!
Only blocking comments from me are:
- The license date that was updated in an old file.
- Clarifying that
findSuperClassArgIndexFromHeritage
works correctly.
Thank you so much!
classDeclarationName, | ||
analyzer, | ||
undefined, | ||
true /* isMixinClass */ |
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 action needed now (unless you want!), but this is enough parameters, especially with booleans and other literals, that I would generally go for named arguments.
}; | ||
}; | ||
|
||
const findSuperClassArgIndexFromHeritage = ( |
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 finding the index in the mixin function's parameter list or the heritage call expression's argument list?
Note that in general, the superclass arg could be a named property too. I'm not sure what TypeScript's rules are.
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 is the index in the function's parameter list, based on the heritage of the class
i think if we want to change this, we should probably do it in a follow-up since it could be a bit of a refactor to allow an object to be used as a parameter
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 we should fix this, especially if TypeScript is strict about recognizing mixins. We can keep an eye on it.
I think we should merge this now and open an issue to address known problems in the mixin superclass lookup. |
Replaces #4120.
This is actually kevin's branch but caught up from main, and various tests added.