mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-14 18:05:27 +07:00
`dataclass_transform` support posed a number of challenges to the current AST/PSI stubs separation in our architecture. For the standard "dataclasses" module and the "attrs" package API, we could rely on well-known names and defaults to recognize and preserve the information about decorator arguments and field specifier arguments in PSI stubs. With `dataclass_transform` however, effectively any decorator call or extending any base class can indicate using a "magical" API that should generate dataclass-like entities. At the moment of building PSI stubs we can't be sure, because we can't leave the boundaries of the current file to resolve these names and determine if these decorators and base classes are decorated themselves with `dataclass_transform`. To support that, we instead rely on well-known keyword argument names documented in the spec, e.g. "kw_only" or "frozen". In other words, whenever we encounter any decorator call or a superclass list with such keyword arguments, we generate a `PyDataclassStub` stub for the corresponding class. The same thing is happening with class attribute initializers, i.e. whenever we see a function call with argument such as "default" or "kw_only" in their RHS, we generate a `PyDataclassFieldStub` for the corresponding target expression. Both of these stub interfaces now can contain null values for the corresponding properties if they were not specified directly in the class definition. Finally, for the `dataclass_transform` decorator itself, a new custom decorator stub was introduced -- `PyDataclassTransformDecoratorStub`, it preserves its keyword arguments, such as "keyword_only_default" or "frozen_default" controlling the default properties of generated dataclasses. Later, when we need concluded information about specific dataclass properties, e.g. in `PyDataclassTypeProvider` to generate a constructor signature, or in `PyDataclassInspection`, we try to "resolve" this incomplete information from stubs into finalized `PyDataclassParameters` and `PyDataclassFieldParameters` that contain non-null versions of the same fields. The main entry points for that are `resolveDataclassParameters` and `resolveDataclassFieldParameters`. These methods additionally handle the situations where decorators, superclass lists and field specifiers lack any keyword arguments, and thus, there were no automatically created custom stubs for them. All the existing usages of `PyDataclassStub` and `PyDataclassFieldStub` were updated to operate on `PyDataclassParameters` and `PyDataclassFieldParameters` instead. Counterparts of the tests on various inspection checks for the standard dataclasses definitions were added for dataclasses created with `dataclass_transform`, even though the spec is unclear on some aspects the expected type checker semantics, e.g. if combining "eq=False" and "order=True" or specifying both "default" and "default_factory" for a field should be reported. I tried to follow common sense when enabling existing checks for such arbitrary user-defined dataclass APIs. GitOrigin-RevId: 4180a1e32b5e4025fc4e3ed49bb8d67af0d60e66