From 30d216ffe01223e225bd3c9946f016b8f648500b Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 1 Jun 2023 08:52:47 +0200 Subject: [PATCH 01/60] Add initial Python language project --- .../.gitignore | 3 + .../CHANGELOG.md | 6 ++ .../Cargo.toml | 38 +++++++ .../tree-sitter-stack-graphs-python/LICENSE | 0 .../tree-sitter-stack-graphs-python/README.md | 98 +++++++++++++++++++ .../rust/bin.rs | 32 ++++++ .../rust/lib.rs | 48 +++++++++ .../rust/test.rs | 23 +++++ .../src/builtins.cfg | 1 + .../src/builtins.py | 0 .../src/stack-graphs.tsg | 42 ++++++++ .../test/test.py | 0 12 files changed, 291 insertions(+) create mode 100644 languages/tree-sitter-stack-graphs-python/.gitignore create mode 100644 languages/tree-sitter-stack-graphs-python/CHANGELOG.md create mode 100644 languages/tree-sitter-stack-graphs-python/Cargo.toml create mode 100644 languages/tree-sitter-stack-graphs-python/LICENSE create mode 100644 languages/tree-sitter-stack-graphs-python/README.md create mode 100644 languages/tree-sitter-stack-graphs-python/rust/bin.rs create mode 100644 languages/tree-sitter-stack-graphs-python/rust/lib.rs create mode 100644 languages/tree-sitter-stack-graphs-python/rust/test.rs create mode 100644 languages/tree-sitter-stack-graphs-python/src/builtins.cfg create mode 100644 languages/tree-sitter-stack-graphs-python/src/builtins.py create mode 100644 languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg create mode 100644 languages/tree-sitter-stack-graphs-python/test/test.py diff --git a/languages/tree-sitter-stack-graphs-python/.gitignore b/languages/tree-sitter-stack-graphs-python/.gitignore new file mode 100644 index 000000000..faf6459fb --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/.gitignore @@ -0,0 +1,3 @@ +*.html +/Cargo.lock +/target diff --git a/languages/tree-sitter-stack-graphs-python/CHANGELOG.md b/languages/tree-sitter-stack-graphs-python/CHANGELOG.md new file mode 100644 index 000000000..9e6604deb --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/CHANGELOG.md @@ -0,0 +1,6 @@ +# Changelog for tree-sitter-stack-graphs-python + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). diff --git a/languages/tree-sitter-stack-graphs-python/Cargo.toml b/languages/tree-sitter-stack-graphs-python/Cargo.toml new file mode 100644 index 000000000..9270879c0 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/Cargo.toml @@ -0,0 +1,38 @@ +[package] +name = "tree-sitter-stack-graphs-python" +version = "0.1.0" +description = "Stack graphs definition for Python using tree-sitter-python" +readme = "README.md" +keywords = ["tree-sitter", "stack-graphs", "python"] +authors = [ + "GitHub ", +] +license = "MIT OR Apache-2.0" +edition = "2018" + +[[bin]] +name = "tree-sitter-stack-graphs-python" +path = "rust/bin.rs" +required-features = ["cli"] + +[lib] +path = "rust/lib.rs" +test = false + +[[test]] +name = "test" +path = "rust/test.rs" +harness = false + +[features] +cli = ["anyhow", "clap", "tree-sitter-stack-graphs/cli"] + +[dependencies] +anyhow = { version = "1.0", optional = true } +clap = { version = "4", optional = true, features = ["derive"] } +tree-sitter-stack-graphs = { version = "0.7", path = "../../tree-sitter-stack-graphs" } +tree-sitter-python = "0.20.2" + +[dev-dependencies] +anyhow = "1.0" +tree-sitter-stack-graphs = { version = "0.7", path = "../../tree-sitter-stack-graphs", features = ["cli"] } diff --git a/languages/tree-sitter-stack-graphs-python/LICENSE b/languages/tree-sitter-stack-graphs-python/LICENSE new file mode 100644 index 000000000..e69de29bb diff --git a/languages/tree-sitter-stack-graphs-python/README.md b/languages/tree-sitter-stack-graphs-python/README.md new file mode 100644 index 000000000..3bf115da0 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/README.md @@ -0,0 +1,98 @@ +# tree-sitter-stack-graphs definition for Python + +This project defines tree-sitter-stack-graphs rules for Python using the [tree-sitter-python][] grammar. + +[tree-sitter-python]: https://crates.io/crates/tree-sitter-python + +## Usage + +To use this library, add the following to your `Cargo.toml`: + +``` toml +[dependencies] +tree-sitter-stack-graphs-python = "0.1.0" +``` + +Check out our [documentation](https://docs.rs/tree-sitter-stack-graphs-python/*/) for more details on how to use this library. + +## Command-line Program + +The command-line program for `tree-sitter-stack-graphs-python` lets you do stack graph based analysis and lookup from the command line. + +Install the program using `cargo install` as follows: + +``` sh +$ cargo install --features cli tree-sitter-stack-graphs-python +$ tree-sitter-stack-graphs-python --help +``` + +## Development + +The project is written in Rust, and requires a recent version installed. Rust can be installed and updated using [rustup][]. + +[rustup]: https://rustup.rs/ + +The project is organized as follows: + +- The stack graph rules are defined in `src/stack-graphs.tsg`. +- Builtins sources and configuration are defined in `src/builtins.py` and `builtins.cfg` respectively. +- Tests are put into the `test` directory. + +### Building and Running Tests + +Build the project by running: + +``` sh +$ cargo build +``` + +Run the tests as follows: + +``` sh +$ cargo test +``` + +The project consists of a library and a CLI. By default, running `cargo` only applies to the library. To run `cargo` commands on the CLI as well, add `--features cli` or `--all-features`. + +Run the CLI from source as follows: + +``` sh +$ cargo run --features cli -- ARGS +``` + +Sources are formatted using the standard Rust formatted, which is applied by running: + +``` sh +$ cargo fmt +``` + +### Writing TSG + +The stack graph rules are written in [tree-sitter-graph][]. Checkout the [examples][], +which contain self-contained TSG rules for specific language features. A VSCode +[extension][] is available that provides syntax highlighting for TSG files. + +[tree-sitter-graph]: https://github.com/tree-sitter/tree-sitter-graph +[examples]: https://github.com/github/stack-graphs/blob/main/tree-sitter-stack-graphs/examples/ +[extension]: https://marketplace.visualstudio.com/items?itemName=tree-sitter.tree-sitter-graph + +Parse and test a single file by executing the following commands: + +``` sh +$ cargo run --features cli -- parse FILES... +$ cargo run --features cli -- test TESTFILES... +``` + +Generate a visualization to debug failing tests by passing the `-V` flag: + +``` sh +$ cargo run --features cli -- test -V TESTFILES... +``` + +To generate the visualization regardless of test outcome, execute: + +``` sh +$ cargo run --features cli -- test -V --output-mode=always TESTFILES... +``` + +Go to https://crates.io/crates/tree-sitter-stack-graphs for links to examples and documentation. diff --git a/languages/tree-sitter-stack-graphs-python/rust/bin.rs b/languages/tree-sitter-stack-graphs-python/rust/bin.rs new file mode 100644 index 000000000..dc9a6772c --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/rust/bin.rs @@ -0,0 +1,32 @@ +// -*- coding: utf-8 -*- +// ------------------------------------------------------------------------------------------------ +// Copyright © 2023, stack-graphs authors. +// Licensed under either of Apache License, Version 2.0, or MIT license, at your option. +// Please see the LICENSE-APACHE or LICENSE-MIT files in this distribution for license details. +// ------------------------------------------------------------------------------------------------ + +use anyhow::anyhow; +use clap::Parser; +use tree_sitter_stack_graphs::cli::database::default_user_database_path_for_crate; +use tree_sitter_stack_graphs::cli::provided_languages::Subcommands; +use tree_sitter_stack_graphs::NoCancellation; + +fn main() -> anyhow::Result<()> { + let lc = match tree_sitter_stack_graphs_python::try_language_configuration(&NoCancellation) { + Ok(lc) => lc, + Err(err) => { + eprintln!("{}", err.display_pretty()); + return Err(anyhow!("Language configuration error")); + } + }; + let cli = Cli::parse(); + let default_db_path = default_user_database_path_for_crate(env!("CARGO_PKG_NAME"))?; + cli.subcommand.run(default_db_path, vec![lc]) +} + +#[derive(Parser)] +#[clap(about, version)] +pub struct Cli { + #[clap(subcommand)] + subcommand: Subcommands, +} diff --git a/languages/tree-sitter-stack-graphs-python/rust/lib.rs b/languages/tree-sitter-stack-graphs-python/rust/lib.rs new file mode 100644 index 000000000..74176a475 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/rust/lib.rs @@ -0,0 +1,48 @@ +// -*- coding: utf-8 -*- +// ------------------------------------------------------------------------------------------------ +// Copyright © 2023, stack-graphs authors. +// Licensed under either of Apache License, Version 2.0, or MIT license, at your option. +// Please see the LICENSE-APACHE or LICENSE-MIT files in this distribution for license details. +// ------------------------------------------------------------------------------------------------ + +use tree_sitter_stack_graphs::loader::LanguageConfiguration; +use tree_sitter_stack_graphs::loader::LoadError; +use tree_sitter_stack_graphs::CancellationFlag; + +/// The stack graphs tsg source for this language. +pub const STACK_GRAPHS_TSG_PATH: &str = "src/stack-graphs.tsg"; +/// The stack graphs tsg source for this language. +pub const STACK_GRAPHS_TSG_SOURCE: &str = include_str!("../src/stack-graphs.tsg"); + +/// The stack graphs builtins configuration for this language. +pub const STACK_GRAPHS_BUILTINS_CONFIG: &str = include_str!("../src/builtins.cfg"); +/// The stack graphs builtins path for this language +pub const STACK_GRAPHS_BUILTINS_PATH: &str = "src/builtins.py"; +/// The stack graphs builtins source for this language. +pub const STACK_GRAPHS_BUILTINS_SOURCE: &str = include_str!("../src/builtins.py"); + +/// The name of the file path global variable. +pub const FILE_PATH_VAR: &str = "FILE_PATH"; + +pub fn language_configuration(cancellation_flag: &dyn CancellationFlag) -> LanguageConfiguration { + try_language_configuration(cancellation_flag).unwrap_or_else(|err| panic!("{}", err)) +} + +pub fn try_language_configuration( + cancellation_flag: &dyn CancellationFlag, +) -> Result { + LanguageConfiguration::from_sources( + tree_sitter_python::language(), + Some(String::from("source.py")), + None, + vec![String::from("py")], + STACK_GRAPHS_TSG_PATH.into(), + STACK_GRAPHS_TSG_SOURCE, + Some(( + STACK_GRAPHS_BUILTINS_PATH.into(), + STACK_GRAPHS_BUILTINS_SOURCE, + )), + Some(STACK_GRAPHS_BUILTINS_CONFIG), + cancellation_flag, + ) +} diff --git a/languages/tree-sitter-stack-graphs-python/rust/test.rs b/languages/tree-sitter-stack-graphs-python/rust/test.rs new file mode 100644 index 000000000..c81edf0d4 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/rust/test.rs @@ -0,0 +1,23 @@ +// -*- coding: utf-8 -*- +// ------------------------------------------------------------------------------------------------ +// Copyright © 2023, stack-graphs authors. +// Licensed under either of Apache License, Version 2.0, or MIT license, at your option. +// Please see the LICENSE-APACHE or LICENSE-MIT files in this distribution for license details. +// ------------------------------------------------------------------------------------------------ + +use anyhow::anyhow; +use std::path::PathBuf; +use tree_sitter_stack_graphs::ci::Tester; +use tree_sitter_stack_graphs::NoCancellation; + +fn main() -> anyhow::Result<()> { + let lc = match tree_sitter_stack_graphs_python::try_language_configuration(&NoCancellation) { + Ok(lc) => lc, + Err(err) => { + eprintln!("{}", err.display_pretty()); + return Err(anyhow!("Language configuration error")); + } + }; + let test_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("test"); + Tester::new(vec![lc], vec![test_path]).run() +} diff --git a/languages/tree-sitter-stack-graphs-python/src/builtins.cfg b/languages/tree-sitter-stack-graphs-python/src/builtins.cfg new file mode 100644 index 000000000..d685061be --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/src/builtins.cfg @@ -0,0 +1 @@ +[globals] diff --git a/languages/tree-sitter-stack-graphs-python/src/builtins.py b/languages/tree-sitter-stack-graphs-python/src/builtins.py new file mode 100644 index 000000000..e69de29bb diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg new file mode 100644 index 000000000..99647e75b --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -0,0 +1,42 @@ +;; -*- coding: utf-8 -*- +;; ------------------------------------------------------------------------------------------------ +;; Copyright © 2023, stack-graphs authors. +;; Licensed under either of Apache License, Version 2.0, or MIT license, at your option. +;; Please see the LICENSE-APACHE or LICENSE-MIT files in this distribution for license details. +;; ------------------------------------------------------------------------------------------------ + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Stack graphs definition for Python +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Global Variables +;; ^^^^^^^^^^^^^^^^ + +global FILE_PATH +global ROOT_NODE +global JUMP_TO_SCOPE_NODE + +;; Attribute Shorthands +;; ^^^^^^^^^^^^^^^^^^^^ + +attribute node_definition = node => type = "pop_symbol", node_symbol = node, is_definition +attribute node_reference = node => type = "push_symbol", node_symbol = node, is_reference +attribute pop_node = node => type = "pop_symbol", node_symbol = node +attribute pop_scoped_node = node => type = "pop_scoped_symbol", node_symbol = node +attribute pop_scoped_symbol = symbol => type = "pop_scoped_symbol", symbol = symbol +attribute pop_symbol = symbol => type = "pop_symbol", symbol = symbol +attribute push_node = node => type = "push_symbol", node_symbol = node +attribute push_scoped_node = node => type = "push_scoped_symbol", node_symbol = node +attribute push_scoped_symbol = symbol => type = "push_scoped_symbol", symbol = symbol +attribute push_symbol = symbol => type = "push_symbol", symbol = symbol +attribute scoped_node_definition = node => type = "pop_scoped_symbol", node_symbol = node, is_definition +attribute scoped_node_reference = node => type = "push_scoped_symbol", node_symbol = node, is_reference +attribute symbol_definition = symbol => type = "pop_symbol", symbol = symbol, is_definition +attribute symbol_reference = symbol => type = "push_symbol", symbol = symbol, is_reference + +attribute node_symbol = node => symbol = (source-text node), source_node = node + +;; Stack Graph Rules +;; ^^^^^^^^^^^^^^^^^ + +; Have fun! diff --git a/languages/tree-sitter-stack-graphs-python/test/test.py b/languages/tree-sitter-stack-graphs-python/test/test.py new file mode 100644 index 000000000..e69de29bb From 75a3ec5939ead46a7d50c18ad8a936067402c4f6 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 1 Jun 2023 09:37:26 +0200 Subject: [PATCH 02/60] Add legacy queries and tests for reference --- .../src/stack-graphs.scm | 779 ++++++++++++++++++ .../test/legacy.skip/aliased_imports.py | 31 + .../test/legacy.skip/attributes.py | 14 + .../test/legacy.skip/blocks.py | 21 + .../test/legacy.skip/chained_functions.py | 23 + .../test/legacy.skip/chained_methods.py | 27 + .../test/legacy.skip/class_members.py | 23 + .../test/legacy.skip/decorators.py | 10 + .../test/legacy.skip/exceptions.py | 5 + .../test/legacy.skip/functions.py | 31 + .../test/legacy.skip/imported_functions.py | 17 + .../test/legacy.skip/imports.py | 31 + .../test/legacy.skip/instance_members.py | 38 + .../test/legacy.skip/loops.py | 19 + .../test/legacy.skip/many_definitions.py | 76 ++ .../test/legacy.skip/pattern_matching.py | 39 + .../test/legacy.skip/redundant_reexport.py | 15 + .../test/legacy.skip/relative_imports.py | 60 ++ .../test/legacy.skip/statement_bindings.py | 9 + .../test/legacy.skip/superclasses.py | 19 + .../test/{ => legacy.skip}/test.py | 0 .../test/legacy.skip/tuples.py | 38 + .../test/legacy.skip/wildcard_import.py | 21 + 23 files changed, 1346 insertions(+) create mode 100644 languages/tree-sitter-stack-graphs-python/src/stack-graphs.scm create mode 100644 languages/tree-sitter-stack-graphs-python/test/legacy.skip/aliased_imports.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/legacy.skip/attributes.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/legacy.skip/blocks.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/legacy.skip/chained_functions.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/legacy.skip/chained_methods.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/legacy.skip/class_members.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/legacy.skip/decorators.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/legacy.skip/exceptions.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/legacy.skip/functions.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/legacy.skip/imported_functions.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/legacy.skip/imports.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/legacy.skip/instance_members.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/legacy.skip/loops.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/legacy.skip/many_definitions.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/legacy.skip/pattern_matching.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/legacy.skip/redundant_reexport.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/legacy.skip/relative_imports.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/legacy.skip/statement_bindings.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/legacy.skip/superclasses.py rename languages/tree-sitter-stack-graphs-python/test/{ => legacy.skip}/test.py (100%) create mode 100644 languages/tree-sitter-stack-graphs-python/test/legacy.skip/tuples.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/legacy.skip/wildcard_import.py diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.scm b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.scm new file mode 100644 index 000000000..380af7d95 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.scm @@ -0,0 +1,779 @@ +;; -*- coding: utf-8 -*- +;; ------------------------------------------------------------------------------------------------ +;; Copyright © 2023, stack-graphs authors. +;; Licensed under either of Apache License, Version 2.0, or MIT license, at your option. +;; Please see the LICENSE-APACHE or LICENSE-MIT files in this distribution for license details. +;; ------------------------------------------------------------------------------------------------ + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; LEGACY DEFINITION! INCLUDED FOR REFERENCE ONLY! ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Modules and Imports +;--------------------- + +(module) @mod +{ + var module_def = @mod.file_def + attr module_def "no_span" + var module_ref = @mod.file_ref + attr module_ref "no_span" + var parent_module_def = module_def + var parent_module_ref = module_ref + var grandparent_module_ref = module_ref + + scan filepath { + "([^/]+)/" + { + edge module_def -> module_def.dot + edge module_def.dot -> module_def.next_def + edge module_ref.next_ref -> module_ref.dot + edge module_ref.dot -> module_ref + + attr module_def "pop" = $1 + attr module_def.dot "pop" = "." + attr module_ref "push" = $1 + attr module_ref.dot "push" = "." + + set grandparent_module_ref = parent_module_ref + set parent_module_def = module_def + set parent_module_ref = module_ref + set module_ref = module_ref.next_ref + set module_def = module_def.next_def + attr module_def "no_span" + attr module_ref "no_span" + } + + "__init__\\.py$" + { + attr parent_module_def "definition" + } + + "([^/]+)$" + { + edge module_def -> module_def.dot + edge module_def.dot -> module_def.next_def + + attr module_def "definition", "pop" = (replace $1 "\\.py" "") + attr module_def.dot "pop" = "." + + set module_def = module_def.next_def + attr module_def "no_span" + attr module_ref "no_span" + } + } + + edge root -> @mod.file_def + edge @mod.file_ref -> root + edge module_def -> @mod.after_scope + + edge @mod.before_scope -> @mod.global_dot + edge @mod.global -> root + attr @mod.global "push" = "" + + edge @mod.global_dot -> @mod.global + attr @mod.global_dot "push" = "." + + var @mod::parent_module = parent_module_ref + var @mod::grandparent_module = grandparent_module_ref + var @mod::bottom = @mod.after_scope + var @mod::global = @mod.global + var @mod::global_dot = @mod.global_dot +} + +(import_statement + name: (dotted_name + . (identifier) @root_name)) @stmt +{ + edge @stmt.after_scope -> @root_name.def, "precedence" = 1 + edge @root_name.ref -> root + attr @root_name.ref "push", "reference" + attr @root_name.def "pop", "definition" +} + +(import_statement + name: (aliased_import + (dotted_name . (identifier) @root_name))) @stmt +{ + edge @stmt.after_scope -> @root_name.def + edge @root_name.ref -> root + attr @root_name.ref "push", "reference" +} + +(import_from_statement + module_name: (dotted_name + . (identifier) @prefix_root_name)) @stmt +{ + edge @prefix_root_name.ref -> root + attr @prefix_root_name.ref "push", "reference" +} + +(import_from_statement + name: (dotted_name + . (identifier) @import_root_name)) @stmt +{ + edge @stmt.after_scope -> @import_root_name.def, "precedence" = 1 + edge @import_root_name.ref -> @import_root_name.ref_dot + attr @import_root_name.def "pop", "definition" + attr @import_root_name.ref "push", "reference" + attr @import_root_name.ref_dot "push" = "." +} + +(import_from_statement + name: (aliased_import + (dotted_name + . (identifier) @import_root_name))) @stmt +{ + edge @import_root_name.ref -> @import_root_name.ref_dot + attr @import_root_name.ref "push", "reference" + attr @import_root_name.ref_dot "push" = "." +} + +(import_from_statement + module_name: [ + (dotted_name (identifier) @prefix_leaf_name .) + (relative_import (dotted_name (identifier) @prefix_leaf_name .)) + (relative_import (import_prefix) @prefix_leaf_name .) + ] + name: [ + (dotted_name + . (identifier) @import_root_name) + (aliased_import + (dotted_name + . (identifier) @import_root_name)) + ]) +{ + edge @import_root_name.ref_dot -> @prefix_leaf_name.ref +} + +[ + (import_from_statement + (aliased_import + name: (dotted_name (identifier) @name .) + alias: (identifier) @alias)) + (import_statement + (aliased_import + name: (dotted_name (identifier) @name .) + alias: (identifier) @alias)) +] @stmt +{ + edge @stmt.after_scope -> @alias + edge @alias -> @name.ref + attr @alias "pop", "definition" +} + +[ + (import_statement + name: (dotted_name + (identifier) @leaf_name .)) + (import_from_statement + name: (dotted_name + (identifier) @leaf_name .)) +] +{ + attr @leaf_name.def "pop", "definition" + attr @leaf_name.ref "push", "reference" + edge @leaf_name.def -> @leaf_name.ref +} + +(relative_import + (import_prefix) @prefix + (#eq? @prefix ".")) @import +{ + edge @prefix.ref -> @import::parent_module +} + +(relative_import + (import_prefix) @prefix + (#eq? @prefix "..")) @import +{ + edge @prefix.ref -> @import::grandparent_module +} + +(relative_import + (import_prefix) @prefix + (dotted_name + . (identifier) @name)) +{ + attr @name.ref "push", "reference" + attr @name.ref_dot "push" = "." + edge @name.ref -> @name.ref_dot + edge @name.ref_dot -> @prefix.ref +} + +[ + (import_from_statement + module_name: (relative_import + (dotted_name + (identifier) @parent_name + . + (identifier) @child_name))) + (import_from_statement + module_name: (dotted_name + (identifier) @parent_name + . + (identifier) @child_name)) +] +{ + attr @child_name.ref "push", "reference" + attr @child_name.ref_dot "push" = "." + edge @child_name.ref -> @child_name.ref_dot + edge @child_name.ref_dot -> @parent_name.ref +} + +(import_from_statement + module_name: (dotted_name + . (identifier) @root_name)) +{ + attr @root_name.ref "push", "reference" + edge @root_name.ref -> root +} + +(import_from_statement + module_name: (dotted_name + (identifier) @leaf_name .) + (wildcard_import) @star) @stmt +{ + edge @stmt.after_scope -> @star.ref_dot, "precedence" = 1 + edge @star.ref_dot -> @leaf_name.ref + attr @star.ref_dot "push" = "." +} + +[ + (import_statement + name: (dotted_name + (identifier) @parent_name + . + (identifier) @child_name)) + (import_from_statement + name: (dotted_name + (identifier) @parent_name + . + (identifier) @child_name)) + (import_from_statement + name: (aliased_import + name: (dotted_name + (identifier) @parent_name + . + (identifier) @child_name))) +] +{ + edge @child_name.ref -> @child_name.ref_dot + edge @child_name.ref_dot -> @parent_name.ref + edge @parent_name.def -> @parent_name.def_dot + edge @parent_name.def_dot -> @child_name.def + attr @child_name.def "pop", "definition" + attr @child_name.ref "push","reference" + attr @parent_name.def_dot "pop" = "." + attr @child_name.ref_dot "push" = "." +} + +;-------- +; Scopes +;-------- + +[ + (module (_) @last_stmt .) + (block (_) @last_stmt .) +] @block +{ + edge @block.after_scope -> @last_stmt.after_scope +} + +[ + (module (_) @stmt1 . (_) @stmt2) + (block (_) @stmt1 . (_) @stmt2) +] +{ + edge @stmt2.before_scope -> @stmt1.after_scope +} + +[ + (module (_) @stmt) + (block (_) @stmt) +] +{ + edge @stmt.after_scope -> @stmt.before_scope + let @stmt::local_scope = @stmt.before_scope +} + +[ + (block . (_) @stmt) + (module . (_) @stmt) +] @block +{ + edge @stmt.before_scope -> @block.before_scope +} + +(block (_) @stmt . ) @block +{ + edge @block.after_scope -> @stmt.after_scope +} + +(function_definition (block) @block) +{ + edge @block.before_scope -> @block::local_scope +} + +[ + (while_statement (block) @block) + (if_statement (block) @block) + (with_statement (block) @block) + (try_statement (block) @block) + (for_statement (block) @block) + (_ [ + (else_clause (block) @block) + (elif_clause (block) @block) + (except_clause (block) @block) + (finally_clause (block) @block) + ]) +] @stmt +{ + edge @block.before_scope -> @block::local_scope + edge @stmt.after_scope -> @block.after_scope +} + +(match_statement (case_clause) @block) @stmt +{ + let @block::local_scope = @block.before_scope + edge @block.before_scope -> @stmt.before_scope + edge @stmt.after_scope -> @block.after_scope +} + +[ + (for_statement) + (while_statement) +] @stmt +{ + edge @stmt.before_scope -> @stmt.after_scope +} + +;------------- +; Definitions +;------------- + +[ + (assignment + left: (_) @pattern + right: (_) @value) + (with_item + value: + (as_pattern + (_) @value + alias: (as_pattern_target (_) @pattern))) +] +{ + edge @pattern.input -> @value.output +} + +(function_definition + name: (identifier) @name + parameters: (parameters) @params + body: (block) @body) @func +{ + attr @name "definiens" = @func + edge @func.after_scope -> @name + edge @name -> @func.call + edge @func.call -> @func.return_value + edge @body.before_scope -> @params.after_scope + edge @body.before_scope -> @func.drop_scope + edge @func.drop_scope -> @func::bottom + attr @func.drop_scope "drop" + attr @name "pop", "definition" + attr @func.call "pop" = "()", "pop-scope" + attr @params.before_scope "jump-to" + attr @func.return_value "endpoint" + let @func::function_returns = @func.return_value + + ; Prevent functions defined inside of method bodies from being treated like methods + let @body::class_self_scope = nil + let @body::class_member_attr_scope = nil +} + +;; +;; BEGIN BIG GNARLY DISJUNCTION +;; +;; The following pair of rules is intended to capture the following behavior: +;; +;; If a function definition is used to define a method, by being inside a class +;; definition, then we make its syntax type `method`. Otherwise, we make it's +;; syntax type `function`. Unfortunately, because of the limitations on negation +;; and binding in tree sitter queries, we cannot negate `class_definition` or +;; similar things directly. Instead, we have to manually push the negation down +;; to form the finite disjunction it corresponds to. +;; + +[ + (class_definition (block (decorated_definition (function_definition name: (_)@name)))) + (class_definition (block (function_definition name: (_)@name))) +] +{ + attr @name "syntax_type" = "method" +} + +[ + (module (decorated_definition (function_definition name: (_)@name))) + (module (function_definition name: (_)@name)) + + (if_statement (block (decorated_definition (function_definition name: (_)@name)))) + (if_statement (block (function_definition name: (_)@name))) + + (elif_clause (block (decorated_definition (function_definition name: (_)@name)))) + (elif_clause (block (function_definition name: (_)@name))) + + (else_clause (block (decorated_definition (function_definition name: (_)@name)))) + (else_clause (block (function_definition name: (_)@name))) + + (case_clause (block (decorated_definition (function_definition name: (_)@name)))) + (case_clause (block (function_definition name: (_)@name))) + + (for_statement (block (decorated_definition (function_definition name: (_)@name)))) + (for_statement (block (function_definition name: (_)@name))) + + (while_statement (block (decorated_definition (function_definition name: (_)@name)))) + (while_statement (block (function_definition name: (_)@name))) + + (try_statement (block (decorated_definition (function_definition name: (_)@name)))) + (try_statement (block (function_definition name: (_)@name))) + + (except_clause (block (decorated_definition (function_definition name: (_)@name)))) + (except_clause (block (function_definition name: (_)@name))) + + (finally_clause (block (decorated_definition (function_definition name: (_)@name)))) + (finally_clause (block (function_definition name: (_)@name))) + + (with_statement (block (decorated_definition (function_definition name: (_)@name)))) + (with_statement (block (function_definition name: (_)@name))) + + (function_definition (block (decorated_definition (function_definition name: (_)@name)))) + (function_definition (block (function_definition name: (_)@name))) +] +{ + attr @name "syntax_type" = "function" +} + +;; +;; END BIG GNARLY DISJUNCTION +;; + +(function_definition + parameters: (parameters + . (identifier) @param) + body: (block) @body) +{ + edge @param.input -> @param::class_self_scope + edge @param::class_member_attr_scope -> @param.output + edge @param.output -> @body.after_scope + attr @param.output "push" +} + +(parameter/identifier) @param +{ + attr @param.input "definition", "pop" + attr @param.param_name "push" + edge @param.input -> @param.param_index + edge @param.input -> @param.param_name +} + +[ + (parameter/default_parameter + name: (identifier) @name + value: (_) @value) @param + (parameter/typed_default_parameter + name: (_) @name + value: (_) @value) @param +] +{ + attr @name "definition", "pop" + attr @param.param_name "push" = @name + edge @name -> @param.param_name + edge @name -> @param.param_index + edge @param.input -> @name + edge @name -> @value.output +} + +[ + (parameter/typed_parameter + . (_) @name) @param + (parameter/list_splat_pattern + (_) @name) @param + (parameter/dictionary_splat_pattern + (_) @name) @param +] +{ + attr @name "definition", "pop" + attr @param.param_name "push" = @name + edge @name -> @param.param_name + edge @name -> @param.param_index + edge @param.input -> @name +} + +[ + (pattern_list (_) @pattern) + (tuple_pattern (_) @pattern) +] @list +{ + let statement_scope = @list::local_scope + let @pattern::local_scope = @pattern.pattern_before_scope + edge statement_scope -> @pattern::local_scope, "precedence" = (+ 1 (child-index @pattern)) + + edge @pattern.pattern_index -> @list.input + edge @pattern.input -> @pattern.pattern_index + attr @pattern.pattern_index "push" = (child-index @pattern) +} + +(parameters + (_) @param) @params +{ + attr @param.param_index "push" = (child-index @param) + edge @param.param_index -> @params.before_scope + edge @params.after_scope -> @param.input + edge @param.param_name -> @params.before_scope +} + +(return_statement (_) @expr) @stmt +{ + edge @stmt::function_returns -> @expr.output +} + +(class_definition + name: (identifier) @name) @class +{ + attr @name "definiens" = @class + attr @name "syntax_type" = "class" + edge @class.parent_scope -> @class::class_parent_scope + edge @class.parent_scope -> @class::local_scope + edge @class.after_scope -> @name + edge @name -> @class.call + edge @name -> @class.dot + edge @class.dot -> @class.members + edge @class.call -> @class.call_drop + edge @class.call_drop -> @class.self_scope + edge @class.self_scope -> @class.super_scope + edge @class.self_scope -> @class.self_dot + edge @class.self_dot -> @class.members + edge @class.members -> @class.member_attrs + attr @class.call "pop" = "()", "pop-scope" + attr @class.call_drop "drop" + attr @class.dot "pop" = "." + attr @class.self_dot "pop" = "." + attr @name "pop", "definition" + attr @class.member_attrs "push" = "." + attr @class.self_scope "endpoint" + let @class::super_scope = @class.super_scope + let @class::class_parent_scope = @class.parent_scope + let @class::class_self_scope = @class.call_drop + let @class::class_member_attr_scope = @class.member_attrs +} + +(class_definition + body: (block + (_) @last_stmt .) @body) @class +{ + edge @class.members -> @last_stmt.after_scope +} + +(class_definition + superclasses: (argument_list + (_) @superclass)) @class +{ + edge @class.super_scope -> @superclass.output +} + +(decorated_definition + definition: (_) @def) @stmt +{ + edge @def.before_scope -> @stmt.before_scope + edge @stmt.after_scope -> @def.after_scope +} + +(case_clause + pattern: (_) @pattern + consequence: (_) @consequence) @clause +{ + edge @consequence.before_scope -> @pattern.new_bindings + edge @consequence.before_scope -> @clause.before_scope + edge @clause.after_scope -> @consequence.after_scope +} + +;------------- +; Expressions +;------------- + +(call + function: (_) @fn + arguments: (argument_list) @args) @call +{ + edge @call.output -> @call.output_args + edge @call.output_args -> @fn.output + attr @call.output_args "push" = "()", "push-scope" = @args +} + +(call + function: (attribute + object: (_) @receiver) + arguments: (argument_list + (expression) @arg) @args) +{ + edge @args -> @arg.arg_index + edge @receiver -> @receiver.arg_index + + attr @receiver.arg_index "pop" = "0" + edge @receiver.arg_index -> @receiver.output + + attr @arg.arg_index "pop" = (+ 1 (child-index @arg)) + edge @arg.arg_index -> @arg.output +} + +(call + arguments: (argument_list + (keyword_argument + name: (identifier) @name + value: (_) @val) @arg) @args) @call +{ + edge @args -> @arg.arg_name + attr @arg.arg_name "pop" = @name + edge @arg.arg_name -> @val.output +} + +(argument_list + (expression) @arg) @args +{ + edge @args -> @arg.arg_index + attr @arg.arg_index "pop" = (child-index @arg) + edge @arg.arg_index -> @arg.output +} + +( + (call + function: (identifier) @fn-name) @call + (#eq? @fn-name "super") +) +{ + edge @call.output -> @call::super_scope +} + +[ + (tuple (_) @element) + (expression_list (_) @element) +] @tuple +{ + edge @tuple.output -> @element.el_index + attr @element.el_index "pop" = (child-index @element) + edge @element.el_index -> @element.output + + edge @tuple.new_bindings -> @element.new_bindings +} + +(attribute + object: (_) @object + attribute: (identifier) @name) @expr +{ + edge @expr.output -> @name.output + edge @name.output -> @expr.output_dot + edge @expr.output_dot -> @object.output + edge @object.input -> @expr.input_dot + edge @expr.input_dot -> @name.input + edge @name.input -> @expr.input + attr @expr.output_dot "push" = "." + attr @expr.input_dot "pop" = "." + attr @name.input "pop" + attr @name.output "push" +} + +(pattern/attribute + attribute: (identifier) @name) +{ + attr @name.input "definition" +} + +(primary_expression/attribute + attribute: (identifier) @name) +{ + attr @name.output "reference" +} + +(primary_expression/identifier) @id +{ + edge @id.output -> @id::local_scope + edge @id.output -> @id::class_parent_scope + edge @id::local_scope -> @id.input + attr @id.input "pop" + attr @id.output "push", "reference" + + attr @id.new_binding_pop "pop", "definition" + edge @id.new_bindings -> @id.new_binding_pop +} + +(pattern/identifier) @id +{ + edge @id.output -> @id::local_scope + edge @id.output -> @id::class_parent_scope + edge @id::local_scope -> @id.input, "precedence" = 1 + attr @id.input "pop", "definition" + attr @id.output "push" + + attr @id.new_binding_pop "pop", "definition" + edge @id.new_bindings -> @id.new_binding_pop +} + +(as_pattern + (expression) @value + alias: (as_pattern_target (primary_expression/identifier) @id)) @as_pattern +{ + edge @id.output -> @id::local_scope + edge @id.output -> @id::class_parent_scope + edge @id::local_scope -> @id.input, "precedence" = 1 + attr @id.input "pop", "definition" + attr @id.output "push" + + edge @as_pattern.new_bindings -> @value.new_bindings + edge @as_pattern.new_bindings -> @id.new_bindings +} + +(list) @list +{ + edge @list.output -> @list.called + edge @list.called -> @list::global_dot + attr @list.called "push" = "list" +} + +(list (_) @el) @list +{ + edge @list.new_bindings -> @el.new_bindings +} + +(dictionary (pair) @pair) @dict +{ + edge @dict.new_bindings -> @pair.new_bindings +} + +(pair + value: (_) @value) @pair +{ + edge @pair.new_bindings -> @value.new_bindings +} + +(set (_) @el) @set +{ + edge @set.new_bindings -> @el.new_bindings +} + +(list_splat (_) @splatted) @splat +{ +attr @splat.new_bindings_pop "pop" = @splatted, "definition" +edge @splat.new_bindings -> @splat.new_bindings_pop +} + +(binary_operator + (_) @left + (_) @right) @binop +{ + edge @binop.new_bindings -> @left.new_bindings + edge @binop.new_bindings -> @right.new_bindings +} + +(case_pattern (_) @expr) @pat +{ + edge @pat.new_bindings -> @expr.new_bindings +} diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/aliased_imports.py b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/aliased_imports.py new file mode 100644 index 000000000..d988757a5 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/aliased_imports.py @@ -0,0 +1,31 @@ +#------ path: foo.py ------# + +# module +class A: + a = 1 + +class B: + class C: + class D: + d = 2 + +#------ path: main.py ---# + +from foo import A as X, B.C.D as Y +import foo as f + +print X.a, Y.d +# ^ defined: 5 +# ^ defined: 10 + +print A, B.C +# ^ defined: +# ^ defined: +# ^ defined: + +print f.B +# ^ defined: 2, 15 +# ^ defined: 7 + +print foo +# ^ defined: diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/attributes.py b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/attributes.py new file mode 100644 index 000000000..6dd3d0e48 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/attributes.py @@ -0,0 +1,14 @@ +a = 1 + +a.b = 2 + +a.c.d = 5 + +print a.b +# ^ defined: 1 +# ^ defined: 3 + +print a.c, a.c.d +# ^ defined: 1 +# ^ defined: +# ^ defined: 5 diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/blocks.py b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/blocks.py new file mode 100644 index 000000000..462890baf --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/blocks.py @@ -0,0 +1,21 @@ +def f(): + if a: + b = 1 + else: + c = 2 + + print b, c + # ^ defined: 3 + # ^ defined: 5 + +class G: + if d: + e = 1 + + print e + # ^ defined: 13 + +print b, c, e +# ^ defined: +# ^ defined: +# ^ defined: diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/chained_functions.py b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/chained_functions.py new file mode 100644 index 000000000..ef1dac21d --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/chained_functions.py @@ -0,0 +1,23 @@ +class A: + w = 1 + x = 2 + y = 3 + z = 4 + +def get_a(): + return A +def get_b(): + return get_a() +def get_c(): + return get_b() +def get_d(): + return get_c() +def get_e(): + return get_d() +def get_f(): + return get_e() + +g = get_f(A) +print g.x, g.y +# ^ defined: 3 +# ^ defined: 4 diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/chained_methods.py b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/chained_methods.py new file mode 100644 index 000000000..9c4f53115 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/chained_methods.py @@ -0,0 +1,27 @@ +class Builder: + def set_a(self, a): + self.a = a + return self + + def set_b(self, b): + self.b = b + return self + + def set_c(self, c): + self.c = c + return self + + def set_d(self, d): + self.d = d + return self + + def set_e(self, e): + self.d = d + return self + +Builder().set_a('a1').set_b('b2').set_c('c3').set_d('d4').set_e('e4') +# ^ defined: 2 +# ^ defined: 6 +# ^ defined: 10 +# ^ defined: 14 +# ^ defined: 18 diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/class_members.py b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/class_members.py new file mode 100644 index 000000000..c67ace992 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/class_members.py @@ -0,0 +1,23 @@ +a = 1 + +class B: + c = a + # ^ defined: 1 + + def d(self): + return self.c + + class E: + f = a + # ^ defined: 1 + +print B.c +# ^ defined: 3 +# ^ defined: 1, 4 + +print B.d(1) +# ^ defined: 7 + +print B.a, E.a +# ^ defined: +# ^ defined: diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/decorators.py b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/decorators.py new file mode 100644 index 000000000..b55f44b2f --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/decorators.py @@ -0,0 +1,10 @@ +from a import deprecated +from b import ignore_warnings + +class A: + @deprecated + # ^ defined: 1 + @ignore_warnings.all + # ^ defined: 2 + def b(self): + pass diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/exceptions.py b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/exceptions.py new file mode 100644 index 000000000..b6b2e57e1 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/exceptions.py @@ -0,0 +1,5 @@ +try: + print() +except Exception as e: + x = e + # ^ defined: 3 diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/functions.py b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/functions.py new file mode 100644 index 000000000..31a1d6782 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/functions.py @@ -0,0 +1,31 @@ +import a.x.y +import b.x.y + +def get_x(value): + return value.x + # ^ defined: 4 + +print get_x(a).y +# ^ defined: 1 + +print get_x(b).y +# ^ defined: 2 + +def get_a(): + return a + +print get_a(b).x +# ^ defined: 1 + +print get_x(foo=1, value=a).y +# ^ defined: 1 + +def foo(w: int, x, y=1, z: int=4, *args, **dict): + local = x +# ^ defined: 23 + print(args, w, z) +# ^ defined: 23 +# ^ defined: 23 +# ^ defined: 23 + return y +# ^ defined: 23 diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/imported_functions.py b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/imported_functions.py new file mode 100644 index 000000000..495697740 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/imported_functions.py @@ -0,0 +1,17 @@ +#------ path: a.py ------# + +def foo(x): + return x + +#------ path: b.py ------# + +class A: + bar = 1 + +#------ path: main.py ---------# + +from a import * +from b import * + +foo(A).bar +# ^ defined: 9 diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/imports.py b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/imports.py new file mode 100644 index 000000000..2f21795da --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/imports.py @@ -0,0 +1,31 @@ +#------ path: one/two.py -----------# + +# module +import a.b.c + +d = 1 + +e = a.b + +#------ path: three/__init__.py ---# + +# module +f = 3 + +#------ path: main.py -------------# + +from one.two import d, e.c +# ^ defined: 2 +# ^ defined: 6, 17 +# ^ defined: 4, 8, 17 + +import three +# ^ defined: 11, 22 + +print(d, e.c) +# ^ defined: 6, 17 +# ^ defined: 4, 17 + +print three.f +# ^ defined: 11, 22 +# ^ defined: 13 diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/instance_members.py b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/instance_members.py new file mode 100644 index 000000000..38a6b6d75 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/instance_members.py @@ -0,0 +1,38 @@ +#---- path: a.py ------- + +class A: + def __init__(self, b, c): + self.b = b + self.c = A(c, 1) + + def get_b(self): + return self.b + # ^ defined: 4, 5 + + def get_c(self): + return self.c + # ^ defined: 6 + + def get_all(self): + return [self.get_b(), self.get_c()] + # ^ defined: 8 + # ^ defined: 12 + +a = A(1, 2) +a.get_all() +# ^ defined: 16 + +a.b +# ^ defined: 4, 5 + +a.c.b +# ^ defined: 4, 5 +# ^ defined: 6 + +#----- path: main.py --------- + +import a + +print a.A, a.a +# ^ defined: 3 +# ^ defined: 21 diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/loops.py b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/loops.py new file mode 100644 index 000000000..2f0663295 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/loops.py @@ -0,0 +1,19 @@ +class Node3: + value = 3 +class Node2: + value = 2 + next = Node3 +class Node1: + value = 1 + next = Node2 + +def linked_list_search(l, item): + node = l + while node: + if node.value == item: + return node + # ^ defined: 10, 11, 16 + node = node.next + +linked_list_search(Node1, 5).value +# ^ defined: 6 diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/many_definitions.py b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/many_definitions.py new file mode 100644 index 000000000..f85f3a8ec --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/many_definitions.py @@ -0,0 +1,76 @@ +#--- path: a.py ---# + +def f0(a): return X.a + X.b +def f1(a): return f0(1) +def f2(a): return f1(2) +def f3(a): return f2(3) +def f4(a): return f3(4) +def f5(a): return f4(5) +def f6(a): return f5(6) +def f7(a): return f6(7) +def f8(a): return f7(8) +def f9(a): return f8(9) + +class C1: + def m0(self, b): return f9(0) + def m1(self, b): return self.m0(1) + def m2(self, b): return self.m1(2) + def m3(self, b): return self.m2(3) + def m4(self, b): return self.m3(4) + def m5(self, b): return self.m4(5) + def m6(self, b): return self.m5(6) + def m7(self, b): return self.m6(7) + def m8(self, b): return self.m7(8) + +def f10(): return C1.m8(0) +def f11(): return f10(1) +def f12(): return X.c(2) +def f13(): return X.c(3) +def f14(): return x(4) +def f15(): return x(5) +def f16(): return x(6) +def f17(): return x(7) +def f18(): return x(8) + +class C2: + def m0(self): return X.d(0) + def m1(self): return X.d(1) + def m2(self): return X.d(2) + def m3(self): return X.d(3) + def m4(self): return X.d(4) + def m5(self): return X.d(5) + def m6(self): return X.d(6) + def m7(self): return X.d(7) + def m8(self): return X.d(8) + +#--- path: main.py ---# + +from a import * + +print f0(), f4(), f8() +# ^ defined: 3 +# ^ defined: 7 +# ^ defined: 11 + +print C1.m0, C1().m0(), C1.m4, C1().m4, C1.m8, C1.m8 +# ^ defined: 14 +# ^ defined: 15 +# ^ defined: 15 +# ^ defined: 19 +# ^ defined: 19 +# ^ defined: 23 +# ^ defined: 23 + +print f10(), f14(), f18() +# ^ defined: 25 +# ^ defined: 29 +# ^ defined: 33 + +print C2.m0, C2().m0(), C2.m4, C2().m4, C2.m8, C2.m8 +# ^ defined: 35 +# ^ defined: 36 +# ^ defined: 36 +# ^ defined: 40 +# ^ defined: 40 +# ^ defined: 44 +# ^ defined: 44 diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/pattern_matching.py b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/pattern_matching.py new file mode 100644 index 000000000..58c0d16fc --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/pattern_matching.py @@ -0,0 +1,39 @@ +command = 1 +current_room = 2 +character = 3 + +match command.split(): + # ^ defined: 1 + case ["quit"]: + print("Goodbye!") + quit_game() + case ["look"]: + current_room.describe() + # ^ defined: 2 + case ["get", obj]: + character.get(obj, current_room) + # ^ defined: 3 + # ^ defined: 13 + # ^ defined: 2 + case ["go", direction]: + current_room = current_room.neighbor(direction) + # ^ defined: 18 + case { "foo": foo }: + print(foo) + # ^ defined: 21 + case {bar,quux}: + print(bar,quux) + # ^ defined: 24 + # ^ defined: 24 + case ["grab", { "key": {garply}}]: + print(garply) + # ^ defined: 28 + case ["drop", *objs]: + print(objs) + # ^ defined: 31 + case ["get", obj] | ["pick", "up", obj] | ["pick", obj, "up"]: + print(obj) + # ^ defined: 34, 34, 34 + case ["go", ("north" | "south" | "east" | "west") as direction2]: + current_room = current_room.neighbor(direction2) + # ^ defined: 37 diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/redundant_reexport.py b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/redundant_reexport.py new file mode 100644 index 000000000..53afca29e --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/redundant_reexport.py @@ -0,0 +1,15 @@ +#--- path: a/__init__.py ---# + +from . import child + +#--- path: a/child.py ---- + +def f(): + pass + +#--- path: main.py ---# + +import a + +print a.child.f() +# ^ defined: 7 diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/relative_imports.py b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/relative_imports.py new file mode 100644 index 000000000..2d6e14eb4 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/relative_imports.py @@ -0,0 +1,60 @@ +#------ path: foo/bar/main.py ------# + +from . import a +from .b import B +from ..c import see +from ..c.d import D + +print a.A +# ^ defined: 3, 24 +# ^ defined: 26 + +print B.bee +# ^ defined: 4, 31 +# ^ defined: 32 + +print see() +# ^ defined: 5, 37 + + +print D.d +# ^ defined: 44 + +#------ path: foo/bar/a.py --------# + +# module +A = "a" + +#------ path: foo/bar/b.py --------# + +# module +class B: + bee = 1 + +#------ path: foo/c.py ------------# + +# module +def see(): + pass + +#------ path: foo/c/d.py ---------# + +# module +class D: + d = "d" + +#------ path: foo/e/g.py ---# + +# module +G = 1 + +#------ path: foo/e/__init__.py ---# + +# module +from .g import G +# ^ defined: 49, 54 + +from ..c import see +# ^ defined: 37, 57 + +E = 1 diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/statement_bindings.py b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/statement_bindings.py new file mode 100644 index 000000000..6e3a13abb --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/statement_bindings.py @@ -0,0 +1,9 @@ +import a.b +import c.d + +with a as x, c as y: + print x.b, y.d + # ^ defined: 1, 4 + # ^ defined: 1 + # ^ defined: 2, 4 + # ^ defined: 2 diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/superclasses.py b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/superclasses.py new file mode 100644 index 000000000..849a192a6 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/superclasses.py @@ -0,0 +1,19 @@ +class A: + def __init__(self): + self.some_attr = 2 + + def some_method(self): + print self + +class B(A): + def method2(self): + print self.some_attr, self.some_method() + # ^ defined: 3 + # ^ defined: 5, 14 + + def some_method(self): + pass + + def other(self): + super().some_method() + # ^ defined: 5 diff --git a/languages/tree-sitter-stack-graphs-python/test/test.py b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/test.py similarity index 100% rename from languages/tree-sitter-stack-graphs-python/test/test.py rename to languages/tree-sitter-stack-graphs-python/test/legacy.skip/test.py diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/tuples.py b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/tuples.py new file mode 100644 index 000000000..1ea6ee3ef --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/tuples.py @@ -0,0 +1,38 @@ +class a: + x = 1 +class b: + x = 1 +class c: + x = 1 + +(a1, b1) = (a, b) +a2, b2 = (a, b) +(a3, b3) = (a, b) +a4, b4 = a, b + +print a1.x, b1.x +# ^ defined: 2 +# ^ defined: 4 +print a2.x, b2.x +# ^ defined: 2 +# ^ defined: 4 +print a3.x, b3.x +# ^ defined: 2 +# ^ defined: 4 +print a4.x, b4.x +# ^ defined: 2 +# ^ defined: 4 + +t = (a, b), c +(a5, b5), c5 = t + +print a5.x, b5.x, c5.x +# ^ defined: 2 +# ^ defined: 4 +# ^ defined: 6 + +(a6, (b6, c6)) = (a, (b, c)) + +print a6.x, b6.x +# ^ defined: 2 +# ^ defined: 4 diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/wildcard_import.py b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/wildcard_import.py new file mode 100644 index 000000000..f2ac040f2 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/legacy.skip/wildcard_import.py @@ -0,0 +1,21 @@ +#------ path: one/two.py ------# + +a = 1 +b = 2 + +#------ path: one/three.py ------# + +b = 3 +c = 4 + +#------ path: main.py ---------# + +from one.two import * +from one.three import * + +print a +# ^ defined: 3 +print b +# ^ defined: 8 +print c +# ^ defined: 9 From decf584c173adcfc038b3f8c398c0025715832bf Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 1 Jun 2023 09:42:41 +0200 Subject: [PATCH 03/60] convert: copy old --- .../src/stack-graphs.tsg | 770 +++++++++++++++++- 1 file changed, 767 insertions(+), 3 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 99647e75b..99fd0acaf 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -36,7 +36,771 @@ attribute symbol_reference = symbol => type = "push_symbol", symbol = symbol attribute node_symbol = node => symbol = (source-text node), source_node = node -;; Stack Graph Rules -;; ^^^^^^^^^^^^^^^^^ +; Modules and Imports +;--------------------- -; Have fun! +(module) @mod +{ + var module_def = @mod.file_def + attr module_def "no_span" + var module_ref = @mod.file_ref + attr module_ref "no_span" + var parent_module_def = module_def + var parent_module_ref = module_ref + var grandparent_module_ref = module_ref + + scan filepath { + "([^/]+)/" + { + edge module_def -> module_def.dot + edge module_def.dot -> module_def.next_def + edge module_ref.next_ref -> module_ref.dot + edge module_ref.dot -> module_ref + + attr module_def "pop" = $1 + attr module_def.dot "pop" = "." + attr module_ref "push" = $1 + attr module_ref.dot "push" = "." + + set grandparent_module_ref = parent_module_ref + set parent_module_def = module_def + set parent_module_ref = module_ref + set module_ref = module_ref.next_ref + set module_def = module_def.next_def + attr module_def "no_span" + attr module_ref "no_span" + } + + "__init__\\.py$" + { + attr parent_module_def "definition" + } + + "([^/]+)$" + { + edge module_def -> module_def.dot + edge module_def.dot -> module_def.next_def + + attr module_def "definition", "pop" = (replace $1 "\\.py" "") + attr module_def.dot "pop" = "." + + set module_def = module_def.next_def + attr module_def "no_span" + attr module_ref "no_span" + } + } + + edge root -> @mod.file_def + edge @mod.file_ref -> root + edge module_def -> @mod.after_scope + + edge @mod.before_scope -> @mod.global_dot + edge @mod.global -> root + attr @mod.global "push" = "" + + edge @mod.global_dot -> @mod.global + attr @mod.global_dot "push" = "." + + var @mod::parent_module = parent_module_ref + var @mod::grandparent_module = grandparent_module_ref + var @mod::bottom = @mod.after_scope + var @mod::global = @mod.global + var @mod::global_dot = @mod.global_dot +} + +(import_statement + name: (dotted_name + . (identifier) @root_name)) @stmt +{ + edge @stmt.after_scope -> @root_name.def, "precedence" = 1 + edge @root_name.ref -> root + attr @root_name.ref "push", "reference" + attr @root_name.def "pop", "definition" +} + +(import_statement + name: (aliased_import + (dotted_name . (identifier) @root_name))) @stmt +{ + edge @stmt.after_scope -> @root_name.def + edge @root_name.ref -> root + attr @root_name.ref "push", "reference" +} + +(import_from_statement + module_name: (dotted_name + . (identifier) @prefix_root_name)) @stmt +{ + edge @prefix_root_name.ref -> root + attr @prefix_root_name.ref "push", "reference" +} + +(import_from_statement + name: (dotted_name + . (identifier) @import_root_name)) @stmt +{ + edge @stmt.after_scope -> @import_root_name.def, "precedence" = 1 + edge @import_root_name.ref -> @import_root_name.ref_dot + attr @import_root_name.def "pop", "definition" + attr @import_root_name.ref "push", "reference" + attr @import_root_name.ref_dot "push" = "." +} + +(import_from_statement + name: (aliased_import + (dotted_name + . (identifier) @import_root_name))) @stmt +{ + edge @import_root_name.ref -> @import_root_name.ref_dot + attr @import_root_name.ref "push", "reference" + attr @import_root_name.ref_dot "push" = "." +} + +(import_from_statement + module_name: [ + (dotted_name (identifier) @prefix_leaf_name .) + (relative_import (dotted_name (identifier) @prefix_leaf_name .)) + (relative_import (import_prefix) @prefix_leaf_name .) + ] + name: [ + (dotted_name + . (identifier) @import_root_name) + (aliased_import + (dotted_name + . (identifier) @import_root_name)) + ]) +{ + edge @import_root_name.ref_dot -> @prefix_leaf_name.ref +} + +[ + (import_from_statement + (aliased_import + name: (dotted_name (identifier) @name .) + alias: (identifier) @alias)) + (import_statement + (aliased_import + name: (dotted_name (identifier) @name .) + alias: (identifier) @alias)) +] @stmt +{ + edge @stmt.after_scope -> @alias + edge @alias -> @name.ref + attr @alias "pop", "definition" +} + +[ + (import_statement + name: (dotted_name + (identifier) @leaf_name .)) + (import_from_statement + name: (dotted_name + (identifier) @leaf_name .)) +] +{ + attr @leaf_name.def "pop", "definition" + attr @leaf_name.ref "push", "reference" + edge @leaf_name.def -> @leaf_name.ref +} + +(relative_import + (import_prefix) @prefix + (#eq? @prefix ".")) @import +{ + edge @prefix.ref -> @import::parent_module +} + +(relative_import + (import_prefix) @prefix + (#eq? @prefix "..")) @import +{ + edge @prefix.ref -> @import::grandparent_module +} + +(relative_import + (import_prefix) @prefix + (dotted_name + . (identifier) @name)) +{ + attr @name.ref "push", "reference" + attr @name.ref_dot "push" = "." + edge @name.ref -> @name.ref_dot + edge @name.ref_dot -> @prefix.ref +} + +[ + (import_from_statement + module_name: (relative_import + (dotted_name + (identifier) @parent_name + . + (identifier) @child_name))) + (import_from_statement + module_name: (dotted_name + (identifier) @parent_name + . + (identifier) @child_name)) +] +{ + attr @child_name.ref "push", "reference" + attr @child_name.ref_dot "push" = "." + edge @child_name.ref -> @child_name.ref_dot + edge @child_name.ref_dot -> @parent_name.ref +} + +(import_from_statement + module_name: (dotted_name + . (identifier) @root_name)) +{ + attr @root_name.ref "push", "reference" + edge @root_name.ref -> root +} + +(import_from_statement + module_name: (dotted_name + (identifier) @leaf_name .) + (wildcard_import) @star) @stmt +{ + edge @stmt.after_scope -> @star.ref_dot, "precedence" = 1 + edge @star.ref_dot -> @leaf_name.ref + attr @star.ref_dot "push" = "." +} + +[ + (import_statement + name: (dotted_name + (identifier) @parent_name + . + (identifier) @child_name)) + (import_from_statement + name: (dotted_name + (identifier) @parent_name + . + (identifier) @child_name)) + (import_from_statement + name: (aliased_import + name: (dotted_name + (identifier) @parent_name + . + (identifier) @child_name))) +] +{ + edge @child_name.ref -> @child_name.ref_dot + edge @child_name.ref_dot -> @parent_name.ref + edge @parent_name.def -> @parent_name.def_dot + edge @parent_name.def_dot -> @child_name.def + attr @child_name.def "pop", "definition" + attr @child_name.ref "push","reference" + attr @parent_name.def_dot "pop" = "." + attr @child_name.ref_dot "push" = "." +} + +;-------- +; Scopes +;-------- + +[ + (module (_) @last_stmt .) + (block (_) @last_stmt .) +] @block +{ + edge @block.after_scope -> @last_stmt.after_scope +} + +[ + (module (_) @stmt1 . (_) @stmt2) + (block (_) @stmt1 . (_) @stmt2) +] +{ + edge @stmt2.before_scope -> @stmt1.after_scope +} + +[ + (module (_) @stmt) + (block (_) @stmt) +] +{ + edge @stmt.after_scope -> @stmt.before_scope + let @stmt::local_scope = @stmt.before_scope +} + +[ + (block . (_) @stmt) + (module . (_) @stmt) +] @block +{ + edge @stmt.before_scope -> @block.before_scope +} + +(block (_) @stmt . ) @block +{ + edge @block.after_scope -> @stmt.after_scope +} + +(function_definition (block) @block) +{ + edge @block.before_scope -> @block::local_scope +} + +[ + (while_statement (block) @block) + (if_statement (block) @block) + (with_statement (block) @block) + (try_statement (block) @block) + (for_statement (block) @block) + (_ [ + (else_clause (block) @block) + (elif_clause (block) @block) + (except_clause (block) @block) + (finally_clause (block) @block) + ]) +] @stmt +{ + edge @block.before_scope -> @block::local_scope + edge @stmt.after_scope -> @block.after_scope +} + +(match_statement (case_clause) @block) @stmt +{ + let @block::local_scope = @block.before_scope + edge @block.before_scope -> @stmt.before_scope + edge @stmt.after_scope -> @block.after_scope +} + +[ + (for_statement) + (while_statement) +] @stmt +{ + edge @stmt.before_scope -> @stmt.after_scope +} + +;------------- +; Definitions +;------------- + +[ + (assignment + left: (_) @pattern + right: (_) @value) + (with_item + value: + (as_pattern + (_) @value + alias: (as_pattern_target (_) @pattern))) +] +{ + edge @pattern.input -> @value.output +} + +(function_definition + name: (identifier) @name + parameters: (parameters) @params + body: (block) @body) @func +{ + attr @name "definiens" = @func + edge @func.after_scope -> @name + edge @name -> @func.call + edge @func.call -> @func.return_value + edge @body.before_scope -> @params.after_scope + edge @body.before_scope -> @func.drop_scope + edge @func.drop_scope -> @func::bottom + attr @func.drop_scope "drop" + attr @name "pop", "definition" + attr @func.call "pop" = "()", "pop-scope" + attr @params.before_scope "jump-to" + attr @func.return_value "endpoint" + let @func::function_returns = @func.return_value + + ; Prevent functions defined inside of method bodies from being treated like methods + let @body::class_self_scope = nil + let @body::class_member_attr_scope = nil +} + +;; +;; BEGIN BIG GNARLY DISJUNCTION +;; +;; The following pair of rules is intended to capture the following behavior: +;; +;; If a function definition is used to define a method, by being inside a class +;; definition, then we make its syntax type `method`. Otherwise, we make it's +;; syntax type `function`. Unfortunately, because of the limitations on negation +;; and binding in tree sitter queries, we cannot negate `class_definition` or +;; similar things directly. Instead, we have to manually push the negation down +;; to form the finite disjunction it corresponds to. +;; + +[ + (class_definition (block (decorated_definition (function_definition name: (_)@name)))) + (class_definition (block (function_definition name: (_)@name))) +] +{ + attr @name "syntax_type" = "method" +} + +[ + (module (decorated_definition (function_definition name: (_)@name))) + (module (function_definition name: (_)@name)) + + (if_statement (block (decorated_definition (function_definition name: (_)@name)))) + (if_statement (block (function_definition name: (_)@name))) + + (elif_clause (block (decorated_definition (function_definition name: (_)@name)))) + (elif_clause (block (function_definition name: (_)@name))) + + (else_clause (block (decorated_definition (function_definition name: (_)@name)))) + (else_clause (block (function_definition name: (_)@name))) + + (case_clause (block (decorated_definition (function_definition name: (_)@name)))) + (case_clause (block (function_definition name: (_)@name))) + + (for_statement (block (decorated_definition (function_definition name: (_)@name)))) + (for_statement (block (function_definition name: (_)@name))) + + (while_statement (block (decorated_definition (function_definition name: (_)@name)))) + (while_statement (block (function_definition name: (_)@name))) + + (try_statement (block (decorated_definition (function_definition name: (_)@name)))) + (try_statement (block (function_definition name: (_)@name))) + + (except_clause (block (decorated_definition (function_definition name: (_)@name)))) + (except_clause (block (function_definition name: (_)@name))) + + (finally_clause (block (decorated_definition (function_definition name: (_)@name)))) + (finally_clause (block (function_definition name: (_)@name))) + + (with_statement (block (decorated_definition (function_definition name: (_)@name)))) + (with_statement (block (function_definition name: (_)@name))) + + (function_definition (block (decorated_definition (function_definition name: (_)@name)))) + (function_definition (block (function_definition name: (_)@name))) +] +{ + attr @name "syntax_type" = "function" +} + +;; +;; END BIG GNARLY DISJUNCTION +;; + +(function_definition + parameters: (parameters + . (identifier) @param) + body: (block) @body) +{ + edge @param.input -> @param::class_self_scope + edge @param::class_member_attr_scope -> @param.output + edge @param.output -> @body.after_scope + attr @param.output "push" +} + +(parameter/identifier) @param +{ + attr @param.input "definition", "pop" + attr @param.param_name "push" + edge @param.input -> @param.param_index + edge @param.input -> @param.param_name +} + +[ + (parameter/default_parameter + name: (identifier) @name + value: (_) @value) @param + (parameter/typed_default_parameter + name: (_) @name + value: (_) @value) @param +] +{ + attr @name "definition", "pop" + attr @param.param_name "push" = @name + edge @name -> @param.param_name + edge @name -> @param.param_index + edge @param.input -> @name + edge @name -> @value.output +} + +[ + (parameter/typed_parameter + . (_) @name) @param + (parameter/list_splat_pattern + (_) @name) @param + (parameter/dictionary_splat_pattern + (_) @name) @param +] +{ + attr @name "definition", "pop" + attr @param.param_name "push" = @name + edge @name -> @param.param_name + edge @name -> @param.param_index + edge @param.input -> @name +} + +[ + (pattern_list (_) @pattern) + (tuple_pattern (_) @pattern) +] @list +{ + let statement_scope = @list::local_scope + let @pattern::local_scope = @pattern.pattern_before_scope + edge statement_scope -> @pattern::local_scope, "precedence" = (+ 1 (child-index @pattern)) + + edge @pattern.pattern_index -> @list.input + edge @pattern.input -> @pattern.pattern_index + attr @pattern.pattern_index "push" = (child-index @pattern) +} + +(parameters + (_) @param) @params +{ + attr @param.param_index "push" = (child-index @param) + edge @param.param_index -> @params.before_scope + edge @params.after_scope -> @param.input + edge @param.param_name -> @params.before_scope +} + +(return_statement (_) @expr) @stmt +{ + edge @stmt::function_returns -> @expr.output +} + +(class_definition + name: (identifier) @name) @class +{ + attr @name "definiens" = @class + attr @name "syntax_type" = "class" + edge @class.parent_scope -> @class::class_parent_scope + edge @class.parent_scope -> @class::local_scope + edge @class.after_scope -> @name + edge @name -> @class.call + edge @name -> @class.dot + edge @class.dot -> @class.members + edge @class.call -> @class.call_drop + edge @class.call_drop -> @class.self_scope + edge @class.self_scope -> @class.super_scope + edge @class.self_scope -> @class.self_dot + edge @class.self_dot -> @class.members + edge @class.members -> @class.member_attrs + attr @class.call "pop" = "()", "pop-scope" + attr @class.call_drop "drop" + attr @class.dot "pop" = "." + attr @class.self_dot "pop" = "." + attr @name "pop", "definition" + attr @class.member_attrs "push" = "." + attr @class.self_scope "endpoint" + let @class::super_scope = @class.super_scope + let @class::class_parent_scope = @class.parent_scope + let @class::class_self_scope = @class.call_drop + let @class::class_member_attr_scope = @class.member_attrs +} + +(class_definition + body: (block + (_) @last_stmt .) @body) @class +{ + edge @class.members -> @last_stmt.after_scope +} + +(class_definition + superclasses: (argument_list + (_) @superclass)) @class +{ + edge @class.super_scope -> @superclass.output +} + +(decorated_definition + definition: (_) @def) @stmt +{ + edge @def.before_scope -> @stmt.before_scope + edge @stmt.after_scope -> @def.after_scope +} + +(case_clause + pattern: (_) @pattern + consequence: (_) @consequence) @clause +{ + edge @consequence.before_scope -> @pattern.new_bindings + edge @consequence.before_scope -> @clause.before_scope + edge @clause.after_scope -> @consequence.after_scope +} + +;------------- +; Expressions +;------------- + +(call + function: (_) @fn + arguments: (argument_list) @args) @call +{ + edge @call.output -> @call.output_args + edge @call.output_args -> @fn.output + attr @call.output_args "push" = "()", "push-scope" = @args +} + +(call + function: (attribute + object: (_) @receiver) + arguments: (argument_list + (expression) @arg) @args) +{ + edge @args -> @arg.arg_index + edge @receiver -> @receiver.arg_index + + attr @receiver.arg_index "pop" = "0" + edge @receiver.arg_index -> @receiver.output + + attr @arg.arg_index "pop" = (+ 1 (child-index @arg)) + edge @arg.arg_index -> @arg.output +} + +(call + arguments: (argument_list + (keyword_argument + name: (identifier) @name + value: (_) @val) @arg) @args) @call +{ + edge @args -> @arg.arg_name + attr @arg.arg_name "pop" = @name + edge @arg.arg_name -> @val.output +} + +(argument_list + (expression) @arg) @args +{ + edge @args -> @arg.arg_index + attr @arg.arg_index "pop" = (child-index @arg) + edge @arg.arg_index -> @arg.output +} + +( + (call + function: (identifier) @fn-name) @call + (#eq? @fn-name "super") +) +{ + edge @call.output -> @call::super_scope +} + +[ + (tuple (_) @element) + (expression_list (_) @element) +] @tuple +{ + edge @tuple.output -> @element.el_index + attr @element.el_index "pop" = (child-index @element) + edge @element.el_index -> @element.output + + edge @tuple.new_bindings -> @element.new_bindings +} + +(attribute + object: (_) @object + attribute: (identifier) @name) @expr +{ + edge @expr.output -> @name.output + edge @name.output -> @expr.output_dot + edge @expr.output_dot -> @object.output + edge @object.input -> @expr.input_dot + edge @expr.input_dot -> @name.input + edge @name.input -> @expr.input + attr @expr.output_dot "push" = "." + attr @expr.input_dot "pop" = "." + attr @name.input "pop" + attr @name.output "push" +} + +(pattern/attribute + attribute: (identifier) @name) +{ + attr @name.input "definition" +} + +(primary_expression/attribute + attribute: (identifier) @name) +{ + attr @name.output "reference" +} + +(primary_expression/identifier) @id +{ + edge @id.output -> @id::local_scope + edge @id.output -> @id::class_parent_scope + edge @id::local_scope -> @id.input + attr @id.input "pop" + attr @id.output "push", "reference" + + attr @id.new_binding_pop "pop", "definition" + edge @id.new_bindings -> @id.new_binding_pop +} + +(pattern/identifier) @id +{ + edge @id.output -> @id::local_scope + edge @id.output -> @id::class_parent_scope + edge @id::local_scope -> @id.input, "precedence" = 1 + attr @id.input "pop", "definition" + attr @id.output "push" + + attr @id.new_binding_pop "pop", "definition" + edge @id.new_bindings -> @id.new_binding_pop +} + +(as_pattern + (expression) @value + alias: (as_pattern_target (primary_expression/identifier) @id)) @as_pattern +{ + edge @id.output -> @id::local_scope + edge @id.output -> @id::class_parent_scope + edge @id::local_scope -> @id.input, "precedence" = 1 + attr @id.input "pop", "definition" + attr @id.output "push" + + edge @as_pattern.new_bindings -> @value.new_bindings + edge @as_pattern.new_bindings -> @id.new_bindings +} + +(list) @list +{ + edge @list.output -> @list.called + edge @list.called -> @list::global_dot + attr @list.called "push" = "list" +} + +(list (_) @el) @list +{ + edge @list.new_bindings -> @el.new_bindings +} + +(dictionary (pair) @pair) @dict +{ + edge @dict.new_bindings -> @pair.new_bindings +} + +(pair + value: (_) @value) @pair +{ + edge @pair.new_bindings -> @value.new_bindings +} + +(set (_) @el) @set +{ + edge @set.new_bindings -> @el.new_bindings +} + +(list_splat (_) @splatted) @splat +{ +attr @splat.new_bindings_pop "pop" = @splatted, "definition" +edge @splat.new_bindings -> @splat.new_bindings_pop +} + +(binary_operator + (_) @left + (_) @right) @binop +{ + edge @binop.new_bindings -> @left.new_bindings + edge @binop.new_bindings -> @right.new_bindings +} + +(case_pattern (_) @expr) @pat +{ + edge @pat.new_bindings -> @expr.new_bindings +} From edfe903f0f5b976fd08d490e9ffe1925ea724ed0 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 1 Jun 2023 09:42:59 +0200 Subject: [PATCH 04/60] convert: attr syntax --- .../src/stack-graphs.tsg | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 99fd0acaf..5aed50404 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -42,9 +42,9 @@ attribute node_symbol = node => symbol = (source-text node), source_n (module) @mod { var module_def = @mod.file_def - attr module_def "no_span" + attr (module_def) "no_span" var module_ref = @mod.file_ref - attr module_ref "no_span" + attr (module_ref) "no_span" var parent_module_def = module_def var parent_module_ref = module_ref var grandparent_module_ref = module_ref @@ -57,9 +57,9 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge module_ref.next_ref -> module_ref.dot edge module_ref.dot -> module_ref - attr module_def "pop" = $1 + attr (module_def) "pop" = $1 attr module_def.dot "pop" = "." - attr module_ref "push" = $1 + attr (module_ref) "push" = $1 attr module_ref.dot "push" = "." set grandparent_module_ref = parent_module_ref @@ -67,13 +67,13 @@ attribute node_symbol = node => symbol = (source-text node), source_n set parent_module_ref = module_ref set module_ref = module_ref.next_ref set module_def = module_def.next_def - attr module_def "no_span" - attr module_ref "no_span" + attr (module_def) "no_span" + attr (module_ref) "no_span" } "__init__\\.py$" { - attr parent_module_def "definition" + attr (parent_module_def) "definition" } "([^/]+)$" @@ -81,12 +81,12 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge module_def -> module_def.dot edge module_def.dot -> module_def.next_def - attr module_def "definition", "pop" = (replace $1 "\\.py" "") + attr (module_def) "definition", "pop" = (replace $1 "\\.py" "") attr module_def.dot "pop" = "." set module_def = module_def.next_def - attr module_def "no_span" - attr module_ref "no_span" + attr (module_def) "no_span" + attr (module_ref) "no_span" } } From 58c67fd2dbc806ebb331c6a26deb1f45ec1bf871 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 1 Jun 2023 09:43:51 +0200 Subject: [PATCH 05/60] convert: no_span --- .../src/stack-graphs.tsg | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 5aed50404..afe702317 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -42,9 +42,9 @@ attribute node_symbol = node => symbol = (source-text node), source_n (module) @mod { var module_def = @mod.file_def - attr (module_def) "no_span" + attr (module_def) empty_source_span var module_ref = @mod.file_ref - attr (module_ref) "no_span" + attr (module_ref) empty_source_span var parent_module_def = module_def var parent_module_ref = module_ref var grandparent_module_ref = module_ref @@ -67,8 +67,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n set parent_module_ref = module_ref set module_ref = module_ref.next_ref set module_def = module_def.next_def - attr (module_def) "no_span" - attr (module_ref) "no_span" + attr (module_def) empty_source_span + attr (module_ref) empty_source_span } "__init__\\.py$" @@ -85,8 +85,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n attr module_def.dot "pop" = "." set module_def = module_def.next_def - attr (module_def) "no_span" - attr (module_ref) "no_span" + attr (module_def) empty_source_span + attr (module_ref) empty_source_span } } From a830ef55ab2b304f3d59c438d1ba1dfcf942537e Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 1 Jun 2023 09:48:03 +0200 Subject: [PATCH 06/60] convert: more attr syntax --- .../src/stack-graphs.tsg | 150 +++++++++--------- 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index afe702317..f6d557b50 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -58,9 +58,9 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge module_ref.dot -> module_ref attr (module_def) "pop" = $1 - attr module_def.dot "pop" = "." + attr (module_def.dot) "pop" = "." attr (module_ref) "push" = $1 - attr module_ref.dot "push" = "." + attr (module_ref.dot) "push" = "." set grandparent_module_ref = parent_module_ref set parent_module_def = module_def @@ -82,7 +82,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge module_def.dot -> module_def.next_def attr (module_def) "definition", "pop" = (replace $1 "\\.py" "") - attr module_def.dot "pop" = "." + attr (module_def.dot) "pop" = "." set module_def = module_def.next_def attr (module_def) empty_source_span @@ -96,10 +96,10 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @mod.before_scope -> @mod.global_dot edge @mod.global -> root - attr @mod.global "push" = "" + attr (@mod.global) "push" = "" edge @mod.global_dot -> @mod.global - attr @mod.global_dot "push" = "." + attr (@mod.global_dot) "push" = "." var @mod::parent_module = parent_module_ref var @mod::grandparent_module = grandparent_module_ref @@ -114,8 +114,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n { edge @stmt.after_scope -> @root_name.def, "precedence" = 1 edge @root_name.ref -> root - attr @root_name.ref "push", "reference" - attr @root_name.def "pop", "definition" + attr (@root_name.ref) "push", "reference" + attr (@root_name.def) "pop", "definition" } (import_statement @@ -124,7 +124,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n { edge @stmt.after_scope -> @root_name.def edge @root_name.ref -> root - attr @root_name.ref "push", "reference" + attr (@root_name.ref) "push", "reference" } (import_from_statement @@ -132,7 +132,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n . (identifier) @prefix_root_name)) @stmt { edge @prefix_root_name.ref -> root - attr @prefix_root_name.ref "push", "reference" + attr (@prefix_root_name.ref) "push", "reference" } (import_from_statement @@ -141,9 +141,9 @@ attribute node_symbol = node => symbol = (source-text node), source_n { edge @stmt.after_scope -> @import_root_name.def, "precedence" = 1 edge @import_root_name.ref -> @import_root_name.ref_dot - attr @import_root_name.def "pop", "definition" - attr @import_root_name.ref "push", "reference" - attr @import_root_name.ref_dot "push" = "." + attr (@import_root_name.def) "pop", "definition" + attr (@import_root_name.ref) "push", "reference" + attr (@import_root_name.ref_dot) "push" = "." } (import_from_statement @@ -152,8 +152,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n . (identifier) @import_root_name))) @stmt { edge @import_root_name.ref -> @import_root_name.ref_dot - attr @import_root_name.ref "push", "reference" - attr @import_root_name.ref_dot "push" = "." + attr (@import_root_name.ref) "push", "reference" + attr (@import_root_name.ref_dot) "push" = "." } (import_from_statement @@ -186,7 +186,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n { edge @stmt.after_scope -> @alias edge @alias -> @name.ref - attr @alias "pop", "definition" + attr (@alias) "pop", "definition" } [ @@ -198,8 +198,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n (identifier) @leaf_name .)) ] { - attr @leaf_name.def "pop", "definition" - attr @leaf_name.ref "push", "reference" + attr (@leaf_name.def) "pop", "definition" + attr (@leaf_name.ref) "push", "reference" edge @leaf_name.def -> @leaf_name.ref } @@ -222,8 +222,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n (dotted_name . (identifier) @name)) { - attr @name.ref "push", "reference" - attr @name.ref_dot "push" = "." + attr (@name.ref) "push", "reference" + attr (@name.ref_dot) "push" = "." edge @name.ref -> @name.ref_dot edge @name.ref_dot -> @prefix.ref } @@ -242,8 +242,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n (identifier) @child_name)) ] { - attr @child_name.ref "push", "reference" - attr @child_name.ref_dot "push" = "." + attr (@child_name.ref) "push", "reference" + attr (@child_name.ref_dot) "push" = "." edge @child_name.ref -> @child_name.ref_dot edge @child_name.ref_dot -> @parent_name.ref } @@ -252,7 +252,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n module_name: (dotted_name . (identifier) @root_name)) { - attr @root_name.ref "push", "reference" + attr (@root_name.ref) "push", "reference" edge @root_name.ref -> root } @@ -263,7 +263,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n { edge @stmt.after_scope -> @star.ref_dot, "precedence" = 1 edge @star.ref_dot -> @leaf_name.ref - attr @star.ref_dot "push" = "." + attr (@star.ref_dot) "push" = "." } [ @@ -289,10 +289,10 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @child_name.ref_dot -> @parent_name.ref edge @parent_name.def -> @parent_name.def_dot edge @parent_name.def_dot -> @child_name.def - attr @child_name.def "pop", "definition" - attr @child_name.ref "push","reference" - attr @parent_name.def_dot "pop" = "." - attr @child_name.ref_dot "push" = "." + attr (@child_name.def) "pop", "definition" + attr (@child_name.ref) "push","reference" + attr (@parent_name.def_dot) "pop" = "." + attr (@child_name.ref_dot) "push" = "." } ;-------- @@ -398,18 +398,18 @@ attribute node_symbol = node => symbol = (source-text node), source_n parameters: (parameters) @params body: (block) @body) @func { - attr @name "definiens" = @func + attr (@name) "definiens" = @func edge @func.after_scope -> @name edge @name -> @func.call edge @func.call -> @func.return_value edge @body.before_scope -> @params.after_scope edge @body.before_scope -> @func.drop_scope edge @func.drop_scope -> @func::bottom - attr @func.drop_scope "drop" - attr @name "pop", "definition" - attr @func.call "pop" = "()", "pop-scope" - attr @params.before_scope "jump-to" - attr @func.return_value "endpoint" + attr (@func.drop_scope) "drop" + attr (@name) "pop", "definition" + attr (@func.call) "pop" = "()", "pop-scope" + attr (@params.before_scope) "jump-to" + attr (@func.return_value) "endpoint" let @func::function_returns = @func.return_value ; Prevent functions defined inside of method bodies from being treated like methods @@ -435,7 +435,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n (class_definition (block (function_definition name: (_)@name))) ] { - attr @name "syntax_type" = "method" + attr (@name) "syntax_type" = "method" } [ @@ -476,7 +476,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n (function_definition (block (function_definition name: (_)@name))) ] { - attr @name "syntax_type" = "function" + attr (@name) "syntax_type" = "function" } ;; @@ -491,13 +491,13 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @param.input -> @param::class_self_scope edge @param::class_member_attr_scope -> @param.output edge @param.output -> @body.after_scope - attr @param.output "push" + attr (@param.output) "push" } (parameter/identifier) @param { - attr @param.input "definition", "pop" - attr @param.param_name "push" + attr (@param.input) "definition", "pop" + attr (@param.param_name) "push" edge @param.input -> @param.param_index edge @param.input -> @param.param_name } @@ -511,8 +511,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n value: (_) @value) @param ] { - attr @name "definition", "pop" - attr @param.param_name "push" = @name + attr (@name) "definition", "pop" + attr (@param.param_name) "push" = @name edge @name -> @param.param_name edge @name -> @param.param_index edge @param.input -> @name @@ -528,8 +528,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n (_) @name) @param ] { - attr @name "definition", "pop" - attr @param.param_name "push" = @name + attr (@name) "definition", "pop" + attr (@param.param_name) "push" = @name edge @name -> @param.param_name edge @name -> @param.param_index edge @param.input -> @name @@ -546,13 +546,13 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @pattern.pattern_index -> @list.input edge @pattern.input -> @pattern.pattern_index - attr @pattern.pattern_index "push" = (child-index @pattern) + attr (@pattern.pattern_index) "push" = (child-index @pattern) } (parameters (_) @param) @params { - attr @param.param_index "push" = (child-index @param) + attr (@param.param_index) "push" = (child-index @param) edge @param.param_index -> @params.before_scope edge @params.after_scope -> @param.input edge @param.param_name -> @params.before_scope @@ -566,8 +566,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n (class_definition name: (identifier) @name) @class { - attr @name "definiens" = @class - attr @name "syntax_type" = "class" + attr (@name) "definiens" = @class + attr (@name) "syntax_type" = "class" edge @class.parent_scope -> @class::class_parent_scope edge @class.parent_scope -> @class::local_scope edge @class.after_scope -> @name @@ -580,13 +580,13 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @class.self_scope -> @class.self_dot edge @class.self_dot -> @class.members edge @class.members -> @class.member_attrs - attr @class.call "pop" = "()", "pop-scope" - attr @class.call_drop "drop" - attr @class.dot "pop" = "." - attr @class.self_dot "pop" = "." - attr @name "pop", "definition" - attr @class.member_attrs "push" = "." - attr @class.self_scope "endpoint" + attr (@class.call) "pop" = "()", "pop-scope" + attr (@class.call_drop) "drop" + attr (@class.dot) "pop" = "." + attr (@class.self_dot) "pop" = "." + attr (@name) "pop", "definition" + attr (@class.member_attrs) "push" = "." + attr (@class.self_scope) "endpoint" let @class::super_scope = @class.super_scope let @class::class_parent_scope = @class.parent_scope let @class::class_self_scope = @class.call_drop @@ -633,7 +633,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n { edge @call.output -> @call.output_args edge @call.output_args -> @fn.output - attr @call.output_args "push" = "()", "push-scope" = @args + attr (@call.output_args) "push" = "()", "push-scope" = @args } (call @@ -645,10 +645,10 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @args -> @arg.arg_index edge @receiver -> @receiver.arg_index - attr @receiver.arg_index "pop" = "0" + attr (@receiver.arg_index) "pop" = "0" edge @receiver.arg_index -> @receiver.output - attr @arg.arg_index "pop" = (+ 1 (child-index @arg)) + attr (@arg.arg_index) "pop" = (+ 1 (child-index @arg)) edge @arg.arg_index -> @arg.output } @@ -659,7 +659,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n value: (_) @val) @arg) @args) @call { edge @args -> @arg.arg_name - attr @arg.arg_name "pop" = @name + attr (@arg.arg_name) "pop" = @name edge @arg.arg_name -> @val.output } @@ -667,7 +667,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n (expression) @arg) @args { edge @args -> @arg.arg_index - attr @arg.arg_index "pop" = (child-index @arg) + attr (@arg.arg_index) "pop" = (child-index @arg) edge @arg.arg_index -> @arg.output } @@ -686,7 +686,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n ] @tuple { edge @tuple.output -> @element.el_index - attr @element.el_index "pop" = (child-index @element) + attr (@element.el_index) "pop" = (child-index @element) edge @element.el_index -> @element.output edge @tuple.new_bindings -> @element.new_bindings @@ -702,22 +702,22 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @object.input -> @expr.input_dot edge @expr.input_dot -> @name.input edge @name.input -> @expr.input - attr @expr.output_dot "push" = "." - attr @expr.input_dot "pop" = "." - attr @name.input "pop" - attr @name.output "push" + attr (@expr.output_dot) "push" = "." + attr (@expr.input_dot) "pop" = "." + attr (@name.input) "pop" + attr (@name.output) "push" } (pattern/attribute attribute: (identifier) @name) { - attr @name.input "definition" + attr (@name.input) "definition" } (primary_expression/attribute attribute: (identifier) @name) { - attr @name.output "reference" + attr (@name.output) "reference" } (primary_expression/identifier) @id @@ -725,10 +725,10 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @id.output -> @id::local_scope edge @id.output -> @id::class_parent_scope edge @id::local_scope -> @id.input - attr @id.input "pop" - attr @id.output "push", "reference" + attr (@id.input) "pop" + attr (@id.output) "push", "reference" - attr @id.new_binding_pop "pop", "definition" + attr (@id.new_binding_pop) "pop", "definition" edge @id.new_bindings -> @id.new_binding_pop } @@ -737,10 +737,10 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @id.output -> @id::local_scope edge @id.output -> @id::class_parent_scope edge @id::local_scope -> @id.input, "precedence" = 1 - attr @id.input "pop", "definition" - attr @id.output "push" + attr (@id.input) "pop", "definition" + attr (@id.output) "push" - attr @id.new_binding_pop "pop", "definition" + attr (@id.new_binding_pop) "pop", "definition" edge @id.new_bindings -> @id.new_binding_pop } @@ -751,8 +751,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @id.output -> @id::local_scope edge @id.output -> @id::class_parent_scope edge @id::local_scope -> @id.input, "precedence" = 1 - attr @id.input "pop", "definition" - attr @id.output "push" + attr (@id.input) "pop", "definition" + attr (@id.output) "push" edge @as_pattern.new_bindings -> @value.new_bindings edge @as_pattern.new_bindings -> @id.new_bindings @@ -762,7 +762,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n { edge @list.output -> @list.called edge @list.called -> @list::global_dot - attr @list.called "push" = "list" + attr (@list.called) "push" = "list" } (list (_) @el) @list @@ -788,7 +788,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n (list_splat (_) @splatted) @splat { -attr @splat.new_bindings_pop "pop" = @splatted, "definition" +attr (@splat.new_bindings_pop) "pop" = @splatted, "definition" edge @splat.new_bindings -> @splat.new_bindings_pop } From d5a97bd101f600745fa71c1562e9d1b1291def13 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 1 Jun 2023 09:49:10 +0200 Subject: [PATCH 07/60] convert: pop_scoped_symbol --- .../src/stack-graphs.tsg | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index f6d557b50..d7b6c33ed 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -58,7 +58,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge module_ref.dot -> module_ref attr (module_def) "pop" = $1 - attr (module_def.dot) "pop" = "." + attr (module_def.dot) pop_symbol = "." attr (module_ref) "push" = $1 attr (module_ref.dot) "push" = "." @@ -82,7 +82,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge module_def.dot -> module_def.next_def attr (module_def) "definition", "pop" = (replace $1 "\\.py" "") - attr (module_def.dot) "pop" = "." + attr (module_def.dot) pop_symbol = "." set module_def = module_def.next_def attr (module_def) empty_source_span @@ -291,7 +291,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @parent_name.def_dot -> @child_name.def attr (@child_name.def) "pop", "definition" attr (@child_name.ref) "push","reference" - attr (@parent_name.def_dot) "pop" = "." + attr (@parent_name.def_dot) pop_symbol = "." attr (@child_name.ref_dot) "push" = "." } @@ -407,7 +407,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @func.drop_scope -> @func::bottom attr (@func.drop_scope) "drop" attr (@name) "pop", "definition" - attr (@func.call) "pop" = "()", "pop-scope" + attr (@func.call) pop_scoped_symbol = "()" attr (@params.before_scope) "jump-to" attr (@func.return_value) "endpoint" let @func::function_returns = @func.return_value @@ -580,10 +580,10 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @class.self_scope -> @class.self_dot edge @class.self_dot -> @class.members edge @class.members -> @class.member_attrs - attr (@class.call) "pop" = "()", "pop-scope" + attr (@class.call) pop_scoped_symbol = "()" attr (@class.call_drop) "drop" - attr (@class.dot) "pop" = "." - attr (@class.self_dot) "pop" = "." + attr (@class.dot) pop_symbol = "." + attr (@class.self_dot) pop_symbol = "." attr (@name) "pop", "definition" attr (@class.member_attrs) "push" = "." attr (@class.self_scope) "endpoint" @@ -645,7 +645,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @args -> @arg.arg_index edge @receiver -> @receiver.arg_index - attr (@receiver.arg_index) "pop" = "0" + attr (@receiver.arg_index) pop_symbol = "0" edge @receiver.arg_index -> @receiver.output attr (@arg.arg_index) "pop" = (+ 1 (child-index @arg)) @@ -703,7 +703,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @expr.input_dot -> @name.input edge @name.input -> @expr.input attr (@expr.output_dot) "push" = "." - attr (@expr.input_dot) "pop" = "." + attr (@expr.input_dot) pop_symbol = "." attr (@name.input) "pop" attr (@name.output) "push" } From 01cf05d84a85afa8d4c944c3ff4ccf01bdca22e6 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 1 Jun 2023 09:50:13 +0200 Subject: [PATCH 08/60] convert: push symbol --- .../src/stack-graphs.tsg | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index d7b6c33ed..e4ef4ada4 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -60,7 +60,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n attr (module_def) "pop" = $1 attr (module_def.dot) pop_symbol = "." attr (module_ref) "push" = $1 - attr (module_ref.dot) "push" = "." + attr (module_ref.dot) push_symbol = "." set grandparent_module_ref = parent_module_ref set parent_module_def = module_def @@ -96,10 +96,10 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @mod.before_scope -> @mod.global_dot edge @mod.global -> root - attr (@mod.global) "push" = "" + attr (@mod.global) push_symbol = "" edge @mod.global_dot -> @mod.global - attr (@mod.global_dot) "push" = "." + attr (@mod.global_dot) push_symbol = "." var @mod::parent_module = parent_module_ref var @mod::grandparent_module = grandparent_module_ref @@ -143,7 +143,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @import_root_name.ref -> @import_root_name.ref_dot attr (@import_root_name.def) "pop", "definition" attr (@import_root_name.ref) "push", "reference" - attr (@import_root_name.ref_dot) "push" = "." + attr (@import_root_name.ref_dot) push_symbol = "." } (import_from_statement @@ -153,7 +153,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n { edge @import_root_name.ref -> @import_root_name.ref_dot attr (@import_root_name.ref) "push", "reference" - attr (@import_root_name.ref_dot) "push" = "." + attr (@import_root_name.ref_dot) push_symbol = "." } (import_from_statement @@ -223,7 +223,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n . (identifier) @name)) { attr (@name.ref) "push", "reference" - attr (@name.ref_dot) "push" = "." + attr (@name.ref_dot) push_symbol = "." edge @name.ref -> @name.ref_dot edge @name.ref_dot -> @prefix.ref } @@ -243,7 +243,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n ] { attr (@child_name.ref) "push", "reference" - attr (@child_name.ref_dot) "push" = "." + attr (@child_name.ref_dot) push_symbol = "." edge @child_name.ref -> @child_name.ref_dot edge @child_name.ref_dot -> @parent_name.ref } @@ -263,7 +263,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n { edge @stmt.after_scope -> @star.ref_dot, "precedence" = 1 edge @star.ref_dot -> @leaf_name.ref - attr (@star.ref_dot) "push" = "." + attr (@star.ref_dot) push_symbol = "." } [ @@ -292,7 +292,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n attr (@child_name.def) "pop", "definition" attr (@child_name.ref) "push","reference" attr (@parent_name.def_dot) pop_symbol = "." - attr (@child_name.ref_dot) "push" = "." + attr (@child_name.ref_dot) push_symbol = "." } ;-------- @@ -585,7 +585,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n attr (@class.dot) pop_symbol = "." attr (@class.self_dot) pop_symbol = "." attr (@name) "pop", "definition" - attr (@class.member_attrs) "push" = "." + attr (@class.member_attrs) push_symbol = "." attr (@class.self_scope) "endpoint" let @class::super_scope = @class.super_scope let @class::class_parent_scope = @class.parent_scope @@ -633,7 +633,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n { edge @call.output -> @call.output_args edge @call.output_args -> @fn.output - attr (@call.output_args) "push" = "()", "push-scope" = @args + attr (@call.output_args) push_scoped_symbol = "()", scope = @args } (call @@ -702,7 +702,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @object.input -> @expr.input_dot edge @expr.input_dot -> @name.input edge @name.input -> @expr.input - attr (@expr.output_dot) "push" = "." + attr (@expr.output_dot) push_symbol = "." attr (@expr.input_dot) pop_symbol = "." attr (@name.input) "pop" attr (@name.output) "push" @@ -762,7 +762,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n { edge @list.output -> @list.called edge @list.called -> @list::global_dot - attr (@list.called) "push" = "list" + attr (@list.called) push_symbol = "list" } (list (_) @el) @list From 3ab39ce7281c4a6a44c6176bde76f1b223c20bea Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 1 Jun 2023 10:04:39 +0200 Subject: [PATCH 09/60] convert: push and pop nodes --- .../src/stack-graphs.tsg | 70 +++++++++---------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index e4ef4ada4..ee9d010eb 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -57,9 +57,9 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge module_ref.next_ref -> module_ref.dot edge module_ref.dot -> module_ref - attr (module_def) "pop" = $1 + attr (module_def) pop_symbol = $1 attr (module_def.dot) pop_symbol = "." - attr (module_ref) "push" = $1 + attr (module_ref) push_symbol = $1 attr (module_ref.dot) push_symbol = "." set grandparent_module_ref = parent_module_ref @@ -81,7 +81,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge module_def -> module_def.dot edge module_def.dot -> module_def.next_def - attr (module_def) "definition", "pop" = (replace $1 "\\.py" "") + attr (module_def) symbol_definition = (replace $1 "\\.py" ""), source_node = @mod attr (module_def.dot) pop_symbol = "." set module_def = module_def.next_def @@ -114,8 +114,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n { edge @stmt.after_scope -> @root_name.def, "precedence" = 1 edge @root_name.ref -> root - attr (@root_name.ref) "push", "reference" - attr (@root_name.def) "pop", "definition" + attr (@root_name.ref) node_reference = @root_name + attr (@root_name.def) node_definition = @root_name } (import_statement @@ -124,7 +124,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n { edge @stmt.after_scope -> @root_name.def edge @root_name.ref -> root - attr (@root_name.ref) "push", "reference" + attr (@root_name.ref) node_reference = @root_name } (import_from_statement @@ -132,7 +132,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n . (identifier) @prefix_root_name)) @stmt { edge @prefix_root_name.ref -> root - attr (@prefix_root_name.ref) "push", "reference" + attr (@prefix_root_name.ref) node_reference = @prefix_root_name } (import_from_statement @@ -141,8 +141,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n { edge @stmt.after_scope -> @import_root_name.def, "precedence" = 1 edge @import_root_name.ref -> @import_root_name.ref_dot - attr (@import_root_name.def) "pop", "definition" - attr (@import_root_name.ref) "push", "reference" + attr (@import_root_name.def) node_definition = @import_root_name + attr (@import_root_name.ref) node_reference = @import_root_name attr (@import_root_name.ref_dot) push_symbol = "." } @@ -152,7 +152,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n . (identifier) @import_root_name))) @stmt { edge @import_root_name.ref -> @import_root_name.ref_dot - attr (@import_root_name.ref) "push", "reference" + attr (@import_root_name.ref) node_reference = @import_root_name attr (@import_root_name.ref_dot) push_symbol = "." } @@ -186,7 +186,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n { edge @stmt.after_scope -> @alias edge @alias -> @name.ref - attr (@alias) "pop", "definition" + attr (@alias) node_definition = @alias } [ @@ -198,8 +198,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n (identifier) @leaf_name .)) ] { - attr (@leaf_name.def) "pop", "definition" - attr (@leaf_name.ref) "push", "reference" + attr (@leaf_name.def) node_definition = @leaf_name + attr (@leaf_name.ref) node_reference = @leaf_name edge @leaf_name.def -> @leaf_name.ref } @@ -222,7 +222,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n (dotted_name . (identifier) @name)) { - attr (@name.ref) "push", "reference" + attr (@name.ref) node_reference = @name attr (@name.ref_dot) push_symbol = "." edge @name.ref -> @name.ref_dot edge @name.ref_dot -> @prefix.ref @@ -242,7 +242,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n (identifier) @child_name)) ] { - attr (@child_name.ref) "push", "reference" + attr (@child_name.ref) node_reference = @child_name attr (@child_name.ref_dot) push_symbol = "." edge @child_name.ref -> @child_name.ref_dot edge @child_name.ref_dot -> @parent_name.ref @@ -252,7 +252,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n module_name: (dotted_name . (identifier) @root_name)) { - attr (@root_name.ref) "push", "reference" + attr (@root_name.ref) node_reference = @root_name edge @root_name.ref -> root } @@ -289,8 +289,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @child_name.ref_dot -> @parent_name.ref edge @parent_name.def -> @parent_name.def_dot edge @parent_name.def_dot -> @child_name.def - attr (@child_name.def) "pop", "definition" - attr (@child_name.ref) "push","reference" + attr (@child_name.def) node_definition = @child_name + attr (@child_name.ref) node_reference = @child_name attr (@parent_name.def_dot) pop_symbol = "." attr (@child_name.ref_dot) push_symbol = "." } @@ -406,7 +406,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @body.before_scope -> @func.drop_scope edge @func.drop_scope -> @func::bottom attr (@func.drop_scope) "drop" - attr (@name) "pop", "definition" + attr (@name) node_definition = @name attr (@func.call) pop_scoped_symbol = "()" attr (@params.before_scope) "jump-to" attr (@func.return_value) "endpoint" @@ -491,13 +491,13 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @param.input -> @param::class_self_scope edge @param::class_member_attr_scope -> @param.output edge @param.output -> @body.after_scope - attr (@param.output) "push" + attr (@param.output) push_node = @param } (parameter/identifier) @param { - attr (@param.input) "definition", "pop" - attr (@param.param_name) "push" + attr (@param.input) node_definition = @param + attr (@param.param_name) push_node = @param edge @param.input -> @param.param_index edge @param.input -> @param.param_name } @@ -511,7 +511,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n value: (_) @value) @param ] { - attr (@name) "definition", "pop" + attr (@name) node_definition = @name attr (@param.param_name) "push" = @name edge @name -> @param.param_name edge @name -> @param.param_index @@ -528,7 +528,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n (_) @name) @param ] { - attr (@name) "definition", "pop" + attr (@name) node_definition = @name attr (@param.param_name) "push" = @name edge @name -> @param.param_name edge @name -> @param.param_index @@ -584,7 +584,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n attr (@class.call_drop) "drop" attr (@class.dot) pop_symbol = "." attr (@class.self_dot) pop_symbol = "." - attr (@name) "pop", "definition" + attr (@name) node_definition = @name attr (@class.member_attrs) push_symbol = "." attr (@class.self_scope) "endpoint" let @class::super_scope = @class.super_scope @@ -704,8 +704,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @name.input -> @expr.input attr (@expr.output_dot) push_symbol = "." attr (@expr.input_dot) pop_symbol = "." - attr (@name.input) "pop" - attr (@name.output) "push" + attr (@name.input) pop_node = @name + attr (@name.output) push_node = @name } (pattern/attribute @@ -725,10 +725,10 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @id.output -> @id::local_scope edge @id.output -> @id::class_parent_scope edge @id::local_scope -> @id.input - attr (@id.input) "pop" - attr (@id.output) "push", "reference" + attr (@id.input) pop_node = @id + attr (@id.output) node_reference = @id - attr (@id.new_binding_pop) "pop", "definition" + attr (@id.new_binding_pop) node_definition = @id edge @id.new_bindings -> @id.new_binding_pop } @@ -737,10 +737,10 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @id.output -> @id::local_scope edge @id.output -> @id::class_parent_scope edge @id::local_scope -> @id.input, "precedence" = 1 - attr (@id.input) "pop", "definition" - attr (@id.output) "push" + attr (@id.input) node_definition = @id + attr (@id.output) push_node = @id - attr (@id.new_binding_pop) "pop", "definition" + attr (@id.new_binding_pop) node_definition = @id edge @id.new_bindings -> @id.new_binding_pop } @@ -751,8 +751,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @id.output -> @id::local_scope edge @id.output -> @id::class_parent_scope edge @id::local_scope -> @id.input, "precedence" = 1 - attr (@id.input) "pop", "definition" - attr (@id.output) "push" + attr (@id.input) node_definition = @id + attr (@id.output) push_node = @id edge @as_pattern.new_bindings -> @value.new_bindings edge @as_pattern.new_bindings -> @id.new_bindings From a838d6e8fab1031d5025b41d7fc6b30aec110bc1 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 1 Jun 2023 10:06:08 +0200 Subject: [PATCH 10/60] convert: push and pop with explicit values --- .../src/stack-graphs.tsg | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index ee9d010eb..6f65fdfbd 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -512,7 +512,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n ] { attr (@name) node_definition = @name - attr (@param.param_name) "push" = @name + attr (@param.param_name) push_node = @name edge @name -> @param.param_name edge @name -> @param.param_index edge @param.input -> @name @@ -529,7 +529,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n ] { attr (@name) node_definition = @name - attr (@param.param_name) "push" = @name + attr (@param.param_name) push_node = @name edge @name -> @param.param_name edge @name -> @param.param_index edge @param.input -> @name @@ -546,13 +546,13 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @pattern.pattern_index -> @list.input edge @pattern.input -> @pattern.pattern_index - attr (@pattern.pattern_index) "push" = (child-index @pattern) + attr (@pattern.pattern_index) push_symbol = (child-index @pattern) } (parameters (_) @param) @params { - attr (@param.param_index) "push" = (child-index @param) + attr (@param.param_index) push_symbol = (child-index @param) edge @param.param_index -> @params.before_scope edge @params.after_scope -> @param.input edge @param.param_name -> @params.before_scope @@ -648,7 +648,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n attr (@receiver.arg_index) pop_symbol = "0" edge @receiver.arg_index -> @receiver.output - attr (@arg.arg_index) "pop" = (+ 1 (child-index @arg)) + attr (@arg.arg_index) pop_symbol = (+ 1 (child-index @arg)) edge @arg.arg_index -> @arg.output } @@ -659,7 +659,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n value: (_) @val) @arg) @args) @call { edge @args -> @arg.arg_name - attr (@arg.arg_name) "pop" = @name + attr (@arg.arg_name) pop_node = @name edge @arg.arg_name -> @val.output } @@ -667,7 +667,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n (expression) @arg) @args { edge @args -> @arg.arg_index - attr (@arg.arg_index) "pop" = (child-index @arg) + attr (@arg.arg_index) pop_symbol = (child-index @arg) edge @arg.arg_index -> @arg.output } @@ -686,7 +686,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n ] @tuple { edge @tuple.output -> @element.el_index - attr (@element.el_index) "pop" = (child-index @element) + attr (@element.el_index) pop_symbol = (child-index @element) edge @element.el_index -> @element.output edge @tuple.new_bindings -> @element.new_bindings @@ -788,7 +788,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n (list_splat (_) @splatted) @splat { -attr (@splat.new_bindings_pop) "pop" = @splatted, "definition" +attr (@splat.new_bindings_pop) node_definition = @splatted edge @splat.new_bindings -> @splat.new_bindings_pop } From b3179de0b457b539a6066ede2386fa6a4575b5eb Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 1 Jun 2023 10:08:29 +0200 Subject: [PATCH 11/60] convert: more references and definitions --- .../tree-sitter-stack-graphs-python/src/stack-graphs.tsg | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 6f65fdfbd..7088f8b6f 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -73,7 +73,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n "__init__\\.py$" { - attr (parent_module_def) "definition" + attr (parent_module_def) node_definition = @mod } "([^/]+)$" @@ -711,13 +711,13 @@ attribute node_symbol = node => symbol = (source-text node), source_n (pattern/attribute attribute: (identifier) @name) { - attr (@name.input) "definition" + attr (@name.input) node_definition = @name } (primary_expression/attribute attribute: (identifier) @name) { - attr (@name.output) "reference" + attr (@name.output) node_reference = @name } (primary_expression/identifier) @id From 2f2a4ccb601ce10b1b8adc84018717bda7994e08 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 1 Jun 2023 10:11:18 +0200 Subject: [PATCH 12/60] convert: edge precedence --- .../src/stack-graphs.tsg | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 7088f8b6f..b5433f967 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -112,7 +112,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n name: (dotted_name . (identifier) @root_name)) @stmt { - edge @stmt.after_scope -> @root_name.def, "precedence" = 1 + edge @stmt.after_scope -> @root_name.def + attr (@stmt.after_scope -> @root_name.def) precedence = 1 edge @root_name.ref -> root attr (@root_name.ref) node_reference = @root_name attr (@root_name.def) node_definition = @root_name @@ -139,7 +140,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n name: (dotted_name . (identifier) @import_root_name)) @stmt { - edge @stmt.after_scope -> @import_root_name.def, "precedence" = 1 + edge @stmt.after_scope -> @import_root_name.def + attr (@stmt.after_scope -> @import_root_name.def) precedence = 1 edge @import_root_name.ref -> @import_root_name.ref_dot attr (@import_root_name.def) node_definition = @import_root_name attr (@import_root_name.ref) node_reference = @import_root_name @@ -261,7 +263,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n (identifier) @leaf_name .) (wildcard_import) @star) @stmt { - edge @stmt.after_scope -> @star.ref_dot, "precedence" = 1 + edge @stmt.after_scope -> @star.ref_dot + attr (@stmt.after_scope -> @star.ref_dot) precedence = 1 edge @star.ref_dot -> @leaf_name.ref attr (@star.ref_dot) push_symbol = "." } @@ -542,7 +545,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n { let statement_scope = @list::local_scope let @pattern::local_scope = @pattern.pattern_before_scope - edge statement_scope -> @pattern::local_scope, "precedence" = (+ 1 (child-index @pattern)) + edge statement_scope -> @pattern::local_scope + attr (statement_scope -> @pattern::local_scope) precedence = (+ 1 (child-index @pattern)) edge @pattern.pattern_index -> @list.input edge @pattern.input -> @pattern.pattern_index @@ -736,7 +740,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n { edge @id.output -> @id::local_scope edge @id.output -> @id::class_parent_scope - edge @id::local_scope -> @id.input, "precedence" = 1 + edge @id::local_scope -> @id.input + attr (@id::local_scope -> @id.input) precedence = 1 attr (@id.input) node_definition = @id attr (@id.output) push_node = @id @@ -750,7 +755,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n { edge @id.output -> @id::local_scope edge @id.output -> @id::class_parent_scope - edge @id::local_scope -> @id.input, "precedence" = 1 + edge @id::local_scope -> @id.input + attr (@id::local_scope -> @id.input) precedence = 1 attr (@id.input) node_definition = @id attr (@id.output) push_node = @id From 90399c7c91aa5abb6bd16c9b27d830c4dd290b17 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 1 Jun 2023 10:14:54 +0200 Subject: [PATCH 13/60] convert: drop --- .../tree-sitter-stack-graphs-python/src/stack-graphs.tsg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index b5433f967..84e8fddb0 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -408,7 +408,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @body.before_scope -> @params.after_scope edge @body.before_scope -> @func.drop_scope edge @func.drop_scope -> @func::bottom - attr (@func.drop_scope) "drop" + attr (@func.drop_scope) type = "drop_scopes" attr (@name) node_definition = @name attr (@func.call) pop_scoped_symbol = "()" attr (@params.before_scope) "jump-to" @@ -585,7 +585,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @class.self_dot -> @class.members edge @class.members -> @class.member_attrs attr (@class.call) pop_scoped_symbol = "()" - attr (@class.call_drop) "drop" + attr (@class.call_drop) type = "drop_scopes" attr (@class.dot) pop_symbol = "." attr (@class.self_dot) pop_symbol = "." attr (@name) node_definition = @name From cfc004ad453f143d6f2e08bbe17228e5745e6d25 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 1 Jun 2023 10:15:36 +0200 Subject: [PATCH 14/60] convert: endpoint --- .../tree-sitter-stack-graphs-python/src/stack-graphs.tsg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 84e8fddb0..9b959b271 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -412,7 +412,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n attr (@name) node_definition = @name attr (@func.call) pop_scoped_symbol = "()" attr (@params.before_scope) "jump-to" - attr (@func.return_value) "endpoint" + attr (@func.return_value) is_exported let @func::function_returns = @func.return_value ; Prevent functions defined inside of method bodies from being treated like methods @@ -590,7 +590,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n attr (@class.self_dot) pop_symbol = "." attr (@name) node_definition = @name attr (@class.member_attrs) push_symbol = "." - attr (@class.self_scope) "endpoint" + attr (@class.self_scope) is_exported let @class::super_scope = @class.super_scope let @class::class_parent_scope = @class.parent_scope let @class::class_self_scope = @class.call_drop From b14aba9220314697c0c470ff97cc72b4b1a8d7a1 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 1 Jun 2023 10:17:25 +0200 Subject: [PATCH 15/60] convert: definiens --- .../tree-sitter-stack-graphs-python/src/stack-graphs.tsg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 9b959b271..fac43e2b3 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -401,7 +401,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n parameters: (parameters) @params body: (block) @body) @func { - attr (@name) "definiens" = @func + attr (@name) definiens_node = @func edge @func.after_scope -> @name edge @name -> @func.call edge @func.call -> @func.return_value @@ -570,7 +570,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n (class_definition name: (identifier) @name) @class { - attr (@name) "definiens" = @class + attr (@name) definiens_node = @class attr (@name) "syntax_type" = "class" edge @class.parent_scope -> @class::class_parent_scope edge @class.parent_scope -> @class::local_scope From 129aa5d3a651fb025139931aa290f15b92f1c8e6 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 1 Jun 2023 10:18:08 +0200 Subject: [PATCH 16/60] convert: syntax type --- .../tree-sitter-stack-graphs-python/src/stack-graphs.tsg | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index fac43e2b3..d86aba3e0 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -438,7 +438,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n (class_definition (block (function_definition name: (_)@name))) ] { - attr (@name) "syntax_type" = "method" + attr (@name) syntax_type = "method" } [ @@ -479,7 +479,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n (function_definition (block (function_definition name: (_)@name))) ] { - attr (@name) "syntax_type" = "function" + attr (@name) syntax_type = "function" } ;; @@ -571,7 +571,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n name: (identifier) @name) @class { attr (@name) definiens_node = @class - attr (@name) "syntax_type" = "class" + attr (@name) syntax_type = "class" edge @class.parent_scope -> @class::class_parent_scope edge @class.parent_scope -> @class::local_scope edge @class.after_scope -> @name From dba45d9ddcc8e9bf60948f62f0ec362bf15d8014 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 1 Jun 2023 10:18:54 +0200 Subject: [PATCH 17/60] convert: jump --- languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index d86aba3e0..0ddad1079 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -411,7 +411,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n attr (@func.drop_scope) type = "drop_scopes" attr (@name) node_definition = @name attr (@func.call) pop_scoped_symbol = "()" - attr (@params.before_scope) "jump-to" + edge @params.before_scope -> JUMP_TO_SCOPE_NODE attr (@func.return_value) is_exported let @func::function_returns = @func.return_value From 6bb4d577d1e811fb76204ac751fbd63db649feb0 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 1 Jun 2023 15:38:22 +0200 Subject: [PATCH 18/60] convert: nodes --- .../src/stack-graphs.tsg | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 0ddad1079..1323bccba 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -36,6 +36,49 @@ attribute symbol_reference = symbol => type = "push_symbol", symbol = symbol attribute node_symbol = node => symbol = (source-text node), source_node = node +;; Nodes +;; ^^^^^ + +(_)@node { + node @node.after_scope + node @node.arg_index + node @node.arg_name + node @node.before_scope + node @node.call + node @node.call_drop + node @node.called + node @node.def + node @node.def_dot + node @node.dot + node @node.drop_scope + node @node.el_index + node @node.file_def + node @node.file_ref + node @node.global + node @node.global_dot + node @node.input + node @node.input_dot + node @node.member_attrs + node @node.members + node @node.new_binding_pop + node @node.new_bindings + node @node.new_bindings_pop + node @node.output + node @node.output_args + node @node.output_dot + node @node.param_index + node @node.param_name + node @node.parent_scope + node @node.pattern_before_scope + node @node.pattern_index + node @node.ref + node @node.ref_dot + node @node.return_value + node @node.self_dot + node @node.self_scope + node @node.super_scope +} + ; Modules and Imports ;--------------------- From da3728c74f269dd8240e45a49ad2090aa183527a Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 1 Jun 2023 19:49:58 +0200 Subject: [PATCH 19/60] convert: scoped variables --- .../src/stack-graphs.tsg | 101 ++++++++++-------- 1 file changed, 58 insertions(+), 43 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 1323bccba..896ab715a 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -79,6 +79,21 @@ attribute node_symbol = node => symbol = (source-text node), source_n node @node.super_scope } +;; Inherited Variables +;; ^^^^^^^^^^^^^^^^^^^ + +inherit .bottom +inherit .class_member_attr_scope +inherit .class_parent_scope +inherit .class_self_scope +inherit .function_returns +inherit .global +inherit .global_dot +inherit .grandparent_module +inherit .local_scope +inherit .parent_module +inherit .super_scope + ; Modules and Imports ;--------------------- @@ -92,7 +107,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n var parent_module_ref = module_ref var grandparent_module_ref = module_ref - scan filepath { + scan FILE_PATH { "([^/]+)/" { edge module_def -> module_def.dot @@ -144,11 +159,11 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @mod.global_dot -> @mod.global attr (@mod.global_dot) push_symbol = "." - var @mod::parent_module = parent_module_ref - var @mod::grandparent_module = grandparent_module_ref - var @mod::bottom = @mod.after_scope - var @mod::global = @mod.global - var @mod::global_dot = @mod.global_dot + let @mod.parent_module = parent_module_ref + let @mod.grandparent_module = grandparent_module_ref + let @mod.bottom = @mod.after_scope + let @mod.global = @mod.global + let @mod.global_dot = @mod.global_dot } (import_statement @@ -252,14 +267,14 @@ attribute node_symbol = node => symbol = (source-text node), source_n (import_prefix) @prefix (#eq? @prefix ".")) @import { - edge @prefix.ref -> @import::parent_module + edge @prefix.ref -> @import.parent_module } (relative_import (import_prefix) @prefix (#eq? @prefix "..")) @import { - edge @prefix.ref -> @import::grandparent_module + edge @prefix.ref -> @import.grandparent_module } (relative_import @@ -367,7 +382,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n ] { edge @stmt.after_scope -> @stmt.before_scope - let @stmt::local_scope = @stmt.before_scope + let @stmt.local_scope = @stmt.before_scope } [ @@ -385,7 +400,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n (function_definition (block) @block) { - edge @block.before_scope -> @block::local_scope + edge @block.before_scope -> @block.local_scope } [ @@ -402,13 +417,13 @@ attribute node_symbol = node => symbol = (source-text node), source_n ]) ] @stmt { - edge @block.before_scope -> @block::local_scope + edge @block.before_scope -> @block.local_scope edge @stmt.after_scope -> @block.after_scope } (match_statement (case_clause) @block) @stmt { - let @block::local_scope = @block.before_scope + let @block.local_scope = @block.before_scope edge @block.before_scope -> @stmt.before_scope edge @stmt.after_scope -> @block.after_scope } @@ -450,17 +465,17 @@ attribute node_symbol = node => symbol = (source-text node), source_n edge @func.call -> @func.return_value edge @body.before_scope -> @params.after_scope edge @body.before_scope -> @func.drop_scope - edge @func.drop_scope -> @func::bottom + edge @func.drop_scope -> @func.bottom attr (@func.drop_scope) type = "drop_scopes" attr (@name) node_definition = @name attr (@func.call) pop_scoped_symbol = "()" edge @params.before_scope -> JUMP_TO_SCOPE_NODE attr (@func.return_value) is_exported - let @func::function_returns = @func.return_value + let @func.function_returns = @func.return_value ; Prevent functions defined inside of method bodies from being treated like methods - let @body::class_self_scope = nil - let @body::class_member_attr_scope = nil + let @body.class_self_scope = nil + let @body.class_member_attr_scope = nil } ;; @@ -534,8 +549,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n . (identifier) @param) body: (block) @body) { - edge @param.input -> @param::class_self_scope - edge @param::class_member_attr_scope -> @param.output + edge @param.input -> @param.class_self_scope + edge @param.class_member_attr_scope -> @param.output edge @param.output -> @body.after_scope attr (@param.output) push_node = @param } @@ -586,10 +601,10 @@ attribute node_symbol = node => symbol = (source-text node), source_n (tuple_pattern (_) @pattern) ] @list { - let statement_scope = @list::local_scope - let @pattern::local_scope = @pattern.pattern_before_scope - edge statement_scope -> @pattern::local_scope - attr (statement_scope -> @pattern::local_scope) precedence = (+ 1 (child-index @pattern)) + let statement_scope = @list.local_scope + let @pattern.local_scope = @pattern.pattern_before_scope + edge statement_scope -> @pattern.local_scope + attr (statement_scope -> @pattern.local_scope) precedence = (plus 1 (child-index @pattern)) edge @pattern.pattern_index -> @list.input edge @pattern.input -> @pattern.pattern_index @@ -607,7 +622,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n (return_statement (_) @expr) @stmt { - edge @stmt::function_returns -> @expr.output + edge @stmt.function_returns -> @expr.output } (class_definition @@ -615,8 +630,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n { attr (@name) definiens_node = @class attr (@name) syntax_type = "class" - edge @class.parent_scope -> @class::class_parent_scope - edge @class.parent_scope -> @class::local_scope + edge @class.parent_scope -> @class.class_parent_scope + edge @class.parent_scope -> @class.local_scope edge @class.after_scope -> @name edge @name -> @class.call edge @name -> @class.dot @@ -634,10 +649,10 @@ attribute node_symbol = node => symbol = (source-text node), source_n attr (@name) node_definition = @name attr (@class.member_attrs) push_symbol = "." attr (@class.self_scope) is_exported - let @class::super_scope = @class.super_scope - let @class::class_parent_scope = @class.parent_scope - let @class::class_self_scope = @class.call_drop - let @class::class_member_attr_scope = @class.member_attrs + let @class.super_scope = @class.super_scope + let @class.class_parent_scope = @class.parent_scope + let @class.class_self_scope = @class.call_drop + let @class.class_member_attr_scope = @class.member_attrs } (class_definition @@ -695,7 +710,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n attr (@receiver.arg_index) pop_symbol = "0" edge @receiver.arg_index -> @receiver.output - attr (@arg.arg_index) pop_symbol = (+ 1 (child-index @arg)) + attr (@arg.arg_index) pop_symbol = (plus 1 (child-index @arg)) edge @arg.arg_index -> @arg.output } @@ -724,7 +739,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n (#eq? @fn-name "super") ) { - edge @call.output -> @call::super_scope + edge @call.output -> @call.super_scope } [ @@ -769,9 +784,9 @@ attribute node_symbol = node => symbol = (source-text node), source_n (primary_expression/identifier) @id { - edge @id.output -> @id::local_scope - edge @id.output -> @id::class_parent_scope - edge @id::local_scope -> @id.input + edge @id.output -> @id.local_scope + edge @id.output -> @id.class_parent_scope + edge @id.local_scope -> @id.input attr (@id.input) pop_node = @id attr (@id.output) node_reference = @id @@ -781,10 +796,10 @@ attribute node_symbol = node => symbol = (source-text node), source_n (pattern/identifier) @id { - edge @id.output -> @id::local_scope - edge @id.output -> @id::class_parent_scope - edge @id::local_scope -> @id.input - attr (@id::local_scope -> @id.input) precedence = 1 + edge @id.output -> @id.local_scope + edge @id.output -> @id.class_parent_scope + edge @id.local_scope -> @id.input + attr (@id.local_scope -> @id.input) precedence = 1 attr (@id.input) node_definition = @id attr (@id.output) push_node = @id @@ -796,10 +811,10 @@ attribute node_symbol = node => symbol = (source-text node), source_n (expression) @value alias: (as_pattern_target (primary_expression/identifier) @id)) @as_pattern { - edge @id.output -> @id::local_scope - edge @id.output -> @id::class_parent_scope - edge @id::local_scope -> @id.input - attr (@id::local_scope -> @id.input) precedence = 1 + edge @id.output -> @id.local_scope + edge @id.output -> @id.class_parent_scope + edge @id.local_scope -> @id.input + attr (@id.local_scope -> @id.input) precedence = 1 attr (@id.input) node_definition = @id attr (@id.output) push_node = @id @@ -810,7 +825,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n (list) @list { edge @list.output -> @list.called - edge @list.called -> @list::global_dot + edge @list.called -> @list.global_dot attr (@list.called) push_symbol = "list" } From 39c262494bdf2252cda5c603918f0cec4fb72bf3 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 1 Jun 2023 19:51:04 +0200 Subject: [PATCH 20/60] convert: root --- .../src/stack-graphs.tsg | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 896ab715a..8460d2527 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -148,12 +148,12 @@ inherit .super_scope } } - edge root -> @mod.file_def - edge @mod.file_ref -> root + edge ROOT_NODE -> @mod.file_def + edge @mod.file_ref -> ROOT_NODE edge module_def -> @mod.after_scope edge @mod.before_scope -> @mod.global_dot - edge @mod.global -> root + edge @mod.global -> ROOT_NODE attr (@mod.global) push_symbol = "" edge @mod.global_dot -> @mod.global @@ -172,7 +172,7 @@ inherit .super_scope { edge @stmt.after_scope -> @root_name.def attr (@stmt.after_scope -> @root_name.def) precedence = 1 - edge @root_name.ref -> root + edge @root_name.ref -> ROOT_NODE attr (@root_name.ref) node_reference = @root_name attr (@root_name.def) node_definition = @root_name } @@ -182,7 +182,7 @@ inherit .super_scope (dotted_name . (identifier) @root_name))) @stmt { edge @stmt.after_scope -> @root_name.def - edge @root_name.ref -> root + edge @root_name.ref -> ROOT_NODE attr (@root_name.ref) node_reference = @root_name } @@ -190,7 +190,7 @@ inherit .super_scope module_name: (dotted_name . (identifier) @prefix_root_name)) @stmt { - edge @prefix_root_name.ref -> root + edge @prefix_root_name.ref -> ROOT_NODE attr (@prefix_root_name.ref) node_reference = @prefix_root_name } @@ -313,7 +313,7 @@ inherit .super_scope . (identifier) @root_name)) { attr (@root_name.ref) node_reference = @root_name - edge @root_name.ref -> root + edge @root_name.ref -> ROOT_NODE } (import_from_statement From 8e05b65573ea1c148aaaaa6860105aa0440dbdd4 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 1 Jun 2023 19:53:19 +0200 Subject: [PATCH 21/60] convert: captures --- .../src/stack-graphs.tsg | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 8460d2527..3746841b7 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -188,7 +188,7 @@ inherit .super_scope (import_from_statement module_name: (dotted_name - . (identifier) @prefix_root_name)) @stmt + . (identifier) @prefix_root_name)) { edge @prefix_root_name.ref -> ROOT_NODE attr (@prefix_root_name.ref) node_reference = @prefix_root_name @@ -209,7 +209,7 @@ inherit .super_scope (import_from_statement name: (aliased_import (dotted_name - . (identifier) @import_root_name))) @stmt + . (identifier) @import_root_name))) { edge @import_root_name.ref -> @import_root_name.ref_dot attr (@import_root_name.ref) node_reference = @import_root_name @@ -474,8 +474,8 @@ inherit .super_scope let @func.function_returns = @func.return_value ; Prevent functions defined inside of method bodies from being treated like methods - let @body.class_self_scope = nil - let @body.class_member_attr_scope = nil + let @body.class_self_scope = #null + let @body.class_member_attr_scope = #null } ;; @@ -657,7 +657,7 @@ inherit .super_scope (class_definition body: (block - (_) @last_stmt .) @body) @class + (_) @last_stmt .)) @class { edge @class.members -> @last_stmt.after_scope } @@ -718,7 +718,7 @@ inherit .super_scope arguments: (argument_list (keyword_argument name: (identifier) @name - value: (_) @val) @arg) @args) @call + value: (_) @val) @arg) @args) { edge @args -> @arg.arg_name attr (@arg.arg_name) pop_node = @name @@ -735,8 +735,8 @@ inherit .super_scope ( (call - function: (identifier) @fn-name) @call - (#eq? @fn-name "super") + function: (identifier) @_fn_name) @call + (#eq? @_fn_name "super") ) { edge @call.output -> @call.super_scope From 10e33f794042323e114132de66bff03d4f4701f6 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 2 Jun 2023 10:45:13 +0200 Subject: [PATCH 22/60] convert: module ref and def --- .../src/stack-graphs.tsg | 73 +++++++++++-------- 1 file changed, 43 insertions(+), 30 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 3746841b7..019a21db6 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -100,51 +100,64 @@ inherit .super_scope (module) @mod { var module_def = @mod.file_def - attr (module_def) empty_source_span + + node parent_module_def_node + var parent_module_def = parent_module_def_node + var module_ref = @mod.file_ref - attr (module_ref) empty_source_span - var parent_module_def = module_def - var parent_module_ref = module_ref - var grandparent_module_ref = module_ref + + node parent_module_ref_node + var parent_module_ref = parent_module_ref_node + + node grandparent_module_ref_node + var grandparent_module_ref = grandparent_module_ref_node scan FILE_PATH { "([^/]+)/" { - edge module_def -> module_def.dot - edge module_def.dot -> module_def.next_def - edge module_ref.next_ref -> module_ref.dot - edge module_ref.dot -> module_ref - + node def_dot + attr (def_dot) pop_symbol = "." + node next_def + ; + edge module_def -> def_dot + edge def_dot -> next_def + ; attr (module_def) pop_symbol = $1 - attr (module_def.dot) pop_symbol = "." + ; + set parent_module_def = module_def + set module_def = next_def + + node ref_dot + attr (ref_dot) push_symbol = "." + node next_ref + ; + edge next_ref -> ref_dot + edge ref_dot -> module_ref + ; attr (module_ref) push_symbol = $1 - attr (module_ref.dot) push_symbol = "." - + ; set grandparent_module_ref = parent_module_ref - set parent_module_def = module_def set parent_module_ref = module_ref - set module_ref = module_ref.next_ref - set module_def = module_def.next_def - attr (module_def) empty_source_span - attr (module_ref) empty_source_span + set module_ref = next_ref } - "__init__\\.py$" + "__init__\.py$" { - attr (parent_module_def) node_definition = @mod + attr (parent_module_def) is_definition, source_node = @mod, empty_source_span } - "([^/]+)$" + "([^/]+)\.py$" { - edge module_def -> module_def.dot - edge module_def.dot -> module_def.next_def - - attr (module_def) symbol_definition = (replace $1 "\\.py" ""), source_node = @mod - attr (module_def.dot) pop_symbol = "." - - set module_def = module_def.next_def - attr (module_def) empty_source_span - attr (module_ref) empty_source_span + node def_dot + attr (def_dot) pop_symbol = "." + node next_def + ; + edge module_def -> def_dot + edge def_dot -> next_def + ; + attr (module_def) pop_symbol = $1, is_definition, source_node = @mod, empty_source_span + ; + set module_def = next_def } } From ff21d32e812d4343393909b087a77f355cb0cdb1 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 2 Jun 2023 10:51:30 +0200 Subject: [PATCH 23/60] convert: global/global_dot --- .../src/stack-graphs.tsg | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 019a21db6..93515f30e 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -54,8 +54,6 @@ attribute node_symbol = node => symbol = (source-text node), source_n node @node.el_index node @node.file_def node @node.file_ref - node @node.global - node @node.global_dot node @node.input node @node.input_dot node @node.member_attrs @@ -165,18 +163,21 @@ inherit .super_scope edge @mod.file_ref -> ROOT_NODE edge module_def -> @mod.after_scope - edge @mod.before_scope -> @mod.global_dot - edge @mod.global -> ROOT_NODE - attr (@mod.global) push_symbol = "" + node global + node global_dot - edge @mod.global_dot -> @mod.global - attr (@mod.global_dot) push_symbol = "." + edge @mod.before_scope -> global_dot + edge global -> ROOT_NODE + attr (global) push_symbol = "" + + edge global_dot -> global + attr (global_dot) push_symbol = "." let @mod.parent_module = parent_module_ref let @mod.grandparent_module = grandparent_module_ref let @mod.bottom = @mod.after_scope - let @mod.global = @mod.global - let @mod.global_dot = @mod.global_dot + let @mod.global = global + let @mod.global_dot = global_dot } (import_statement From fb9e45cbadb164be9562d8ee1e389bb9bdc413e7 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 2 Jun 2023 10:55:16 +0200 Subject: [PATCH 24/60] convert: syntax nodes as graph nodes --- .../src/stack-graphs.tsg | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 93515f30e..e3b54923e 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -259,8 +259,8 @@ inherit .super_scope ] @stmt { edge @stmt.after_scope -> @alias - edge @alias -> @name.ref - attr (@alias) node_definition = @alias + edge @alias.def -> @name.ref + attr (@alias.def) node_definition = @alias } [ @@ -473,15 +473,15 @@ inherit .super_scope parameters: (parameters) @params body: (block) @body) @func { - attr (@name) definiens_node = @func - edge @func.after_scope -> @name - edge @name -> @func.call + attr (@name.def) definiens_node = @func + edge @func.after_scope -> @name.def + edge @name.def -> @func.call edge @func.call -> @func.return_value edge @body.before_scope -> @params.after_scope edge @body.before_scope -> @func.drop_scope edge @func.drop_scope -> @func.bottom attr (@func.drop_scope) type = "drop_scopes" - attr (@name) node_definition = @name + attr (@name.def) node_definition = @name attr (@func.call) pop_scoped_symbol = "()" edge @params.before_scope -> JUMP_TO_SCOPE_NODE attr (@func.return_value) is_exported @@ -510,7 +510,7 @@ inherit .super_scope (class_definition (block (function_definition name: (_)@name))) ] { - attr (@name) syntax_type = "method" + attr (@name.def) syntax_type = "method" } [ @@ -551,7 +551,7 @@ inherit .super_scope (function_definition (block (function_definition name: (_)@name))) ] { - attr (@name) syntax_type = "function" + attr (@name.def) syntax_type = "function" } ;; @@ -586,12 +586,12 @@ inherit .super_scope value: (_) @value) @param ] { - attr (@name) node_definition = @name + attr (@name.def) node_definition = @name attr (@param.param_name) push_node = @name - edge @name -> @param.param_name - edge @name -> @param.param_index - edge @param.input -> @name - edge @name -> @value.output + edge @name.def -> @param.param_name + edge @name.def -> @param.param_index + edge @param.input -> @name.def + edge @name.def -> @value.output } [ @@ -603,11 +603,11 @@ inherit .super_scope (_) @name) @param ] { - attr (@name) node_definition = @name + attr (@name.def) node_definition = @name attr (@param.param_name) push_node = @name - edge @name -> @param.param_name - edge @name -> @param.param_index - edge @param.input -> @name + edge @name.def -> @param.param_name + edge @name.def -> @param.param_index + edge @param.input -> @name.def } [ @@ -642,13 +642,13 @@ inherit .super_scope (class_definition name: (identifier) @name) @class { - attr (@name) definiens_node = @class - attr (@name) syntax_type = "class" + attr (@name.def) definiens_node = @class + attr (@name.def) syntax_type = "class" edge @class.parent_scope -> @class.class_parent_scope edge @class.parent_scope -> @class.local_scope - edge @class.after_scope -> @name - edge @name -> @class.call - edge @name -> @class.dot + edge @class.after_scope -> @name.def + edge @name.def -> @class.call + edge @name.def -> @class.dot edge @class.dot -> @class.members edge @class.call -> @class.call_drop edge @class.call_drop -> @class.self_scope @@ -660,7 +660,7 @@ inherit .super_scope attr (@class.call_drop) type = "drop_scopes" attr (@class.dot) pop_symbol = "." attr (@class.self_dot) pop_symbol = "." - attr (@name) node_definition = @name + attr (@name.def) node_definition = @name attr (@class.member_attrs) push_symbol = "." attr (@class.self_scope) is_exported let @class.super_scope = @class.super_scope From e614b60205d9e2c784a33f6aa5cf0038c7d57a42 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 2 Jun 2023 10:58:43 +0200 Subject: [PATCH 25/60] convert: super scope --- .../src/stack-graphs.tsg | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index e3b54923e..f9d0fc0e2 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -84,13 +84,13 @@ inherit .bottom inherit .class_member_attr_scope inherit .class_parent_scope inherit .class_self_scope +inherit .class_super_scope inherit .function_returns inherit .global inherit .global_dot inherit .grandparent_module inherit .local_scope inherit .parent_module -inherit .super_scope ; Modules and Imports ;--------------------- @@ -663,10 +663,10 @@ inherit .super_scope attr (@name.def) node_definition = @name attr (@class.member_attrs) push_symbol = "." attr (@class.self_scope) is_exported - let @class.super_scope = @class.super_scope + let @class.class_member_attr_scope = @class.member_attrs let @class.class_parent_scope = @class.parent_scope let @class.class_self_scope = @class.call_drop - let @class.class_member_attr_scope = @class.member_attrs + let @class.class_super_scope = @class.super_scope } (class_definition @@ -680,7 +680,7 @@ inherit .super_scope superclasses: (argument_list (_) @superclass)) @class { - edge @class.super_scope -> @superclass.output + edge @class.class_super_scope -> @superclass.output } (decorated_definition @@ -753,7 +753,7 @@ inherit .super_scope (#eq? @_fn_name "super") ) { - edge @call.output -> @call.super_scope + edge @call.output -> @call.class_super_scope } [ From cd0255c73212b671471152336261c96d65acb20c Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 2 Jun 2023 11:15:53 +0200 Subject: [PATCH 26/60] convert: duplicate edge --- .../tree-sitter-stack-graphs-python/src/stack-graphs.tsg | 5 ----- 1 file changed, 5 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index f9d0fc0e2..e19ffdac0 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -407,11 +407,6 @@ inherit .parent_module edge @stmt.before_scope -> @block.before_scope } -(block (_) @stmt . ) @block -{ - edge @block.after_scope -> @stmt.after_scope -} - (function_definition (block) @block) { edge @block.before_scope -> @block.local_scope From 307e03cb757b47041fd32ac93b463b58261a3474 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 2 Jun 2023 11:17:10 +0200 Subject: [PATCH 27/60] convert: duplicate stanza --- .../tree-sitter-stack-graphs-python/src/stack-graphs.tsg | 8 -------- 1 file changed, 8 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index e19ffdac0..91376a956 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -200,14 +200,6 @@ inherit .parent_module attr (@root_name.ref) node_reference = @root_name } -(import_from_statement - module_name: (dotted_name - . (identifier) @prefix_root_name)) -{ - edge @prefix_root_name.ref -> ROOT_NODE - attr (@prefix_root_name.ref) node_reference = @prefix_root_name -} - (import_from_statement name: (dotted_name . (identifier) @import_root_name)) @stmt From 861fbca8f7473c396251be296182d6ca45e1f1c1 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 2 Jun 2023 11:25:15 +0200 Subject: [PATCH 28/60] convert: one more syntax node used directly as grap hnode --- languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 91376a956..3083dcff6 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -250,7 +250,7 @@ inherit .parent_module alias: (identifier) @alias)) ] @stmt { - edge @stmt.after_scope -> @alias + edge @stmt.after_scope -> @alias.def edge @alias.def -> @name.ref attr (@alias.def) node_definition = @alias } From 7aa54c8bd6bac0d694527c8dc09c50ed1be76f04 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 2 Jun 2023 11:29:06 +0200 Subject: [PATCH 29/60] convert: toplevel dummy values for inherited variables --- .../tree-sitter-stack-graphs-python/src/stack-graphs.tsg | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 3083dcff6..851d358ff 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -178,6 +178,14 @@ inherit .parent_module let @mod.bottom = @mod.after_scope let @mod.global = global let @mod.global_dot = global_dot + + ;; add a dummy nodes for inherited variables + node @mod.class_member_attr_scope + node @mod.class_parent_scope + node @mod.class_self_scope + node @mod.class_super_scope + node @mod.function_returns + node @mod.local_scope } (import_statement From 1624d70afd320e5c061100a2167966ad0c76ccb9 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 2 Jun 2023 11:31:11 +0200 Subject: [PATCH 30/60] convert: duplicate attribute --- .../tree-sitter-stack-graphs-python/src/stack-graphs.tsg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 851d358ff..63831ff7d 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -782,13 +782,13 @@ inherit .parent_module (pattern/attribute attribute: (identifier) @name) { - attr (@name.input) node_definition = @name + attr (@name.input) is_definition } (primary_expression/attribute attribute: (identifier) @name) { - attr (@name.output) node_reference = @name + attr (@name.output) is_reference } (primary_expression/identifier) @id From 5318655f366e714e085dbf5fc8818310eaea26f5 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 2 Jun 2023 11:33:55 +0200 Subject: [PATCH 31/60] convert: graph node for argument_list --- .../tree-sitter-stack-graphs-python/src/stack-graphs.tsg | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 63831ff7d..de8198d25 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -704,7 +704,7 @@ inherit .parent_module { edge @call.output -> @call.output_args edge @call.output_args -> @fn.output - attr (@call.output_args) push_scoped_symbol = "()", scope = @args + attr (@call.output_args) push_scoped_symbol = "()", scope = @args.def } (call @@ -713,7 +713,7 @@ inherit .parent_module arguments: (argument_list (expression) @arg) @args) { - edge @args -> @arg.arg_index + edge @args.def -> @arg.arg_index edge @receiver -> @receiver.arg_index attr (@receiver.arg_index) pop_symbol = "0" @@ -729,7 +729,7 @@ inherit .parent_module name: (identifier) @name value: (_) @val) @arg) @args) { - edge @args -> @arg.arg_name + edge @args.def -> @arg.arg_name attr (@arg.arg_name) pop_node = @name edge @arg.arg_name -> @val.output } @@ -737,7 +737,7 @@ inherit .parent_module (argument_list (expression) @arg) @args { - edge @args -> @arg.arg_index + edge @args.def -> @arg.arg_index attr (@arg.arg_index) pop_symbol = (child-index @arg) edge @arg.arg_index -> @arg.output } From ec0f61b6cd93232e57ccb8db0606fcf778b70b25 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 2 Jun 2023 11:34:28 +0200 Subject: [PATCH 32/60] convert: function name --- languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index de8198d25..105c576af 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -738,7 +738,7 @@ inherit .parent_module (expression) @arg) @args { edge @args.def -> @arg.arg_index - attr (@arg.arg_index) pop_symbol = (child-index @arg) + attr (@arg.arg_index) pop_symbol = (named-child-index @arg) edge @arg.arg_index -> @arg.output } From 38595361d9b6fbde5567098c98faffad26244c19 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 2 Jun 2023 11:36:01 +0200 Subject: [PATCH 33/60] convert: export scope --- languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg | 1 + 1 file changed, 1 insertion(+) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 105c576af..d5d980e10 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -705,6 +705,7 @@ inherit .parent_module edge @call.output -> @call.output_args edge @call.output_args -> @fn.output attr (@call.output_args) push_scoped_symbol = "()", scope = @args.def + attr (@args.def) is_exported } (call From 02f4b5e56aa0a22a6aac52c77676c78057fefa5e Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 2 Jun 2023 11:37:19 +0200 Subject: [PATCH 34/60] convert: function name --- .../src/stack-graphs.tsg | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index d5d980e10..8b176f66c 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -613,17 +613,17 @@ inherit .parent_module let statement_scope = @list.local_scope let @pattern.local_scope = @pattern.pattern_before_scope edge statement_scope -> @pattern.local_scope - attr (statement_scope -> @pattern.local_scope) precedence = (plus 1 (child-index @pattern)) + attr (statement_scope -> @pattern.local_scope) precedence = (plus 1 (named-child-index @pattern)) edge @pattern.pattern_index -> @list.input edge @pattern.input -> @pattern.pattern_index - attr (@pattern.pattern_index) push_symbol = (child-index @pattern) + attr (@pattern.pattern_index) push_symbol = (named-child-index @pattern) } (parameters (_) @param) @params { - attr (@param.param_index) push_symbol = (child-index @param) + attr (@param.param_index) push_symbol = (named-child-index @param) edge @param.param_index -> @params.before_scope edge @params.after_scope -> @param.input edge @param.param_name -> @params.before_scope @@ -720,7 +720,7 @@ inherit .parent_module attr (@receiver.arg_index) pop_symbol = "0" edge @receiver.arg_index -> @receiver.output - attr (@arg.arg_index) pop_symbol = (plus 1 (child-index @arg)) + attr (@arg.arg_index) pop_symbol = (plus 1 (named-child-index @arg)) edge @arg.arg_index -> @arg.output } @@ -758,7 +758,7 @@ inherit .parent_module ] @tuple { edge @tuple.output -> @element.el_index - attr (@element.el_index) pop_symbol = (child-index @element) + attr (@element.el_index) pop_symbol = (named-child-index @element) edge @element.el_index -> @element.output edge @tuple.new_bindings -> @element.new_bindings From 6e39e4a4787df62abf6d264ad2ef232209f36df2 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 2 Jun 2023 11:53:22 +0200 Subject: [PATCH 35/60] convert: argument lists --- .../src/stack-graphs.tsg | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 8b176f66c..8d1adf538 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -41,8 +41,6 @@ attribute node_symbol = node => symbol = (source-text node), source_n (_)@node { node @node.after_scope - node @node.arg_index - node @node.arg_name node @node.before_scope node @node.call node @node.call_drop @@ -702,10 +700,12 @@ inherit .parent_module function: (_) @fn arguments: (argument_list) @args) @call { + node @args.args + attr (@args.args) is_exported + edge @call.output -> @call.output_args edge @call.output_args -> @fn.output - attr (@call.output_args) push_scoped_symbol = "()", scope = @args.def - attr (@args.def) is_exported + attr (@call.output_args) push_scoped_symbol = "()", scope = @args.args } (call @@ -714,33 +714,37 @@ inherit .parent_module arguments: (argument_list (expression) @arg) @args) { - edge @args.def -> @arg.arg_index - edge @receiver -> @receiver.arg_index - - attr (@receiver.arg_index) pop_symbol = "0" - edge @receiver.arg_index -> @receiver.output + node receiver_arg_index + attr (receiver_arg_index) pop_symbol = "0" + edge @args.args -> receiver_arg_index + edge receiver_arg_index -> @receiver.output - attr (@arg.arg_index) pop_symbol = (plus 1 (named-child-index @arg)) - edge @arg.arg_index -> @arg.output + ;; FIXME the arguments will also exist with their unshifted indices because of the general + ;; rule below! + node arg_index + attr (arg_index) pop_symbol = (plus 1 (named-child-index @arg)) + edge arg_index -> @arg.output } (call arguments: (argument_list (keyword_argument name: (identifier) @name - value: (_) @val) @arg) @args) + value: (_) @val)) @args) { - edge @args.def -> @arg.arg_name - attr (@arg.arg_name) pop_node = @name - edge @arg.arg_name -> @val.output + node arg_name + edge @args.args -> arg_name + attr (arg_name) pop_node = @name + edge arg_name -> @val.output } (argument_list (expression) @arg) @args { - edge @args.def -> @arg.arg_index - attr (@arg.arg_index) pop_symbol = (named-child-index @arg) - edge @arg.arg_index -> @arg.output + node arg_index + edge @args.args -> arg_index + attr (arg_index) pop_symbol = (named-child-index @arg) + edge arg_index -> @arg.output } ( From ac61586343112446eaf3e3f1a60d6306a6402118 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 2 Jun 2023 12:19:10 +0200 Subject: [PATCH 36/60] convert: duplicate edges --- .../tree-sitter-stack-graphs-python/src/stack-graphs.tsg | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 8d1adf538..090790af3 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -213,8 +213,6 @@ inherit .parent_module edge @stmt.after_scope -> @import_root_name.def attr (@stmt.after_scope -> @import_root_name.def) precedence = 1 edge @import_root_name.ref -> @import_root_name.ref_dot - attr (@import_root_name.def) node_definition = @import_root_name - attr (@import_root_name.ref) node_reference = @import_root_name attr (@import_root_name.ref_dot) push_symbol = "." } @@ -825,12 +823,8 @@ inherit .parent_module (expression) @value alias: (as_pattern_target (primary_expression/identifier) @id)) @as_pattern { - edge @id.output -> @id.local_scope - edge @id.output -> @id.class_parent_scope - edge @id.local_scope -> @id.input attr (@id.local_scope -> @id.input) precedence = 1 - attr (@id.input) node_definition = @id - attr (@id.output) push_node = @id + attr (@id.input) is_definition edge @as_pattern.new_bindings -> @value.new_bindings edge @as_pattern.new_bindings -> @id.new_bindings From a127916f7511bac46cac77c7ab6aa108925699dd Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 2 Jun 2023 12:33:05 +0200 Subject: [PATCH 37/60] convert: duplicate edges --- languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg | 2 -- 1 file changed, 2 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 090790af3..1d79c8e1f 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -268,8 +268,6 @@ inherit .parent_module (identifier) @leaf_name .)) ] { - attr (@leaf_name.def) node_definition = @leaf_name - attr (@leaf_name.ref) node_reference = @leaf_name edge @leaf_name.def -> @leaf_name.ref } From 6407b1dba56dfd876827ad2b8a2fb809e39a3011 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 2 Jun 2023 12:34:46 +0200 Subject: [PATCH 38/60] convert: always create .args --- .../tree-sitter-stack-graphs-python/src/stack-graphs.tsg | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 1d79c8e1f..a88151398 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -696,9 +696,6 @@ inherit .parent_module function: (_) @fn arguments: (argument_list) @args) @call { - node @args.args - attr (@args.args) is_exported - edge @call.output -> @call.output_args edge @call.output_args -> @fn.output attr (@call.output_args) push_scoped_symbol = "()", scope = @args.args @@ -734,6 +731,11 @@ inherit .parent_module edge arg_name -> @val.output } +(argument_list) @args { + node @args.args + attr (@args.args) is_exported +} + (argument_list (expression) @arg) @args { From d5d312ecebab9f351b2727d2af93e6fe009fd0d7 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 2 Jun 2023 12:36:13 +0200 Subject: [PATCH 39/60] Enable tests --- .../test/{legacy.skip => }/aliased_imports.py | 0 .../test/{legacy.skip => }/attributes.py | 0 .../test/{legacy.skip => }/blocks.py | 0 .../test/{legacy.skip => }/chained_functions.py | 0 .../{legacy.skip/chained_methods.py => chained_methods.py.skip} | 0 .../test/{legacy.skip => }/class_members.py | 0 .../test/{legacy.skip => }/decorators.py | 0 .../test/{legacy.skip => }/exceptions.py | 0 .../test/{legacy.skip => }/functions.py | 0 .../test/{legacy.skip => }/imported_functions.py | 0 .../test/{legacy.skip => }/imports.py | 0 .../test/{legacy.skip => }/instance_members.py | 0 .../test/{legacy.skip => }/loops.py | 0 .../test/{legacy.skip => }/many_definitions.py | 0 .../test/{legacy.skip => }/pattern_matching.py | 0 .../test/{legacy.skip => }/redundant_reexport.py | 0 .../test/{legacy.skip => }/relative_imports.py | 0 .../test/{legacy.skip => }/statement_bindings.py | 0 .../test/{legacy.skip => }/superclasses.py | 0 .../test/{legacy.skip => }/test.py | 0 .../test/{legacy.skip => }/tuples.py | 0 .../test/{legacy.skip => }/wildcard_import.py | 0 22 files changed, 0 insertions(+), 0 deletions(-) rename languages/tree-sitter-stack-graphs-python/test/{legacy.skip => }/aliased_imports.py (100%) rename languages/tree-sitter-stack-graphs-python/test/{legacy.skip => }/attributes.py (100%) rename languages/tree-sitter-stack-graphs-python/test/{legacy.skip => }/blocks.py (100%) rename languages/tree-sitter-stack-graphs-python/test/{legacy.skip => }/chained_functions.py (100%) rename languages/tree-sitter-stack-graphs-python/test/{legacy.skip/chained_methods.py => chained_methods.py.skip} (100%) rename languages/tree-sitter-stack-graphs-python/test/{legacy.skip => }/class_members.py (100%) rename languages/tree-sitter-stack-graphs-python/test/{legacy.skip => }/decorators.py (100%) rename languages/tree-sitter-stack-graphs-python/test/{legacy.skip => }/exceptions.py (100%) rename languages/tree-sitter-stack-graphs-python/test/{legacy.skip => }/functions.py (100%) rename languages/tree-sitter-stack-graphs-python/test/{legacy.skip => }/imported_functions.py (100%) rename languages/tree-sitter-stack-graphs-python/test/{legacy.skip => }/imports.py (100%) rename languages/tree-sitter-stack-graphs-python/test/{legacy.skip => }/instance_members.py (100%) rename languages/tree-sitter-stack-graphs-python/test/{legacy.skip => }/loops.py (100%) rename languages/tree-sitter-stack-graphs-python/test/{legacy.skip => }/many_definitions.py (100%) rename languages/tree-sitter-stack-graphs-python/test/{legacy.skip => }/pattern_matching.py (100%) rename languages/tree-sitter-stack-graphs-python/test/{legacy.skip => }/redundant_reexport.py (100%) rename languages/tree-sitter-stack-graphs-python/test/{legacy.skip => }/relative_imports.py (100%) rename languages/tree-sitter-stack-graphs-python/test/{legacy.skip => }/statement_bindings.py (100%) rename languages/tree-sitter-stack-graphs-python/test/{legacy.skip => }/superclasses.py (100%) rename languages/tree-sitter-stack-graphs-python/test/{legacy.skip => }/test.py (100%) rename languages/tree-sitter-stack-graphs-python/test/{legacy.skip => }/tuples.py (100%) rename languages/tree-sitter-stack-graphs-python/test/{legacy.skip => }/wildcard_import.py (100%) diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/aliased_imports.py b/languages/tree-sitter-stack-graphs-python/test/aliased_imports.py similarity index 100% rename from languages/tree-sitter-stack-graphs-python/test/legacy.skip/aliased_imports.py rename to languages/tree-sitter-stack-graphs-python/test/aliased_imports.py diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/attributes.py b/languages/tree-sitter-stack-graphs-python/test/attributes.py similarity index 100% rename from languages/tree-sitter-stack-graphs-python/test/legacy.skip/attributes.py rename to languages/tree-sitter-stack-graphs-python/test/attributes.py diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/blocks.py b/languages/tree-sitter-stack-graphs-python/test/blocks.py similarity index 100% rename from languages/tree-sitter-stack-graphs-python/test/legacy.skip/blocks.py rename to languages/tree-sitter-stack-graphs-python/test/blocks.py diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/chained_functions.py b/languages/tree-sitter-stack-graphs-python/test/chained_functions.py similarity index 100% rename from languages/tree-sitter-stack-graphs-python/test/legacy.skip/chained_functions.py rename to languages/tree-sitter-stack-graphs-python/test/chained_functions.py diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/chained_methods.py b/languages/tree-sitter-stack-graphs-python/test/chained_methods.py.skip similarity index 100% rename from languages/tree-sitter-stack-graphs-python/test/legacy.skip/chained_methods.py rename to languages/tree-sitter-stack-graphs-python/test/chained_methods.py.skip diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/class_members.py b/languages/tree-sitter-stack-graphs-python/test/class_members.py similarity index 100% rename from languages/tree-sitter-stack-graphs-python/test/legacy.skip/class_members.py rename to languages/tree-sitter-stack-graphs-python/test/class_members.py diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/decorators.py b/languages/tree-sitter-stack-graphs-python/test/decorators.py similarity index 100% rename from languages/tree-sitter-stack-graphs-python/test/legacy.skip/decorators.py rename to languages/tree-sitter-stack-graphs-python/test/decorators.py diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/exceptions.py b/languages/tree-sitter-stack-graphs-python/test/exceptions.py similarity index 100% rename from languages/tree-sitter-stack-graphs-python/test/legacy.skip/exceptions.py rename to languages/tree-sitter-stack-graphs-python/test/exceptions.py diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/functions.py b/languages/tree-sitter-stack-graphs-python/test/functions.py similarity index 100% rename from languages/tree-sitter-stack-graphs-python/test/legacy.skip/functions.py rename to languages/tree-sitter-stack-graphs-python/test/functions.py diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/imported_functions.py b/languages/tree-sitter-stack-graphs-python/test/imported_functions.py similarity index 100% rename from languages/tree-sitter-stack-graphs-python/test/legacy.skip/imported_functions.py rename to languages/tree-sitter-stack-graphs-python/test/imported_functions.py diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/imports.py b/languages/tree-sitter-stack-graphs-python/test/imports.py similarity index 100% rename from languages/tree-sitter-stack-graphs-python/test/legacy.skip/imports.py rename to languages/tree-sitter-stack-graphs-python/test/imports.py diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/instance_members.py b/languages/tree-sitter-stack-graphs-python/test/instance_members.py similarity index 100% rename from languages/tree-sitter-stack-graphs-python/test/legacy.skip/instance_members.py rename to languages/tree-sitter-stack-graphs-python/test/instance_members.py diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/loops.py b/languages/tree-sitter-stack-graphs-python/test/loops.py similarity index 100% rename from languages/tree-sitter-stack-graphs-python/test/legacy.skip/loops.py rename to languages/tree-sitter-stack-graphs-python/test/loops.py diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/many_definitions.py b/languages/tree-sitter-stack-graphs-python/test/many_definitions.py similarity index 100% rename from languages/tree-sitter-stack-graphs-python/test/legacy.skip/many_definitions.py rename to languages/tree-sitter-stack-graphs-python/test/many_definitions.py diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/pattern_matching.py b/languages/tree-sitter-stack-graphs-python/test/pattern_matching.py similarity index 100% rename from languages/tree-sitter-stack-graphs-python/test/legacy.skip/pattern_matching.py rename to languages/tree-sitter-stack-graphs-python/test/pattern_matching.py diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/redundant_reexport.py b/languages/tree-sitter-stack-graphs-python/test/redundant_reexport.py similarity index 100% rename from languages/tree-sitter-stack-graphs-python/test/legacy.skip/redundant_reexport.py rename to languages/tree-sitter-stack-graphs-python/test/redundant_reexport.py diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/relative_imports.py b/languages/tree-sitter-stack-graphs-python/test/relative_imports.py similarity index 100% rename from languages/tree-sitter-stack-graphs-python/test/legacy.skip/relative_imports.py rename to languages/tree-sitter-stack-graphs-python/test/relative_imports.py diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/statement_bindings.py b/languages/tree-sitter-stack-graphs-python/test/statement_bindings.py similarity index 100% rename from languages/tree-sitter-stack-graphs-python/test/legacy.skip/statement_bindings.py rename to languages/tree-sitter-stack-graphs-python/test/statement_bindings.py diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/superclasses.py b/languages/tree-sitter-stack-graphs-python/test/superclasses.py similarity index 100% rename from languages/tree-sitter-stack-graphs-python/test/legacy.skip/superclasses.py rename to languages/tree-sitter-stack-graphs-python/test/superclasses.py diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/test.py b/languages/tree-sitter-stack-graphs-python/test/test.py similarity index 100% rename from languages/tree-sitter-stack-graphs-python/test/legacy.skip/test.py rename to languages/tree-sitter-stack-graphs-python/test/test.py diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/tuples.py b/languages/tree-sitter-stack-graphs-python/test/tuples.py similarity index 100% rename from languages/tree-sitter-stack-graphs-python/test/legacy.skip/tuples.py rename to languages/tree-sitter-stack-graphs-python/test/tuples.py diff --git a/languages/tree-sitter-stack-graphs-python/test/legacy.skip/wildcard_import.py b/languages/tree-sitter-stack-graphs-python/test/wildcard_import.py similarity index 100% rename from languages/tree-sitter-stack-graphs-python/test/legacy.skip/wildcard_import.py rename to languages/tree-sitter-stack-graphs-python/test/wildcard_import.py From 8d8c7e07b4ca3e9515af1bf58c2f1e22e036e332 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 2 Jun 2023 19:06:30 +0200 Subject: [PATCH 40/60] convert: comment out syntax_type and definiens_node which are not yet supported --- .../src/stack-graphs.tsg | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index a88151398..23b69b499 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -462,7 +462,7 @@ inherit .parent_module parameters: (parameters) @params body: (block) @body) @func { - attr (@name.def) definiens_node = @func +; attr (@name.def) definiens_node = @func edge @func.after_scope -> @name.def edge @name.def -> @func.call edge @func.call -> @func.return_value @@ -495,52 +495,52 @@ inherit .parent_module ;; [ - (class_definition (block (decorated_definition (function_definition name: (_)@name)))) - (class_definition (block (function_definition name: (_)@name))) + (class_definition (block (decorated_definition (function_definition name: (_)@_name)))) + (class_definition (block (function_definition name: (_)@_name))) ] { - attr (@name.def) syntax_type = "method" +; attr (@name.def) syntax_type = "method" } [ - (module (decorated_definition (function_definition name: (_)@name))) - (module (function_definition name: (_)@name)) + (module (decorated_definition (function_definition name: (_)@_name))) + (module (function_definition name: (_)@_name)) - (if_statement (block (decorated_definition (function_definition name: (_)@name)))) - (if_statement (block (function_definition name: (_)@name))) + (if_statement (block (decorated_definition (function_definition name: (_)@_name)))) + (if_statement (block (function_definition name: (_)@_name))) - (elif_clause (block (decorated_definition (function_definition name: (_)@name)))) - (elif_clause (block (function_definition name: (_)@name))) + (elif_clause (block (decorated_definition (function_definition name: (_)@_name)))) + (elif_clause (block (function_definition name: (_)@_name))) - (else_clause (block (decorated_definition (function_definition name: (_)@name)))) - (else_clause (block (function_definition name: (_)@name))) + (else_clause (block (decorated_definition (function_definition name: (_)@_name)))) + (else_clause (block (function_definition name: (_)@_name))) - (case_clause (block (decorated_definition (function_definition name: (_)@name)))) - (case_clause (block (function_definition name: (_)@name))) + (case_clause (block (decorated_definition (function_definition name: (_)@_name)))) + (case_clause (block (function_definition name: (_)@_name))) - (for_statement (block (decorated_definition (function_definition name: (_)@name)))) - (for_statement (block (function_definition name: (_)@name))) + (for_statement (block (decorated_definition (function_definition name: (_)@_name)))) + (for_statement (block (function_definition name: (_)@_name))) - (while_statement (block (decorated_definition (function_definition name: (_)@name)))) - (while_statement (block (function_definition name: (_)@name))) + (while_statement (block (decorated_definition (function_definition name: (_)@_name)))) + (while_statement (block (function_definition name: (_)@_name))) - (try_statement (block (decorated_definition (function_definition name: (_)@name)))) - (try_statement (block (function_definition name: (_)@name))) + (try_statement (block (decorated_definition (function_definition name: (_)@_name)))) + (try_statement (block (function_definition name: (_)@_name))) - (except_clause (block (decorated_definition (function_definition name: (_)@name)))) - (except_clause (block (function_definition name: (_)@name))) + (except_clause (block (decorated_definition (function_definition name: (_)@_name)))) + (except_clause (block (function_definition name: (_)@_name))) - (finally_clause (block (decorated_definition (function_definition name: (_)@name)))) - (finally_clause (block (function_definition name: (_)@name))) + (finally_clause (block (decorated_definition (function_definition name: (_)@_name)))) + (finally_clause (block (function_definition name: (_)@_name))) - (with_statement (block (decorated_definition (function_definition name: (_)@name)))) - (with_statement (block (function_definition name: (_)@name))) + (with_statement (block (decorated_definition (function_definition name: (_)@_name)))) + (with_statement (block (function_definition name: (_)@_name))) - (function_definition (block (decorated_definition (function_definition name: (_)@name)))) - (function_definition (block (function_definition name: (_)@name))) + (function_definition (block (decorated_definition (function_definition name: (_)@_name)))) + (function_definition (block (function_definition name: (_)@_name))) ] { - attr (@name.def) syntax_type = "function" +; attr (@name.def) syntax_type = "function" } ;; @@ -631,8 +631,8 @@ inherit .parent_module (class_definition name: (identifier) @name) @class { - attr (@name.def) definiens_node = @class - attr (@name.def) syntax_type = "class" +; attr (@name.def) definiens_node = @class +; attr (@name.def) syntax_type = "class" edge @class.parent_scope -> @class.class_parent_scope edge @class.parent_scope -> @class.local_scope edge @class.after_scope -> @name.def From e44bad923c8f91e788e6a3ed18e093e6ca7f4ba4 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Wed, 15 Nov 2023 12:06:56 +0100 Subject: [PATCH 41/60] Re-enable syntax_type and definiens_node --- .../src/stack-graphs.tsg | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 23b69b499..a88151398 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -462,7 +462,7 @@ inherit .parent_module parameters: (parameters) @params body: (block) @body) @func { -; attr (@name.def) definiens_node = @func + attr (@name.def) definiens_node = @func edge @func.after_scope -> @name.def edge @name.def -> @func.call edge @func.call -> @func.return_value @@ -495,52 +495,52 @@ inherit .parent_module ;; [ - (class_definition (block (decorated_definition (function_definition name: (_)@_name)))) - (class_definition (block (function_definition name: (_)@_name))) + (class_definition (block (decorated_definition (function_definition name: (_)@name)))) + (class_definition (block (function_definition name: (_)@name))) ] { -; attr (@name.def) syntax_type = "method" + attr (@name.def) syntax_type = "method" } [ - (module (decorated_definition (function_definition name: (_)@_name))) - (module (function_definition name: (_)@_name)) + (module (decorated_definition (function_definition name: (_)@name))) + (module (function_definition name: (_)@name)) - (if_statement (block (decorated_definition (function_definition name: (_)@_name)))) - (if_statement (block (function_definition name: (_)@_name))) + (if_statement (block (decorated_definition (function_definition name: (_)@name)))) + (if_statement (block (function_definition name: (_)@name))) - (elif_clause (block (decorated_definition (function_definition name: (_)@_name)))) - (elif_clause (block (function_definition name: (_)@_name))) + (elif_clause (block (decorated_definition (function_definition name: (_)@name)))) + (elif_clause (block (function_definition name: (_)@name))) - (else_clause (block (decorated_definition (function_definition name: (_)@_name)))) - (else_clause (block (function_definition name: (_)@_name))) + (else_clause (block (decorated_definition (function_definition name: (_)@name)))) + (else_clause (block (function_definition name: (_)@name))) - (case_clause (block (decorated_definition (function_definition name: (_)@_name)))) - (case_clause (block (function_definition name: (_)@_name))) + (case_clause (block (decorated_definition (function_definition name: (_)@name)))) + (case_clause (block (function_definition name: (_)@name))) - (for_statement (block (decorated_definition (function_definition name: (_)@_name)))) - (for_statement (block (function_definition name: (_)@_name))) + (for_statement (block (decorated_definition (function_definition name: (_)@name)))) + (for_statement (block (function_definition name: (_)@name))) - (while_statement (block (decorated_definition (function_definition name: (_)@_name)))) - (while_statement (block (function_definition name: (_)@_name))) + (while_statement (block (decorated_definition (function_definition name: (_)@name)))) + (while_statement (block (function_definition name: (_)@name))) - (try_statement (block (decorated_definition (function_definition name: (_)@_name)))) - (try_statement (block (function_definition name: (_)@_name))) + (try_statement (block (decorated_definition (function_definition name: (_)@name)))) + (try_statement (block (function_definition name: (_)@name))) - (except_clause (block (decorated_definition (function_definition name: (_)@_name)))) - (except_clause (block (function_definition name: (_)@_name))) + (except_clause (block (decorated_definition (function_definition name: (_)@name)))) + (except_clause (block (function_definition name: (_)@name))) - (finally_clause (block (decorated_definition (function_definition name: (_)@_name)))) - (finally_clause (block (function_definition name: (_)@_name))) + (finally_clause (block (decorated_definition (function_definition name: (_)@name)))) + (finally_clause (block (function_definition name: (_)@name))) - (with_statement (block (decorated_definition (function_definition name: (_)@_name)))) - (with_statement (block (function_definition name: (_)@_name))) + (with_statement (block (decorated_definition (function_definition name: (_)@name)))) + (with_statement (block (function_definition name: (_)@name))) - (function_definition (block (decorated_definition (function_definition name: (_)@_name)))) - (function_definition (block (function_definition name: (_)@_name))) + (function_definition (block (decorated_definition (function_definition name: (_)@name)))) + (function_definition (block (function_definition name: (_)@name))) ] { -; attr (@name.def) syntax_type = "function" + attr (@name.def) syntax_type = "function" } ;; @@ -631,8 +631,8 @@ inherit .parent_module (class_definition name: (identifier) @name) @class { -; attr (@name.def) definiens_node = @class -; attr (@name.def) syntax_type = "class" + attr (@name.def) definiens_node = @class + attr (@name.def) syntax_type = "class" edge @class.parent_scope -> @class.class_parent_scope edge @class.parent_scope -> @class.local_scope edge @class.after_scope -> @name.def From 5a63def5d66fd5ef048d219f3abf3525dbc7e380 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Wed, 15 Nov 2023 12:07:26 +0100 Subject: [PATCH 42/60] Don't crash visualization on self edges --- stack-graphs/src/visualization/visualization.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/stack-graphs/src/visualization/visualization.js b/stack-graphs/src/visualization/visualization.js index 116850791..6fdab1ef6 100644 --- a/stack-graphs/src/visualization/visualization.js +++ b/stack-graphs/src/visualization/visualization.js @@ -24,6 +24,7 @@ class StackGraph { this.graph = graph; this.paths = paths; + this.cleanup_data(); this.compute_data(); this.current_node = null; @@ -33,6 +34,19 @@ class StackGraph { this.render(); } + cleanup_data() { + let idx = 0; + while (idx < this.graph.edges.length) { + let edge = this.graph.edges[idx]; + if (edge.source.file === edge.sink.file && edge.source.local_id === edge.sink.local_id) { + console.log("ignoring self loop", edge); + this.graph.edges.splice(idx, 1); + } else { + idx += 1; + } + } + } + compute_data() { this.F = {}; this.ID = {}; @@ -47,7 +61,6 @@ class StackGraph { const file = graph.files[i]; this.F[file] = i; } - console.log(this.F); } compute_node_data() { From fe70ba08f34bfec2aa9cb485117ba4ceb827fc65 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Wed, 15 Nov 2023 12:21:09 +0100 Subject: [PATCH 43/60] Cleanup accidental self loop --- .../src/stack-graphs.tsg | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index a88151398..d538431b0 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -64,7 +64,6 @@ attribute node_symbol = node => symbol = (source-text node), source_n node @node.output_dot node @node.param_index node @node.param_name - node @node.parent_scope node @node.pattern_before_scope node @node.pattern_index node @node.ref @@ -633,8 +632,6 @@ inherit .parent_module { attr (@name.def) definiens_node = @class attr (@name.def) syntax_type = "class" - edge @class.parent_scope -> @class.class_parent_scope - edge @class.parent_scope -> @class.local_scope edge @class.after_scope -> @name.def edge @name.def -> @class.call edge @name.def -> @class.dot @@ -652,10 +649,17 @@ inherit .parent_module attr (@name.def) node_definition = @name attr (@class.member_attrs) push_symbol = "." attr (@class.self_scope) is_exported - let @class.class_member_attr_scope = @class.member_attrs - let @class.class_parent_scope = @class.parent_scope - let @class.class_self_scope = @class.call_drop - let @class.class_super_scope = @class.super_scope +} + +(class_definition + body: (_) @body) @class +{ + let @body.class_member_attr_scope = @class.member_attrs + node @body.class_parent_scope + edge @body.class_parent_scope -> @class.class_parent_scope + edge @body.class_parent_scope -> @class.local_scope + let @body.class_self_scope = @class.call_drop + let @body.class_super_scope = @class.super_scope } (class_definition @@ -669,7 +673,7 @@ inherit .parent_module superclasses: (argument_list (_) @superclass)) @class { - edge @class.class_super_scope -> @superclass.output + edge @class.super_scope -> @superclass.output } (decorated_definition From dbfb1720f2347ba6afb38cab6c27402c2d10bca1 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Wed, 15 Nov 2023 12:40:08 +0100 Subject: [PATCH 44/60] Fix module start lines and do not expect definitions at assertion position --- .../test/aliased_imports.py | 2 +- .../tree-sitter-stack-graphs-python/test/imports.py | 10 +++++----- .../test/relative_imports.py | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/test/aliased_imports.py b/languages/tree-sitter-stack-graphs-python/test/aliased_imports.py index d988757a5..0373a33be 100644 --- a/languages/tree-sitter-stack-graphs-python/test/aliased_imports.py +++ b/languages/tree-sitter-stack-graphs-python/test/aliased_imports.py @@ -24,7 +24,7 @@ class D: # ^ defined: print f.B -# ^ defined: 2, 15 +# ^ defined: 3, 15 # ^ defined: 7 print foo diff --git a/languages/tree-sitter-stack-graphs-python/test/imports.py b/languages/tree-sitter-stack-graphs-python/test/imports.py index 2f21795da..96d561813 100644 --- a/languages/tree-sitter-stack-graphs-python/test/imports.py +++ b/languages/tree-sitter-stack-graphs-python/test/imports.py @@ -15,17 +15,17 @@ #------ path: main.py -------------# from one.two import d, e.c -# ^ defined: 2 -# ^ defined: 6, 17 -# ^ defined: 4, 8, 17 +# ^ defined: 3 +# ^ defined: 6 +# ^ defined: 4, 8 import three -# ^ defined: 11, 22 +# ^ defined: 12 print(d, e.c) # ^ defined: 6, 17 # ^ defined: 4, 17 print three.f -# ^ defined: 11, 22 +# ^ defined: 12, 22 # ^ defined: 13 diff --git a/languages/tree-sitter-stack-graphs-python/test/relative_imports.py b/languages/tree-sitter-stack-graphs-python/test/relative_imports.py index 2d6e14eb4..f14571575 100644 --- a/languages/tree-sitter-stack-graphs-python/test/relative_imports.py +++ b/languages/tree-sitter-stack-graphs-python/test/relative_imports.py @@ -6,7 +6,7 @@ from ..c.d import D print a.A -# ^ defined: 3, 24 +# ^ defined: 3, 25 # ^ defined: 26 print B.bee @@ -52,9 +52,9 @@ class D: # module from .g import G -# ^ defined: 49, 54 +# ^ defined: 49 from ..c import see -# ^ defined: 37, 57 +# ^ defined: 37 E = 1 From 2d8fd6bf0a9fd064782a8a4900d4b75276de9772 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Wed, 15 Nov 2023 12:47:47 +0100 Subject: [PATCH 45/60] Factor out identifier rules --- .../src/stack-graphs.tsg | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index d538431b0..80a0a2625 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -192,17 +192,13 @@ inherit .parent_module edge @stmt.after_scope -> @root_name.def attr (@stmt.after_scope -> @root_name.def) precedence = 1 edge @root_name.ref -> ROOT_NODE - attr (@root_name.ref) node_reference = @root_name - attr (@root_name.def) node_definition = @root_name } (import_statement name: (aliased_import - (dotted_name . (identifier) @root_name))) @stmt + (dotted_name . (identifier) @root_name))) { - edge @stmt.after_scope -> @root_name.def edge @root_name.ref -> ROOT_NODE - attr (@root_name.ref) node_reference = @root_name } (import_from_statement @@ -221,7 +217,6 @@ inherit .parent_module . (identifier) @import_root_name))) { edge @import_root_name.ref -> @import_root_name.ref_dot - attr (@import_root_name.ref) node_reference = @import_root_name attr (@import_root_name.ref_dot) push_symbol = "." } @@ -255,7 +250,6 @@ inherit .parent_module { edge @stmt.after_scope -> @alias.def edge @alias.def -> @name.ref - attr (@alias.def) node_definition = @alias } [ @@ -289,7 +283,6 @@ inherit .parent_module (dotted_name . (identifier) @name)) { - attr (@name.ref) node_reference = @name attr (@name.ref_dot) push_symbol = "." edge @name.ref -> @name.ref_dot edge @name.ref_dot -> @prefix.ref @@ -309,7 +302,6 @@ inherit .parent_module (identifier) @child_name)) ] { - attr (@child_name.ref) node_reference = @child_name attr (@child_name.ref_dot) push_symbol = "." edge @child_name.ref -> @child_name.ref_dot edge @child_name.ref_dot -> @parent_name.ref @@ -319,7 +311,6 @@ inherit .parent_module module_name: (dotted_name . (identifier) @root_name)) { - attr (@root_name.ref) node_reference = @root_name edge @root_name.ref -> ROOT_NODE } @@ -357,8 +348,6 @@ inherit .parent_module edge @child_name.ref_dot -> @parent_name.ref edge @parent_name.def -> @parent_name.def_dot edge @parent_name.def_dot -> @child_name.def - attr (@child_name.def) node_definition = @child_name - attr (@child_name.ref) node_reference = @child_name attr (@parent_name.def_dot) pop_symbol = "." attr (@child_name.ref_dot) push_symbol = "." } @@ -442,6 +431,10 @@ inherit .parent_module ; Definitions ;------------- +(identifier) @name { + attr (@name.def) node_definition = @name +} + [ (assignment left: (_) @pattern @@ -469,7 +462,6 @@ inherit .parent_module edge @body.before_scope -> @func.drop_scope edge @func.drop_scope -> @func.bottom attr (@func.drop_scope) type = "drop_scopes" - attr (@name.def) node_definition = @name attr (@func.call) pop_scoped_symbol = "()" edge @params.before_scope -> JUMP_TO_SCOPE_NODE attr (@func.return_value) is_exported @@ -574,7 +566,6 @@ inherit .parent_module value: (_) @value) @param ] { - attr (@name.def) node_definition = @name attr (@param.param_name) push_node = @name edge @name.def -> @param.param_name edge @name.def -> @param.param_index @@ -591,7 +582,6 @@ inherit .parent_module (_) @name) @param ] { - attr (@name.def) node_definition = @name attr (@param.param_name) push_node = @name edge @name.def -> @param.param_name edge @name.def -> @param.param_index @@ -646,7 +636,6 @@ inherit .parent_module attr (@class.call_drop) type = "drop_scopes" attr (@class.dot) pop_symbol = "." attr (@class.self_dot) pop_symbol = "." - attr (@name.def) node_definition = @name attr (@class.member_attrs) push_symbol = "." attr (@class.self_scope) is_exported } @@ -696,6 +685,10 @@ inherit .parent_module ; Expressions ;------------- +(identifier) @name { + attr (@name.ref) node_reference = @name +} + (call function: (_) @fn arguments: (argument_list) @args) @call From fd57fbd4b462d82889464984b1e9fdecd974f668 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Wed, 15 Nov 2023 13:07:03 +0100 Subject: [PATCH 46/60] Add bug test --- .../relative_import_resolves_to_itself.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 languages/tree-sitter-stack-graphs-python/test/bugs.skip/relative_import_resolves_to_itself.py diff --git a/languages/tree-sitter-stack-graphs-python/test/bugs.skip/relative_import_resolves_to_itself.py b/languages/tree-sitter-stack-graphs-python/test/bugs.skip/relative_import_resolves_to_itself.py new file mode 100644 index 000000000..838595ab7 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/bugs.skip/relative_import_resolves_to_itself.py @@ -0,0 +1,14 @@ +#--- path: a/__init__.py ---# +from . import b +# ^ defined: 6 + +#--- path: a/b/__init__.py ---# +B = 'b' + +#--- path: main.py ---# +from a import b +# ^ defined: 6 + +print b.B +# ^ defined: 9, 6 +# ^ defined: 6 \ No newline at end of file From 2f619fa3d72524bca0d7eb64db37596d01eed036 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Wed, 15 Nov 2023 13:10:20 +0100 Subject: [PATCH 47/60] Fix Python grammar versions --- languages/tree-sitter-stack-graphs-python/Cargo.toml | 2 +- tree-sitter-stack-graphs/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/Cargo.toml b/languages/tree-sitter-stack-graphs-python/Cargo.toml index 9270879c0..ca123cc0f 100644 --- a/languages/tree-sitter-stack-graphs-python/Cargo.toml +++ b/languages/tree-sitter-stack-graphs-python/Cargo.toml @@ -31,7 +31,7 @@ cli = ["anyhow", "clap", "tree-sitter-stack-graphs/cli"] anyhow = { version = "1.0", optional = true } clap = { version = "4", optional = true, features = ["derive"] } tree-sitter-stack-graphs = { version = "0.7", path = "../../tree-sitter-stack-graphs" } -tree-sitter-python = "0.20.2" +tree-sitter-python = "=0.20.2" [dev-dependencies] anyhow = "1.0" diff --git a/tree-sitter-stack-graphs/Cargo.toml b/tree-sitter-stack-graphs/Cargo.toml index 2de26a86f..d5429304a 100644 --- a/tree-sitter-stack-graphs/Cargo.toml +++ b/tree-sitter-stack-graphs/Cargo.toml @@ -82,4 +82,4 @@ walkdir = { version = "2.3", optional = true } [dev-dependencies] pretty_assertions = "0.7" -tree-sitter-python = "0.19.1" +tree-sitter-python = "=0.19.1" From aae723f0fdf97678224fe91c63542edbe9391054 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Wed, 15 Nov 2023 14:18:43 +0100 Subject: [PATCH 48/60] Remove obsolete nodes because of general identifier rules --- .../tree-sitter-stack-graphs-python/src/stack-graphs.tsg | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 80a0a2625..945428672 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -56,7 +56,6 @@ attribute node_symbol = node => symbol = (source-text node), source_n node @node.input_dot node @node.member_attrs node @node.members - node @node.new_binding_pop node @node.new_bindings node @node.new_bindings_pop node @node.output @@ -799,8 +798,7 @@ inherit .parent_module attr (@id.input) pop_node = @id attr (@id.output) node_reference = @id - attr (@id.new_binding_pop) node_definition = @id - edge @id.new_bindings -> @id.new_binding_pop + edge @id.new_bindings -> @id.def } (pattern/identifier) @id @@ -812,8 +810,7 @@ inherit .parent_module attr (@id.input) node_definition = @id attr (@id.output) push_node = @id - attr (@id.new_binding_pop) node_definition = @id - edge @id.new_bindings -> @id.new_binding_pop + edge @id.new_bindings -> @id.def } (as_pattern From 0b54f6c38a1c031a70c8bdc7aebea59608bd91fc Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Wed, 15 Nov 2023 14:30:28 +0100 Subject: [PATCH 49/60] Fix rule to make it similar to others --- languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 945428672..b1845109c 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -854,8 +854,7 @@ inherit .parent_module (list_splat (_) @splatted) @splat { -attr (@splat.new_bindings_pop) node_definition = @splatted -edge @splat.new_bindings -> @splat.new_bindings_pop + edge @splat.new_bindings -> @splatted.new_bindings } (binary_operator From a899983928d3a0be7bae4fcbfce86ae3b9204e6f Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Wed, 15 Nov 2023 16:45:48 +0100 Subject: [PATCH 50/60] Reuse general definition for parameters --- .../src/stack-graphs.tsg | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index b1845109c..f86683c8c 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -542,18 +542,18 @@ inherit .parent_module . (identifier) @param) body: (block) @body) { - edge @param.input -> @param.class_self_scope + edge @param.def -> @param.class_self_scope edge @param.class_member_attr_scope -> @param.output edge @param.output -> @body.after_scope attr (@param.output) push_node = @param } -(parameter/identifier) @param +(parameter/identifier) @param @name { - attr (@param.input) node_definition = @param attr (@param.param_name) push_node = @param - edge @param.input -> @param.param_index - edge @param.input -> @param.param_name + edge @name.def -> @param.param_name + edge @name.def -> @param.param_index + edge @param.input -> @name.def } [ From 1668eece08d779b5083e319687f65976d1eb27b2 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Wed, 15 Nov 2023 17:01:07 +0100 Subject: [PATCH 51/60] Lower .before_scope and .after_scope --- .../src/stack-graphs.tsg | 56 ++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index f86683c8c..588f7bcf4 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -39,9 +39,63 @@ attribute node_symbol = node => symbol = (source-text node), source_n ;; Nodes ;; ^^^^^ -(_)@node { +(module) @node { + node @node.after_scope + node @node.before_scope +} + +[ + ; _simple_statement + (future_import_statement) + (import_statement) + (import_from_statement) + (print_statement) + (assert_statement) + (expression_statement) + (return_statement) + (delete_statement) + (raise_statement) + (pass_statement) + (break_statement) + (continue_statement) + (global_statement) + (nonlocal_statement) + (exec_statement) + ; _compund_statement + (if_statement) + (for_statement) + (while_statement) + (try_statement) + (with_statement) + (function_definition) + (class_definition) + (decorated_definition) + (match_statement) + ; block + (block) + ; statement clauses + (elif_clause) + (else_clause) + (case_clause) + (except_clause) + (finally_clause) + (with_clause) +] @node { node @node.after_scope node @node.before_scope +} + +(parameters) @node { + node @node.after_scope + node @node.before_scope +} + +(comment) @node { + node @node.after_scope + node @node.before_scope +} + +(_)@node { node @node.call node @node.call_drop node @node.called From e1a0dcfe805205439b02d7df6258d8c0a1993eea Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Wed, 15 Nov 2023 17:06:15 +0100 Subject: [PATCH 52/60] Lower .input and .output --- .../src/stack-graphs.tsg | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 588f7bcf4..740f08233 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -90,9 +90,24 @@ attribute node_symbol = node => symbol = (source-text node), source_n node @node.before_scope } +[ + (identifier) + (expression) + (expression_list) + (primary_expression) + (pattern) + (pattern_list) + (parameter) +] @node { + node @node.input + node @node.output +} + (comment) @node { node @node.after_scope node @node.before_scope + node @node.input + node @node.output } (_)@node { @@ -106,13 +121,11 @@ attribute node_symbol = node => symbol = (source-text node), source_n node @node.el_index node @node.file_def node @node.file_ref - node @node.input node @node.input_dot node @node.member_attrs node @node.members node @node.new_bindings node @node.new_bindings_pop - node @node.output node @node.output_args node @node.output_dot node @node.param_index From 94365dcac5aed77022178c1038f393997a7b10e9 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Wed, 15 Nov 2023 17:13:25 +0100 Subject: [PATCH 53/60] Lower more nodes --- .../src/stack-graphs.tsg | 50 ++++++++++++------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 740f08233..424cb2349 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -92,6 +92,18 @@ attribute node_symbol = node => symbol = (source-text node), source_n [ (identifier) + (import_prefix) + (wildcard_import) +] @node { + node @node.def + node @node.def_dot + node @node.ref + node @node.ref_dot +} + +[ + (identifier) + (wildcard_import) (expression) (expression_list) (primary_expression) @@ -106,34 +118,30 @@ attribute node_symbol = node => symbol = (source-text node), source_n (comment) @node { node @node.after_scope node @node.before_scope + node @node.def + node @node.def_dot node @node.input node @node.output + node @node.ref + node @node.ref_dot } (_)@node { node @node.call node @node.call_drop node @node.called - node @node.def - node @node.def_dot node @node.dot node @node.drop_scope node @node.el_index - node @node.file_def - node @node.file_ref - node @node.input_dot node @node.member_attrs node @node.members node @node.new_bindings node @node.new_bindings_pop node @node.output_args - node @node.output_dot node @node.param_index node @node.param_name node @node.pattern_before_scope node @node.pattern_index - node @node.ref - node @node.ref_dot node @node.return_value node @node.self_dot node @node.self_scope @@ -160,12 +168,15 @@ inherit .parent_module (module) @mod { - var module_def = @mod.file_def + node mod_file_def + node mod_file_ref + + var module_def = mod_file_def node parent_module_def_node var parent_module_def = parent_module_def_node - var module_ref = @mod.file_ref + var module_ref = mod_file_ref node parent_module_ref_node var parent_module_ref = parent_module_ref_node @@ -222,8 +233,8 @@ inherit .parent_module } } - edge ROOT_NODE -> @mod.file_def - edge @mod.file_ref -> ROOT_NODE + edge ROOT_NODE -> mod_file_def + edge mod_file_ref -> ROOT_NODE edge module_def -> @mod.after_scope node global @@ -833,14 +844,17 @@ inherit .parent_module object: (_) @object attribute: (identifier) @name) @expr { + node input_dot + node output_dot + edge @expr.output -> @name.output - edge @name.output -> @expr.output_dot - edge @expr.output_dot -> @object.output - edge @object.input -> @expr.input_dot - edge @expr.input_dot -> @name.input + edge @name.output -> output_dot + edge output_dot -> @object.output + edge @object.input -> input_dot + edge input_dot -> @name.input edge @name.input -> @expr.input - attr (@expr.output_dot) push_symbol = "." - attr (@expr.input_dot) pop_symbol = "." + attr (output_dot) push_symbol = "." + attr (input_dot) pop_symbol = "." attr (@name.input) pop_node = @name attr (@name.output) push_node = @name } From bb0f034ed92ec2d082ad211a7b7333e41ebe0a3b Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Wed, 15 Nov 2023 17:34:48 +0100 Subject: [PATCH 54/60] Lower final set of nodes --- .../src/stack-graphs.tsg | 123 ++++++++++-------- 1 file changed, 68 insertions(+), 55 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 424cb2349..0028994c2 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -109,9 +109,16 @@ attribute node_symbol = node => symbol = (source-text node), source_n (primary_expression) (pattern) (pattern_list) + (case_pattern) (parameter) + (pair) + (list_splat) + (parenthesized_list_splat) + (dictionary_splat) + (keyword_argument) ] @node { node @node.input + node @node.new_bindings node @node.output } @@ -121,33 +128,12 @@ attribute node_symbol = node => symbol = (source-text node), source_n node @node.def node @node.def_dot node @node.input + node @node.new_bindings node @node.output node @node.ref node @node.ref_dot } -(_)@node { - node @node.call - node @node.call_drop - node @node.called - node @node.dot - node @node.drop_scope - node @node.el_index - node @node.member_attrs - node @node.members - node @node.new_bindings - node @node.new_bindings_pop - node @node.output_args - node @node.param_index - node @node.param_name - node @node.pattern_before_scope - node @node.pattern_index - node @node.return_value - node @node.self_dot - node @node.self_scope - node @node.super_scope -} - ;; Inherited Variables ;; ^^^^^^^^^^^^^^^^^^^ @@ -531,18 +517,22 @@ inherit .parent_module parameters: (parameters) @params body: (block) @body) @func { + node call + node drop_scope + node return_value + attr (@name.def) definiens_node = @func edge @func.after_scope -> @name.def - edge @name.def -> @func.call - edge @func.call -> @func.return_value + edge @name.def -> call + edge call -> return_value edge @body.before_scope -> @params.after_scope - edge @body.before_scope -> @func.drop_scope - edge @func.drop_scope -> @func.bottom - attr (@func.drop_scope) type = "drop_scopes" - attr (@func.call) pop_scoped_symbol = "()" + edge @body.before_scope -> drop_scope + edge drop_scope -> @func.bottom + attr (drop_scope) type = "drop_scopes" + attr (call) pop_scoped_symbol = "()" edge @params.before_scope -> JUMP_TO_SCOPE_NODE - attr (@func.return_value) is_exported - let @func.function_returns = @func.return_value + attr (return_value) is_exported + let @func.function_returns = return_value ; Prevent functions defined inside of method bodies from being treated like methods let @body.class_self_scope = #null @@ -670,19 +660,24 @@ inherit .parent_module (tuple_pattern (_) @pattern) ] @list { + node pattern_index + let statement_scope = @list.local_scope - let @pattern.local_scope = @pattern.pattern_before_scope + node @pattern.local_scope edge statement_scope -> @pattern.local_scope attr (statement_scope -> @pattern.local_scope) precedence = (plus 1 (named-child-index @pattern)) - edge @pattern.pattern_index -> @list.input - edge @pattern.input -> @pattern.pattern_index - attr (@pattern.pattern_index) push_symbol = (named-child-index @pattern) + edge pattern_index -> @list.input + edge @pattern.input -> pattern_index + attr (pattern_index) push_symbol = (named-child-index @pattern) } (parameters (_) @param) @params { + node @param.param_index + node @param.param_name + attr (@param.param_index) push_symbol = (named-child-index @param) edge @param.param_index -> @params.before_scope edge @params.after_scope -> @param.input @@ -694,27 +689,39 @@ inherit .parent_module edge @stmt.function_returns -> @expr.output } +(class_definition) @class { + node @class.call_drop + node @class.member_attrs + node @class.members + node @class.super_scope +} + (class_definition name: (identifier) @name) @class { + node call + node self_dot + node self_scope + node members_dot + attr (@name.def) definiens_node = @class attr (@name.def) syntax_type = "class" edge @class.after_scope -> @name.def - edge @name.def -> @class.call - edge @name.def -> @class.dot - edge @class.dot -> @class.members - edge @class.call -> @class.call_drop - edge @class.call_drop -> @class.self_scope - edge @class.self_scope -> @class.super_scope - edge @class.self_scope -> @class.self_dot - edge @class.self_dot -> @class.members + edge @name.def -> call + edge @name.def -> members_dot + edge members_dot -> @class.members + edge call -> @class.call_drop + edge @class.call_drop -> self_scope + edge self_scope -> @class.super_scope + edge self_scope -> self_dot + edge self_dot -> @class.members edge @class.members -> @class.member_attrs - attr (@class.call) pop_scoped_symbol = "()" + attr (call) pop_scoped_symbol = "()" attr (@class.call_drop) type = "drop_scopes" - attr (@class.dot) pop_symbol = "." - attr (@class.self_dot) pop_symbol = "." + attr (members_dot) pop_symbol = "." + attr (self_dot) pop_symbol = "." attr (@class.member_attrs) push_symbol = "." - attr (@class.self_scope) is_exported + attr (self_scope) is_exported } (class_definition @@ -770,9 +777,11 @@ inherit .parent_module function: (_) @fn arguments: (argument_list) @args) @call { - edge @call.output -> @call.output_args - edge @call.output_args -> @fn.output - attr (@call.output_args) push_scoped_symbol = "()", scope = @args.args + node output_args + + edge @call.output -> output_args + edge output_args -> @fn.output + attr (output_args) push_scoped_symbol = "()", scope = @args.args } (call @@ -833,9 +842,11 @@ inherit .parent_module (expression_list (_) @element) ] @tuple { - edge @tuple.output -> @element.el_index - attr (@element.el_index) pop_symbol = (named-child-index @element) - edge @element.el_index -> @element.output + node el_index + + edge @tuple.output -> el_index + attr (el_index) pop_symbol = (named-child-index @element) + edge el_index -> @element.output edge @tuple.new_bindings -> @element.new_bindings } @@ -907,9 +918,11 @@ inherit .parent_module (list) @list { - edge @list.output -> @list.called - edge @list.called -> @list.global_dot - attr (@list.called) push_symbol = "list" + node called + + edge @list.output -> called + edge called -> @list.global_dot + attr (called) push_symbol = "list" } (list (_) @el) @list From d15cb9b23403907611a093e82e84f4061a7e0c19 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 17 Nov 2023 12:15:55 +0100 Subject: [PATCH 55/60] Add tests --- .../relative_import_resolves_to_itself.py | 14 -------------- .../imports/import_from_module_a_submodule.py | 14 ++++++++++++++ .../test/imports/import_from_module_a_value.py | 13 +++++++++++++ .../import_from_module_a_value_aliased.py | 13 +++++++++++++ .../imports/import_from_module_wildcard.py | 13 +++++++++++++ .../imports/import_from_submodule_a_value.py | 16 ++++++++++++++++ .../import_from_super_package_a_value.py | 10 ++++++++++ ...ort_from_super_package_submodule_a_value.py | 10 ++++++++++ .../import_from_this_package_a_value.py | 10 ++++++++++ ...port_from_this_package_submodule_a_value.py | 10 ++++++++++ .../test/imports/import_module.py | 11 +++++++++++ .../test/imports/import_module_aliased.py | 14 ++++++++++++++ .../test/imports/import_submodule.py | 15 +++++++++++++++ .../imports/import_submodule_aliased.py.skip | 17 +++++++++++++++++ .../relative_import_resolves_to_itself.py.skip | 14 ++++++++++++++ .../require_explicit_submodule_import.py.skip | 18 ++++++++++++++++++ 16 files changed, 198 insertions(+), 14 deletions(-) delete mode 100644 languages/tree-sitter-stack-graphs-python/test/bugs.skip/relative_import_resolves_to_itself.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/imports/import_from_module_a_submodule.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/imports/import_from_module_a_value.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/imports/import_from_module_a_value_aliased.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/imports/import_from_module_wildcard.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/imports/import_from_submodule_a_value.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/imports/import_from_super_package_a_value.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/imports/import_from_super_package_submodule_a_value.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/imports/import_from_this_package_a_value.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/imports/import_from_this_package_submodule_a_value.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/imports/import_module.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/imports/import_module_aliased.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/imports/import_submodule.py create mode 100644 languages/tree-sitter-stack-graphs-python/test/imports/import_submodule_aliased.py.skip create mode 100644 languages/tree-sitter-stack-graphs-python/test/imports/relative_import_resolves_to_itself.py.skip create mode 100644 languages/tree-sitter-stack-graphs-python/test/imports/require_explicit_submodule_import.py.skip diff --git a/languages/tree-sitter-stack-graphs-python/test/bugs.skip/relative_import_resolves_to_itself.py b/languages/tree-sitter-stack-graphs-python/test/bugs.skip/relative_import_resolves_to_itself.py deleted file mode 100644 index 838595ab7..000000000 --- a/languages/tree-sitter-stack-graphs-python/test/bugs.skip/relative_import_resolves_to_itself.py +++ /dev/null @@ -1,14 +0,0 @@ -#--- path: a/__init__.py ---# -from . import b -# ^ defined: 6 - -#--- path: a/b/__init__.py ---# -B = 'b' - -#--- path: main.py ---# -from a import b -# ^ defined: 6 - -print b.B -# ^ defined: 9, 6 -# ^ defined: 6 \ No newline at end of file diff --git a/languages/tree-sitter-stack-graphs-python/test/imports/import_from_module_a_submodule.py b/languages/tree-sitter-stack-graphs-python/test/imports/import_from_module_a_submodule.py new file mode 100644 index 000000000..ea51f9450 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/imports/import_from_module_a_submodule.py @@ -0,0 +1,14 @@ +# --- path: foo/bar.py --- + +BAR = 42 + +# --- path: test.py --- + +from foo import bar + +bar.BAR +# ^ defined: 7, 3 +# ^ defined: 3 + +foo +# ^ defined: diff --git a/languages/tree-sitter-stack-graphs-python/test/imports/import_from_module_a_value.py b/languages/tree-sitter-stack-graphs-python/test/imports/import_from_module_a_value.py new file mode 100644 index 000000000..1eb97ffe2 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/imports/import_from_module_a_value.py @@ -0,0 +1,13 @@ +# --- path: foo.py --- + +FOO = 42 + +# --- path: test.py --- + +from foo import FOO + +FOO +# ^ defined: 7, 3 + +foo +# ^ defined: diff --git a/languages/tree-sitter-stack-graphs-python/test/imports/import_from_module_a_value_aliased.py b/languages/tree-sitter-stack-graphs-python/test/imports/import_from_module_a_value_aliased.py new file mode 100644 index 000000000..088ca9544 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/imports/import_from_module_a_value_aliased.py @@ -0,0 +1,13 @@ +# --- path: foo.py --- + +FOO = 42 + +# --- path: test.py --- + +from foo import FOO as QUX + +QUX +# ^ defined: 7, 3 + +FOO +# ^ defined: diff --git a/languages/tree-sitter-stack-graphs-python/test/imports/import_from_module_wildcard.py b/languages/tree-sitter-stack-graphs-python/test/imports/import_from_module_wildcard.py new file mode 100644 index 000000000..3a1de4ffe --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/imports/import_from_module_wildcard.py @@ -0,0 +1,13 @@ +# --- path: foo.py --- + +FOO = 42 + +# --- path: test.py --- + +from foo import * + +FOO +# ^ defined: 3 + +foo +# ^ defined: diff --git a/languages/tree-sitter-stack-graphs-python/test/imports/import_from_submodule_a_value.py b/languages/tree-sitter-stack-graphs-python/test/imports/import_from_submodule_a_value.py new file mode 100644 index 000000000..8d89d8538 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/imports/import_from_submodule_a_value.py @@ -0,0 +1,16 @@ +# --- path: foo/bar.py --- + +BAR = 42 + +# --- path: test.py --- + +from foo.bar import BAR + +BAR +# ^ defined: 7, 3 + +foo +# ^ defined: + +bar +# ^ defined: diff --git a/languages/tree-sitter-stack-graphs-python/test/imports/import_from_super_package_a_value.py b/languages/tree-sitter-stack-graphs-python/test/imports/import_from_super_package_a_value.py new file mode 100644 index 000000000..961cd1622 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/imports/import_from_super_package_a_value.py @@ -0,0 +1,10 @@ +# --- path: foo/__init__.py --- + +FOO = 42 + +# --- path: foo/bar/test.py --- + +from .. import FOO + +FOO +# ^ defined: 7, 3 diff --git a/languages/tree-sitter-stack-graphs-python/test/imports/import_from_super_package_submodule_a_value.py b/languages/tree-sitter-stack-graphs-python/test/imports/import_from_super_package_submodule_a_value.py new file mode 100644 index 000000000..75652f7cd --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/imports/import_from_super_package_submodule_a_value.py @@ -0,0 +1,10 @@ +# --- path: foo/bar.py --- + +BAR = 42 + +# --- path: foo/baz/test.py --- + +from ..bar import BAR + +BAR +# ^ defined: 7, 3 diff --git a/languages/tree-sitter-stack-graphs-python/test/imports/import_from_this_package_a_value.py b/languages/tree-sitter-stack-graphs-python/test/imports/import_from_this_package_a_value.py new file mode 100644 index 000000000..f8de8042c --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/imports/import_from_this_package_a_value.py @@ -0,0 +1,10 @@ +# --- path: foo/__init__.py --- + +FOO = 42 + +# --- path: foo/test.py --- + +from . import FOO + +FOO +# ^ defined: 7, 3 diff --git a/languages/tree-sitter-stack-graphs-python/test/imports/import_from_this_package_submodule_a_value.py b/languages/tree-sitter-stack-graphs-python/test/imports/import_from_this_package_submodule_a_value.py new file mode 100644 index 000000000..dc64ce387 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/imports/import_from_this_package_submodule_a_value.py @@ -0,0 +1,10 @@ +# --- path: foo/bar.py --- + +BAR = 42 + +# --- path: foo/test.py --- + +from .bar import BAR + +BAR +# ^ defined: 7, 3 diff --git a/languages/tree-sitter-stack-graphs-python/test/imports/import_module.py b/languages/tree-sitter-stack-graphs-python/test/imports/import_module.py new file mode 100644 index 000000000..897acdf63 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/imports/import_module.py @@ -0,0 +1,11 @@ +# --- path: foo.py --- + +FOO = 42 + +# --- path: test.py --- + +import foo + +foo.FOO +# ^ defined: 7, 3 +# ^ defined: 3 diff --git a/languages/tree-sitter-stack-graphs-python/test/imports/import_module_aliased.py b/languages/tree-sitter-stack-graphs-python/test/imports/import_module_aliased.py new file mode 100644 index 000000000..220a6b72d --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/imports/import_module_aliased.py @@ -0,0 +1,14 @@ +# --- path: foo.py --- + +FOO = 42 + +# --- path: test.py --- + +import foo as qux + +qux.FOO +# ^ defined: 7, 3 +# ^ defined: 3 + +foo +# ^ defined: diff --git a/languages/tree-sitter-stack-graphs-python/test/imports/import_submodule.py b/languages/tree-sitter-stack-graphs-python/test/imports/import_submodule.py new file mode 100644 index 000000000..312cd66a1 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/imports/import_submodule.py @@ -0,0 +1,15 @@ +# --- path: foo/bar.py --- + +BAR = 42 + +# --- path: test.py --- + +import foo.bar + +foo.bar.BAR +# ^ defined: 7 +# ^ defined: 7, 3 +# ^ defined: 3 + +bar +# ^ defined: diff --git a/languages/tree-sitter-stack-graphs-python/test/imports/import_submodule_aliased.py.skip b/languages/tree-sitter-stack-graphs-python/test/imports/import_submodule_aliased.py.skip new file mode 100644 index 000000000..dd84f39b5 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/imports/import_submodule_aliased.py.skip @@ -0,0 +1,17 @@ +# --- path: foo/bar.py --- + +BAR = 42 + +# --- path: test.py --- + +import foo.bar as qux + +qux.BAR +# ^ defined: 7 +# ^ defined: 3 + +foo +# ^ defined: + +bar +# ^ defined: diff --git a/languages/tree-sitter-stack-graphs-python/test/imports/relative_import_resolves_to_itself.py.skip b/languages/tree-sitter-stack-graphs-python/test/imports/relative_import_resolves_to_itself.py.skip new file mode 100644 index 000000000..2cdb2cf66 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/imports/relative_import_resolves_to_itself.py.skip @@ -0,0 +1,14 @@ +# --- path: foo/__init__.py --- +from . import bar +# ^ defined: 6 + +# --- path: foo/bar/__init__.py --- +BAR = 'b' + +# --- path: main.py --- +from foo import bar +# ^ defined: 6 + +bar.BAR +# ^ defined: 9, 6 +# ^ defined: 6 diff --git a/languages/tree-sitter-stack-graphs-python/test/imports/require_explicit_submodule_import.py.skip b/languages/tree-sitter-stack-graphs-python/test/imports/require_explicit_submodule_import.py.skip new file mode 100644 index 000000000..a9d12848c --- /dev/null +++ b/languages/tree-sitter-stack-graphs-python/test/imports/require_explicit_submodule_import.py.skip @@ -0,0 +1,18 @@ +# --- path: foo/__init__.py --- + +FOO = 42 + +# --- path: foo/bar.py --- + +BAR = 42 + +# --- path: test.py --- + +import foo + +foo.FOO +# ^ defined: 11, 3 +# ^ defined: 3 + +foo.bar +# ^ defined: From 34eba6ea3fc32f424c05d990634e318109d121b5 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 18 Jan 2024 15:13:42 +0100 Subject: [PATCH 56/60] Update README --- .../tree-sitter-stack-graphs-python/README.md | 100 ++++++++++++------ 1 file changed, 70 insertions(+), 30 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/README.md b/languages/tree-sitter-stack-graphs-python/README.md index 3bf115da0..b5fbc2f32 100644 --- a/languages/tree-sitter-stack-graphs-python/README.md +++ b/languages/tree-sitter-stack-graphs-python/README.md @@ -4,27 +4,73 @@ This project defines tree-sitter-stack-graphs rules for Python using the [tree-s [tree-sitter-python]: https://crates.io/crates/tree-sitter-python -## Usage +- [API documentation](https://docs.rs/tree-sitter-stack-graphs-python/) +- [Release notes](https://github.com/github/stack-graphs/blob/main/languages/tree-sitter-stack-graphs-python/CHANGELOG.md) + +## Using the API To use this library, add the following to your `Cargo.toml`: -``` toml +```toml [dependencies] tree-sitter-stack-graphs-python = "0.1.0" ``` Check out our [documentation](https://docs.rs/tree-sitter-stack-graphs-python/*/) for more details on how to use this library. -## Command-line Program +## Using the Command-line Program The command-line program for `tree-sitter-stack-graphs-python` lets you do stack graph based analysis and lookup from the command line. -Install the program using `cargo install` as follows: +The CLI can be run as follows: -``` sh -$ cargo install --features cli tree-sitter-stack-graphs-python -$ tree-sitter-stack-graphs-python --help -``` +1. _(Installed)_ Install the CLI using Cargo as follows: + + ```sh + cargo install --features cli tree-sitter-stack-graphs-python + ``` + + After this, the CLI should be available as `tree-sitter-stack-graphs-python`. + +2. _(From source)_ Instead of installing the CLI, it can also be run directly from the crate directory, as a replacement for a `tree-sitter-stack-graphs-python` invocation, as follows: + + ```sh + cargo run --features cli -- + ``` + +The basic CLI workflow for the command-line program is to index source code and issue queries against the resulting database: + +1. Index a source folder as follows: + + ```sh + tree-sitter-stack-graphs-python index SOURCE_DIR + ``` + + _Indexing will skip any files that have already be indexed. To force a re-index, add the `-f` flag._ + + To check the status if a source folder, run: + + ```sh + tree-sitter-stack-graphs-python status SOURCE_DIR + ``` + + To clean the database and start with a clean slate, run: + + ```sh + tree-sitter-stack-graphs-python clean + ``` + + _Pass the `--delete` flag to not just empty the database, but also delete it. This is useful to resolve `unsupported database version` errors that may occur after a version update._ + +2. Run a query to find the definition(s) for a reference on a given line and column, run: + + ```sh + tree-sitter-stack-graphs-python query definition SOURCE_PATH:LINE:COLUMN + ``` + + Resulting definitions are printed, including a source line if the source file is available. + +Discover all available commands and flags by passing the `-h` flag to the CLI directly, or to any of the subcommands. ## Development @@ -35,35 +81,29 @@ The project is written in Rust, and requires a recent version installed. Rust c The project is organized as follows: - The stack graph rules are defined in `src/stack-graphs.tsg`. -- Builtins sources and configuration are defined in `src/builtins.py` and `builtins.cfg` respectively. +- Builtins sources and configuration are defined in `src/builtins.it` and `builtins.cfg` respectively. - Tests are put into the `test` directory. -### Building and Running Tests - -Build the project by running: - -``` sh -$ cargo build -``` +### Running Tests Run the tests as follows: -``` sh -$ cargo test +```sh +cargo test ``` The project consists of a library and a CLI. By default, running `cargo` only applies to the library. To run `cargo` commands on the CLI as well, add `--features cli` or `--all-features`. Run the CLI from source as follows: -``` sh -$ cargo run --features cli -- ARGS +```sh +cargo run --features cli -- ARGS ``` Sources are formatted using the standard Rust formatted, which is applied by running: -``` sh -$ cargo fmt +```sh +cargo fmt ``` ### Writing TSG @@ -78,21 +118,21 @@ which contain self-contained TSG rules for specific language features. A VSCode Parse and test a single file by executing the following commands: -``` sh -$ cargo run --features cli -- parse FILES... -$ cargo run --features cli -- test TESTFILES... +```sh +cargo run --features cli -- parse FILES... +cargo run --features cli -- test TESTFILES... ``` Generate a visualization to debug failing tests by passing the `-V` flag: -``` sh -$ cargo run --features cli -- test -V TESTFILES... +```sh +cargo run --features cli -- test -V TESTFILES... ``` To generate the visualization regardless of test outcome, execute: -``` sh -$ cargo run --features cli -- test -V --output-mode=always TESTFILES... +```sh +cargo run --features cli -- test -V --output-mode=always TESTFILES... ``` -Go to https://crates.io/crates/tree-sitter-stack-graphs for links to examples and documentation. +Go to for links to examples and documentation. From c23f7ca23d354b08ba9b80adee5433f0f815513b Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 16 Nov 2023 12:33:46 +0100 Subject: [PATCH 57/60] Upgrade Python and reorganize rules according to syntax categories --- .../Cargo.toml | 2 +- .../src/stack-graphs.tsg | 726 ++++++++++++------ .../test/pattern_matching.py | 7 +- 3 files changed, 517 insertions(+), 218 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/Cargo.toml b/languages/tree-sitter-stack-graphs-python/Cargo.toml index ca123cc0f..4ac4c0633 100644 --- a/languages/tree-sitter-stack-graphs-python/Cargo.toml +++ b/languages/tree-sitter-stack-graphs-python/Cargo.toml @@ -31,7 +31,7 @@ cli = ["anyhow", "clap", "tree-sitter-stack-graphs/cli"] anyhow = { version = "1.0", optional = true } clap = { version = "4", optional = true, features = ["derive"] } tree-sitter-stack-graphs = { version = "0.7", path = "../../tree-sitter-stack-graphs" } -tree-sitter-python = "=0.20.2" +tree-sitter-python = "=0.20.4" [dev-dependencies] anyhow = "1.0" diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 0028994c2..00314b687 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -45,6 +45,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n } [ + ; _statement ; _simple_statement (future_import_statement) (import_statement) @@ -61,7 +62,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n (global_statement) (nonlocal_statement) (exec_statement) - ; _compund_statement + (type_alias_statement) + ; _compound_statement (if_statement) (for_statement) (while_statement) @@ -74,18 +76,23 @@ attribute node_symbol = node => symbol = (source-text node), source_n ; block (block) ; statement clauses + (if_clause) (elif_clause) (else_clause) - (case_clause) + (except_group_clause) (except_clause) (finally_clause) (with_clause) + (case_clause) ] @node { node @node.after_scope node @node.before_scope } -(parameters) @node { +[ + (parameters) + (lambda_parameters) +] @node { node @node.after_scope node @node.before_scope } @@ -102,20 +109,95 @@ attribute node_symbol = node => symbol = (source-text node), source_n } [ + ; expressions + (comparison_operator) + (not_operator) + (boolean_operator) + (lambda) + ;(primary_expression) ; unfolded below + (conditional_expression) + (named_expression) + (as_pattern) + ; primary_expression + (await) + (binary_operator) (identifier) - (wildcard_import) - (expression) + ;(keyword_identifier) ; invalid query pattern? + (string) + (concatenated_string) + (integer) + (float) + (true) + (false) + (none) + (unary_operator) + (attribute) + (subscript) + (call) + (list) + (list_comprehension) + (dictionary) + (dictionary_comprehension) + (set) + (set_comprehension) + (tuple) + (parenthesized_expression) + (generator_expression) + (ellipsis) + (list_splat) + + ; expression list (expression_list) - (primary_expression) - (pattern) - (pattern_list) + + ; pattern + (pattern/identifier) + ;(keyword_identifier) ; invalid query pattern? + ;(subscript) + ;(attribute) + (list_splat_pattern) + (tuple_pattern) + (list_pattern) + ; _simple_patterns + (class_pattern) + (splat_pattern) + (union_pattern) + ;(list_pattern) ; already in pattern + ;(tuple_pattern) ; already in pattern + (dict_pattern) + ;(string) ; already in primary_expression + ;(concatenated_string) ; already in primary_expression + ;(true) ; already in primary_expression + ;(false) ; already in primary_expression + ;(none) ; already in primary_expression + ;(integer) ; already in primary_expression + ;(float) ; already in primary_expression + (complex_pattern) + (dotted_name) + ; _as_attern + (as_pattern) + ; keyword pattern + (keyword_pattern) + ; case pattern (case_pattern) - (parameter) - (pair) - (list_splat) - (parenthesized_list_splat) - (dictionary_splat) - (keyword_argument) + ; with item + (with_item) + + ; pattern list + (pattern_list) + + ; parameter + ;(identifier) ; already in expressions + (typed_parameter) + (default_parameter) + (typed_default_parameter) + ;(list_splat_pattern) ; already in patterns + ;(tuple_pattern) ; already in patterns + (keyword_separator) + (positional_separator) + (dictionary_splat_pattern) + + ; parameters + (parameters) ] @node { node @node.input node @node.new_bindings @@ -149,8 +231,16 @@ inherit .grandparent_module inherit .local_scope inherit .parent_module -; Modules and Imports -;--------------------- +;; +;; # # +;; ## ## #### ##### # # # ###### #### +;; # # # # # # # # # # # # # +;; # # # # # # # # # # ##### #### +;; # # # # # # # # # # # +;; # # # # # # # # # # # # +;; # # #### ##### #### ###### ###### #### +;; +;; Modules (module) @mod { @@ -248,6 +338,18 @@ inherit .parent_module node @mod.local_scope } +;; +;; ### +;; # # # ##### #### ##### ##### #### +;; # ## ## # # # # # # # # +;; # # ## # # # # # # # # #### +;; # # # ##### # # ##### # # +;; # # # # # # # # # # # +;; ### # # # #### # # # #### +;; +;; Imports + +;; import _.X (import_statement name: (dotted_name . (identifier) @root_name)) @stmt @@ -257,6 +359,7 @@ inherit .parent_module edge @root_name.ref -> ROOT_NODE } +;; import _.X as _ (import_statement name: (aliased_import (dotted_name . (identifier) @root_name))) @@ -264,6 +367,7 @@ inherit .parent_module edge @root_name.ref -> ROOT_NODE } +;; from _ import _.X (import_from_statement name: (dotted_name . (identifier) @import_root_name)) @stmt @@ -274,6 +378,7 @@ inherit .parent_module attr (@import_root_name.ref_dot) push_symbol = "." } +;; from _ import _.X as _ (import_from_statement name: (aliased_import (dotted_name @@ -283,6 +388,11 @@ inherit .parent_module attr (@import_root_name.ref_dot) push_symbol = "." } +;; from X._ import _ +;; from ._.X import _ +;; from .._.X import _ +;; from . import _ +;; from .. import _ (import_from_statement module_name: [ (dotted_name (identifier) @prefix_leaf_name .) @@ -300,6 +410,8 @@ inherit .parent_module edge @import_root_name.ref_dot -> @prefix_leaf_name.ref } +;; from _ import _.X as Y +;; import _.X as Y [ (import_from_statement (aliased_import @@ -315,6 +427,8 @@ inherit .parent_module edge @alias.def -> @name.ref } +;; import _.X +;; from _ import _.X [ (import_statement name: (dotted_name @@ -327,6 +441,7 @@ inherit .parent_module edge @leaf_name.def -> @leaf_name.ref } +;; . (relative_import (import_prefix) @prefix (#eq? @prefix ".")) @import @@ -334,6 +449,7 @@ inherit .parent_module edge @prefix.ref -> @import.parent_module } +;; .. (relative_import (import_prefix) @prefix (#eq? @prefix "..")) @import @@ -341,6 +457,8 @@ inherit .parent_module edge @prefix.ref -> @import.grandparent_module } +;; .X +;; ..X (relative_import (import_prefix) @prefix (dotted_name @@ -351,6 +469,7 @@ inherit .parent_module edge @name.ref_dot -> @prefix.ref } +;; from . [ (import_from_statement module_name: (relative_import @@ -370,6 +489,7 @@ inherit .parent_module edge @child_name.ref_dot -> @parent_name.ref } +;; from X._ import _ (import_from_statement module_name: (dotted_name . (identifier) @root_name)) @@ -377,6 +497,7 @@ inherit .parent_module edge @root_name.ref -> ROOT_NODE } +;; from _.X import * (import_from_statement module_name: (dotted_name (identifier) @leaf_name .) @@ -388,6 +509,9 @@ inherit .parent_module attr (@star.ref_dot) push_symbol = "." } +;; import _.X.Y._ +;; from _ import _.X.Y._ +;; from _ import _.X.Y._ as _ [ (import_statement name: (dotted_name @@ -415,9 +539,16 @@ inherit .parent_module attr (@child_name.ref_dot) push_symbol = "." } -;-------- -; Scopes -;-------- +;; +;; ###### +;; # # # #### #### # # #### +;; # # # # # # # # # # +;; ###### # # # # #### #### +;; # # # # # # # # # +;; # # # # # # # # # # # +;; ###### ###### #### #### # # #### +;; +;; Blocks [ (module (_) @last_stmt .) @@ -475,7 +606,7 @@ inherit .parent_module edge @stmt.after_scope -> @block.after_scope } -(match_statement (case_clause) @block) @stmt +(match_statement body: (_) @block) @stmt { let @block.local_scope = @block.before_scope edge @block.before_scope -> @stmt.before_scope @@ -490,26 +621,77 @@ inherit .parent_module edge @stmt.before_scope -> @stmt.after_scope } -;------------- -; Definitions -;------------- +;; +;; ##### +;; # # ##### ## ##### ###### # # ###### # # ##### #### +;; # # # # # # ## ## # ## # # # +;; ##### # # # # ##### # ## # ##### # # # # #### +;; # # ###### # # # # # # # # # # +;; # # # # # # # # # # # ## # # # +;; ##### # # # # ###### # # ###### # # # #### +;; +;; Statements -(identifier) @name { - attr (@name.def) node_definition = @name -} +;;;; Simple Statements -[ - (assignment - left: (_) @pattern - right: (_) @value) - (with_item - value: - (as_pattern - (_) @value - alias: (as_pattern_target (_) @pattern))) -] +(print_statement) {} + +(assert_statement) {} + +(expression_statement) {} + +(return_statement (_) @expr) @stmt { - edge @pattern.input -> @value.output + edge @stmt.function_returns -> @expr.output +} + +(delete_statement) {} + +(raise_statement) {} + +(pass_statement) {} + +(break_statement) {} + +(continue_statement) {} + +(global_statement) {} + +(nonlocal_statement) {} + +(exec_statement) {} + +(type_alias_statement) {} + +;;;; Compound Statements + +(if_statement) {} + +(if_clause) {} + +(elif_clause) {} + +(else_clause) {} + +(for_statement) {} + +(while_statement) {} + +(try_statement) {} + +(except_group_clause) {} + +(except_clause) {} + +(finally_clause) {} + +(with_statement) {} + +(with_clause) {} + +(function_definition + name: (identifier) @name) { + attr (@name.def) node_definition = @name } (function_definition @@ -539,72 +721,6 @@ inherit .parent_module let @body.class_member_attr_scope = #null } -;; -;; BEGIN BIG GNARLY DISJUNCTION -;; -;; The following pair of rules is intended to capture the following behavior: -;; -;; If a function definition is used to define a method, by being inside a class -;; definition, then we make its syntax type `method`. Otherwise, we make it's -;; syntax type `function`. Unfortunately, because of the limitations on negation -;; and binding in tree sitter queries, we cannot negate `class_definition` or -;; similar things directly. Instead, we have to manually push the negation down -;; to form the finite disjunction it corresponds to. -;; - -[ - (class_definition (block (decorated_definition (function_definition name: (_)@name)))) - (class_definition (block (function_definition name: (_)@name))) -] -{ - attr (@name.def) syntax_type = "method" -} - -[ - (module (decorated_definition (function_definition name: (_)@name))) - (module (function_definition name: (_)@name)) - - (if_statement (block (decorated_definition (function_definition name: (_)@name)))) - (if_statement (block (function_definition name: (_)@name))) - - (elif_clause (block (decorated_definition (function_definition name: (_)@name)))) - (elif_clause (block (function_definition name: (_)@name))) - - (else_clause (block (decorated_definition (function_definition name: (_)@name)))) - (else_clause (block (function_definition name: (_)@name))) - - (case_clause (block (decorated_definition (function_definition name: (_)@name)))) - (case_clause (block (function_definition name: (_)@name))) - - (for_statement (block (decorated_definition (function_definition name: (_)@name)))) - (for_statement (block (function_definition name: (_)@name))) - - (while_statement (block (decorated_definition (function_definition name: (_)@name)))) - (while_statement (block (function_definition name: (_)@name))) - - (try_statement (block (decorated_definition (function_definition name: (_)@name)))) - (try_statement (block (function_definition name: (_)@name))) - - (except_clause (block (decorated_definition (function_definition name: (_)@name)))) - (except_clause (block (function_definition name: (_)@name))) - - (finally_clause (block (decorated_definition (function_definition name: (_)@name)))) - (finally_clause (block (function_definition name: (_)@name))) - - (with_statement (block (decorated_definition (function_definition name: (_)@name)))) - (with_statement (block (function_definition name: (_)@name))) - - (function_definition (block (decorated_definition (function_definition name: (_)@name)))) - (function_definition (block (function_definition name: (_)@name))) -] -{ - attr (@name.def) syntax_type = "function" -} - -;; -;; END BIG GNARLY DISJUNCTION -;; - (function_definition parameters: (parameters . (identifier) @param) @@ -616,6 +732,22 @@ inherit .parent_module attr (@param.output) push_node = @param } +(parameters + (_) @param) @params +{ + node @param.param_index + node @param.param_name + + attr (@param.param_index) push_symbol = (named-child-index @param) + edge @param.param_index -> @params.before_scope + edge @params.after_scope -> @param.input + edge @param.param_name -> @params.before_scope +} + +(parameter/identifier) @name { + attr (@name.def) node_definition = @name +} + (parameter/identifier) @param @name { attr (@param.param_name) push_node = @param @@ -655,40 +787,6 @@ inherit .parent_module edge @param.input -> @name.def } -[ - (pattern_list (_) @pattern) - (tuple_pattern (_) @pattern) -] @list -{ - node pattern_index - - let statement_scope = @list.local_scope - node @pattern.local_scope - edge statement_scope -> @pattern.local_scope - attr (statement_scope -> @pattern.local_scope) precedence = (plus 1 (named-child-index @pattern)) - - edge pattern_index -> @list.input - edge @pattern.input -> pattern_index - attr (pattern_index) push_symbol = (named-child-index @pattern) -} - -(parameters - (_) @param) @params -{ - node @param.param_index - node @param.param_name - - attr (@param.param_index) push_symbol = (named-child-index @param) - edge @param.param_index -> @params.before_scope - edge @params.after_scope -> @param.input - edge @param.param_name -> @params.before_scope -} - -(return_statement (_) @expr) @stmt -{ - edge @stmt.function_returns -> @expr.output -} - (class_definition) @class { node @class.call_drop node @class.member_attrs @@ -696,6 +794,11 @@ inherit .parent_module node @class.super_scope } +(class_definition + name: (identifier) @name) { + attr (@name.def) node_definition = @name +} + (class_definition name: (identifier) @name) @class { @@ -756,23 +859,107 @@ inherit .parent_module edge @stmt.after_scope -> @def.after_scope } +(match_statement) {} + (case_clause - pattern: (_) @pattern - consequence: (_) @consequence) @clause + (case_pattern) @pattern + consequence: (_) @consequence) { edge @consequence.before_scope -> @pattern.new_bindings +} + +(case_clause + consequence: (_) @consequence) @clause +{ edge @consequence.before_scope -> @clause.before_scope edge @clause.after_scope -> @consequence.after_scope } -;------------- -; Expressions -;------------- +;; +;; ####### +;; # # # ##### ##### ###### #### #### # #### # # #### +;; # # # # # # # # # # # # # ## # # +;; ##### ## # # # # ##### #### #### # # # # # # #### +;; # ## ##### ##### # # # # # # # # # # +;; # # # # # # # # # # # # # # # ## # # +;; ####### # # # # # ###### #### #### # #### # # #### +;; +;; Expressions + +(conditional_expression) {} + +(named_expression) {} + +(as_pattern) {} + +(await) {} + +(binary_operator + (_) @left + (_) @right) @binop +{ + edge @binop.new_bindings -> @left.new_bindings + edge @binop.new_bindings -> @right.new_bindings +} -(identifier) @name { +(primary_expression/identifier) @name { attr (@name.ref) node_reference = @name } +(primary_expression/identifier) @name +{ + edge @name.output -> @name.local_scope + edge @name.output -> @name.class_parent_scope + edge @name.local_scope -> @name.input + attr (@name.input) pop_node = @name + attr (@name.output) node_reference = @name + + edge @name.new_bindings -> @name.def +} + +(string) {} + +(concatenated_string) {} + +(integer) {} + +(float) {} + +(true) {} + +(false) {} + +(none) {} + +(unary_operator) {} + +(attribute + object: (_) @object + attribute: (identifier) @name) @expr +{ + node input_dot + node output_dot + + edge @expr.output -> @name.output + edge @name.output -> output_dot + edge output_dot -> @object.output + edge @object.input -> input_dot + edge input_dot -> @name.input + edge @name.input -> @expr.input + attr (output_dot) push_symbol = "." + attr (input_dot) pop_symbol = "." + attr (@name.input) pop_node = @name + attr (@name.output) push_node = @name +} + +(primary_expression/attribute + attribute: (identifier) @name) +{ + attr (@name.output) is_reference +} + +(subscript) {} + (call function: (_) @fn arguments: (argument_list) @args) @call @@ -837,6 +1024,42 @@ inherit .parent_module edge @call.output -> @call.class_super_scope } +(list) @list +{ + node called + + edge @list.output -> called + edge called -> @list.global_dot + attr (called) push_symbol = "list" +} + +(list (_) @el) @list +{ + edge @list.new_bindings -> @el.new_bindings +} + +(list_comprehension) {} + +(dictionary (pair) @pair) @dict +{ + edge @dict.new_bindings -> @pair.new_bindings +} + +(pair + value: (_) @value) @pair +{ + edge @pair.new_bindings -> @value.new_bindings +} + +(dictionary_comprehension) {} + +(set (_) @el) @set +{ + edge @set.new_bindings -> @el.new_bindings +} + +(set_comprehension) {} + [ (tuple (_) @element) (expression_list (_) @element) @@ -851,115 +1074,188 @@ inherit .parent_module edge @tuple.new_bindings -> @element.new_bindings } -(attribute - object: (_) @object - attribute: (identifier) @name) @expr +(parenthesized_expression) {} + +(generator_expression) {} + +(ellipsis) {} + +(list_splat (_) @splatted) @splat { - node input_dot - node output_dot + edge @splat.new_bindings -> @splatted.new_bindings +} - edge @expr.output -> @name.output - edge @name.output -> output_dot - edge output_dot -> @object.output - edge @object.input -> input_dot - edge input_dot -> @name.input - edge @name.input -> @expr.input - attr (output_dot) push_symbol = "." - attr (input_dot) pop_symbol = "." - attr (@name.input) pop_node = @name +;; +;; ###### +;; # # ## ##### ##### ###### ##### # # #### +;; # # # # # # # # # ## # # +;; ###### # # # # ##### # # # # # #### +;; # ###### # # # ##### # # # # +;; # # # # # # # # # ## # # +;; # # # # # ###### # # # # #### +;; +;; Patterns + +(pattern/identifier) @name { + attr (@name.def) node_definition = @name +} + +(pattern/identifier) @name +{ + edge @name.output -> @name.local_scope + edge @name.output -> @name.class_parent_scope + edge @name.local_scope -> @name.input + attr (@name.local_scope -> @name.input) precedence = 1 + attr (@name.input) node_definition = @name attr (@name.output) push_node = @name + + edge @name.new_bindings -> @name.def } +(pattern/subscript) {} + (pattern/attribute attribute: (identifier) @name) { attr (@name.input) is_definition } -(primary_expression/attribute - attribute: (identifier) @name) -{ - attr (@name.output) is_reference -} -(primary_expression/identifier) @id +(list_splat_pattern) {} + +[ + (pattern_list (_) @pattern) + (tuple_pattern (_) @pattern) + (list_pattern (_) @pattern) +] @list { - edge @id.output -> @id.local_scope - edge @id.output -> @id.class_parent_scope - edge @id.local_scope -> @id.input - attr (@id.input) pop_node = @id - attr (@id.output) node_reference = @id + node pattern_index - edge @id.new_bindings -> @id.def + let statement_scope = @list.local_scope + node @pattern.local_scope + edge statement_scope -> @pattern.local_scope + attr (statement_scope -> @pattern.local_scope) precedence = (plus 1 (named-child-index @pattern)) + + edge pattern_index -> @list.input + edge @pattern.input -> pattern_index + attr (pattern_index) push_symbol = (named-child-index @pattern) } -(pattern/identifier) @id -{ - edge @id.output -> @id.local_scope - edge @id.output -> @id.class_parent_scope - edge @id.local_scope -> @id.input - attr (@id.local_scope -> @id.input) precedence = 1 - attr (@id.input) node_definition = @id - attr (@id.output) push_node = @id +(class_pattern) {} - edge @id.new_bindings -> @id.def -} +(splat_pattern) {} + +(union_pattern) {} + +(dict_pattern) {} + +(complex_pattern) {} (as_pattern (expression) @value - alias: (as_pattern_target (primary_expression/identifier) @id)) @as_pattern + alias: (as_pattern_target (primary_expression/identifier) @name)) @as_pattern { - attr (@id.local_scope -> @id.input) precedence = 1 - attr (@id.input) is_definition + attr (@name.local_scope -> @name.input) precedence = 1 + attr (@name.input) is_definition edge @as_pattern.new_bindings -> @value.new_bindings - edge @as_pattern.new_bindings -> @id.new_bindings + edge @as_pattern.new_bindings -> @name.new_bindings } -(list) @list -{ - node called - - edge @list.output -> called - edge called -> @list.global_dot - attr (called) push_symbol = "list" -} +(keyword_pattern) {} -(list (_) @el) @list +(case_pattern (_) @expr) @pat { - edge @list.new_bindings -> @el.new_bindings + edge @pat.new_bindings -> @expr.new_bindings } -(dictionary (pair) @pair) @dict +[ + (assignment + left: (_) @pattern + right: (_) @value) + (with_item + value: + (as_pattern + (_) @value + alias: (as_pattern_target (_) @pattern))) +] { - edge @dict.new_bindings -> @pair.new_bindings + edge @pattern.input -> @value.output } -(pair - value: (_) @value) @pair -{ - edge @pair.new_bindings -> @value.new_bindings -} +;; +;; ##### ####### +;; # # # # # # ##### ## # # # # # ##### ###### #### +;; # # # ## # # # # # # # # # # # # # +;; ##### # # # # # # # ## # # # # ##### #### +;; # # # # # # ###### ## # # ##### # # +;; # # # # ## # # # # # # # # # # # +;; ##### # # # # # # # # # # # ###### #### +;; +;; Syntax Types -(set (_) @el) @set -{ - edge @set.new_bindings -> @el.new_bindings -} +;; +;; BEGIN BIG GNARLY DISJUNCTION +;; +;; The following pair of rules is intended to capture the following behavior: +;; +;; If a function definition is used to define a method, by being inside a class +;; definition, then we make its syntax type `method`. Otherwise, we make it's +;; syntax type `function`. Unfortunately, because of the limitations on negation +;; and binding in tree sitter queries, we cannot negate `class_definition` or +;; similar things directly. Instead, we have to manually push the negation down +;; to form the finite disjunction it corresponds to. +;; -(list_splat (_) @splatted) @splat +[ + (class_definition (block (decorated_definition (function_definition name: (_)@name)))) + (class_definition (block (function_definition name: (_)@name))) +] { - edge @splat.new_bindings -> @splatted.new_bindings + attr (@name.def) syntax_type = "method" } -(binary_operator - (_) @left - (_) @right) @binop -{ - edge @binop.new_bindings -> @left.new_bindings - edge @binop.new_bindings -> @right.new_bindings -} +[ + (module (decorated_definition (function_definition name: (_)@name))) + (module (function_definition name: (_)@name)) -(case_pattern (_) @expr) @pat + (if_statement (block (decorated_definition (function_definition name: (_)@name)))) + (if_statement (block (function_definition name: (_)@name))) + + (elif_clause (block (decorated_definition (function_definition name: (_)@name)))) + (elif_clause (block (function_definition name: (_)@name))) + + (else_clause (block (decorated_definition (function_definition name: (_)@name)))) + (else_clause (block (function_definition name: (_)@name))) + + (case_clause (block (decorated_definition (function_definition name: (_)@name)))) + (case_clause (block (function_definition name: (_)@name))) + + (for_statement (block (decorated_definition (function_definition name: (_)@name)))) + (for_statement (block (function_definition name: (_)@name))) + + (while_statement (block (decorated_definition (function_definition name: (_)@name)))) + (while_statement (block (function_definition name: (_)@name))) + + (try_statement (block (decorated_definition (function_definition name: (_)@name)))) + (try_statement (block (function_definition name: (_)@name))) + + (except_clause (block (decorated_definition (function_definition name: (_)@name)))) + (except_clause (block (function_definition name: (_)@name))) + + (finally_clause (block (decorated_definition (function_definition name: (_)@name)))) + (finally_clause (block (function_definition name: (_)@name))) + + (with_statement (block (decorated_definition (function_definition name: (_)@name)))) + (with_statement (block (function_definition name: (_)@name))) + + (function_definition (block (decorated_definition (function_definition name: (_)@name)))) + (function_definition (block (function_definition name: (_)@name))) +] { - edge @pat.new_bindings -> @expr.new_bindings + attr (@name.def) syntax_type = "function" } + +;; +;; END BIG GNARLY DISJUNCTION +;; diff --git a/languages/tree-sitter-stack-graphs-python/test/pattern_matching.py b/languages/tree-sitter-stack-graphs-python/test/pattern_matching.py index 58c0d16fc..d6b8980a3 100644 --- a/languages/tree-sitter-stack-graphs-python/test/pattern_matching.py +++ b/languages/tree-sitter-stack-graphs-python/test/pattern_matching.py @@ -21,11 +21,11 @@ case { "foo": foo }: print(foo) # ^ defined: 21 - case {bar,quux}: + case {"bar": bar, "quux": quux}: print(bar,quux) # ^ defined: 24 # ^ defined: 24 - case ["grab", { "key": {garply}}]: + case ["grab", { "key": {"garply": garply}}]: print(garply) # ^ defined: 28 case ["drop", *objs]: @@ -37,3 +37,6 @@ case ["go", ("north" | "south" | "east" | "west") as direction2]: current_room = current_room.neighbor(direction2) # ^ defined: 37 + case (foo, "bar"): + print(foo) + # ^ defined: 40 From 41c8f32fa628c86dfdd76e75a3f9debac65c4d0a Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 17 Nov 2023 19:09:37 +0100 Subject: [PATCH 58/60] Reorganize imports --- .../src/stack-graphs.tsg | 393 ++++++++++-------- ...ed.py.skip => import_submodule_aliased.py} | 2 +- 2 files changed, 232 insertions(+), 163 deletions(-) rename languages/tree-sitter-stack-graphs-python/test/imports/{import_submodule_aliased.py.skip => import_submodule_aliased.py} (89%) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 00314b687..2c8c1e847 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -99,8 +99,6 @@ attribute node_symbol = node => symbol = (source-text node), source_n [ (identifier) - (import_prefix) - (wildcard_import) ] @node { node @node.def node @node.def_dot @@ -108,6 +106,19 @@ attribute node_symbol = node => symbol = (source-text node), source_n node @node.ref_dot } +[ + (dotted_name) + (aliased_import) + (relative_import) + (wildcard_import) + (import_prefix) +] @node { + node @node.after_scope + node @node.before_scope + node @node.def + node @node.ref +} + [ ; expressions (comparison_operator) @@ -349,194 +360,252 @@ inherit .parent_module ;; ;; Imports -;; import _.X -(import_statement - name: (dotted_name - . (identifier) @root_name)) @stmt -{ - edge @stmt.after_scope -> @root_name.def - attr (@stmt.after_scope -> @root_name.def) precedence = 1 - edge @root_name.ref -> ROOT_NODE +;; Import References +;; ^^^^^^^^^^^^^^^^^ + +;;;; Dotted Names +;; +;; (dotted_name).ref node to connect to to use the reference +;; (dotted_name).before_scope node to connect from to ensure the reference resolves + +;; all names are references +[ + (import_statement name: (dotted_name (identifier) @name)) + (future_import_statement name: (dotted_name (identifier) @name)) + (import_from_statement name: (dotted_name (identifier) @name)) + (import_statement name: (aliased_import name: (dotted_name (identifier) @name))) + (future_import_statement name: (aliased_import name: (dotted_name (identifier) @name))) + (import_from_statement name: (aliased_import name: (dotted_name (identifier) @name))) + (import_from_statement module_name: (dotted_name (identifier) @name)) + (import_from_statement module_name: (relative_import (dotted_name (identifier) @name))) +] { + attr (@name.ref) node_reference = @name } -;; import _.X as _ -(import_statement - name: (aliased_import - (dotted_name . (identifier) @root_name))) -{ - edge @root_name.ref -> ROOT_NODE +;; references are chained +[ + (import_statement name: (dotted_name (identifier) @left . (identifier) @right)) + (future_import_statement name: (dotted_name (identifier) @left . (identifier) @right)) + (import_from_statement name: (dotted_name (identifier) @left . (identifier) @right)) + (import_statement name: (aliased_import name: (dotted_name (identifier) @left . (identifier) @right))) + (future_import_statement name: (aliased_import name: (dotted_name (identifier) @left . (identifier) @right))) + (import_from_statement name: (aliased_import name: (dotted_name (identifier) @left . (identifier) @right))) + (import_from_statement module_name: (dotted_name (identifier) @left . (identifier) @right)) + (import_from_statement module_name: (relative_import (dotted_name (identifier) @left . (identifier) @right))) +] { + node push_dot + attr (push_dot) push_symbol = "." + + edge @right.ref -> push_dot + edge push_dot -> @left.ref +} + +;; lookup first reference +[ + (import_statement name: (dotted_name . (identifier) @first) @dotted) + (future_import_statement name: (dotted_name . (identifier) @first) @dotted) + (import_from_statement name: (dotted_name . (identifier) @first) @dotted) + (import_statement name: (aliased_import name: (dotted_name . (identifier) @first) @dotted)) + (future_import_statement name: (aliased_import name: (dotted_name . (identifier) @first) @dotted)) + (import_from_statement name: (aliased_import name: (dotted_name . (identifier) @first) @dotted)) + (import_from_statement module_name: (dotted_name . (identifier) @first) @dotted) + (import_from_statement module_name: (relative_import (dotted_name . (identifier) @first) @dotted)) +] { + edge @first.ref -> @dotted.before_scope +} + +;; expose last reference +[ + (import_statement name: (dotted_name (identifier) @last .) @dotted) + (future_import_statement name: (dotted_name (identifier) @last .) @dotted) + (import_from_statement name: (dotted_name (identifier) @last .) @dotted) + (import_statement name: (aliased_import name: (dotted_name (identifier) @last .) @dotted)) + (future_import_statement name: (aliased_import name: (dotted_name (identifier) @last .) @dotted)) + (import_from_statement name: (aliased_import name: (dotted_name (identifier) @last .) @dotted)) + (import_from_statement module_name: (dotted_name (identifier) @last .) @dotted) + (import_from_statement module_name: (relative_import (dotted_name (identifier) @last .) @dotted)) +] { + edge @dotted.ref -> @last.ref +} + +;;;; Aliased Import +;; +;; An aliased import behaves like its wrapped dotted_name as a reference +;; +;; (aliased_import).ref node to connect to, to use the reference +;; (aliased_import).before_scope node to connect from to ensure the reference resolves + +(aliased_import name: (dotted_name) @dotted) @aliased { + edge @aliased.ref -> @dotted.ref + edge @dotted.before_scope -> @aliased.before_scope } -;; from _ import _.X -(import_from_statement - name: (dotted_name - . (identifier) @import_root_name)) @stmt -{ - edge @stmt.after_scope -> @import_root_name.def - attr (@stmt.after_scope -> @import_root_name.def) precedence = 1 - edge @import_root_name.ref -> @import_root_name.ref_dot - attr (@import_root_name.ref_dot) push_symbol = "." +;;;; Relative Import +;; +;; A relative import behaves like its wrapped dotted_name as a reference +;; +;; (relative_import).ref node to connect to, to use the reference +;; (relative_import).before_scope node to connect from to ensure the reference resolves + +(relative_import (import_prefix) . (dotted_name) @dotted) @relative { + edge @relative.ref -> @dotted.ref + + node push_dot + attr (push_dot) push_symbol = "." + + edge @dotted.before_scope -> push_dot + edge push_dot -> @relative.before_scope } -;; from _ import _.X as _ -(import_from_statement - name: (aliased_import - (dotted_name - . (identifier) @import_root_name))) -{ - edge @import_root_name.ref -> @import_root_name.ref_dot - attr (@import_root_name.ref_dot) push_symbol = "." -} - -;; from X._ import _ -;; from ._.X import _ -;; from .._.X import _ -;; from . import _ -;; from .. import _ -(import_from_statement - module_name: [ - (dotted_name (identifier) @prefix_leaf_name .) - (relative_import (dotted_name (identifier) @prefix_leaf_name .)) - (relative_import (import_prefix) @prefix_leaf_name .) - ] - name: [ - (dotted_name - . (identifier) @import_root_name) - (aliased_import - (dotted_name - . (identifier) @import_root_name)) - ]) -{ - edge @import_root_name.ref_dot -> @prefix_leaf_name.ref +(relative_import (import_prefix) .) @relative { + edge @relative.ref -> @relative.before_scope +} + +;;;; Wildcard Import +;; +;; A wildcard import simply passes through +;; +;; (wildcard_import).ref node to connect to, to use the reference +;; (wildcard_import).before_scope node to connect from to ensure the reference resolves + +(wildcard_import) @wildcard { + edge @wildcard.ref -> @wildcard.before_scope } -;; from _ import _.X as Y -;; import _.X as Y +;;;; Import from +;; +;; The imported references are resolved in the from module + [ - (import_from_statement - (aliased_import - name: (dotted_name (identifier) @name .) - alias: (identifier) @alias)) - (import_statement - (aliased_import - name: (dotted_name (identifier) @name .) - alias: (identifier) @alias)) -] @stmt -{ - edge @stmt.after_scope -> @alias.def - edge @alias.def -> @name.ref + (import_from_statement module_name: (_) @left name: (_) @right) + (import_from_statement module_name: (_) @left (wildcard_import) @right) +] { + node push_dot + attr (push_dot) push_symbol = "." + + edge @right.before_scope -> push_dot + edge push_dot -> @left.ref } -;; import _.X -;; from _ import _.X +;;;; Non-relative Imports +;; +;; Non-relative imports are resolved in the root scope + [ - (import_statement - name: (dotted_name - (identifier) @leaf_name .)) - (import_from_statement - name: (dotted_name - (identifier) @leaf_name .)) -] -{ - edge @leaf_name.def -> @leaf_name.ref + (import_statement name: (_) @name) + (import_from_statement module_name: (dotted_name) @name) +] { + edge @name.before_scope -> ROOT_NODE } -;; . -(relative_import - (import_prefix) @prefix - (#eq? @prefix ".")) @import -{ - edge @prefix.ref -> @import.parent_module +;;;; Relative Imports +;; +;; Relative imports are resolved in scopes related to the current module + +;; . imports resolve in parent module scope +(import_from_statement module_name: (relative_import (import_prefix) @prefix (#eq? @prefix ".")) @relative) { + edge @relative.before_scope -> @prefix.parent_module } -;; .. -(relative_import - (import_prefix) @prefix - (#eq? @prefix "..")) @import -{ - edge @prefix.ref -> @import.grandparent_module +;; .. imports resolve in grandparent module scope +(import_from_statement module_name: (relative_import (import_prefix) @prefix (#eq? @prefix "..")) @relative) { + edge @relative.before_scope -> @prefix.grandparent_module } -;; .X -;; ..X -(relative_import - (import_prefix) @prefix - (dotted_name - . (identifier) @name)) -{ - attr (@name.ref_dot) push_symbol = "." - edge @name.ref -> @name.ref_dot - edge @name.ref_dot -> @prefix.ref +;;;; Future Imports +;; +;; We don't know the future, so we cannot connect references of future imports anywhere. Maybe one day? + +;; Import Definitions +;; ^^^^^^^^^^^^^^^^^^ + +;;;; Dotted Names & Aliased Imports +;; +;; (dotted_name).after_scope node to connect to, to expose the definition +;; (dotted_name).def node to connect from, to give definition content + +;; unaliased names and aliases are definitions +[ + (import_statement name: (dotted_name (identifier) @name)) + (future_import_statement name: (dotted_name (identifier) @name)) + (import_from_statement name: (dotted_name (identifier) @name)) + (import_statement name: (aliased_import alias: (identifier) @name)) + (future_import_statement name: (aliased_import alias: (identifier) @name)) + (import_from_statement name: (aliased_import alias: (identifier) @name)) +] { + attr (@name.def) node_definition = @name } -;; from . +;; definitions are chained [ - (import_from_statement - module_name: (relative_import - (dotted_name - (identifier) @parent_name - . - (identifier) @child_name))) - (import_from_statement - module_name: (dotted_name - (identifier) @parent_name - . - (identifier) @child_name)) -] -{ - attr (@child_name.ref_dot) push_symbol = "." - edge @child_name.ref -> @child_name.ref_dot - edge @child_name.ref_dot -> @parent_name.ref + (import_statement name: (dotted_name (identifier) @left . (identifier) @right)) + (future_import_statement name: (dotted_name (identifier) @left . (identifier) @right)) + (import_from_statement name: (dotted_name (identifier) @left . (identifier) @right)) +] { + node pop_dot + attr (pop_dot) pop_symbol = "." + + edge @left.def -> pop_dot + edge pop_dot -> @right.def } -;; from X._ import _ -(import_from_statement - module_name: (dotted_name - . (identifier) @root_name)) -{ - edge @root_name.ref -> ROOT_NODE +;; connect last definition +[ + (import_statement name: (dotted_name (identifier) @last .) @outer) + (future_import_statement name: (dotted_name (identifier) @last .) @outer) + (import_from_statement name: (dotted_name (identifier) @last .) @outer) + (import_statement name: (aliased_import alias: (identifier) @last ) @outer) + (future_import_statement name: (aliased_import alias: (identifier) @last ) @outer) + (import_from_statement name: (aliased_import alias: (identifier) @last ) @outer) +] { + edge @last.def -> @outer.def } -;; from _.X import * -(import_from_statement - module_name: (dotted_name - (identifier) @leaf_name .) - (wildcard_import) @star) @stmt -{ - edge @stmt.after_scope -> @star.ref_dot - attr (@stmt.after_scope -> @star.ref_dot) precedence = 1 - edge @star.ref_dot -> @leaf_name.ref - attr (@star.ref_dot) push_symbol = "." +;; expose first definition +[ + (import_statement name: (dotted_name . (identifier) @first) @outer) + (future_import_statement name: (dotted_name . (identifier) @first) @outer) + (import_from_statement name: (dotted_name . (identifier) @first) @outer) + (import_statement name: (aliased_import alias: (identifier) @first ) @outer) + (future_import_statement name: (aliased_import alias: (identifier) @first ) @outer) + (import_from_statement name: (aliased_import alias: (identifier) @first ) @outer) +] { + edge @outer.after_scope -> @first.def +} + +;;;; Wildcard Import +;; +;; Wildcard imports simply pass through + +(wildcard_import) @wildcard { + edge @wildcard.after_scope -> @wildcard.def } -;; import _.X.Y._ -;; from _ import _.X.Y._ -;; from _ import _.X.Y._ as _ +;;;; Import Definitions -> References +;; +;; The definitions introduced by imports are connected to the corresponding references + [ - (import_statement - name: (dotted_name - (identifier) @parent_name - . - (identifier) @child_name)) - (import_from_statement - name: (dotted_name - (identifier) @parent_name - . - (identifier) @child_name)) - (import_from_statement - name: (aliased_import - name: (dotted_name - (identifier) @parent_name - . - (identifier) @child_name))) -] -{ - edge @child_name.ref -> @child_name.ref_dot - edge @child_name.ref_dot -> @parent_name.ref - edge @parent_name.def -> @parent_name.def_dot - edge @parent_name.def_dot -> @child_name.def - attr (@parent_name.def_dot) pop_symbol = "." - attr (@child_name.ref_dot) push_symbol = "." + (import_statement name: (_) @name) + (future_import_statement name: (_) @name) + (import_from_statement name: (_) @name) + (import_from_statement (wildcard_import) @name) +] { + edge @name.def -> @name.ref +} + +;;;; Imports +;; +;; The definitions introduced by imports are visible after the import statement + +[ + (import_statement name: (_) @name) + (future_import_statement name: (_) @name) + (import_from_statement name: (_) @name) + (import_from_statement (wildcard_import) @name) +] @stmt { + edge @stmt.after_scope -> @name.after_scope + attr (@stmt.after_scope -> @name.after_scope) precedence = 1 } ;; diff --git a/languages/tree-sitter-stack-graphs-python/test/imports/import_submodule_aliased.py.skip b/languages/tree-sitter-stack-graphs-python/test/imports/import_submodule_aliased.py similarity index 89% rename from languages/tree-sitter-stack-graphs-python/test/imports/import_submodule_aliased.py.skip rename to languages/tree-sitter-stack-graphs-python/test/imports/import_submodule_aliased.py index dd84f39b5..b6bfdf7b7 100644 --- a/languages/tree-sitter-stack-graphs-python/test/imports/import_submodule_aliased.py.skip +++ b/languages/tree-sitter-stack-graphs-python/test/imports/import_submodule_aliased.py @@ -7,7 +7,7 @@ import foo.bar as qux qux.BAR -# ^ defined: 7 +# ^ defined: 7, 3 # ^ defined: 3 foo From 9135ff5cb66a71e9cda1f11af85e1903066ee4ed Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 30 Nov 2023 17:59:53 +0100 Subject: [PATCH 59/60] Fix parameter definitions --- .../src/stack-graphs.tsg | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index 2c8c1e847..e784c37fc 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -813,12 +813,10 @@ inherit .parent_module edge @param.param_name -> @params.before_scope } -(parameter/identifier) @name { - attr (@name.def) node_definition = @name -} (parameter/identifier) @param @name { + attr (@name.def) node_definition = @name attr (@param.param_name) push_node = @param edge @name.def -> @param.param_name edge @name.def -> @param.param_index @@ -827,13 +825,13 @@ inherit .parent_module [ (parameter/default_parameter - name: (identifier) @name + name: (_) @name value: (_) @value) @param (parameter/typed_default_parameter name: (_) @name value: (_) @value) @param -] -{ +] { + attr (@name.def) node_definition = @name attr (@param.param_name) push_node = @name edge @name.def -> @param.param_name edge @name.def -> @param.param_index @@ -848,8 +846,8 @@ inherit .parent_module (_) @name) @param (parameter/dictionary_splat_pattern (_) @name) @param -] -{ +] { + attr (@name.def) node_definition = @name attr (@param.param_name) push_node = @name edge @name.def -> @param.param_name edge @name.def -> @param.param_index From 0f4bf9b5e14a71f451663c0383a6f26fe9c566c1 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 30 Nov 2023 23:47:41 +0100 Subject: [PATCH 60/60] Fixes for pattern identifiers --- .../src/stack-graphs.tsg | 58 ++++++++++++------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg index e784c37fc..7cddd6783 100644 --- a/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg @@ -1163,20 +1163,28 @@ inherit .parent_module ;; ;; Patterns -(pattern/identifier) @name { - attr (@name.def) node_definition = @name -} -(pattern/identifier) @name -{ - edge @name.output -> @name.local_scope - edge @name.output -> @name.class_parent_scope - edge @name.local_scope -> @name.input - attr (@name.local_scope -> @name.input) precedence = 1 - attr (@name.input) node_definition = @name - attr (@name.output) push_node = @name +[ + (pattern/identifier) @name @pattern + ; identifiers in patterns + (as_pattern (identifier) @name .) @pattern + (keyword_pattern (identifier) @name) @pattern + (splat_pattern (identifier) @name) @pattern + ; every context where _simple_pattern is used, because matching + ; pattern/dotted_name does not work + (case_pattern (dotted_name . (_) @name .) @pattern) + (keyword_pattern (dotted_name . (_) @name .) @pattern) + (union_pattern (dotted_name . (_) @name .) @pattern) +] { + attr (@name.def) node_definition = @name + edge @pattern.output -> @pattern.local_scope + edge @pattern.output -> @pattern.class_parent_scope + edge @pattern.local_scope -> @pattern.input + attr (@pattern.local_scope -> @pattern.input) precedence = 1 + attr (@pattern.input) node_definition = @name + attr (@pattern.output) push_node = @name - edge @name.new_bindings -> @name.def + edge @pattern.new_bindings -> @name.def } (pattern/subscript) {} @@ -1188,7 +1196,9 @@ inherit .parent_module } -(list_splat_pattern) {} +(list_splat_pattern (_) @pattern) @list { + edge @list.new_bindings -> @pattern.new_bindings +} [ (pattern_list (_) @pattern) @@ -1208,19 +1218,27 @@ inherit .parent_module attr (pattern_index) push_symbol = (named-child-index @pattern) } -(class_pattern) {} +(class_pattern (case_pattern) @pattern) @class { + edge @class.new_bindings -> @pattern.new_bindings +} -(splat_pattern) {} +(splat_pattern (_) @pattern) @splat { + edge @splat.new_bindings -> @pattern.new_bindings +} -(union_pattern) {} +(union_pattern (_) @pattern) @union { + edge @union.new_bindings -> @pattern.new_bindings +} -(dict_pattern) {} +(dict_pattern (_) @pattern) @dict { + edge @dict.new_bindings -> @pattern.new_bindings +} (complex_pattern) {} (as_pattern (expression) @value - alias: (as_pattern_target (primary_expression/identifier) @name)) @as_pattern + alias: (as_pattern_target (identifier) @name)) @as_pattern { attr (@name.local_scope -> @name.input) precedence = 1 attr (@name.input) is_definition @@ -1231,9 +1249,9 @@ inherit .parent_module (keyword_pattern) {} -(case_pattern (_) @expr) @pat +(case_pattern (_) @pattern) @case { - edge @pat.new_bindings -> @expr.new_bindings + edge @case.new_bindings -> @pattern.new_bindings } [