LibCST icon indicating copy to clipboard operation
LibCST copied to clipboard

[feature][metadata] add SuperClassProvider

Open jimmylai opened this issue 5 years ago • 0 comments

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

jimmylai avatar Mar 25 '20 21:03 jimmylai