feat(parser): parse function param defaults and sinks
This commit is contained in:
@@ -44,7 +44,9 @@ class Function:
|
|||||||
name: str
|
name: str
|
||||||
posonlyargs: list[Argument]
|
posonlyargs: list[Argument]
|
||||||
args: list[Argument]
|
args: list[Argument]
|
||||||
|
sink: Optional[Argument]
|
||||||
kwonlyargs: list[Argument]
|
kwonlyargs: list[Argument]
|
||||||
|
kw_sink: Optional[Argument]
|
||||||
returns: Optional[MidasType]
|
returns: Optional[MidasType]
|
||||||
body: list[Stmt]
|
body: list[Stmt]
|
||||||
|
|
||||||
@@ -53,6 +55,7 @@ class Function:
|
|||||||
location: Optional[Location] = None
|
location: Optional[Location] = None
|
||||||
name: str
|
name: str
|
||||||
type: Optional[MidasType]
|
type: Optional[MidasType]
|
||||||
|
default: Optional[Expr]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def all_args(self) -> list[Argument]:
|
def all_args(self) -> list[Argument]:
|
||||||
|
|||||||
@@ -117,7 +117,9 @@ class Function(Stmt):
|
|||||||
name: str
|
name: str
|
||||||
posonlyargs: list[Argument]
|
posonlyargs: list[Argument]
|
||||||
args: list[Argument]
|
args: list[Argument]
|
||||||
|
sink: Optional[Argument]
|
||||||
kwonlyargs: list[Argument]
|
kwonlyargs: list[Argument]
|
||||||
|
kw_sink: Optional[Argument]
|
||||||
returns: Optional[MidasType]
|
returns: Optional[MidasType]
|
||||||
body: list[Stmt]
|
body: list[Stmt]
|
||||||
|
|
||||||
@@ -126,6 +128,7 @@ class Function(Stmt):
|
|||||||
location: Optional[Location] = None
|
location: Optional[Location] = None
|
||||||
name: str
|
name: str
|
||||||
type: Optional[MidasType]
|
type: Optional[MidasType]
|
||||||
|
default: Optional[Expr]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def all_args(self) -> list[Argument]:
|
def all_args(self) -> list[Argument]:
|
||||||
|
|||||||
@@ -136,14 +136,23 @@ class PythonParser:
|
|||||||
args=ast.arguments(
|
args=ast.arguments(
|
||||||
posonlyargs=posonlyargs,
|
posonlyargs=posonlyargs,
|
||||||
args=args,
|
args=args,
|
||||||
|
vararg=sink,
|
||||||
kwonlyargs=kwonlyargs,
|
kwonlyargs=kwonlyargs,
|
||||||
|
kwarg=kw_sink,
|
||||||
|
defaults=defaults,
|
||||||
|
kw_defaults=kw_defaults,
|
||||||
),
|
),
|
||||||
returns=returns,
|
returns=returns,
|
||||||
body=raw_body,
|
body=raw_body,
|
||||||
):
|
):
|
||||||
|
|
||||||
def parse_args(args_list: list[ast.arg]) -> list[Function.Argument]:
|
def parse_args(
|
||||||
return [self._parse_function_argument(arg) for arg in args_list]
|
args_list: list[ast.arg], defaults: list[Optional[Expr]]
|
||||||
|
) -> list[Function.Argument]:
|
||||||
|
return [
|
||||||
|
self._parse_function_argument(arg, default)
|
||||||
|
for arg, default in zip(args_list, defaults)
|
||||||
|
]
|
||||||
|
|
||||||
body: list[Stmt] = []
|
body: list[Stmt] = []
|
||||||
for stmt in raw_body:
|
for stmt in raw_body:
|
||||||
@@ -152,19 +161,49 @@ class PythonParser:
|
|||||||
body.append(stmts)
|
body.append(stmts)
|
||||||
elif stmts is not None:
|
elif stmts is not None:
|
||||||
body.extend(stmts)
|
body.extend(stmts)
|
||||||
|
|
||||||
|
parsed_defaults: list[Optional[Expr]] = [
|
||||||
|
self.parse_expr(default) for default in defaults
|
||||||
|
]
|
||||||
|
n_posargs: int = len(posonlyargs)
|
||||||
|
n_args: int = len(args)
|
||||||
|
n_all_posargs = n_posargs + n_args
|
||||||
|
parsed_defaults = [
|
||||||
|
None,
|
||||||
|
] * (n_all_posargs - len(defaults)) + parsed_defaults
|
||||||
|
|
||||||
|
posargs_defaults: list[Optional[Expr]] = parsed_defaults[:n_posargs]
|
||||||
|
args_defaults: list[Optional[Expr]] = parsed_defaults[n_posargs:]
|
||||||
|
kwargs_defaults: list[Optional[Expr]] = [
|
||||||
|
self.parse_expr(default) if default is not None else None
|
||||||
|
for default in kw_defaults
|
||||||
|
]
|
||||||
|
|
||||||
return Function(
|
return Function(
|
||||||
location=loc,
|
location=loc,
|
||||||
name=name,
|
name=name,
|
||||||
posonlyargs=parse_args(posonlyargs),
|
posonlyargs=parse_args(posonlyargs, posargs_defaults),
|
||||||
args=parse_args(args),
|
args=parse_args(args, args_defaults),
|
||||||
kwonlyargs=parse_args(kwonlyargs),
|
sink=(
|
||||||
|
self._parse_function_argument(sink, None)
|
||||||
|
if sink is not None
|
||||||
|
else None
|
||||||
|
),
|
||||||
|
kwonlyargs=parse_args(kwonlyargs, kwargs_defaults),
|
||||||
|
kw_sink=(
|
||||||
|
self._parse_function_argument(kw_sink, None)
|
||||||
|
if kw_sink is not None
|
||||||
|
else None
|
||||||
|
),
|
||||||
returns=self._parse_type(returns) if returns is not None else None,
|
returns=self._parse_type(returns) if returns is not None else None,
|
||||||
body=body,
|
body=body,
|
||||||
)
|
)
|
||||||
case _:
|
case _:
|
||||||
print(f"Unsupported function definition: {ast.unparse(node)}")
|
print(f"Unsupported function definition: {ast.unparse(node)}")
|
||||||
|
|
||||||
def _parse_function_argument(self, arg: ast.arg) -> Function.Argument:
|
def _parse_function_argument(
|
||||||
|
self, arg: ast.arg, default: Optional[Expr]
|
||||||
|
) -> Function.Argument:
|
||||||
loc: Location = Location.from_ast(arg)
|
loc: Location = Location.from_ast(arg)
|
||||||
name: str = arg.arg
|
name: str = arg.arg
|
||||||
type: Optional[MidasType] = None
|
type: Optional[MidasType] = None
|
||||||
@@ -174,6 +213,7 @@ class PythonParser:
|
|||||||
location=loc,
|
location=loc,
|
||||||
name=name,
|
name=name,
|
||||||
type=type,
|
type=type,
|
||||||
|
default=default,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _parse_type(
|
def _parse_type(
|
||||||
|
|||||||
Reference in New Issue
Block a user