Skip to content

Commit

Permalink
feat(python): Scope methods (def inside class)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexpovel committed Jul 30, 2024
1 parent 4debfff commit e151d9a
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 3 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1421,6 +1421,7 @@ Language scopes:
- def: Function definitions (*all* `def` block in their entirety)
- async-def: Async function definitions (*all* `async def` block in their
entirety)
- methods: Function definitions inside `class` bodies

--python-query <PYTHON_QUERY>
Scope Python code using a custom tree-sitter query.
Expand Down
21 changes: 18 additions & 3 deletions src/scoping/langs/python.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,18 @@ pub enum PreparedPythonQuery {
FunctionNames,
/// Function calls.
FunctionCalls,
/// Class definitions (in their entirety)
/// Class definitions (in their entirety).
Class,
/// Function definitions (*all* `def` block in their entirety)
/// Function definitions (*all* `def` block in their entirety).
Def,
/// Async function definitions (*all* `async def` block in their entirety)
/// Async function definitions (*all* `async def` block in their entirety).
AsyncDef,
/// Function definitions inside `class` bodies.
Methods,
}

impl From<PreparedPythonQuery> for TSQuery {
#[allow(clippy::too_many_lines)]
fn from(value: PreparedPythonQuery) -> Self {
Self::new(
&Python::lang(),
Expand Down Expand Up @@ -94,6 +97,18 @@ impl From<PreparedPythonQuery> for TSQuery {
PreparedPythonQuery::AsyncDef => {
r#"((function_definition) @def (#match? @def "^async "))"#
}
PreparedPythonQuery::Methods => {
r"
(class_definition
body: (block
[
(function_definition) @method
(decorated_definition definition: (function_definition)) @method
]
)
)
"
}
},
)
.expect("Prepared queries to be valid")
Expand Down
5 changes: 5 additions & 0 deletions tests/langs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@ impl InScopeLinePart {
include_str!("python/base.py"),
Python::new(CodeQuery::Prepared(PreparedPythonQuery::AsyncDef)),
)]
#[case(
"base.py_methods",
include_str!("python/base.py"),
Python::new(CodeQuery::Prepared(PreparedPythonQuery::Methods)),
)]
#[case(
"base.ts_strings",
include_str!("typescript/base.ts"),
Expand Down
73 changes: 73 additions & 0 deletions tests/langs/snapshots/r#mod__langs__base.py_methods.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
source: tests/langs/mod.rs
expression: inscope_parts
---
- n: 51
l: " @staticmethod\n"
m: " ^^^^^^^^^^^^^^^"
- n: 52
l: " def static_decorator(func):\n"
m: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- n: 53
l: " \"\"\"Decorator for static methods.\"\"\"\n"
m: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- n: 54
l: "\n"
m: ^^
- n: 55
l: " def wrapper(*args, **kwargs):\n"
m: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- n: 56
l: " print(\"Static method decorator called\")\n"
m: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- n: 57
l: " return func(*args, **kwargs)\n"
m: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- n: 58
l: "\n"
m: ^^
- n: 59
l: " return wrapper\n"
m: "^^^^^^^^^^^^^^^^^^^^^^ "
- n: 62
l: " @classmethod\n"
m: " ^^^^^^^^^^^^^^"
- n: 63
l: " def class_method(cls) -> None:\n"
m: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- n: 64
l: " \"\"\"Class method.\"\"\"\n"
m: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- n: 65
l: " cls.class_var += \" updated\"\n"
m: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- n: 66
l: " print(f\"Class variable is now {cls.class_var}\")\n"
m: "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ "
- n: 69
l: " def instance_method(self) -> None:\n"
m: " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
- n: 70
l: " \"\"\"Instance method.\"\"\"\n"
m: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- n: 71
l: " self.instance_var = \"Instance variable\"\n"
m: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- n: 72
l: " print(f\"Instance variable is {self.instance_var}\")\n"
m: "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ "
- n: 74
l: " @staticmethod\n"
m: " ^^^^^^^^^^^^^^^"
- n: 75
l: " @static_decorator\n"
m: ^^^^^^^^^^^^^^^^^^^^^^^
- n: 76
l: " def static_method() -> None:\n"
m: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- n: 77
l: " \"\"\"Static method.\"\"\"\n"
m: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- n: 78
l: " print(\"Inside static method\")\n"
m: "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ "

0 comments on commit e151d9a

Please sign in to comment.