Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic directives for actions, captures, lists, modes, and tags #144

Merged
merged 24 commits into from
May 21, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Combine info and add signature to actions
  • Loading branch information
wenkokke committed May 21, 2023
commit cda1c787f3708eb7dd5f79467440776c3bf724f6
151 changes: 21 additions & 130 deletions src/talondoc/analysis/registry/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import itertools
import json
from collections.abc import Callable, Iterator, Mapping, Sequence
from dataclasses import dataclass
from dataclasses import asdict, dataclass, fields
from functools import singledispatchmethod
from typing import Any, ClassVar, Optional, Union, cast, overload

Expand Down Expand Up @@ -245,127 +245,6 @@ def _get_list_value(self, name: data.ListName) -> Optional[data.ListValue]:
_LOGGER.warning(e)
return None

######################################################################
# Combine data
######################################################################

@singledispatchmethod
def group(self, group: Sequence[GroupData]) -> Optional[GroupData]:
if group:
raise TypeError(type(group[0]))
else:
return None

@group.register
def _(self, group: Sequence[data.Action]) -> Optional[data.Action]:
if group:
name = group[0].name
description = None
location = group[0].location
parent_name = group[0].parent_name
parent_type = group[0].parent_type
function_name = None
function_signature = None
for obj in group:
assert obj.name == name
description = description or obj.description
function_name = function_name or obj.function_name
function_signature = function_signature or obj.function_signature
return data.Action(
name=name,
description=description,
location=location,
parent_name=parent_name,
parent_type=parent_type,
function_name=function_name,
function_signature=function_signature,
)
else:
return None

@group.register
def _(self, group: Sequence[data.Capture]) -> Optional[data.Capture]:
if group:
name = group[0].name
rule = group[0].rule
description = None
location = group[0].location
parent_name = group[0].parent_name
parent_type = group[0].parent_type
function_name = None
function_signature = None
for obj in group:
assert obj.name == name
description = description or obj.description
function_name = function_name or obj.function_name
function_signature = function_signature or obj.function_signature
return data.Capture(
name=name,
description=description,
location=location,
parent_name=parent_name,
parent_type=parent_type,
rule=rule,
function_name=function_name,
function_signature=function_signature,
)
else:
return None

@group.register
def _(self, group: Sequence[data.List]) -> Optional[data.List]:
if group:
name = group[0].name
description = None
location = group[0].location
parent_name = group[0].parent_name
parent_type = group[0].parent_type
value = None
value_type_hint = None
for obj in group:
assert obj.name == name
description = description or obj.description
value = value or obj.value
value_type_hint = value_type_hint or obj.value_type_hint
return data.List(
name=name,
description=description,
location=location,
parent_name=parent_name,
parent_type=parent_type,
value=value,
value_type_hint=value_type_hint,
)
else:
return None

@group.register
def _(self, group: Sequence[data.Setting]) -> Optional[data.Setting]:
if group:
name = group[0].name
description = None
location = group[0].location
parent_name = group[0].parent_name
parent_type = group[0].parent_type
value = None
value_type_hint = None
for obj in group:
assert obj.name == name
description = description or obj.description
value = value or obj.value
value_type_hint = value_type_hint or obj.value_type_hint
return data.Setting(
name=name,
description=description,
location=location,
parent_name=parent_name,
parent_type=parent_type,
value=value,
value_type_hint=value_type_hint,
)
else:
return None

######################################################################
# Look Up Data
######################################################################
Expand Down Expand Up @@ -437,6 +316,26 @@ def lookup(
def lookup(self, cls: type[Data], name: Any) -> Optional[Any]:
return self._typed_store(cls).get(self.resolve_name(name), None)

def lookup_default(
self, cls: type[GroupDataVar], name: str
) -> Optional[GroupDataVar]:
declaration, default_overrides, _ = self.lookup_partition(cls, name)
return self._combine(cls, itertools.chain((declaration,), default_overrides))

def _combine(
self, cls: type[GroupDataVar], data: Iterator[Optional[GroupDataVar]]
) -> Optional[GroupDataVar]:
init_keys: set[str] = {field.name for field in fields(cls) if field.init}
init_args: dict[str, Any] = {}
for datum in data:
if isinstance(datum, cls):
for name in init_keys:
init_args[name] = init_args.get(name, getattr(datum, name))
if init_args:
return cls(**init_args)
else:
return None

def lookup_description(self, cls: type[Data], name: Any) -> Optional[str]:
if issubclass(cls, SimpleData):
simple = self.lookup(cls, name)
Expand Down Expand Up @@ -496,14 +395,6 @@ def _complexity(obj: GroupDataVar) -> int:
return (declaration, default_overrides, other_overrides)
return (None, (), ())

def lookup_default(
self, cls: type[GroupDataVar], name: str
) -> Optional[GroupDataVar]:
declaration, default_overrides, _ = self.lookup_partition(cls, name)
return cast(
Optional[GroupDataVar], self.group([declaration, *default_overrides])
)

def lookup_default_function(
self, cls: type[GroupDataHasFunction], name: str
) -> Optional[Callable[..., Any]]:
Expand Down
14 changes: 7 additions & 7 deletions src/talondoc/analysis/registry/data/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ def from_dict(cls, value: JsonValue) -> "Command":
parent_name=field_parent_name(value),
)

def to_dict(self) -> JsonValue:
def to_dict(self) -> dict[str, JsonValue]:
return {
"rule": self.rule.text,
"script": self.script.text,
Expand Down Expand Up @@ -423,7 +423,7 @@ def from_dict(cls, value: JsonValue) -> "Action":
parent_type=field_parent_type(value),
)

def to_dict(self) -> JsonValue:
def to_dict(self) -> dict[str, JsonValue]:
return {
"function_name": None,
"function_signature": asdict_opt(asdict_signature)(self.function_signature),
Expand Down Expand Up @@ -475,7 +475,7 @@ def from_dict(cls, value: JsonValue) -> "Capture":
parent_type=field_parent_type(value),
)

def to_dict(self) -> JsonValue:
def to_dict(self) -> dict[str, JsonValue]:
return {
"rule": self.rule.text,
"function_name": None,
Expand Down Expand Up @@ -525,7 +525,7 @@ def from_dict(cls, value: JsonValue) -> "List":
parent_type=field_parent_type(value),
)

def to_dict(self) -> JsonValue:
def to_dict(self) -> dict[str, JsonValue]:
return {
"value": asdict_opt(asdict_list_value)(self.value),
"value_type_hint": asdict_opt(asdict_class)(self.value_type_hint),
Expand Down Expand Up @@ -562,7 +562,7 @@ def from_dict(cls, value: JsonValue) -> "Setting":
parent_type=field_parent_type(value),
)

def to_dict(self) -> JsonValue:
def to_dict(self) -> dict[str, JsonValue]:
return {
"value": asdict_opt(asdict_pickle)(self.value),
"value_type_hint": asdict_opt(asdict_class)(self.value_type_hint),
Expand Down Expand Up @@ -593,7 +593,7 @@ def from_dict(cls, value: JsonValue) -> "Mode":
parent_name=field_parent_name(value),
)

def to_dict(self) -> JsonValue:
def to_dict(self) -> dict[str, JsonValue]:
return {
"name": self.name,
"description": self.description,
Expand Down Expand Up @@ -621,7 +621,7 @@ def from_dict(cls, value: JsonValue) -> "Tag":
parent_name=field_parent_name(value),
)

def to_dict(self) -> JsonValue:
def to_dict(self) -> dict[str, JsonValue]:
return {
"name": self.name,
"description": self.description,
Expand Down
2 changes: 1 addition & 1 deletion src/talondoc/analysis/registry/data/abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ def from_dict(cls, value: JsonValue) -> Self:
...

@abstractmethod
def to_dict(self) -> JsonValue:
def to_dict(self) -> dict[str, JsonValue]:
...


Expand Down
9 changes: 4 additions & 5 deletions src/talondoc/sphinx/directives/action.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import inspect

from docutils import nodes
from sphinx import addnodes
from typing_extensions import override
Expand Down Expand Up @@ -26,13 +28,10 @@ def get_signatures(self) -> list[str]:
def handle_signature(self, sig: str, signode: addnodes.desc_signature) -> str:
default = self.talon.registry.lookup_default(data.Action, sig)
if default:
signode += desc_name(nodes.Text(default.name))
signature = default.function_signature or inspect.Signature()
signode += desc_name(nodes.Text(default.name + str(signature)))
if default.description:
signode += desc_content(paragraph(nodes.Text(default.description)))
if default.function_signature:
signode += desc_content(
paragraph(nodes.Text(str(default.function_signature)))
)
return default.name
else:
e = UnknownReference(
Expand Down