mirror of
https://github.com/Instagram/LibCST.git
synced 2025-12-23 10:35:53 +00:00
[metadata] consolidate MetadataWrapper methods to the same file
This commit is contained in:
parent
0d77f653ec
commit
337abb26c9
4 changed files with 69 additions and 91 deletions
|
|
@ -1,63 +0,0 @@
|
|||
# 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 TYPE_CHECKING, Collection, MutableSet
|
||||
|
||||
from libcst._exceptions import MetadataException
|
||||
from libcst.metadata.base_provider import (
|
||||
BatchableMetadataProvider,
|
||||
ProviderT,
|
||||
_gen_batchable,
|
||||
)
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from libcst.metadata.wrapper import MetadataWrapper # noqa: F401
|
||||
|
||||
|
||||
def _gather_providers(
|
||||
providers: Collection[ProviderT], gathered: MutableSet[ProviderT]
|
||||
) -> MutableSet[ProviderT]:
|
||||
"""
|
||||
Recursively gathers all the given providers and their dependencies.
|
||||
"""
|
||||
for P in providers:
|
||||
if P not in gathered:
|
||||
gathered.add(P)
|
||||
_gather_providers(P.METADATA_DEPENDENCIES, gathered)
|
||||
return gathered
|
||||
|
||||
|
||||
def _resolve_impl(wrapper: "MetadataWrapper", providers: Collection[ProviderT]) -> None:
|
||||
"""
|
||||
Updates the _metadata map on wrapper with metadata from the given providers
|
||||
as well as their dependencies.
|
||||
"""
|
||||
providers = set(providers) - set(wrapper._metadata.keys())
|
||||
remaining = _gather_providers(providers, set())
|
||||
|
||||
completed = set()
|
||||
while len(remaining) > 0:
|
||||
batchable = set()
|
||||
|
||||
for P in remaining:
|
||||
if set(P.METADATA_DEPENDENCIES).issubset(completed):
|
||||
if issubclass(P, BatchableMetadataProvider):
|
||||
batchable.add(P)
|
||||
else:
|
||||
wrapper._metadata[P] = P()._gen(wrapper)
|
||||
completed.add(P)
|
||||
|
||||
metadata_batch = _gen_batchable(wrapper, [p() for p in batchable])
|
||||
wrapper._metadata.update(metadata_batch)
|
||||
completed |= batchable
|
||||
|
||||
if len(completed) == 0 and len(batchable) == 0:
|
||||
# remaining must be non-empty at this point
|
||||
names = ", ".join([P.__name__ for P in remaining])
|
||||
raise MetadataException(f"Detected circular dependencies in {names}")
|
||||
|
||||
remaining -= completed
|
||||
|
|
@ -5,17 +5,7 @@
|
|||
|
||||
# pyre-strict
|
||||
from types import MappingProxyType
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
Generic,
|
||||
Iterable,
|
||||
Mapping,
|
||||
MutableMapping,
|
||||
Type,
|
||||
TypeVar,
|
||||
cast,
|
||||
)
|
||||
from typing import TYPE_CHECKING, Generic, Mapping, MutableMapping, Type, TypeVar, cast
|
||||
|
||||
from libcst._batched_visitor import BatchableCSTVisitor
|
||||
from libcst._metadata_dependent import (
|
||||
|
|
@ -144,18 +134,3 @@ class BatchableMetadataProvider(
|
|||
implementation should be provided in _gen_impl.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def _gen_batchable(
|
||||
wrapper: "MetadataWrapper",
|
||||
# pyre-fixme[2]: Parameter `providers` must have a type that does not contain `Any`
|
||||
providers: Iterable[BatchableMetadataProvider[Any]],
|
||||
) -> Mapping[ProviderT, Mapping["CSTNode", object]]:
|
||||
"""
|
||||
Returns map of metadata mappings from resolving ``providers`` on ``wrapper``.
|
||||
"""
|
||||
wrapper.visit_batched(providers)
|
||||
|
||||
# Make immutable metadata mapping
|
||||
# pyre-ignore[7]
|
||||
return {type(p): MappingProxyType(dict(p._computed)) for p in providers}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ from libcst.metadata import (
|
|||
MetadataWrapper,
|
||||
VisitorMetadataProvider,
|
||||
)
|
||||
from libcst.metadata.base_provider import _gen_batchable
|
||||
from libcst.metadata.wrapper import _gen_batchable
|
||||
from libcst.testing.utils import UnitTest
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,12 +7,15 @@
|
|||
|
||||
import textwrap
|
||||
from contextlib import ExitStack
|
||||
from types import MappingProxyType
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
Collection,
|
||||
Iterable,
|
||||
Mapping,
|
||||
MutableMapping,
|
||||
MutableSet,
|
||||
Optional,
|
||||
Type,
|
||||
TypeVar,
|
||||
|
|
@ -20,7 +23,8 @@ from typing import (
|
|||
)
|
||||
|
||||
from libcst._batched_visitor import BatchableCSTVisitor, VisitorMethod, visit_batched
|
||||
from libcst.metadata._resolver import _resolve_impl
|
||||
from libcst._exceptions import MetadataException
|
||||
from libcst.metadata.base_provider import BatchableMetadataProvider
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -36,6 +40,68 @@ if TYPE_CHECKING:
|
|||
_T = TypeVar("_T")
|
||||
|
||||
|
||||
def _gen_batchable(
|
||||
wrapper: "MetadataWrapper",
|
||||
# pyre-fixme[2]: Parameter `providers` must have a type that does not contain `Any`
|
||||
providers: Iterable[BatchableMetadataProvider[Any]],
|
||||
) -> Mapping["ProviderT", Mapping["CSTNode", object]]:
|
||||
"""
|
||||
Returns map of metadata mappings from resolving ``providers`` on ``wrapper``.
|
||||
"""
|
||||
wrapper.visit_batched(providers)
|
||||
|
||||
# Make immutable metadata mapping
|
||||
# pyre-ignore[7]
|
||||
return {type(p): MappingProxyType(dict(p._computed)) for p in providers}
|
||||
|
||||
|
||||
def _gather_providers(
|
||||
providers: Collection["ProviderT"], gathered: MutableSet["ProviderT"]
|
||||
) -> MutableSet["ProviderT"]:
|
||||
"""
|
||||
Recursively gathers all the given providers and their dependencies.
|
||||
"""
|
||||
for P in providers:
|
||||
if P not in gathered:
|
||||
gathered.add(P)
|
||||
_gather_providers(P.METADATA_DEPENDENCIES, gathered)
|
||||
return gathered
|
||||
|
||||
|
||||
def _resolve_impl(
|
||||
wrapper: "MetadataWrapper", providers: Collection["ProviderT"]
|
||||
) -> None:
|
||||
"""
|
||||
Updates the _metadata map on wrapper with metadata from the given providers
|
||||
as well as their dependencies.
|
||||
"""
|
||||
providers = set(providers) - set(wrapper._metadata.keys())
|
||||
remaining = _gather_providers(providers, set())
|
||||
|
||||
completed = set()
|
||||
while len(remaining) > 0:
|
||||
batchable = set()
|
||||
|
||||
for P in remaining:
|
||||
if set(P.METADATA_DEPENDENCIES).issubset(completed):
|
||||
if issubclass(P, BatchableMetadataProvider):
|
||||
batchable.add(P)
|
||||
else:
|
||||
wrapper._metadata[P] = P()._gen(wrapper)
|
||||
completed.add(P)
|
||||
|
||||
metadata_batch = _gen_batchable(wrapper, [p() for p in batchable])
|
||||
wrapper._metadata.update(metadata_batch)
|
||||
completed |= batchable
|
||||
|
||||
if len(completed) == 0 and len(batchable) == 0:
|
||||
# remaining must be non-empty at this point
|
||||
names = ", ".join([P.__name__ for P in remaining])
|
||||
raise MetadataException(f"Detected circular dependencies in {names}")
|
||||
|
||||
remaining -= completed
|
||||
|
||||
|
||||
class MetadataWrapper:
|
||||
"""
|
||||
A wrapper around a :class:`~libcst.Module` that stores associated metadata
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue