[feature][metadata] add SuperClassProvider
In some lint or codemod use cases, we want to know the super classes of a class to see if it's inherited from a specific class in order to enforce convention or codemods on all subclasses.
The superclass information requires full repository analysis due to multiple inheritance. We can leverage Pyre for that which is similar to the existing TypeInferenceProvider .
https://libcst.readthedocs.io/en/latest/metadata.html#type-inference-metadata
Prerequisite: pyre query support superclasses query given a list of paths.
The current pyre query "superclasses(...)" only supports fully qualified class name but that requires caller to pass the name. To make it more efficient, we want to add the path support to pyer query, so FullRepoManager can pass a list of path to pyre query to read all classes in those paths and their superclasses. To map superclasses data to LibCST syntax tree, we also need the location info.
The pyre query interface for TypeInferenceProvider is: pyre query "types(path=path1, path=path2, ...)" and the output format is
https://github.com/Instagram/LibCST/blob/2fb0db33d1b393228a6b45f7749e6df659f186b2/libcst/tests/pyre/simple_class.json#L1-L15
We want to have a similar interface for SuperClassProvider: pyre query "superclasses(path=path1, path=path2, ...)" and the output format is
List[
{
class_name: fully qualified string
location: location fields
superclasses: list of superclasses (fully qualified string)
}
]
CC @shannonzhu
Implementing SuperClassProvider
We want to implement a SuperClassProvider which returns a list of superclasses on ClassDef node or ClassDef.name node.
TypeInferenceProvider can be used as an example.
https://github.com/Instagram/LibCST/blob/2fb0db33d1b393228a6b45f7749e6df659f186b2/libcst/metadata/type_inference_provider.py#L40
We also need some mocked integration tests by extending this script: https://github.com/Instagram/LibCST/blob/2fb0db33d1b393228a6b45f7749e6df659f186b2/libcst/tests/test_pyre_integration.py
The script generates pyre json output by running pyre query and store as test artifacts in dir https://github.com/Instagram/LibCST/tree/2fb0db33d1b393228a6b45f7749e6df659f186b2/libcst/tests/pyre The test cases in the file checks whether each node has expected output. We also run the artifact generation in CI to make sure we address needed changes when we upgrade Pyre or update the test examples. https://github.com/Instagram/LibCST/blob/master/.circleci/config.yml#L78
For unit tests, we can reuse the generated artifacts and verify the correctness of superclass like https://github.com/Instagram/LibCST/blob/2fb0db33d1b393228a6b45f7749e6df659f186b2/libcst/metadata/tests/test_type_inference_provider.py#L18