LibCST/libcst/metadata/base_provider.py
Ray Zeng d0ecb018e1 Port line and column numbers to metadata framework
Refactors codegen to write position information to the `__metadata__`
fields in nodes keyed by `BasicPositionProvider` and
`SyntacticPositionProvider` as defined in position_metadata.py.

This commit also updates `deep_equals` to ignore dataclass fields that
are marked `compare=False` to avoid comparing metadata when doing
equality checks.
2019-07-22 19:53:49 -07:00

40 lines
1.2 KiB
Python

# Copyright (c) Facebook, Inc. and its affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
# pyre-strict
from typing import Generic, TypeVar
import libcst.nodes as cst
from libcst._base_visitor import CSTVisitor
_T = TypeVar("_T")
class BaseMetadataProvider(CSTVisitor, Generic[_T]):
"""
Base class for metadata providers to subclass off of.
"""
def leave_Module(
self, orig_node: cst.Module, updated_node: cst.Module
) -> cst.Module:
# TODO: We may need to change the behavior of CSTVisitor or create a
# subclass to make sure MetaDataProviders don't mutate the tree.
# A metadata provider can't modify the tree.
# This ensures no copying is done (which would erase metadata).
assert orig_node.deep_equals(updated_node)
return orig_node
def generate(self, module: cst.Module) -> None:
"""
Convenience method to run metadata provider over a module.
"""
module.visit(self)
@classmethod
def set_metadata(cls, node: cst.CSTNode, value: _T) -> None:
node.__metadata__[cls] = value