mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-07 13:15:06 +00:00
[ty] Add environment variable to dump Salsa memory usage stats (#18928)
## Summary Setting `TY_MEMORY_REPORT=full` will generate and print a memory usage report to the CLI after a `ty check` run: ``` =======SALSA STRUCTS======= `Definition` metadata=7.24MB fields=17.38MB count=181062 `Expression` metadata=4.45MB fields=5.94MB count=92804 `member_lookup_with_policy_::interned_arguments` metadata=1.97MB fields=2.25MB count=35176 ... =======SALSA QUERIES======= `File -> ty_python_semantic::semantic_index::SemanticIndex` metadata=11.46MB fields=88.86MB count=1638 `Definition -> ty_python_semantic::types::infer::TypeInference` metadata=24.52MB fields=86.68MB count=146018 `File -> ruff_db::parsed::ParsedModule` metadata=0.12MB fields=69.06MB count=1642 ... =======SALSA SUMMARY======= TOTAL MEMORY USAGE: 577.61MB struct metadata = 29.00MB struct fields = 35.68MB memo metadata = 103.87MB memo fields = 409.06MB ``` Eventually, we should integrate these numbers into CI in some form. The one limitation currently is that heap allocations in salsa structs (e.g. interned values) are not tracked, but memoized values should have full coverage. We may also want a peak memory usage counter (that accounts for non-salsa memory), but that is relatively simple to profile manually (e.g. `time -v ty check`) and would require a compile-time option to avoid runtime overhead.
This commit is contained in:
parent
a1579d82d0
commit
6f7b1c9bb3
79 changed files with 905 additions and 207 deletions
150
Cargo.lock
generated
150
Cargo.lock
generated
|
@ -169,6 +169,36 @@ dependencies = [
|
|||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "attribute-derive"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0053e96dd3bec5b4879c23a138d6ef26f2cb936c9cdc96274ac2b9ed44b5bb54"
|
||||
dependencies = [
|
||||
"attribute-derive-macro",
|
||||
"derive-where",
|
||||
"manyhow",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "attribute-derive-macro"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "463b53ad0fd5b460af4b1915fe045ff4d946d025fb6c4dc3337752eaa980f71b"
|
||||
dependencies = [
|
||||
"collection_literals",
|
||||
"interpolator",
|
||||
"manyhow",
|
||||
"proc-macro-utils",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"quote-use",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.4.0"
|
||||
|
@ -519,6 +549,12 @@ dependencies = [
|
|||
"regex-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "collection_literals"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "186dce98367766de751c42c4f03970fc60fc012296e706ccbb9d5df9b6c1e271"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.3"
|
||||
|
@ -808,6 +844,17 @@ dependencies = [
|
|||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive-where"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "510c292c8cf384b1a340b816a9a6cf2599eb8f566a44949024af88418000c50b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diff"
|
||||
version = "0.1.13"
|
||||
|
@ -1067,6 +1114,29 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "get-size-derive2"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea12180b12b82e9b7c01dfe91138208604961bb2bd7e93058d6786e5d770b104"
|
||||
dependencies = [
|
||||
"attribute-derive",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "get-size2"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a37e4d438f7550dbd4938f1bcde41538653616513678d647665a7332ea3c030"
|
||||
dependencies = [
|
||||
"compact_str",
|
||||
"get-size-derive2",
|
||||
"hashbrown 0.15.4",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getopts"
|
||||
version = "0.2.21"
|
||||
|
@ -1455,6 +1525,12 @@ dependencies = [
|
|||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "interpolator"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71dd52191aae121e8611f1e8dc3e324dd0dd1dee1e6dd91d10ee07a3cfb4d9d8"
|
||||
|
||||
[[package]]
|
||||
name = "intrusive-collections"
|
||||
version = "0.9.7"
|
||||
|
@ -1716,9 +1792,9 @@ checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
|
|||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.12"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
|
||||
checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
|
@ -1755,6 +1831,29 @@ dependencies = [
|
|||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "manyhow"
|
||||
version = "0.11.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b33efb3ca6d3b07393750d4030418d594ab1139cee518f0dc88db70fec873587"
|
||||
dependencies = [
|
||||
"manyhow-macros",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "manyhow-macros"
|
||||
version = "0.11.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46fce34d199b78b6e6073abf984c9cf5fd3e9330145a93ee0738a7443e371495"
|
||||
dependencies = [
|
||||
"proc-macro-utils",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "markdown"
|
||||
version = "1.0.0"
|
||||
|
@ -2315,6 +2414,17 @@ dependencies = [
|
|||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-utils"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eeaf08a13de400bc215877b5bdc088f241b12eb42f0a548d3390dc1c56bb7071"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.95"
|
||||
|
@ -2391,6 +2501,28 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote-use"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9619db1197b497a36178cfc736dc96b271fe918875fbf1344c436a7e93d0321e"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"quote-use-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote-use-macros"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82ebfb7faafadc06a7ab141a6f67bcfb24cb8beb158c6fe933f2f035afa99f35"
|
||||
dependencies = [
|
||||
"proc-macro-utils",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r-efi"
|
||||
version = "5.2.0"
|
||||
|
@ -2680,6 +2812,7 @@ dependencies = [
|
|||
"dunce",
|
||||
"etcetera",
|
||||
"filetime",
|
||||
"get-size2",
|
||||
"glob",
|
||||
"ignore",
|
||||
"insta",
|
||||
|
@ -2795,6 +2928,7 @@ dependencies = [
|
|||
name = "ruff_index"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"get-size2",
|
||||
"ruff_macros",
|
||||
"salsa",
|
||||
"static_assertions",
|
||||
|
@ -2907,6 +3041,7 @@ dependencies = [
|
|||
"aho-corasick",
|
||||
"bitflags 2.9.1",
|
||||
"compact_str",
|
||||
"get-size2",
|
||||
"is-macro",
|
||||
"itertools 0.14.0",
|
||||
"memchr",
|
||||
|
@ -3006,6 +3141,7 @@ dependencies = [
|
|||
"bitflags 2.9.1",
|
||||
"bstr",
|
||||
"compact_str",
|
||||
"get-size2",
|
||||
"insta",
|
||||
"memchr",
|
||||
"ruff_annotate_snippets",
|
||||
|
@ -3112,6 +3248,7 @@ dependencies = [
|
|||
name = "ruff_source_file"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"get-size2",
|
||||
"memchr",
|
||||
"ruff_text_size",
|
||||
"serde",
|
||||
|
@ -3121,6 +3258,7 @@ dependencies = [
|
|||
name = "ruff_text_size"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"get-size2",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_test",
|
||||
|
@ -3249,7 +3387,7 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
|||
[[package]]
|
||||
name = "salsa"
|
||||
version = "0.22.0"
|
||||
source = "git+https://github.com/salsa-rs/salsa.git?rev=09627e450566f894956710a3fd923dc80462ae6d#09627e450566f894956710a3fd923dc80462ae6d"
|
||||
source = "git+https://github.com/salsa-rs/salsa?rev=0666e2018bc35376b1ac4f98906f2d04d11e5fe4#0666e2018bc35376b1ac4f98906f2d04d11e5fe4"
|
||||
dependencies = [
|
||||
"boxcar",
|
||||
"compact_str",
|
||||
|
@ -3273,12 +3411,12 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "salsa-macro-rules"
|
||||
version = "0.22.0"
|
||||
source = "git+https://github.com/salsa-rs/salsa.git?rev=09627e450566f894956710a3fd923dc80462ae6d#09627e450566f894956710a3fd923dc80462ae6d"
|
||||
source = "git+https://github.com/salsa-rs/salsa?rev=0666e2018bc35376b1ac4f98906f2d04d11e5fe4#0666e2018bc35376b1ac4f98906f2d04d11e5fe4"
|
||||
|
||||
[[package]]
|
||||
name = "salsa-macros"
|
||||
version = "0.22.0"
|
||||
source = "git+https://github.com/salsa-rs/salsa.git?rev=09627e450566f894956710a3fd923dc80462ae6d#09627e450566f894956710a3fd923dc80462ae6d"
|
||||
source = "git+https://github.com/salsa-rs/salsa?rev=0666e2018bc35376b1ac4f98906f2d04d11e5fe4#0666e2018bc35376b1ac4f98906f2d04d11e5fe4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -3991,6 +4129,7 @@ dependencies = [
|
|||
"camino",
|
||||
"colored 3.0.0",
|
||||
"crossbeam",
|
||||
"get-size2",
|
||||
"globset",
|
||||
"insta",
|
||||
"notify",
|
||||
|
@ -4030,6 +4169,7 @@ dependencies = [
|
|||
"countme",
|
||||
"dir-test",
|
||||
"drop_bomb",
|
||||
"get-size2",
|
||||
"glob",
|
||||
"hashbrown 0.15.4",
|
||||
"indexmap",
|
||||
|
|
|
@ -79,6 +79,12 @@ etcetera = { version = "0.10.0" }
|
|||
fern = { version = "0.7.0" }
|
||||
filetime = { version = "0.2.23" }
|
||||
getrandom = { version = "0.3.1" }
|
||||
get-size2 = { version = "0.5.0", features = [
|
||||
"derive",
|
||||
"smallvec",
|
||||
"hashbrown",
|
||||
"compact-str"
|
||||
] }
|
||||
glob = { version = "0.3.1" }
|
||||
globset = { version = "0.4.14" }
|
||||
globwalk = { version = "0.9.1" }
|
||||
|
@ -131,7 +137,7 @@ regex-automata = { version = "0.4.9" }
|
|||
rustc-hash = { version = "2.0.0" }
|
||||
rustc-stable-hash = { version = "0.1.2" }
|
||||
# When updating salsa, make sure to also update the revision in `fuzz/Cargo.toml`
|
||||
salsa = { git = "https://github.com/salsa-rs/salsa.git", rev = "09627e450566f894956710a3fd923dc80462ae6d" }
|
||||
salsa = { git = "https://github.com/salsa-rs/salsa", rev = "0666e2018bc35376b1ac4f98906f2d04d11e5fe4" }
|
||||
schemars = { version = "0.8.16" }
|
||||
seahash = { version = "4.1.0" }
|
||||
serde = { version = "1.0.197", features = ["derive"] }
|
||||
|
|
|
@ -14,10 +14,10 @@ license = { workspace = true }
|
|||
ruff_annotate_snippets = { workspace = true }
|
||||
ruff_cache = { workspace = true, optional = true }
|
||||
ruff_notebook = { workspace = true }
|
||||
ruff_python_ast = { workspace = true }
|
||||
ruff_python_ast = { workspace = true, features = ["get-size"] }
|
||||
ruff_python_parser = { workspace = true }
|
||||
ruff_python_trivia = { workspace = true }
|
||||
ruff_source_file = { workspace = true }
|
||||
ruff_source_file = { workspace = true, features = ["get-size"] }
|
||||
ruff_text_size = { workspace = true }
|
||||
|
||||
anstyle = { workspace = true }
|
||||
|
@ -27,6 +27,7 @@ countme = { workspace = true }
|
|||
dashmap = { workspace = true }
|
||||
dunce = { workspace = true }
|
||||
filetime = { workspace = true }
|
||||
get-size2 = { workspace = true }
|
||||
glob = { workspace = true }
|
||||
ignore = { workspace = true, optional = true }
|
||||
matchit = { workspace = true }
|
||||
|
|
|
@ -19,7 +19,7 @@ mod stylesheet;
|
|||
/// characteristics in the inputs given to the tool. Typically, but not always,
|
||||
/// a characteristic is a deficiency. An example of a characteristic that is
|
||||
/// _not_ a deficiency is the `reveal_type` diagnostic for our type checker.
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
#[derive(Debug, Clone, Eq, PartialEq, get_size2::GetSize)]
|
||||
pub struct Diagnostic {
|
||||
/// The actual diagnostic.
|
||||
///
|
||||
|
@ -270,7 +270,7 @@ impl Diagnostic {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
#[derive(Debug, Clone, Eq, PartialEq, get_size2::GetSize)]
|
||||
struct DiagnosticInner {
|
||||
id: DiagnosticId,
|
||||
severity: Severity,
|
||||
|
@ -342,7 +342,7 @@ impl Eq for RenderingSortKey<'_> {}
|
|||
/// Currently, the order in which sub-diagnostics are rendered relative to one
|
||||
/// another (for a single parent diagnostic) is the order in which they were
|
||||
/// attached to the diagnostic.
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
#[derive(Debug, Clone, Eq, PartialEq, get_size2::GetSize)]
|
||||
pub struct SubDiagnostic {
|
||||
/// Like with `Diagnostic`, we box the `SubDiagnostic` to make it
|
||||
/// pointer-sized.
|
||||
|
@ -443,7 +443,7 @@ impl SubDiagnostic {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
#[derive(Debug, Clone, Eq, PartialEq, get_size2::GetSize)]
|
||||
struct SubDiagnosticInner {
|
||||
severity: Severity,
|
||||
message: DiagnosticMessage,
|
||||
|
@ -471,7 +471,7 @@ struct SubDiagnosticInner {
|
|||
///
|
||||
/// Messages attached to annotations should also be as brief and specific as
|
||||
/// possible. Long messages could negative impact the quality of rendering.
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
#[derive(Debug, Clone, Eq, PartialEq, get_size2::GetSize)]
|
||||
pub struct Annotation {
|
||||
/// The span of this annotation, corresponding to some subsequence of the
|
||||
/// user's input that we want to highlight.
|
||||
|
@ -591,7 +591,7 @@ impl Annotation {
|
|||
///
|
||||
/// These tags are used to provide additional information about the annotation.
|
||||
/// and are passed through to the language server protocol.
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
#[derive(Debug, Clone, Eq, PartialEq, get_size2::GetSize)]
|
||||
pub enum DiagnosticTag {
|
||||
/// Unused or unnecessary code. Used for unused parameters, unreachable code, etc.
|
||||
Unnecessary,
|
||||
|
@ -605,7 +605,7 @@ pub enum DiagnosticTag {
|
|||
/// be in kebab case, e.g. `no-foo` (all lower case).
|
||||
///
|
||||
/// Rules use kebab case, e.g. `no-foo`.
|
||||
#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, get_size2::GetSize)]
|
||||
pub struct LintName(&'static str);
|
||||
|
||||
impl LintName {
|
||||
|
@ -645,7 +645,7 @@ impl PartialEq<&str> for LintName {
|
|||
}
|
||||
|
||||
/// Uniquely identifies the kind of a diagnostic.
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash, get_size2::GetSize)]
|
||||
pub enum DiagnosticId {
|
||||
Panic,
|
||||
|
||||
|
@ -800,7 +800,7 @@ impl std::fmt::Display for DiagnosticId {
|
|||
///
|
||||
/// This enum presents a unified interface to these two types for the sake of creating [`Span`]s and
|
||||
/// emitting diagnostics from both ty and ruff.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, get_size2::GetSize)]
|
||||
pub enum UnifiedFile {
|
||||
Ty(File),
|
||||
Ruff(SourceFile),
|
||||
|
@ -852,7 +852,7 @@ impl DiagnosticSource {
|
|||
/// It consists of a `File` and an optional range into that file. When the
|
||||
/// range isn't present, it semantically implies that the diagnostic refers to
|
||||
/// the entire file. For example, when the file should be executable but isn't.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, get_size2::GetSize)]
|
||||
pub struct Span {
|
||||
file: UnifiedFile,
|
||||
range: Option<TextRange>,
|
||||
|
@ -924,7 +924,7 @@ impl From<crate::files::FileRange> for Span {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, get_size2::GetSize)]
|
||||
pub enum Severity {
|
||||
Info,
|
||||
Warning,
|
||||
|
@ -1087,7 +1087,7 @@ impl std::fmt::Display for ConciseMessage<'_> {
|
|||
/// In most cases, callers shouldn't need to use this. Instead, there is
|
||||
/// a blanket trait implementation for `IntoDiagnosticMessage` for
|
||||
/// anything that implements `std::fmt::Display`.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, get_size2::GetSize)]
|
||||
pub struct DiagnosticMessage(Box<str>);
|
||||
|
||||
impl DiagnosticMessage {
|
||||
|
|
|
@ -308,6 +308,9 @@ pub struct File {
|
|||
count: Count<File>,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for File {}
|
||||
|
||||
impl File {
|
||||
/// Reads the content of the file into a [`String`].
|
||||
///
|
||||
|
|
|
@ -2,6 +2,7 @@ use std::fmt::Formatter;
|
|||
use std::sync::Arc;
|
||||
|
||||
use arc_swap::ArcSwapOption;
|
||||
use get_size2::GetSize;
|
||||
use ruff_python_ast::{AnyRootNodeRef, ModModule, NodeIndex};
|
||||
use ruff_python_parser::{ParseOptions, Parsed, parse_unchecked};
|
||||
|
||||
|
@ -20,7 +21,7 @@ use crate::source::source_text;
|
|||
/// reflected in the changed AST offsets.
|
||||
/// The other reason is that Ruff's AST doesn't implement `Eq` which Salsa requires
|
||||
/// for determining if a query result is unchanged.
|
||||
#[salsa::tracked(returns(ref), no_eq)]
|
||||
#[salsa::tracked(returns(ref), no_eq, heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub fn parsed_module(db: &dyn Db, file: File) -> ParsedModule {
|
||||
let _span = tracing::trace_span!("parsed_module", ?file).entered();
|
||||
|
||||
|
@ -44,9 +45,10 @@ pub fn parsed_module_impl(db: &dyn Db, file: File) -> Parsed<ModModule> {
|
|||
///
|
||||
/// This type manages instances of the module AST. A particular instance of the AST
|
||||
/// is represented with the [`ParsedModuleRef`] type.
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, get_size2::GetSize)]
|
||||
pub struct ParsedModule {
|
||||
file: File,
|
||||
#[get_size(size_fn = arc_swap_size)]
|
||||
inner: Arc<ArcSwapOption<indexed::IndexedModule>>,
|
||||
}
|
||||
|
||||
|
@ -142,6 +144,18 @@ impl std::ops::Deref for ParsedModuleRef {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the heap-size of the currently stored `T` in the `ArcSwap`.
|
||||
fn arc_swap_size<T>(arc_swap: &Arc<ArcSwapOption<T>>) -> usize
|
||||
where
|
||||
T: GetSize,
|
||||
{
|
||||
if let Some(value) = &*arc_swap.load() {
|
||||
T::get_heap_size(value)
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
mod indexed {
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -150,7 +164,7 @@ mod indexed {
|
|||
use ruff_python_parser::Parsed;
|
||||
|
||||
/// A wrapper around the AST that allows access to AST nodes by index.
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, get_size2::GetSize)]
|
||||
pub struct IndexedModule {
|
||||
index: Box<[AnyRootNodeRef<'static>]>,
|
||||
pub parsed: Parsed<ModModule>,
|
||||
|
|
|
@ -11,7 +11,7 @@ use crate::Db;
|
|||
use crate::files::{File, FilePath};
|
||||
|
||||
/// Reads the source text of a python text file (must be valid UTF8) or notebook.
|
||||
#[salsa::tracked]
|
||||
#[salsa::tracked(heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub fn source_text(db: &dyn Db, file: File) -> SourceText {
|
||||
let path = file.path(db);
|
||||
let _span = tracing::trace_span!("source_text", file = %path).entered();
|
||||
|
@ -65,7 +65,7 @@ fn is_notebook(path: &FilePath) -> bool {
|
|||
/// The file containing the source text can either be a text file or a notebook.
|
||||
///
|
||||
/// Cheap cloneable in `O(1)`.
|
||||
#[derive(Clone, Eq, PartialEq)]
|
||||
#[derive(Clone, Eq, PartialEq, get_size2::GetSize)]
|
||||
pub struct SourceText {
|
||||
inner: Arc<SourceTextInner>,
|
||||
}
|
||||
|
@ -123,8 +123,9 @@ impl std::fmt::Debug for SourceText {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq)]
|
||||
#[derive(Eq, PartialEq, get_size2::GetSize)]
|
||||
struct SourceTextInner {
|
||||
#[get_size(ignore)]
|
||||
count: Count<SourceText>,
|
||||
kind: SourceTextKind,
|
||||
read_error: Option<SourceTextError>,
|
||||
|
@ -136,6 +137,19 @@ enum SourceTextKind {
|
|||
Notebook(Box<Notebook>),
|
||||
}
|
||||
|
||||
impl get_size2::GetSize for SourceTextKind {
|
||||
fn get_heap_size(&self) -> usize {
|
||||
match self {
|
||||
SourceTextKind::Text(text) => text.get_heap_size(),
|
||||
// TODO: The `get-size` derive does not support ignoring enum variants.
|
||||
//
|
||||
// Jupyter notebooks are not very relevant for memory profiling, and contain
|
||||
// arbitrary JSON values that do not implement the `GetSize` trait.
|
||||
SourceTextKind::Notebook(_) => 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for SourceTextKind {
|
||||
fn from(value: String) -> Self {
|
||||
SourceTextKind::Text(value)
|
||||
|
@ -148,7 +162,7 @@ impl From<Notebook> for SourceTextKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, PartialEq, Eq, Clone)]
|
||||
#[derive(Debug, thiserror::Error, PartialEq, Eq, Clone, get_size2::GetSize)]
|
||||
pub enum SourceTextError {
|
||||
#[error("Failed to read notebook: {0}`")]
|
||||
FailedToReadNotebook(String),
|
||||
|
@ -157,7 +171,7 @@ pub enum SourceTextError {
|
|||
}
|
||||
|
||||
/// Computes the [`LineIndex`] for `file`.
|
||||
#[salsa::tracked]
|
||||
#[salsa::tracked(heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub fn line_index(db: &dyn Db, file: File) -> LineIndex {
|
||||
let _span = tracing::trace_span!("line_index", ?file).entered();
|
||||
|
||||
|
|
|
@ -503,6 +503,12 @@ impl ToOwned for SystemPath {
|
|||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct SystemPathBuf(#[cfg_attr(feature = "schemars", schemars(with = "String"))] Utf8PathBuf);
|
||||
|
||||
impl get_size2::GetSize for SystemPathBuf {
|
||||
fn get_heap_size(&self) -> usize {
|
||||
self.0.capacity()
|
||||
}
|
||||
}
|
||||
|
||||
impl SystemPathBuf {
|
||||
pub fn new() -> Self {
|
||||
Self(Utf8PathBuf::new())
|
||||
|
|
|
@ -87,6 +87,12 @@ impl ToOwned for VendoredPath {
|
|||
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
|
||||
pub struct VendoredPathBuf(Utf8PathBuf);
|
||||
|
||||
impl get_size2::GetSize for VendoredPathBuf {
|
||||
fn get_heap_size(&self) -> usize {
|
||||
self.0.capacity()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for VendoredPathBuf {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
|
|
|
@ -14,6 +14,7 @@ license = { workspace = true }
|
|||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
get-size2 = { workspace = true }
|
||||
ruff_macros = { workspace = true }
|
||||
salsa = { workspace = true, optional = true }
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ use std::marker::PhantomData;
|
|||
use std::ops::{Deref, DerefMut, RangeBounds};
|
||||
|
||||
/// An owned sequence of `T` indexed by `I`
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Hash, get_size2::GetSize)]
|
||||
#[repr(transparent)]
|
||||
pub struct IndexVec<I, T> {
|
||||
pub raw: Vec<T>,
|
||||
|
|
|
@ -22,6 +22,7 @@ ruff_text_size = { workspace = true }
|
|||
aho-corasick = { workspace = true }
|
||||
bitflags = { workspace = true }
|
||||
compact_str = { workspace = true }
|
||||
get-size2 = { workspace = true, optional = true }
|
||||
is-macro = { workspace = true }
|
||||
itertools = { workspace = true }
|
||||
memchr = { workspace = true }
|
||||
|
@ -40,6 +41,7 @@ serde = [
|
|||
"dep:ruff_cache",
|
||||
"compact_str/serde",
|
||||
]
|
||||
get-size = ["dep:get-size2"]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
@ -316,6 +316,7 @@ def write_owned_enum(out: list[str], ast: Ast) -> None:
|
|||
if group.doc is not None:
|
||||
write_rustdoc(out, group.doc)
|
||||
out.append("#[derive(Clone, Debug, PartialEq)]")
|
||||
out.append('#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]')
|
||||
out.append(f"pub enum {group.owned_enum_ty} {{")
|
||||
for node in group.nodes:
|
||||
out.append(f"{node.variant}({node.ty}),")
|
||||
|
@ -515,6 +516,7 @@ def write_ref_enum(out: list[str], ast: Ast) -> None:
|
|||
if group.doc is not None:
|
||||
write_rustdoc(out, group.doc)
|
||||
out.append("""#[derive(Clone, Copy, Debug, PartialEq, is_macro::Is)]""")
|
||||
out.append('#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]')
|
||||
out.append(f"""pub enum {group.ref_enum_ty}<'a> {{""")
|
||||
for node in group.nodes:
|
||||
if group.add_suffix_to_is_methods:
|
||||
|
@ -604,6 +606,7 @@ def write_anynoderef(out: list[str], ast: Ast) -> None:
|
|||
out.append("""
|
||||
/// A flattened enumeration of all AST nodes.
|
||||
#[derive(Copy, Clone, Debug, is_macro::Is, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum AnyNodeRef<'a> {
|
||||
""")
|
||||
for node in ast.all_nodes:
|
||||
|
@ -782,6 +785,7 @@ def write_root_anynoderef(out: list[str], ast: Ast) -> None:
|
|||
/// `AnyNodeRef` has top-level `AnyNodeRef::ModModule` and `AnyNodeRef::ModExpression`
|
||||
/// variants.
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum AnyRootNodeRef<'a> {
|
||||
""")
|
||||
for group in ast.groups:
|
||||
|
@ -963,6 +967,7 @@ def write_node(out: list[str], ast: Ast) -> None:
|
|||
+ "".join(f", {derive}" for derive in node.derives)
|
||||
+ ")]"
|
||||
)
|
||||
out.append('#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]')
|
||||
name = node.name
|
||||
out.append(f"pub struct {name} {{")
|
||||
out.append("pub node_index: crate::AtomicNodeIndex,")
|
||||
|
|
76
crates/ruff_python_ast/src/generated.rs
generated
76
crates/ruff_python_ast/src/generated.rs
generated
|
@ -6,6 +6,7 @@ use crate::visitor::source_order::SourceOrderVisitor;
|
|||
|
||||
/// See also [mod](https://docs.python.org/3/library/ast.html#ast.mod)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum Mod {
|
||||
Module(crate::ModModule),
|
||||
Expression(crate::ModExpression),
|
||||
|
@ -120,6 +121,7 @@ impl Mod {
|
|||
|
||||
/// See also [stmt](https://docs.python.org/3/library/ast.html#ast.stmt)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum Stmt {
|
||||
FunctionDef(crate::StmtFunctionDef),
|
||||
ClassDef(crate::StmtClassDef),
|
||||
|
@ -1292,6 +1294,7 @@ impl Stmt {
|
|||
|
||||
/// See also [expr](https://docs.python.org/3/library/ast.html#ast.expr)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum Expr {
|
||||
BoolOp(crate::ExprBoolOp),
|
||||
Named(crate::ExprNamed),
|
||||
|
@ -2832,6 +2835,7 @@ impl Expr {
|
|||
|
||||
/// See also [excepthandler](https://docs.python.org/3/library/ast.html#ast.excepthandler)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum ExceptHandler {
|
||||
ExceptHandler(crate::ExceptHandlerExceptHandler),
|
||||
}
|
||||
|
@ -2895,6 +2899,7 @@ impl ExceptHandler {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum InterpolatedStringElement {
|
||||
Interpolation(crate::InterpolatedElement),
|
||||
Literal(crate::InterpolatedStringLiteralElement),
|
||||
|
@ -3009,6 +3014,7 @@ impl InterpolatedStringElement {
|
|||
|
||||
/// See also [pattern](https://docs.python.org/3/library/ast.html#ast.pattern)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum Pattern {
|
||||
MatchValue(crate::PatternMatchValue),
|
||||
MatchSingleton(crate::PatternMatchSingleton),
|
||||
|
@ -3399,6 +3405,7 @@ impl Pattern {
|
|||
|
||||
/// See also [type_param](https://docs.python.org/3/library/ast.html#ast.type_param)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum TypeParam {
|
||||
TypeVar(crate::TypeParamTypeVar),
|
||||
TypeVarTuple(crate::TypeParamTypeVarTuple),
|
||||
|
@ -4838,6 +4845,7 @@ impl TypeParam {
|
|||
|
||||
/// See also [mod](https://docs.python.org/3/library/ast.html#ast.mod)
|
||||
#[derive(Clone, Copy, Debug, PartialEq, is_macro::Is)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum ModRef<'a> {
|
||||
Module(&'a crate::ModModule),
|
||||
Expression(&'a crate::ModExpression),
|
||||
|
@ -4884,6 +4892,7 @@ impl crate::HasNodeIndex for ModRef<'_> {
|
|||
|
||||
/// See also [stmt](https://docs.python.org/3/library/ast.html#ast.stmt)
|
||||
#[derive(Clone, Copy, Debug, PartialEq, is_macro::Is)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum StmtRef<'a> {
|
||||
#[is(name = "function_def_stmt")]
|
||||
FunctionDef(&'a crate::StmtFunctionDef),
|
||||
|
@ -5185,6 +5194,7 @@ impl crate::HasNodeIndex for StmtRef<'_> {
|
|||
|
||||
/// See also [expr](https://docs.python.org/3/library/ast.html#ast.expr)
|
||||
#[derive(Clone, Copy, Debug, PartialEq, is_macro::Is)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum ExprRef<'a> {
|
||||
#[is(name = "bool_op_expr")]
|
||||
BoolOp(&'a crate::ExprBoolOp),
|
||||
|
@ -5574,6 +5584,7 @@ impl crate::HasNodeIndex for ExprRef<'_> {
|
|||
|
||||
/// See also [excepthandler](https://docs.python.org/3/library/ast.html#ast.excepthandler)
|
||||
#[derive(Clone, Copy, Debug, PartialEq, is_macro::Is)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum ExceptHandlerRef<'a> {
|
||||
ExceptHandler(&'a crate::ExceptHandlerExceptHandler),
|
||||
}
|
||||
|
@ -5609,6 +5620,7 @@ impl crate::HasNodeIndex for ExceptHandlerRef<'_> {
|
|||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, is_macro::Is)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum InterpolatedStringElementRef<'a> {
|
||||
Interpolation(&'a crate::InterpolatedElement),
|
||||
Literal(&'a crate::InterpolatedStringLiteralElement),
|
||||
|
@ -5657,6 +5669,7 @@ impl crate::HasNodeIndex for InterpolatedStringElementRef<'_> {
|
|||
|
||||
/// See also [pattern](https://docs.python.org/3/library/ast.html#ast.pattern)
|
||||
#[derive(Clone, Copy, Debug, PartialEq, is_macro::Is)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum PatternRef<'a> {
|
||||
MatchValue(&'a crate::PatternMatchValue),
|
||||
MatchSingleton(&'a crate::PatternMatchSingleton),
|
||||
|
@ -5763,6 +5776,7 @@ impl crate::HasNodeIndex for PatternRef<'_> {
|
|||
|
||||
/// See also [type_param](https://docs.python.org/3/library/ast.html#ast.type_param)
|
||||
#[derive(Clone, Copy, Debug, PartialEq, is_macro::Is)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum TypeParamRef<'a> {
|
||||
TypeVar(&'a crate::TypeParamTypeVar),
|
||||
TypeVarTuple(&'a crate::TypeParamTypeVarTuple),
|
||||
|
@ -5819,6 +5833,7 @@ impl crate::HasNodeIndex for TypeParamRef<'_> {
|
|||
|
||||
/// A flattened enumeration of all AST nodes.
|
||||
#[derive(Copy, Clone, Debug, is_macro::Is, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum AnyNodeRef<'a> {
|
||||
ModModule(&'a crate::ModModule),
|
||||
ModExpression(&'a crate::ModExpression),
|
||||
|
@ -7418,6 +7433,7 @@ impl AnyNodeRef<'_> {
|
|||
/// `AnyNodeRef` has top-level `AnyNodeRef::ModModule` and `AnyNodeRef::ModExpression`
|
||||
/// variants.
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum AnyRootNodeRef<'a> {
|
||||
Mod(&'a Mod),
|
||||
Stmt(&'a Stmt),
|
||||
|
@ -8935,6 +8951,7 @@ impl AnyNodeRef<'_> {
|
|||
|
||||
/// See also [Module](https://docs.python.org/3/library/ast.html#ast.Module)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ModModule {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -8943,6 +8960,7 @@ pub struct ModModule {
|
|||
|
||||
/// See also [Module](https://docs.python.org/3/library/ast.html#ast.Module)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ModExpression {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -8954,6 +8972,7 @@ pub struct ModExpression {
|
|||
///
|
||||
/// This type differs from the original Python AST, as it collapses the synchronous and asynchronous variants into a single type.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StmtFunctionDef {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -8968,6 +8987,7 @@ pub struct StmtFunctionDef {
|
|||
|
||||
/// See also [ClassDef](https://docs.python.org/3/library/ast.html#ast.ClassDef)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StmtClassDef {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -8980,6 +9000,7 @@ pub struct StmtClassDef {
|
|||
|
||||
/// See also [Return](https://docs.python.org/3/library/ast.html#ast.Return)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StmtReturn {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -8988,6 +9009,7 @@ pub struct StmtReturn {
|
|||
|
||||
/// See also [Delete](https://docs.python.org/3/library/ast.html#ast.Delete)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StmtDelete {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -8996,6 +9018,7 @@ pub struct StmtDelete {
|
|||
|
||||
/// See also [TypeAlias](https://docs.python.org/3/library/ast.html#ast.TypeAlias)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StmtTypeAlias {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9006,6 +9029,7 @@ pub struct StmtTypeAlias {
|
|||
|
||||
/// See also [Assign](https://docs.python.org/3/library/ast.html#ast.Assign)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StmtAssign {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9015,6 +9039,7 @@ pub struct StmtAssign {
|
|||
|
||||
/// See also [AugAssign](https://docs.python.org/3/library/ast.html#ast.AugAssign)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StmtAugAssign {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9025,6 +9050,7 @@ pub struct StmtAugAssign {
|
|||
|
||||
/// See also [AnnAssign](https://docs.python.org/3/library/ast.html#ast.AnnAssign)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StmtAnnAssign {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9039,6 +9065,7 @@ pub struct StmtAnnAssign {
|
|||
///
|
||||
/// This type differs from the original Python AST, as it collapses the synchronous and asynchronous variants into a single type.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StmtFor {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9052,6 +9079,7 @@ pub struct StmtFor {
|
|||
/// See also [While](https://docs.python.org/3/library/ast.html#ast.While)
|
||||
/// and [AsyncWhile](https://docs.python.org/3/library/ast.html#ast.AsyncWhile).
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StmtWhile {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9062,6 +9090,7 @@ pub struct StmtWhile {
|
|||
|
||||
/// See also [If](https://docs.python.org/3/library/ast.html#ast.If)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StmtIf {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9075,6 +9104,7 @@ pub struct StmtIf {
|
|||
///
|
||||
/// This type differs from the original Python AST, as it collapses the synchronous and asynchronous variants into a single type.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StmtWith {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9085,6 +9115,7 @@ pub struct StmtWith {
|
|||
|
||||
/// See also [Match](https://docs.python.org/3/library/ast.html#ast.Match)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StmtMatch {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9094,6 +9125,7 @@ pub struct StmtMatch {
|
|||
|
||||
/// See also [Raise](https://docs.python.org/3/library/ast.html#ast.Raise)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StmtRaise {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9104,6 +9136,7 @@ pub struct StmtRaise {
|
|||
/// See also [Try](https://docs.python.org/3/library/ast.html#ast.Try)
|
||||
/// and [TryStar](https://docs.python.org/3/library/ast.html#ast.TryStar)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StmtTry {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9116,6 +9149,7 @@ pub struct StmtTry {
|
|||
|
||||
/// See also [Assert](https://docs.python.org/3/library/ast.html#ast.Assert)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StmtAssert {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9125,6 +9159,7 @@ pub struct StmtAssert {
|
|||
|
||||
/// See also [Import](https://docs.python.org/3/library/ast.html#ast.Import)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StmtImport {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9133,6 +9168,7 @@ pub struct StmtImport {
|
|||
|
||||
/// See also [ImportFrom](https://docs.python.org/3/library/ast.html#ast.ImportFrom)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StmtImportFrom {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9143,6 +9179,7 @@ pub struct StmtImportFrom {
|
|||
|
||||
/// See also [Global](https://docs.python.org/3/library/ast.html#ast.Global)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StmtGlobal {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9151,6 +9188,7 @@ pub struct StmtGlobal {
|
|||
|
||||
/// See also [Nonlocal](https://docs.python.org/3/library/ast.html#ast.Nonlocal)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StmtNonlocal {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9159,6 +9197,7 @@ pub struct StmtNonlocal {
|
|||
|
||||
/// See also [Expr](https://docs.python.org/3/library/ast.html#ast.Expr)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StmtExpr {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9167,6 +9206,7 @@ pub struct StmtExpr {
|
|||
|
||||
/// See also [Pass](https://docs.python.org/3/library/ast.html#ast.Pass)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StmtPass {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9174,6 +9214,7 @@ pub struct StmtPass {
|
|||
|
||||
/// See also [Break](https://docs.python.org/3/library/ast.html#ast.Break)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StmtBreak {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9181,6 +9222,7 @@ pub struct StmtBreak {
|
|||
|
||||
/// See also [Continue](https://docs.python.org/3/library/ast.html#ast.Continue)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StmtContinue {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9241,6 +9283,7 @@ pub struct StmtContinue {
|
|||
/// [Escape kind]: crate::IpyEscapeKind
|
||||
///
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StmtIpyEscapeCommand {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9250,6 +9293,7 @@ pub struct StmtIpyEscapeCommand {
|
|||
|
||||
/// See also [BoolOp](https://docs.python.org/3/library/ast.html#ast.BoolOp)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprBoolOp {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9259,6 +9303,7 @@ pub struct ExprBoolOp {
|
|||
|
||||
/// See also [NamedExpr](https://docs.python.org/3/library/ast.html#ast.NamedExpr)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprNamed {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9268,6 +9313,7 @@ pub struct ExprNamed {
|
|||
|
||||
/// See also [BinOp](https://docs.python.org/3/library/ast.html#ast.BinOp)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprBinOp {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9278,6 +9324,7 @@ pub struct ExprBinOp {
|
|||
|
||||
/// See also [UnaryOp](https://docs.python.org/3/library/ast.html#ast.UnaryOp)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprUnaryOp {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9287,6 +9334,7 @@ pub struct ExprUnaryOp {
|
|||
|
||||
/// See also [Lambda](https://docs.python.org/3/library/ast.html#ast.Lambda)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprLambda {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9296,6 +9344,7 @@ pub struct ExprLambda {
|
|||
|
||||
/// See also [IfExp](https://docs.python.org/3/library/ast.html#ast.IfExp)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprIf {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9306,6 +9355,7 @@ pub struct ExprIf {
|
|||
|
||||
/// See also [Dict](https://docs.python.org/3/library/ast.html#ast.Dict)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprDict {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9314,6 +9364,7 @@ pub struct ExprDict {
|
|||
|
||||
/// See also [Set](https://docs.python.org/3/library/ast.html#ast.Set)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprSet {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9322,6 +9373,7 @@ pub struct ExprSet {
|
|||
|
||||
/// See also [ListComp](https://docs.python.org/3/library/ast.html#ast.ListComp)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprListComp {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9331,6 +9383,7 @@ pub struct ExprListComp {
|
|||
|
||||
/// See also [SetComp](https://docs.python.org/3/library/ast.html#ast.SetComp)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprSetComp {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9340,6 +9393,7 @@ pub struct ExprSetComp {
|
|||
|
||||
/// See also [DictComp](https://docs.python.org/3/library/ast.html#ast.DictComp)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprDictComp {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9350,6 +9404,7 @@ pub struct ExprDictComp {
|
|||
|
||||
/// See also [GeneratorExp](https://docs.python.org/3/library/ast.html#ast.GeneratorExp)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprGenerator {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9360,6 +9415,7 @@ pub struct ExprGenerator {
|
|||
|
||||
/// See also [Await](https://docs.python.org/3/library/ast.html#ast.Await)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprAwait {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9368,6 +9424,7 @@ pub struct ExprAwait {
|
|||
|
||||
/// See also [Yield](https://docs.python.org/3/library/ast.html#ast.Yield)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprYield {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9376,6 +9433,7 @@ pub struct ExprYield {
|
|||
|
||||
/// See also [YieldFrom](https://docs.python.org/3/library/ast.html#ast.YieldFrom)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprYieldFrom {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9384,6 +9442,7 @@ pub struct ExprYieldFrom {
|
|||
|
||||
/// See also [Compare](https://docs.python.org/3/library/ast.html#ast.Compare)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprCompare {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9394,6 +9453,7 @@ pub struct ExprCompare {
|
|||
|
||||
/// See also [Call](https://docs.python.org/3/library/ast.html#ast.Call)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprCall {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9410,6 +9470,7 @@ pub struct ExprCall {
|
|||
///
|
||||
/// See also [JoinedStr](https://docs.python.org/3/library/ast.html#ast.JoinedStr)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprFString {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9425,6 +9486,7 @@ pub struct ExprFString {
|
|||
///
|
||||
/// See also [TemplateStr](https://docs.python.org/3/library/ast.html#ast.TemplateStr)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprTString {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9434,6 +9496,7 @@ pub struct ExprTString {
|
|||
/// An AST node that represents either a single-part string literal
|
||||
/// or an implicitly concatenated string literal.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprStringLiteral {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9443,6 +9506,7 @@ pub struct ExprStringLiteral {
|
|||
/// An AST node that represents either a single-part bytestring literal
|
||||
/// or an implicitly concatenated bytestring literal.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprBytesLiteral {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9450,6 +9514,7 @@ pub struct ExprBytesLiteral {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprNumberLiteral {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9457,6 +9522,7 @@ pub struct ExprNumberLiteral {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Default)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprBooleanLiteral {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9464,12 +9530,14 @@ pub struct ExprBooleanLiteral {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Default)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprNoneLiteral {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Default)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprEllipsisLiteral {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9477,6 +9545,7 @@ pub struct ExprEllipsisLiteral {
|
|||
|
||||
/// See also [Attribute](https://docs.python.org/3/library/ast.html#ast.Attribute)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprAttribute {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9487,6 +9556,7 @@ pub struct ExprAttribute {
|
|||
|
||||
/// See also [Subscript](https://docs.python.org/3/library/ast.html#ast.Subscript)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprSubscript {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9497,6 +9567,7 @@ pub struct ExprSubscript {
|
|||
|
||||
/// See also [Starred](https://docs.python.org/3/library/ast.html#ast.Starred)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprStarred {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9506,6 +9577,7 @@ pub struct ExprStarred {
|
|||
|
||||
/// See also [Name](https://docs.python.org/3/library/ast.html#ast.Name)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprName {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9515,6 +9587,7 @@ pub struct ExprName {
|
|||
|
||||
/// See also [List](https://docs.python.org/3/library/ast.html#ast.List)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprList {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9524,6 +9597,7 @@ pub struct ExprList {
|
|||
|
||||
/// See also [Tuple](https://docs.python.org/3/library/ast.html#ast.Tuple)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprTuple {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9534,6 +9608,7 @@ pub struct ExprTuple {
|
|||
|
||||
/// See also [Slice](https://docs.python.org/3/library/ast.html#ast.Slice)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprSlice {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
@ -9554,6 +9629,7 @@ pub struct ExprSlice {
|
|||
/// For more information related to terminology and syntax of escape commands,
|
||||
/// see [`StmtIpyEscapeCommand`].
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExprIpyEscapeCommand {
|
||||
pub node_index: crate::AtomicNodeIndex,
|
||||
pub range: ruff_text_size::TextRange,
|
||||
|
|
|
@ -3,6 +3,7 @@ use std::str::FromStr;
|
|||
|
||||
/// A Python integer literal. Represents both small (fits in an `i64`) and large integers.
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct Int(Number);
|
||||
|
||||
impl FromStr for Int {
|
||||
|
@ -216,6 +217,7 @@ impl From<u64> for Int {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
enum Number {
|
||||
/// A "small" number that can be represented as an `u64`.
|
||||
Small(u64),
|
||||
|
|
|
@ -10,6 +10,7 @@ use crate::generated::ExprName;
|
|||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "cache", derive(ruff_macros::CacheKey))]
|
||||
#[cfg_attr(feature = "salsa", derive(salsa::Update))]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct Name(compact_str::CompactString);
|
||||
|
||||
impl Name {
|
||||
|
|
|
@ -19,7 +19,7 @@ where
|
|||
///
|
||||
/// This type is interiorly mutable to allow assigning node indices
|
||||
/// on-demand after parsing.
|
||||
#[derive(Default)]
|
||||
#[derive(Default, get_size2::GetSize)]
|
||||
pub struct AtomicNodeIndex(AtomicU32);
|
||||
|
||||
impl AtomicNodeIndex {
|
||||
|
@ -41,6 +41,7 @@ impl AtomicNodeIndex {
|
|||
|
||||
/// A unique index for a node within an AST.
|
||||
#[derive(PartialEq, Eq, Debug, PartialOrd, Ord, Clone, Copy, Hash)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct NodeIndex(u32);
|
||||
|
||||
impl NodeIndex {
|
||||
|
|
|
@ -47,6 +47,7 @@ impl StmtClassDef {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ElifElseClause {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -133,6 +134,7 @@ impl ExprRef<'_> {
|
|||
///
|
||||
/// [1]: https://docs.python.org/3/reference/expressions.html#displays-for-lists-sets-and-dictionaries
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct DictItem {
|
||||
pub key: Option<Expr>,
|
||||
pub value: Expr,
|
||||
|
@ -316,6 +318,7 @@ impl<'a> IntoIterator for &'a ExprSet {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct InterpolatedStringFormatSpec {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -324,6 +327,7 @@ pub struct InterpolatedStringFormatSpec {
|
|||
|
||||
/// See also [FormattedValue](https://docs.python.org/3/library/ast.html#ast.FormattedValue)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct InterpolatedElement {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -335,6 +339,7 @@ pub struct InterpolatedElement {
|
|||
|
||||
/// An `FStringLiteralElement` with an empty `value` is an invalid f-string element.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct InterpolatedStringLiteralElement {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -357,6 +362,7 @@ impl Deref for InterpolatedStringLiteralElement {
|
|||
|
||||
/// Transforms a value prior to formatting it.
|
||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, is_macro::Is)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
#[repr(i8)]
|
||||
#[expect(clippy::cast_possible_wrap)]
|
||||
pub enum ConversionFlag {
|
||||
|
@ -383,6 +389,7 @@ impl ConversionFlag {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct DebugText {
|
||||
/// The text between the `{` and the expression node.
|
||||
pub leading: String,
|
||||
|
@ -403,6 +410,7 @@ impl ExprFString {
|
|||
|
||||
/// The value representing an [`ExprFString`].
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct FStringValue {
|
||||
inner: FStringValueInner,
|
||||
}
|
||||
|
@ -539,6 +547,7 @@ impl<'a> IntoIterator for &'a mut FStringValue {
|
|||
|
||||
/// An internal representation of [`FStringValue`].
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
enum FStringValueInner {
|
||||
/// A single f-string i.e., `f"foo"`.
|
||||
///
|
||||
|
@ -552,6 +561,7 @@ enum FStringValueInner {
|
|||
|
||||
/// An f-string part which is either a string literal or an f-string.
|
||||
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum FStringPart {
|
||||
Literal(StringLiteral),
|
||||
FString(FString),
|
||||
|
@ -595,6 +605,7 @@ impl ExprTString {
|
|||
|
||||
/// The value representing an [`ExprTString`].
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct TStringValue {
|
||||
inner: TStringValueInner,
|
||||
}
|
||||
|
@ -717,6 +728,7 @@ impl<'a> IntoIterator for &'a mut TStringValue {
|
|||
|
||||
/// An internal representation of [`TStringValue`].
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
enum TStringValueInner {
|
||||
/// A single t-string i.e., `t"foo"`.
|
||||
///
|
||||
|
@ -731,6 +743,7 @@ enum TStringValueInner {
|
|||
/// An t-string part which is either a string literal, an f-string,
|
||||
/// or a t-string.
|
||||
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum TStringPart {
|
||||
Literal(StringLiteral),
|
||||
FString(FString),
|
||||
|
@ -862,6 +875,8 @@ bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
impl get_size2::GetSize for InterpolatedStringFlagsInner {}
|
||||
|
||||
/// Flags that can be queried to obtain information
|
||||
/// regarding the prefixes and quotes used for an f-string.
|
||||
///
|
||||
|
@ -879,6 +894,7 @@ bitflags! {
|
|||
/// will properly handle nested f-strings. For usage that doesn't fit into one of these categories,
|
||||
/// the public constructor [`FStringFlags::empty`] can be used.
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct FStringFlags(InterpolatedStringFlagsInner);
|
||||
|
||||
impl FStringFlags {
|
||||
|
@ -975,6 +991,7 @@ impl FStringFlags {
|
|||
/// will properly handle nested t-strings. For usage that doesn't fit into one of these categories,
|
||||
/// the public constructor [`TStringFlags::empty`] can be used.
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct TStringFlags(InterpolatedStringFlagsInner);
|
||||
|
||||
impl TStringFlags {
|
||||
|
@ -1129,6 +1146,7 @@ impl fmt::Debug for TStringFlags {
|
|||
|
||||
/// An AST node that represents a single f-string which is part of an [`ExprFString`].
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct FString {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -1149,6 +1167,7 @@ impl From<FString> for Expr {
|
|||
|
||||
/// A newtype wrapper around a list of [`InterpolatedStringElement`].
|
||||
#[derive(Clone, Default, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct InterpolatedStringElements(Vec<InterpolatedStringElement>);
|
||||
|
||||
impl InterpolatedStringElements {
|
||||
|
@ -1209,6 +1228,7 @@ impl fmt::Debug for InterpolatedStringElements {
|
|||
|
||||
/// An AST node that represents a single t-string which is part of an [`ExprTString`].
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct TString {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -1240,6 +1260,7 @@ impl ExprStringLiteral {
|
|||
|
||||
/// The value representing a [`ExprStringLiteral`].
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StringLiteralValue {
|
||||
inner: StringLiteralValueInner,
|
||||
}
|
||||
|
@ -1397,6 +1418,7 @@ impl fmt::Display for StringLiteralValue {
|
|||
|
||||
/// An internal representation of [`StringLiteralValue`].
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
enum StringLiteralValueInner {
|
||||
/// A single string literal i.e., `"foo"`.
|
||||
Single(StringLiteral),
|
||||
|
@ -1440,6 +1462,8 @@ bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
impl get_size2::GetSize for StringLiteralFlagsInner {}
|
||||
|
||||
/// Flags that can be queried to obtain information
|
||||
/// regarding the prefixes and quotes used for a string literal.
|
||||
///
|
||||
|
@ -1453,6 +1477,7 @@ bitflags! {
|
|||
/// handle surrounding f-strings. For usage that doesn't fit into one of these categories, the
|
||||
/// public constructor [`StringLiteralFlags::empty`] can be used.
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StringLiteralFlags(StringLiteralFlagsInner);
|
||||
|
||||
impl StringLiteralFlags {
|
||||
|
@ -1581,6 +1606,7 @@ impl fmt::Debug for StringLiteralFlags {
|
|||
/// An AST node that represents a single string literal which is part of an
|
||||
/// [`ExprStringLiteral`].
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct StringLiteral {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -1637,6 +1663,7 @@ impl From<StringLiteral> for Expr {
|
|||
/// An internal representation of [`StringLiteral`] that represents an
|
||||
/// implicitly concatenated string.
|
||||
#[derive(Clone)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
struct ConcatenatedStringLiteral {
|
||||
/// The individual [`StringLiteral`] parts that make up the concatenated string.
|
||||
strings: Vec<StringLiteral>,
|
||||
|
@ -1689,6 +1716,7 @@ impl ExprBytesLiteral {
|
|||
|
||||
/// The value representing a [`ExprBytesLiteral`].
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct BytesLiteralValue {
|
||||
inner: BytesLiteralValueInner,
|
||||
}
|
||||
|
@ -1817,6 +1845,7 @@ impl<'a> From<&'a BytesLiteralValue> for Cow<'a, [u8]> {
|
|||
|
||||
/// An internal representation of [`BytesLiteralValue`].
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
enum BytesLiteralValueInner {
|
||||
/// A single-part bytestring literal i.e., `b"foo"`.
|
||||
Single(BytesLiteral),
|
||||
|
@ -1851,6 +1880,8 @@ bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
impl get_size2::GetSize for BytesLiteralFlagsInner {}
|
||||
|
||||
/// Flags that can be queried to obtain information
|
||||
/// regarding the prefixes and quotes used for a bytes literal.
|
||||
///
|
||||
|
@ -1863,6 +1894,7 @@ bitflags! {
|
|||
/// will properly handle surrounding f-strings. For usage that doesn't fit into one of these
|
||||
/// categories, the public constructor [`BytesLiteralFlags::empty`] can be used.
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct BytesLiteralFlags(BytesLiteralFlagsInner);
|
||||
|
||||
impl BytesLiteralFlags {
|
||||
|
@ -1972,6 +2004,7 @@ impl fmt::Debug for BytesLiteralFlags {
|
|||
/// An AST node that represents a single bytes literal which is part of an
|
||||
/// [`ExprBytesLiteral`].
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct BytesLiteral {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -2328,6 +2361,7 @@ impl From<TStringFlags> for AnyStringFlags {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum Number {
|
||||
Int(int::Int),
|
||||
Float(f64),
|
||||
|
@ -2395,6 +2429,7 @@ impl<'a> IntoIterator for &'a ExprTuple {
|
|||
|
||||
/// See also [expr_context](https://docs.python.org/3/library/ast.html#ast.expr_context)
|
||||
#[derive(Clone, Debug, PartialEq, is_macro::Is, Copy, Hash, Eq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum ExprContext {
|
||||
Load,
|
||||
Store,
|
||||
|
@ -2404,6 +2439,7 @@ pub enum ExprContext {
|
|||
|
||||
/// See also [boolop](https://docs.python.org/3/library/ast.html#ast.BoolOp)
|
||||
#[derive(Clone, Debug, PartialEq, is_macro::Is, Copy, Hash, Eq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum BoolOp {
|
||||
And,
|
||||
Or,
|
||||
|
@ -2426,6 +2462,7 @@ impl fmt::Display for BoolOp {
|
|||
|
||||
/// See also [operator](https://docs.python.org/3/library/ast.html#ast.operator)
|
||||
#[derive(Clone, Debug, PartialEq, is_macro::Is, Copy, Hash, Eq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum Operator {
|
||||
Add,
|
||||
Sub,
|
||||
|
@ -2527,6 +2564,7 @@ impl fmt::Display for Operator {
|
|||
|
||||
/// See also [unaryop](https://docs.python.org/3/library/ast.html#ast.unaryop)
|
||||
#[derive(Clone, Debug, PartialEq, is_macro::Is, Copy, Hash, Eq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum UnaryOp {
|
||||
Invert,
|
||||
Not,
|
||||
|
@ -2553,6 +2591,7 @@ impl fmt::Display for UnaryOp {
|
|||
|
||||
/// See also [cmpop](https://docs.python.org/3/library/ast.html#ast.cmpop)
|
||||
#[derive(Clone, Debug, PartialEq, is_macro::Is, Copy, Hash, Eq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum CmpOp {
|
||||
Eq,
|
||||
NotEq,
|
||||
|
@ -2607,6 +2646,7 @@ impl fmt::Display for CmpOp {
|
|||
|
||||
/// See also [comprehension](https://docs.python.org/3/library/ast.html#ast.comprehension)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct Comprehension {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -2618,6 +2658,7 @@ pub struct Comprehension {
|
|||
|
||||
/// See also [ExceptHandler](https://docs.python.org/3/library/ast.html#ast.ExceptHandler)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ExceptHandlerExceptHandler {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -2628,6 +2669,7 @@ pub struct ExceptHandlerExceptHandler {
|
|||
|
||||
/// See also [arg](https://docs.python.org/3/library/ast.html#ast.arg)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct Parameter {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -2647,6 +2689,7 @@ impl Parameter {
|
|||
|
||||
/// See also [keyword](https://docs.python.org/3/library/ast.html#ast.keyword)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct Keyword {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -2656,6 +2699,7 @@ pub struct Keyword {
|
|||
|
||||
/// See also [alias](https://docs.python.org/3/library/ast.html#ast.alias)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct Alias {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -2665,6 +2709,7 @@ pub struct Alias {
|
|||
|
||||
/// See also [withitem](https://docs.python.org/3/library/ast.html#ast.withitem)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct WithItem {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -2674,6 +2719,7 @@ pub struct WithItem {
|
|||
|
||||
/// See also [match_case](https://docs.python.org/3/library/ast.html#ast.match_case)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct MatchCase {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -2751,6 +2797,7 @@ pub struct IrrefutablePattern {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum IrrefutablePatternKind {
|
||||
Name(Name),
|
||||
Wildcard,
|
||||
|
@ -2758,6 +2805,7 @@ pub enum IrrefutablePatternKind {
|
|||
|
||||
/// See also [MatchValue](https://docs.python.org/3/library/ast.html#ast.MatchValue)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct PatternMatchValue {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -2766,6 +2814,7 @@ pub struct PatternMatchValue {
|
|||
|
||||
/// See also [MatchSingleton](https://docs.python.org/3/library/ast.html#ast.MatchSingleton)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct PatternMatchSingleton {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -2774,6 +2823,7 @@ pub struct PatternMatchSingleton {
|
|||
|
||||
/// See also [MatchSequence](https://docs.python.org/3/library/ast.html#ast.MatchSequence)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct PatternMatchSequence {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -2782,6 +2832,7 @@ pub struct PatternMatchSequence {
|
|||
|
||||
/// See also [MatchMapping](https://docs.python.org/3/library/ast.html#ast.MatchMapping)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct PatternMatchMapping {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -2792,6 +2843,7 @@ pub struct PatternMatchMapping {
|
|||
|
||||
/// See also [MatchClass](https://docs.python.org/3/library/ast.html#ast.MatchClass)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct PatternMatchClass {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -2804,6 +2856,7 @@ pub struct PatternMatchClass {
|
|||
///
|
||||
/// Like [`Arguments`], but for [`PatternMatchClass`].
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct PatternArguments {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -2816,6 +2869,7 @@ pub struct PatternArguments {
|
|||
///
|
||||
/// Like [`Keyword`], but for [`PatternMatchClass`].
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct PatternKeyword {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -2825,6 +2879,7 @@ pub struct PatternKeyword {
|
|||
|
||||
/// See also [MatchStar](https://docs.python.org/3/library/ast.html#ast.MatchStar)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct PatternMatchStar {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -2833,6 +2888,7 @@ pub struct PatternMatchStar {
|
|||
|
||||
/// See also [MatchAs](https://docs.python.org/3/library/ast.html#ast.MatchAs)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct PatternMatchAs {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -2842,6 +2898,7 @@ pub struct PatternMatchAs {
|
|||
|
||||
/// See also [MatchOr](https://docs.python.org/3/library/ast.html#ast.MatchOr)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct PatternMatchOr {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -2868,6 +2925,7 @@ impl TypeParam {
|
|||
|
||||
/// See also [TypeVar](https://docs.python.org/3/library/ast.html#ast.TypeVar)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct TypeParamTypeVar {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -2878,6 +2936,7 @@ pub struct TypeParamTypeVar {
|
|||
|
||||
/// See also [ParamSpec](https://docs.python.org/3/library/ast.html#ast.ParamSpec)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct TypeParamParamSpec {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -2887,6 +2946,7 @@ pub struct TypeParamParamSpec {
|
|||
|
||||
/// See also [TypeVarTuple](https://docs.python.org/3/library/ast.html#ast.TypeVarTuple)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct TypeParamTypeVarTuple {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -2896,6 +2956,7 @@ pub struct TypeParamTypeVarTuple {
|
|||
|
||||
/// See also [decorator](https://docs.python.org/3/library/ast.html#ast.decorator)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct Decorator {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -2970,6 +3031,7 @@ impl Ranged for AnyParameterRef<'_> {
|
|||
/// NOTE: This type differs from the original Python AST. See: [arguments](https://docs.python.org/3/library/ast.html#ast.arguments).
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Default)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct Parameters {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -3189,6 +3251,7 @@ impl<'a> IntoIterator for &'a Box<Parameters> {
|
|||
/// NOTE: This type is different from original Python AST.
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct ParameterWithDefault {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -3233,6 +3296,7 @@ impl ParameterWithDefault {
|
|||
/// typically used for `metaclass`, with any additional arguments being passed to the `metaclass`.
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct Arguments {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -3383,6 +3447,7 @@ impl Arguments {
|
|||
/// the `T`, `U`, and `V` type parameters in the order they appear in the source code.
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct TypeParams {
|
||||
pub range: TextRange,
|
||||
pub node_index: AtomicNodeIndex,
|
||||
|
@ -3406,6 +3471,7 @@ pub type Suite = Vec<Stmt>;
|
|||
///
|
||||
/// [IPython Syntax]: https://github.com/ipython/ipython/blob/635815e8f1ded5b764d66cacc80bbe25e9e2587f/IPython/core/inputtransformer2.py#L335-L343
|
||||
#[derive(PartialEq, Eq, Debug, Clone, Hash, Copy)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum IpyEscapeKind {
|
||||
/// Send line to underlying system shell (`!`).
|
||||
Shell,
|
||||
|
@ -3497,6 +3563,7 @@ impl IpyEscapeKind {
|
|||
/// ...
|
||||
/// ```
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct Identifier {
|
||||
pub id: Name,
|
||||
pub range: TextRange,
|
||||
|
@ -3572,6 +3639,7 @@ impl From<Identifier> for Name {
|
|||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Hash, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub enum Singleton {
|
||||
None,
|
||||
True,
|
||||
|
|
|
@ -5,6 +5,7 @@ use std::{fmt, str::FromStr};
|
|||
/// N.B. This does not necessarily represent a Python version that we actually support.
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
#[cfg_attr(feature = "cache", derive(ruff_macros::CacheKey))]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct PythonVersion {
|
||||
pub major: u8,
|
||||
pub minor: u8,
|
||||
|
|
|
@ -13,13 +13,14 @@ license = { workspace = true }
|
|||
[lib]
|
||||
|
||||
[dependencies]
|
||||
ruff_python_ast = { workspace = true }
|
||||
ruff_python_ast = { workspace = true, features = ["get-size"] }
|
||||
ruff_python_trivia = { workspace = true }
|
||||
ruff_text_size = { workspace = true }
|
||||
ruff_text_size = { workspace = true, features = ["get-size"] }
|
||||
|
||||
bitflags = { workspace = true }
|
||||
bstr = { workspace = true }
|
||||
compact_str = { workspace = true }
|
||||
get-size2 = { workspace = true }
|
||||
memchr = { workspace = true }
|
||||
rustc-hash = { workspace = true }
|
||||
static_assertions = { workspace = true }
|
||||
|
|
|
@ -7,7 +7,7 @@ use crate::{TokenKind, string::InterpolatedStringKind};
|
|||
|
||||
/// Represents represent errors that occur during parsing and are
|
||||
/// returned by the `parse_*` functions.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, get_size2::GetSize)]
|
||||
pub struct ParseError {
|
||||
pub error: ParseErrorType,
|
||||
pub location: TextRange,
|
||||
|
@ -49,7 +49,7 @@ impl ParseError {
|
|||
}
|
||||
|
||||
/// Represents the different types of errors that can occur during parsing of an f-string or t-string.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, get_size2::GetSize)]
|
||||
pub enum InterpolatedStringErrorType {
|
||||
/// Expected a right brace after an opened left brace.
|
||||
UnclosedLbrace,
|
||||
|
@ -95,7 +95,7 @@ impl std::fmt::Display for InterpolatedStringErrorType {
|
|||
}
|
||||
|
||||
/// Represents the different types of errors that can occur during parsing.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, get_size2::GetSize)]
|
||||
pub enum ParseErrorType {
|
||||
/// An unexpected error occurred.
|
||||
OtherError(String),
|
||||
|
@ -384,7 +384,7 @@ impl std::fmt::Display for LexicalError {
|
|||
}
|
||||
|
||||
/// Represents the different types of errors that can occur during lexing.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, get_size2::GetSize)]
|
||||
pub enum LexicalErrorType {
|
||||
// TODO: Can probably be removed, the places it is used seem to be able
|
||||
// to use the `UnicodeError` variant instead.
|
||||
|
@ -468,7 +468,7 @@ impl std::fmt::Display for LexicalErrorType {
|
|||
///
|
||||
/// An example of a version-related error is the use of a `match` statement before Python 3.10, when
|
||||
/// it was first introduced. See [`UnsupportedSyntaxErrorKind`] for other kinds of errors.
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
#[derive(Debug, PartialEq, Clone, get_size2::GetSize)]
|
||||
pub struct UnsupportedSyntaxError {
|
||||
pub kind: UnsupportedSyntaxErrorKind,
|
||||
pub range: TextRange,
|
||||
|
@ -483,28 +483,28 @@ impl Ranged for UnsupportedSyntaxError {
|
|||
}
|
||||
|
||||
/// The type of tuple unpacking for [`UnsupportedSyntaxErrorKind::StarTuple`].
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, get_size2::GetSize)]
|
||||
pub enum StarTupleKind {
|
||||
Return,
|
||||
Yield,
|
||||
}
|
||||
|
||||
/// The type of PEP 701 f-string error for [`UnsupportedSyntaxErrorKind::Pep701FString`].
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, get_size2::GetSize)]
|
||||
pub enum FStringKind {
|
||||
Backslash,
|
||||
Comment,
|
||||
NestedQuote,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, get_size2::GetSize)]
|
||||
pub enum UnparenthesizedNamedExprKind {
|
||||
SequenceIndex,
|
||||
SetLiteral,
|
||||
SetComprehension,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, get_size2::GetSize)]
|
||||
pub enum UnsupportedSyntaxErrorKind {
|
||||
Match,
|
||||
Walrus,
|
||||
|
@ -988,7 +988,7 @@ impl Display for UnsupportedSyntaxError {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, get_size2::GetSize)]
|
||||
pub enum RelaxedDecoratorError {
|
||||
CallExpression,
|
||||
Other(&'static str),
|
||||
|
|
|
@ -304,7 +304,7 @@ pub fn parse_unchecked_source(source: &str, source_type: PySourceType) -> Parsed
|
|||
}
|
||||
|
||||
/// Represents the parsed source code.
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
#[derive(Debug, PartialEq, Clone, get_size2::GetSize)]
|
||||
pub struct Parsed<T> {
|
||||
syntax: T,
|
||||
tokens: Tokens,
|
||||
|
@ -474,7 +474,7 @@ impl Parsed<ModExpression> {
|
|||
}
|
||||
|
||||
/// Tokens represents a vector of lexed [`Token`].
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, get_size2::GetSize)]
|
||||
pub struct Tokens {
|
||||
raw: Vec<Token>,
|
||||
}
|
||||
|
|
|
@ -890,7 +890,7 @@ impl SemanticSyntaxChecker {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, get_size2::GetSize)]
|
||||
pub struct SemanticSyntaxError {
|
||||
pub kind: SemanticSyntaxErrorKind,
|
||||
pub range: TextRange,
|
||||
|
@ -981,7 +981,7 @@ impl Display for SemanticSyntaxError {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, get_size2::GetSize)]
|
||||
pub enum SemanticSyntaxErrorKind {
|
||||
/// Represents the use of a `__future__` import after the beginning of a file.
|
||||
///
|
||||
|
@ -1303,7 +1303,7 @@ pub enum SemanticSyntaxErrorKind {
|
|||
NonlocalDeclarationAtModuleLevel,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, get_size2::GetSize)]
|
||||
pub enum AwaitOutsideAsyncFunctionKind {
|
||||
Await,
|
||||
AsyncFor,
|
||||
|
@ -1322,7 +1322,7 @@ impl Display for AwaitOutsideAsyncFunctionKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, get_size2::GetSize)]
|
||||
pub enum YieldOutsideFunctionKind {
|
||||
Yield,
|
||||
YieldFrom,
|
||||
|
@ -1345,7 +1345,7 @@ impl Display for YieldOutsideFunctionKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, get_size2::GetSize)]
|
||||
pub enum InvalidExpressionPosition {
|
||||
TypeVarBound,
|
||||
TypeVarDefault,
|
||||
|
@ -1370,7 +1370,7 @@ impl Display for InvalidExpressionPosition {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, get_size2::GetSize)]
|
||||
pub enum InvalidExpressionKind {
|
||||
Yield,
|
||||
NamedExpr,
|
||||
|
@ -1387,7 +1387,7 @@ impl Display for InvalidExpressionKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, get_size2::GetSize)]
|
||||
pub enum WriteToDebugKind {
|
||||
Store,
|
||||
Delete(PythonVersion),
|
||||
|
|
|
@ -17,7 +17,7 @@ use ruff_python_ast::str_prefix::{
|
|||
use ruff_python_ast::{AnyStringFlags, BoolOp, Int, IpyEscapeKind, Operator, StringFlags, UnaryOp};
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, get_size2::GetSize)]
|
||||
pub struct Token {
|
||||
/// The kind of the token.
|
||||
kind: TokenKind,
|
||||
|
@ -124,7 +124,7 @@ impl fmt::Debug for Token {
|
|||
}
|
||||
|
||||
/// A kind of a token.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord, get_size2::GetSize)]
|
||||
pub enum TokenKind {
|
||||
/// Token kind for a name, commonly known as an identifier.
|
||||
Name,
|
||||
|
@ -754,6 +754,8 @@ bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
impl get_size2::GetSize for TokenFlags {}
|
||||
|
||||
impl StringFlags for TokenFlags {
|
||||
fn quote_style(self) -> Quote {
|
||||
if self.intersects(TokenFlags::DOUBLE_QUOTES) {
|
||||
|
|
|
@ -15,12 +15,14 @@ license = { workspace = true }
|
|||
[dependencies]
|
||||
ruff_text_size = { workspace = true }
|
||||
|
||||
get-size2 = { workspace = true, optional = true }
|
||||
memchr = { workspace = true }
|
||||
serde = { workspace = true, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
[features]
|
||||
get-size = ["dep:get-size2"]
|
||||
serde = ["dep:serde", "ruff_text_size/serde"]
|
||||
|
||||
[lints]
|
||||
|
|
|
@ -163,6 +163,7 @@ impl SourceFileBuilder {
|
|||
///
|
||||
/// Cloning a [`SourceFile`] is cheap, because it only requires bumping a reference count.
|
||||
#[derive(Clone, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct SourceFile {
|
||||
inner: Arc<SourceFileInner>,
|
||||
}
|
||||
|
@ -225,6 +226,7 @@ impl Ord for SourceFile {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
struct SourceFileInner {
|
||||
name: Box<str>,
|
||||
code: Box<str>,
|
||||
|
|
|
@ -14,11 +14,13 @@ use serde::{Deserialize, Serialize};
|
|||
///
|
||||
/// Cloning a [`LineIndex`] is cheap because it only requires bumping a reference count.
|
||||
#[derive(Clone, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct LineIndex {
|
||||
inner: Arc<LineIndexInner>,
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
struct LineIndexInner {
|
||||
line_starts: Vec<TextSize>,
|
||||
kind: IndexKind,
|
||||
|
@ -534,6 +536,7 @@ impl Debug for LineIndex {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
enum IndexKind {
|
||||
/// Optimized index for an ASCII only document
|
||||
Ascii,
|
||||
|
|
|
@ -12,6 +12,7 @@ license = { workspace = true }
|
|||
|
||||
[dependencies]
|
||||
serde = { workspace = true, optional = true }
|
||||
get-size2 = { workspace = true, optional = true }
|
||||
schemars = { workspace = true, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
|
@ -20,6 +21,7 @@ static_assertions = { workspace = true }
|
|||
|
||||
[features]
|
||||
serde = ["dep:serde"]
|
||||
get-size = ["dep:get-size2"]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
@ -12,6 +12,7 @@ use {
|
|||
///
|
||||
/// It is a logic error for `start` to be greater than `end`.
|
||||
#[derive(Default, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct TextRange {
|
||||
// Invariant: start <= end
|
||||
start: TextSize,
|
||||
|
|
|
@ -21,6 +21,7 @@ use {
|
|||
/// These escape hatches are primarily required for unit testing and when
|
||||
/// converting from UTF-8 size to another coordinate space, such as UTF-16.
|
||||
#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
|
||||
pub struct TextSize {
|
||||
pub(crate) raw: u32,
|
||||
}
|
||||
|
|
|
@ -143,6 +143,13 @@ fn run_check(args: CheckCommand) -> anyhow::Result<ExitStatus> {
|
|||
main_loop.run(&mut db)?
|
||||
};
|
||||
|
||||
let mut stdout = stdout().lock();
|
||||
match std::env::var("TY_MEMORY_REPORT").as_deref() {
|
||||
Ok("short") => write!(stdout, "{}", db.salsa_memory_dump().display_short())?,
|
||||
Ok("full") => write!(stdout, "{}", db.salsa_memory_dump().display_full())?,
|
||||
_ => {}
|
||||
}
|
||||
|
||||
tracing::trace!("Counts for entire CLI run:\n{}", countme::get_all());
|
||||
|
||||
std::mem::forget(db);
|
||||
|
|
|
@ -27,6 +27,7 @@ anyhow = { workspace = true }
|
|||
camino = { workspace = true }
|
||||
colored = { workspace = true }
|
||||
crossbeam = { workspace = true }
|
||||
get-size2 = { workspace = true }
|
||||
globset = { workspace = true }
|
||||
notify = { workspace = true }
|
||||
pep440_rs = { workspace = true, features = ["version-ranges"] }
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use std::panic::{AssertUnwindSafe, RefUnwindSafe};
|
||||
use std::sync::Arc;
|
||||
use std::{cmp, fmt};
|
||||
|
||||
use crate::metadata::settings::file_settings;
|
||||
use crate::{DEFAULT_LINT_REGISTRY, DummyReporter};
|
||||
|
@ -108,6 +109,171 @@ impl ProjectDatabase {
|
|||
Arc::get_mut(&mut self.system)
|
||||
.expect("ref count should be 1 because `zalsa_mut` drops all other DB references.")
|
||||
}
|
||||
|
||||
/// Returns a [`SalsaMemoryDump`] that can be use to dump Salsa memory usage information
|
||||
/// to the CLI after a typechecker run.
|
||||
pub fn salsa_memory_dump(&self) -> SalsaMemoryDump {
|
||||
let salsa_db = self as &dyn salsa::Database;
|
||||
|
||||
let mut ingredients = salsa_db.structs_info();
|
||||
let mut memos = salsa_db.queries_info().into_iter().collect::<Vec<_>>();
|
||||
|
||||
ingredients.sort_by_key(|ingredient| cmp::Reverse(ingredient.size_of_fields()));
|
||||
memos.sort_by_key(|(_, memo)| cmp::Reverse(memo.size_of_fields()));
|
||||
|
||||
SalsaMemoryDump { ingredients, memos }
|
||||
}
|
||||
}
|
||||
|
||||
/// Stores memory usage information.
|
||||
pub struct SalsaMemoryDump {
|
||||
ingredients: Vec<salsa::IngredientInfo>,
|
||||
memos: Vec<(&'static str, salsa::IngredientInfo)>,
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
impl SalsaMemoryDump {
|
||||
/// Returns a short report that provides total memory usage information.
|
||||
pub fn display_short(&self) -> impl fmt::Display + '_ {
|
||||
struct DisplayShort<'a>(&'a SalsaMemoryDump);
|
||||
|
||||
impl fmt::Display for DisplayShort<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let mut total_fields = 0;
|
||||
let mut total_metadata = 0;
|
||||
for ingredient in &self.0.ingredients {
|
||||
total_metadata += ingredient.size_of_metadata();
|
||||
total_fields += ingredient.size_of_fields();
|
||||
}
|
||||
|
||||
let mut total_memo_fields = 0;
|
||||
let mut total_memo_metadata = 0;
|
||||
for (_, memo) in &self.0.memos {
|
||||
total_memo_fields += memo.size_of_fields();
|
||||
total_memo_metadata += memo.size_of_metadata();
|
||||
}
|
||||
|
||||
writeln!(f, "=======SALSA SUMMARY=======")?;
|
||||
|
||||
writeln!(
|
||||
f,
|
||||
"TOTAL MEMORY USAGE: {:.2}MB",
|
||||
(total_metadata + total_fields + total_memo_fields + total_memo_metadata)
|
||||
as f64
|
||||
/ 1_000_000.,
|
||||
)?;
|
||||
|
||||
writeln!(
|
||||
f,
|
||||
" struct metadata = {:.2}MB",
|
||||
total_metadata as f64 / 1_000_000.,
|
||||
)?;
|
||||
writeln!(
|
||||
f,
|
||||
" struct fields = {:.2}MB",
|
||||
total_fields as f64 / 1_000_000.,
|
||||
)?;
|
||||
writeln!(
|
||||
f,
|
||||
" memo metadata = {:.2}MB",
|
||||
total_memo_metadata as f64 / 1_000_000.,
|
||||
)?;
|
||||
writeln!(
|
||||
f,
|
||||
" memo fields = {:.2}MB",
|
||||
total_memo_fields as f64 / 1_000_000.
|
||||
)?;
|
||||
|
||||
writeln!(f, "QUERY COUNT: {}", self.0.memos.len())?;
|
||||
writeln!(f, "STRUCT COUNT: {}", self.0.ingredients.len())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
DisplayShort(self)
|
||||
}
|
||||
|
||||
/// Returns a short report that provides fine-grained memory usage information per
|
||||
/// Salsa ingredient.
|
||||
pub fn display_full(&self) -> impl fmt::Display + '_ {
|
||||
struct DisplayFull<'a>(&'a SalsaMemoryDump);
|
||||
|
||||
impl fmt::Display for DisplayFull<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
writeln!(f, "=======SALSA STRUCTS=======")?;
|
||||
|
||||
let mut total_fields = 0;
|
||||
let mut total_metadata = 0;
|
||||
for ingredient in &self.0.ingredients {
|
||||
total_metadata += ingredient.size_of_metadata();
|
||||
total_fields += ingredient.size_of_fields();
|
||||
|
||||
writeln!(
|
||||
f,
|
||||
"{:<50} metadata={:<8} fields={:<8} count={}",
|
||||
format!("`{}`", ingredient.debug_name()),
|
||||
format!("{:.2}MB", ingredient.size_of_metadata() as f64 / 1_000_000.),
|
||||
format!("{:.2}MB", ingredient.size_of_fields() as f64 / 1_000_000.),
|
||||
ingredient.count()
|
||||
)?;
|
||||
}
|
||||
|
||||
writeln!(f, "=======SALSA QUERIES=======")?;
|
||||
|
||||
let mut total_memo_fields = 0;
|
||||
let mut total_memo_metadata = 0;
|
||||
for (query_fn, memo) in &self.0.memos {
|
||||
total_memo_fields += memo.size_of_fields();
|
||||
total_memo_metadata += memo.size_of_metadata();
|
||||
|
||||
writeln!(f, "`{query_fn} -> {}`", memo.debug_name())?;
|
||||
|
||||
writeln!(
|
||||
f,
|
||||
" metadata={:<8} fields={:<8} count={}",
|
||||
format!("{:.2}MB", memo.size_of_metadata() as f64 / 1_000_000.),
|
||||
format!("{:.2}MB", memo.size_of_fields() as f64 / 1_000_000.),
|
||||
memo.count()
|
||||
)?;
|
||||
}
|
||||
|
||||
writeln!(f, "=======SALSA SUMMARY=======")?;
|
||||
writeln!(
|
||||
f,
|
||||
"TOTAL MEMORY USAGE: {:.2}MB",
|
||||
(total_metadata + total_fields + total_memo_fields + total_memo_metadata)
|
||||
as f64
|
||||
/ 1_000_000.,
|
||||
)?;
|
||||
|
||||
writeln!(
|
||||
f,
|
||||
" struct metadata = {:.2}MB",
|
||||
total_metadata as f64 / 1_000_000.,
|
||||
)?;
|
||||
writeln!(
|
||||
f,
|
||||
" struct fields = {:.2}MB",
|
||||
total_fields as f64 / 1_000_000.,
|
||||
)?;
|
||||
writeln!(
|
||||
f,
|
||||
" memo metadata = {:.2}MB",
|
||||
total_memo_metadata as f64 / 1_000_000.,
|
||||
)?;
|
||||
writeln!(
|
||||
f,
|
||||
" memo fields = {:.2}MB",
|
||||
total_memo_fields as f64 / 1_000_000.
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
DisplayFull(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Upcast<dyn SemanticDb> for ProjectDatabase {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::glob::{GlobFilterCheckMode, IncludeResult};
|
||||
use crate::metadata::options::{OptionDiagnostic, ToSettingsError};
|
||||
use crate::walk::{ProjectFilesFilter, ProjectFilesWalker};
|
||||
pub use db::{Db, ProjectDatabase};
|
||||
pub use db::{Db, ProjectDatabase, SalsaMemoryDump};
|
||||
use files::{Index, Indexed, IndexedFiles};
|
||||
use metadata::settings::Settings;
|
||||
pub use metadata::{ProjectMetadata, ProjectMetadataError};
|
||||
|
@ -159,7 +159,7 @@ impl Project {
|
|||
/// This is a salsa query to prevent re-computing queries if other, unrelated
|
||||
/// settings change. For example, we don't want that changing the terminal settings
|
||||
/// invalidates any type checking queries.
|
||||
#[salsa::tracked(returns(deref))]
|
||||
#[salsa::tracked(returns(deref), heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub fn rules(self, db: &dyn Db) -> Arc<RuleSelection> {
|
||||
self.settings(db).to_rules()
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ impl Override {
|
|||
}
|
||||
|
||||
/// Resolves the settings for a given file.
|
||||
#[salsa::tracked(returns(ref))]
|
||||
#[salsa::tracked(returns(ref), heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub(crate) fn file_settings(db: &dyn Db, file: File) -> FileSettings {
|
||||
let settings = db.project().settings(db);
|
||||
|
||||
|
@ -155,7 +155,7 @@ pub(crate) fn file_settings(db: &dyn Db, file: File) -> FileSettings {
|
|||
/// This is to make Salsa happy because it requires that queries with only a single argument
|
||||
/// take a salsa-struct as argument, which isn't the case here. The `()` enables salsa's
|
||||
/// automatic interning for the arguments.
|
||||
#[salsa::tracked]
|
||||
#[salsa::tracked(heap_size=get_size2::GetSize::get_heap_size)]
|
||||
fn merge_overrides(db: &dyn Db, overrides: Vec<Arc<InnerOverrideOptions>>, _: ()) -> FileSettings {
|
||||
let mut overrides = overrides.into_iter().rev();
|
||||
let mut merged = (*overrides.next().unwrap()).clone();
|
||||
|
@ -179,7 +179,7 @@ fn merge_overrides(db: &dyn Db, overrides: Vec<Arc<InnerOverrideOptions>>, _: ()
|
|||
}
|
||||
|
||||
/// The resolved settings for a file.
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
#[derive(Debug, Eq, PartialEq, Clone, get_size2::GetSize)]
|
||||
pub enum FileSettings {
|
||||
/// The file uses the global settings.
|
||||
Global,
|
||||
|
@ -197,7 +197,7 @@ impl FileSettings {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
#[derive(Debug, Eq, PartialEq, Clone, get_size2::GetSize)]
|
||||
pub struct OverrideSettings {
|
||||
pub(super) rules: RuleSelection,
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ colored = { workspace = true }
|
|||
compact_str = { workspace = true }
|
||||
countme = { workspace = true }
|
||||
drop_bomb = { workspace = true }
|
||||
get-size2 = { workspace = true }
|
||||
indexmap = { workspace = true }
|
||||
itertools = { workspace = true }
|
||||
ordermap = { workspace = true }
|
||||
|
|
|
@ -89,6 +89,8 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> get_size2::GetSize for AstNodeRef<T> {}
|
||||
|
||||
#[allow(clippy::missing_fields_in_debug)]
|
||||
impl<T> Debug for AstNodeRef<T>
|
||||
where
|
||||
|
|
|
@ -28,7 +28,7 @@ fn dunder_all_names_cycle_initial(_db: &dyn Db, _file: File) -> Option<FxHashSet
|
|||
|
||||
/// Returns a set of names in the `__all__` variable for `file`, [`None`] if it is not defined or
|
||||
/// if it contains invalid elements.
|
||||
#[salsa::tracked(returns(as_ref), cycle_fn=dunder_all_names_cycle_recover, cycle_initial=dunder_all_names_cycle_initial)]
|
||||
#[salsa::tracked(returns(as_ref), cycle_fn=dunder_all_names_cycle_recover, cycle_initial=dunder_all_names_cycle_initial, heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub(crate) fn dunder_all_names(db: &dyn Db, file: File) -> Option<FxHashSet<Name>> {
|
||||
let _span = tracing::trace_span!("dunder_all_names", file=?file.path(db)).entered();
|
||||
|
||||
|
|
|
@ -262,7 +262,7 @@ macro_rules! declare_lint {
|
|||
///
|
||||
/// Implements `PartialEq`, `Eq`, and `Hash` based on the `LintMetadata` pointer
|
||||
/// for fast comparison and lookup.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug, Clone, Copy, get_size2::GetSize)]
|
||||
pub struct LintId {
|
||||
definition: &'static LintMetadata,
|
||||
}
|
||||
|
@ -415,7 +415,7 @@ impl LintRegistry {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Error, Debug, Clone, PartialEq, Eq)]
|
||||
#[derive(Error, Debug, Clone, PartialEq, Eq, get_size2::GetSize)]
|
||||
pub enum GetLintError {
|
||||
/// The name maps to this removed lint.
|
||||
#[error("lint `{0}` has been removed")]
|
||||
|
@ -463,7 +463,7 @@ impl From<&'static LintMetadata> for LintEntry {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, get_size2::GetSize)]
|
||||
pub struct RuleSelection {
|
||||
/// Map with the severity for each enabled lint rule.
|
||||
///
|
||||
|
@ -541,7 +541,7 @@ impl RuleSelection {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Copy, Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Default, Copy, Clone, Debug, PartialEq, Eq, get_size2::GetSize)]
|
||||
pub enum LintSource {
|
||||
/// The user didn't enable the rule explicitly, instead it's enabled by default.
|
||||
#[default]
|
||||
|
|
|
@ -69,7 +69,7 @@ use ruff_index::{IndexVec, newtype_index};
|
|||
|
||||
/// A handle to an association list. Use [`ListStorage`] to access its elements, and
|
||||
/// [`ListBuilder`] to construct other lists based on this one.
|
||||
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, get_size2::GetSize)]
|
||||
pub(crate) struct List<K, V = ()> {
|
||||
last: Option<ListCellId>,
|
||||
_phantom: PhantomData<(K, V)>,
|
||||
|
@ -95,12 +95,12 @@ impl<K, V> Default for List<K, V> {
|
|||
}
|
||||
|
||||
#[newtype_index]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
#[derive(PartialOrd, Ord, get_size2::GetSize)]
|
||||
struct ListCellId;
|
||||
|
||||
/// Stores one or more association lists. This type provides read-only access to the lists. Use a
|
||||
/// [`ListBuilder`] to create lists.
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
#[derive(Debug, Eq, PartialEq, get_size2::GetSize)]
|
||||
pub(crate) struct ListStorage<K, V = ()> {
|
||||
cells: IndexVec<ListCellId, ListCell<K, V>>,
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ pub(crate) struct ListStorage<K, V = ()> {
|
|||
/// **Terminology**: The elements of a cons cell are usually called `head` and `tail` (assuming
|
||||
/// you're not in Lisp-land, where they're called `car` and `cdr`). The elements of a snoc cell
|
||||
/// are usually called `rest` and `last`.
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
#[derive(Debug, Eq, PartialEq, get_size2::GetSize)]
|
||||
struct ListCell<K, V> {
|
||||
rest: Option<ListCellId>,
|
||||
key: K,
|
||||
|
|
|
@ -13,7 +13,7 @@ use crate::{db::Db, module_resolver::file_to_module};
|
|||
/// A module name, e.g. `foo.bar`.
|
||||
///
|
||||
/// Always normalized to the absolute form (never a relative module name, i.e., never `.foo`).
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, get_size2::GetSize)]
|
||||
pub struct ModuleName(compact_str::CompactString);
|
||||
|
||||
impl ModuleName {
|
||||
|
|
|
@ -8,7 +8,7 @@ use super::path::SearchPath;
|
|||
use crate::module_name::ModuleName;
|
||||
|
||||
/// Representation of a Python module.
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Hash, get_size2::GetSize)]
|
||||
pub struct Module {
|
||||
inner: Arc<ModuleInner>,
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ impl std::fmt::Debug for Module {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Hash)]
|
||||
#[derive(PartialEq, Eq, Hash, get_size2::GetSize)]
|
||||
enum ModuleInner {
|
||||
/// A module that resolves to a file (`lib.py` or `package/__init__.py`)
|
||||
FileModule {
|
||||
|
@ -116,7 +116,7 @@ enum ModuleInner {
|
|||
NamespacePackage { name: ModuleName },
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, get_size2::GetSize)]
|
||||
pub enum ModuleKind {
|
||||
/// A single-file module (e.g. `foo.py` or `foo.pyi`)
|
||||
Module,
|
||||
|
@ -135,7 +135,7 @@ impl ModuleKind {
|
|||
}
|
||||
|
||||
/// Enumeration of various core stdlib modules in which important types are located
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum_macros::EnumString)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum_macros::EnumString, get_size2::GetSize)]
|
||||
#[cfg_attr(test, derive(strum_macros::EnumIter))]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum KnownModule {
|
||||
|
|
|
@ -371,7 +371,7 @@ impl From<SitePackagesDiscoveryError> for SearchPathValidationError {
|
|||
|
||||
type SearchPathResult<T> = Result<T, SearchPathValidationError>;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, get_size2::GetSize)]
|
||||
enum SearchPathInner {
|
||||
Extra(SystemPathBuf),
|
||||
FirstParty(SystemPathBuf),
|
||||
|
@ -406,7 +406,7 @@ enum SearchPathInner {
|
|||
/// or the "Editable" category. For the "First-party", "Site-packages"
|
||||
/// and "Standard-library" categories, however, there will always be exactly
|
||||
/// one search path from that category in any given list of search paths.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, get_size2::GetSize)]
|
||||
pub(crate) struct SearchPath(Arc<SearchPathInner>);
|
||||
|
||||
impl SearchPath {
|
||||
|
|
|
@ -30,7 +30,7 @@ pub fn resolve_module(db: &dyn Db, module_name: &ModuleName) -> Option<Module> {
|
|||
///
|
||||
/// This query should not be called directly. Instead, use [`resolve_module`]. It only exists
|
||||
/// because Salsa requires the module name to be an ingredient.
|
||||
#[salsa::tracked]
|
||||
#[salsa::tracked(heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub(crate) fn resolve_module_query<'db>(
|
||||
db: &'db dyn Db,
|
||||
module_name: ModuleNameIngredient<'db>,
|
||||
|
@ -95,7 +95,7 @@ impl std::fmt::Display for SystemOrVendoredPathRef<'_> {
|
|||
/// Resolves the module for the file with the given id.
|
||||
///
|
||||
/// Returns `None` if the file is not a module locatable via any of the known search paths.
|
||||
#[salsa::tracked]
|
||||
#[salsa::tracked(heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub(crate) fn file_to_module(db: &dyn Db, file: File) -> Option<Module> {
|
||||
let _span = tracing::trace_span!("file_to_module", ?file).entered();
|
||||
|
||||
|
@ -297,7 +297,7 @@ impl SearchPaths {
|
|||
/// The editable-install search paths for the first `site-packages` directory
|
||||
/// should come between the two `site-packages` directories when it comes to
|
||||
/// module-resolution priority.
|
||||
#[salsa::tracked(returns(deref))]
|
||||
#[salsa::tracked(returns(deref), heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub(crate) fn dynamic_resolution_paths(db: &dyn Db) -> Vec<SearchPath> {
|
||||
tracing::debug!("Resolving dynamic module resolution paths");
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use ruff_python_ast::{HasNodeIndex, NodeIndex};
|
||||
|
||||
/// Compact key for a node for use in a hash map.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, get_size2::GetSize)]
|
||||
pub(super) struct NodeKey(NodeIndex);
|
||||
|
||||
impl NodeKey {
|
||||
|
|
|
@ -18,7 +18,7 @@ pub(crate) use implicit_globals::{
|
|||
module_type_implicit_global_declaration, module_type_implicit_global_symbol,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, get_size2::GetSize)]
|
||||
pub(crate) enum Boundness {
|
||||
Bound,
|
||||
PossiblyUnbound,
|
||||
|
@ -50,7 +50,7 @@ impl Boundness {
|
|||
/// possibly_unbound: Place::Type(Type::IntLiteral(2), Boundness::PossiblyUnbound),
|
||||
/// non_existent: Place::Unbound,
|
||||
/// ```
|
||||
#[derive(Debug, Clone, PartialEq, Eq, salsa::Update)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
|
||||
pub(crate) enum Place<'db> {
|
||||
Type(Type<'db>, Boundness),
|
||||
Unbound,
|
||||
|
@ -497,7 +497,7 @@ pub(crate) type PlaceFromDeclarationsResult<'db> =
|
|||
/// that this comes with a [`CLASS_VAR`] type qualifier.
|
||||
///
|
||||
/// [`CLASS_VAR`]: crate::types::TypeQualifiers::CLASS_VAR
|
||||
#[derive(Debug, Clone, PartialEq, Eq, salsa::Update)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
|
||||
pub(crate) struct PlaceAndQualifiers<'db> {
|
||||
pub(crate) place: Place<'db>,
|
||||
pub(crate) qualifiers: TypeQualifiers,
|
||||
|
@ -625,7 +625,7 @@ fn place_cycle_initial<'db>(
|
|||
Place::bound(Type::Never).into()
|
||||
}
|
||||
|
||||
#[salsa::tracked(cycle_fn=place_cycle_recover, cycle_initial=place_cycle_initial)]
|
||||
#[salsa::tracked(cycle_fn=place_cycle_recover, cycle_initial=place_cycle_initial, heap_size=get_size2::GetSize::get_heap_size)]
|
||||
fn place_by_id<'db>(
|
||||
db: &'db dyn Db,
|
||||
scope: ScopeId<'db>,
|
||||
|
@ -1312,7 +1312,7 @@ mod implicit_globals {
|
|||
/// Conceptually this function could be a `Set` rather than a list,
|
||||
/// but the number of symbols declared in this scope is likely to be very small,
|
||||
/// so the cost of hashing the names is likely to be more expensive than it's worth.
|
||||
#[salsa::tracked(returns(deref))]
|
||||
#[salsa::tracked(returns(deref), heap_size=get_size2::GetSize::get_heap_size)]
|
||||
fn module_type_symbols<'db>(db: &'db dyn Db) -> smallvec::SmallVec<[ast::name::Name; 8]> {
|
||||
let Some(module_type) = KnownClass::ModuleType
|
||||
.to_class_literal(db)
|
||||
|
|
|
@ -24,6 +24,7 @@ use crate::semantic_index::place::{
|
|||
ScopeKind, ScopedPlaceId,
|
||||
};
|
||||
use crate::semantic_index::use_def::{EagerSnapshotKey, ScopedEagerSnapshotId, UseDefMap};
|
||||
use crate::util::get_size::untracked_arc_size;
|
||||
|
||||
pub mod ast_ids;
|
||||
mod builder;
|
||||
|
@ -46,7 +47,7 @@ type PlaceSet = hashbrown::HashTable<ScopedPlaceId>;
|
|||
/// Returns the semantic index for `file`.
|
||||
///
|
||||
/// Prefer using [`symbol_table`] when working with symbols from a single scope.
|
||||
#[salsa::tracked(returns(ref), no_eq)]
|
||||
#[salsa::tracked(returns(ref), no_eq, heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub(crate) fn semantic_index(db: &dyn Db, file: File) -> SemanticIndex<'_> {
|
||||
let _span = tracing::trace_span!("semantic_index", ?file).entered();
|
||||
|
||||
|
@ -60,7 +61,7 @@ pub(crate) fn semantic_index(db: &dyn Db, file: File) -> SemanticIndex<'_> {
|
|||
/// Using [`place_table`] over [`semantic_index`] has the advantage that
|
||||
/// Salsa can avoid invalidating dependent queries if this scope's place table
|
||||
/// is unchanged.
|
||||
#[salsa::tracked(returns(deref))]
|
||||
#[salsa::tracked(returns(deref), heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub(crate) fn place_table<'db>(db: &'db dyn Db, scope: ScopeId<'db>) -> Arc<PlaceTable> {
|
||||
let file = scope.file(db);
|
||||
let _span = tracing::trace_span!("place_table", scope=?scope.as_id(), ?file).entered();
|
||||
|
@ -80,7 +81,7 @@ pub(crate) fn place_table<'db>(db: &'db dyn Db, scope: ScopeId<'db>) -> Arc<Plac
|
|||
///
|
||||
/// - We cannot resolve relative imports (which aren't allowed in `import` statements) without
|
||||
/// knowing the name of the current module, and whether it's a package.
|
||||
#[salsa::tracked(returns(deref))]
|
||||
#[salsa::tracked(returns(deref), heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub(crate) fn imported_modules<'db>(db: &'db dyn Db, file: File) -> Arc<FxHashSet<ModuleName>> {
|
||||
semantic_index(db, file).imported_modules.clone()
|
||||
}
|
||||
|
@ -90,8 +91,8 @@ pub(crate) fn imported_modules<'db>(db: &'db dyn Db, file: File) -> Arc<FxHashSe
|
|||
/// Using [`use_def_map`] over [`semantic_index`] has the advantage that
|
||||
/// Salsa can avoid invalidating dependent queries if this scope's use-def map
|
||||
/// is unchanged.
|
||||
#[salsa::tracked(returns(deref))]
|
||||
pub(crate) fn use_def_map<'db>(db: &'db dyn Db, scope: ScopeId<'db>) -> Arc<UseDefMap<'db>> {
|
||||
#[salsa::tracked(returns(deref), heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub(crate) fn use_def_map<'db>(db: &'db dyn Db, scope: ScopeId<'db>) -> ArcUseDefMap<'db> {
|
||||
let file = scope.file(db);
|
||||
let _span = tracing::trace_span!("use_def_map", scope=?scope.as_id(), ?file).entered();
|
||||
let index = semantic_index(db, file);
|
||||
|
@ -116,7 +117,10 @@ pub(crate) fn attribute_assignments<'db, 's>(
|
|||
let place_table = index.place_table(function_scope_id);
|
||||
let place = place_table.place_id_by_instance_attribute_name(name)?;
|
||||
let use_def = &index.use_def_maps[function_scope_id];
|
||||
Some((use_def.end_of_scope_bindings(place), function_scope_id))
|
||||
Some((
|
||||
use_def.inner.end_of_scope_bindings(place),
|
||||
function_scope_id,
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -151,7 +155,7 @@ pub(crate) fn attribute_scopes<'db, 's>(
|
|||
}
|
||||
|
||||
/// Returns the module global scope of `file`.
|
||||
#[salsa::tracked]
|
||||
#[salsa::tracked(heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub(crate) fn global_scope(db: &dyn Db, file: File) -> ScopeId<'_> {
|
||||
let _span = tracing::trace_span!("global_scope", ?file).entered();
|
||||
|
||||
|
@ -166,7 +170,7 @@ pub(crate) enum EagerSnapshotResult<'map, 'db> {
|
|||
}
|
||||
|
||||
/// The place tables and use-def maps for all scopes in a file.
|
||||
#[derive(Debug, Update)]
|
||||
#[derive(Debug, Update, get_size2::GetSize)]
|
||||
pub(crate) struct SemanticIndex<'db> {
|
||||
/// List of all place tables in this file, indexed by scope.
|
||||
place_tables: IndexVec<FileScopeId, Arc<PlaceTable>>,
|
||||
|
@ -193,7 +197,7 @@ pub(crate) struct SemanticIndex<'db> {
|
|||
globals_by_scope: FxHashMap<FileScopeId, FxHashSet<ScopedPlaceId>>,
|
||||
|
||||
/// Use-def map for each scope in this file.
|
||||
use_def_maps: IndexVec<FileScopeId, Arc<UseDefMap<'db>>>,
|
||||
use_def_maps: IndexVec<FileScopeId, ArcUseDefMap<'db>>,
|
||||
|
||||
/// Lookup table to map between node ids and ast nodes.
|
||||
///
|
||||
|
@ -232,7 +236,7 @@ impl<'db> SemanticIndex<'db> {
|
|||
/// Use the Salsa cached [`use_def_map()`] query if you only need the
|
||||
/// use-def map for a single scope.
|
||||
#[track_caller]
|
||||
pub(super) fn use_def_map(&self, scope_id: FileScopeId) -> Arc<UseDefMap> {
|
||||
pub(super) fn use_def_map(&self, scope_id: FileScopeId) -> ArcUseDefMap<'_> {
|
||||
self.use_def_maps[scope_id].clone()
|
||||
}
|
||||
|
||||
|
@ -457,7 +461,7 @@ impl<'db> SemanticIndex<'db> {
|
|||
let Some(id) = self.eager_snapshots.get(&key) else {
|
||||
return EagerSnapshotResult::NotFound;
|
||||
};
|
||||
self.use_def_maps[enclosing_scope].eager_snapshot(*id)
|
||||
self.use_def_maps[enclosing_scope].inner.eager_snapshot(*id)
|
||||
}
|
||||
|
||||
pub(crate) fn semantic_syntax_errors(&self) -> &[SemanticSyntaxError] {
|
||||
|
@ -465,6 +469,28 @@ impl<'db> SemanticIndex<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, salsa::Update, get_size2::GetSize)]
|
||||
pub(crate) struct ArcUseDefMap<'db> {
|
||||
#[get_size(size_fn = untracked_arc_size)]
|
||||
inner: Arc<UseDefMap<'db>>,
|
||||
}
|
||||
|
||||
impl<'db> std::ops::Deref for ArcUseDefMap<'db> {
|
||||
type Target = UseDefMap<'db>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl<'db> ArcUseDefMap<'db> {
|
||||
pub(crate) fn new(inner: UseDefMap<'db>) -> Self {
|
||||
Self {
|
||||
inner: Arc::new(inner),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AncestorsIter<'a> {
|
||||
scopes: &'a IndexSlice<FileScopeId, Scope>,
|
||||
next_id: Option<FileScopeId>,
|
||||
|
|
|
@ -24,7 +24,7 @@ use crate::semantic_index::semantic_index;
|
|||
///
|
||||
/// x = foo()
|
||||
/// ```
|
||||
#[derive(Debug, salsa::Update)]
|
||||
#[derive(Debug, salsa::Update, get_size2::GetSize)]
|
||||
pub(crate) struct AstIds {
|
||||
/// Maps expressions to their expression id.
|
||||
expressions_map: FxHashMap<ExpressionNodeKey, ScopedExpressionId>,
|
||||
|
@ -51,6 +51,7 @@ fn ast_ids<'db>(db: &'db dyn Db, scope: ScopeId) -> &'db AstIds {
|
|||
|
||||
/// Uniquely identifies a use of a name in a [`crate::semantic_index::place::FileScopeId`].
|
||||
#[newtype_index]
|
||||
#[derive(get_size2::GetSize)]
|
||||
pub struct ScopedUseId;
|
||||
|
||||
pub trait HasScopedUseId {
|
||||
|
@ -95,7 +96,7 @@ impl HasScopedUseId for ast::ExprRef<'_> {
|
|||
|
||||
/// Uniquely identifies an [`ast::Expr`] in a [`crate::semantic_index::place::FileScopeId`].
|
||||
#[newtype_index]
|
||||
#[derive(salsa::Update)]
|
||||
#[derive(salsa::Update, get_size2::GetSize)]
|
||||
pub struct ScopedExpressionId;
|
||||
|
||||
pub trait HasScopedExpressionId {
|
||||
|
@ -203,7 +204,7 @@ pub(crate) mod node_key {
|
|||
|
||||
use crate::node_key::NodeKey;
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, salsa::Update)]
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, salsa::Update, get_size2::GetSize)]
|
||||
pub(crate) struct ExpressionNodeKey(NodeKey);
|
||||
|
||||
impl From<ast::ExprRef<'_>> for ExpressionNodeKey {
|
||||
|
|
|
@ -20,7 +20,6 @@ use crate::ast_node_ref::AstNodeRef;
|
|||
use crate::module_name::ModuleName;
|
||||
use crate::module_resolver::resolve_module;
|
||||
use crate::node_key::NodeKey;
|
||||
use crate::semantic_index::SemanticIndex;
|
||||
use crate::semantic_index::ast_ids::AstIdsBuilder;
|
||||
use crate::semantic_index::ast_ids::node_key::ExpressionNodeKey;
|
||||
use crate::semantic_index::definition::{
|
||||
|
@ -46,6 +45,7 @@ use crate::semantic_index::reachability_constraints::{
|
|||
use crate::semantic_index::use_def::{
|
||||
EagerSnapshotKey, FlowSnapshot, ScopedEagerSnapshotId, UseDefMapBuilder,
|
||||
};
|
||||
use crate::semantic_index::{ArcUseDefMap, SemanticIndex};
|
||||
use crate::unpack::{Unpack, UnpackKind, UnpackPosition, UnpackValue};
|
||||
use crate::{Db, Program};
|
||||
|
||||
|
@ -998,7 +998,7 @@ impl<'db, 'ast> SemanticIndexBuilder<'db, 'ast> {
|
|||
let mut use_def_maps: IndexVec<_, _> = self
|
||||
.use_def_maps
|
||||
.into_iter()
|
||||
.map(|builder| Arc::new(builder.finish()))
|
||||
.map(|builder| ArcUseDefMap::new(builder.finish()))
|
||||
.collect();
|
||||
|
||||
let mut ast_ids: IndexVec<_, _> = self
|
||||
|
|
|
@ -44,6 +44,9 @@ pub struct Definition<'db> {
|
|||
count: countme::Count<Definition<'static>>,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for Definition<'_> {}
|
||||
|
||||
impl<'db> Definition<'db> {
|
||||
pub(crate) fn scope(self, db: &'db dyn Db) -> ScopeId<'db> {
|
||||
self.file_scope(db).to_scope_id(db, self.file(db))
|
||||
|
@ -59,16 +62,20 @@ impl<'db> Definition<'db> {
|
|||
}
|
||||
|
||||
/// One or more [`Definition`]s.
|
||||
#[derive(Debug, Default, PartialEq, Eq, salsa::Update)]
|
||||
pub struct Definitions<'db>(smallvec::SmallVec<[Definition<'db>; 1]>);
|
||||
#[derive(Debug, Default, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
|
||||
pub struct Definitions<'db> {
|
||||
definitions: smallvec::SmallVec<[Definition<'db>; 1]>,
|
||||
}
|
||||
|
||||
impl<'db> Definitions<'db> {
|
||||
pub(crate) fn single(definition: Definition<'db>) -> Self {
|
||||
Self(smallvec::smallvec![definition])
|
||||
Self {
|
||||
definitions: smallvec::smallvec![definition],
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn push(&mut self, definition: Definition<'db>) {
|
||||
self.0.push(definition);
|
||||
self.definitions.push(definition);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,7 +83,7 @@ impl<'db> Deref for Definitions<'db> {
|
|||
type Target = [Definition<'db>];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
&self.definitions
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,11 +92,11 @@ impl<'a, 'db> IntoIterator for &'a Definitions<'db> {
|
|||
type IntoIter = std::slice::Iter<'a, Definition<'db>>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.0.iter()
|
||||
self.definitions.iter()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, salsa::Update)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
|
||||
pub(crate) enum DefinitionState<'db> {
|
||||
Defined(Definition<'db>),
|
||||
/// Represents the implicit "unbound"/"undeclared" definition of every place.
|
||||
|
@ -999,7 +1006,7 @@ impl ExceptHandlerDefinitionKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, salsa::Update)]
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, salsa::Update, get_size2::GetSize)]
|
||||
pub(crate) struct DefinitionNodeKey(NodeKey);
|
||||
|
||||
impl From<&ast::Alias> for DefinitionNodeKey {
|
||||
|
|
|
@ -62,6 +62,9 @@ pub(crate) struct Expression<'db> {
|
|||
count: countme::Count<Expression<'static>>,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for Expression<'_> {}
|
||||
|
||||
impl<'db> Expression<'db> {
|
||||
pub(crate) fn node_ref<'ast>(
|
||||
self,
|
||||
|
|
|
@ -55,7 +55,7 @@ pub(crate) enum ConstraintKey {
|
|||
/// [`ScopedPredicateId`] to refer to the underlying predicate.
|
||||
///
|
||||
/// [`Predicate`]: crate::semantic_index::predicate::Predicate
|
||||
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, get_size2::GetSize)]
|
||||
pub(crate) struct ScopedNarrowingConstraintPredicate(ScopedPredicateId);
|
||||
|
||||
impl ScopedNarrowingConstraintPredicate {
|
||||
|
@ -72,7 +72,7 @@ impl From<ScopedPredicateId> for ScopedNarrowingConstraintPredicate {
|
|||
}
|
||||
|
||||
/// A collection of narrowing constraints for a given scope.
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
#[derive(Debug, Eq, PartialEq, get_size2::GetSize)]
|
||||
pub(crate) struct NarrowingConstraints {
|
||||
lists: ListStorage<ScopedNarrowingConstraintPredicate>,
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ use crate::node_key::NodeKey;
|
|||
use crate::semantic_index::reachability_constraints::ScopedReachabilityConstraintId;
|
||||
use crate::semantic_index::{PlaceSet, SemanticIndex, semantic_index};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, get_size2::GetSize)]
|
||||
pub(crate) enum PlaceExprSubSegment {
|
||||
/// A member access, e.g. `.y` in `x.y`
|
||||
Member(ast::name::Name),
|
||||
|
@ -38,7 +38,7 @@ impl PlaceExprSubSegment {
|
|||
}
|
||||
|
||||
/// An expression that can be the target of a `Definition`.
|
||||
#[derive(Eq, PartialEq, Debug)]
|
||||
#[derive(Eq, PartialEq, Debug, get_size2::GetSize)]
|
||||
pub struct PlaceExpr {
|
||||
root_name: Name,
|
||||
sub_segments: SmallVec<[PlaceExprSubSegment; 1]>,
|
||||
|
@ -217,7 +217,7 @@ impl PlaceExpr {
|
|||
}
|
||||
|
||||
/// A [`PlaceExpr`] with flags, e.g. whether it is used, bound, an instance attribute, etc.
|
||||
#[derive(Eq, PartialEq, Debug)]
|
||||
#[derive(Eq, PartialEq, Debug, get_size2::GetSize)]
|
||||
pub struct PlaceExprWithFlags {
|
||||
pub(crate) expr: PlaceExpr,
|
||||
flags: PlaceFlags,
|
||||
|
@ -405,6 +405,8 @@ bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
impl get_size2::GetSize for PlaceFlags {}
|
||||
|
||||
/// ID that uniquely identifies a place in a file.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
pub struct FilePlaceId {
|
||||
|
@ -430,7 +432,7 @@ impl From<FilePlaceId> for ScopedPlaceId {
|
|||
|
||||
/// ID that uniquely identifies a place inside a [`Scope`].
|
||||
#[newtype_index]
|
||||
#[derive(salsa::Update)]
|
||||
#[derive(salsa::Update, get_size2::GetSize)]
|
||||
pub struct ScopedPlaceId;
|
||||
|
||||
/// A cross-module identifier of a scope that can be used as a salsa query parameter.
|
||||
|
@ -443,6 +445,9 @@ pub struct ScopeId<'db> {
|
|||
count: countme::Count<ScopeId<'static>>,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for ScopeId<'_> {}
|
||||
|
||||
impl<'db> ScopeId<'db> {
|
||||
pub(crate) fn is_function_like(self, db: &'db dyn Db) -> bool {
|
||||
self.node(db).scope_kind().is_function_like()
|
||||
|
@ -489,7 +494,7 @@ impl<'db> ScopeId<'db> {
|
|||
|
||||
/// ID that uniquely identifies a scope inside of a module.
|
||||
#[newtype_index]
|
||||
#[derive(salsa::Update)]
|
||||
#[derive(salsa::Update, get_size2::GetSize)]
|
||||
pub struct FileScopeId;
|
||||
|
||||
impl FileScopeId {
|
||||
|
@ -512,7 +517,7 @@ impl FileScopeId {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, salsa::Update)]
|
||||
#[derive(Debug, salsa::Update, get_size2::GetSize)]
|
||||
pub struct Scope {
|
||||
parent: Option<FileScopeId>,
|
||||
node: NodeWithScopeKind,
|
||||
|
@ -609,7 +614,7 @@ impl ScopeKind {
|
|||
}
|
||||
|
||||
/// [`PlaceExpr`] table for a specific [`Scope`].
|
||||
#[derive(Default)]
|
||||
#[derive(Default, get_size2::GetSize)]
|
||||
pub struct PlaceTable {
|
||||
/// The place expressions in this scope.
|
||||
places: IndexVec<ScopedPlaceId, PlaceExprWithFlags>,
|
||||
|
@ -932,7 +937,7 @@ impl NodeWithScopeRef<'_> {
|
|||
}
|
||||
|
||||
/// Node that introduces a new scope.
|
||||
#[derive(Clone, Debug, salsa::Update)]
|
||||
#[derive(Clone, Debug, salsa::Update, get_size2::GetSize)]
|
||||
pub enum NodeWithScopeKind {
|
||||
Module,
|
||||
Class(AstNodeRef<ast::StmtClassDef>),
|
||||
|
@ -1011,7 +1016,7 @@ impl NodeWithScopeKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, get_size2::GetSize)]
|
||||
pub(crate) enum NodeWithScopeKey {
|
||||
Module,
|
||||
Class(NodeKey),
|
||||
|
|
|
@ -18,7 +18,7 @@ use crate::semantic_index::place::{FileScopeId, ScopeId, ScopedPlaceId};
|
|||
|
||||
// A scoped identifier for each `Predicate` in a scope.
|
||||
#[newtype_index]
|
||||
#[derive(Ord, PartialOrd)]
|
||||
#[derive(Ord, PartialOrd, get_size2::GetSize)]
|
||||
pub(crate) struct ScopedPredicateId;
|
||||
|
||||
// A collection of predicates for a given scope.
|
||||
|
@ -43,7 +43,7 @@ impl<'db> PredicatesBuilder<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, salsa::Update)]
|
||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
|
||||
pub(crate) struct Predicate<'db> {
|
||||
pub(crate) node: PredicateNode<'db>,
|
||||
pub(crate) is_positive: bool,
|
||||
|
@ -58,7 +58,7 @@ impl Predicate<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, salsa::Update)]
|
||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
|
||||
pub(crate) enum PredicateNode<'db> {
|
||||
Expression(Expression<'db>),
|
||||
Pattern(PatternPredicate<'db>),
|
||||
|
@ -91,6 +91,9 @@ pub(crate) struct PatternPredicate<'db> {
|
|||
count: countme::Count<PatternPredicate<'static>>,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for PatternPredicate<'_> {}
|
||||
|
||||
impl<'db> PatternPredicate<'db> {
|
||||
pub(crate) fn scope(self, db: &'db dyn Db) -> ScopeId<'db> {
|
||||
self.file_scope(db).to_scope_id(db, self.file(db))
|
||||
|
@ -155,6 +158,9 @@ pub(crate) struct StarImportPlaceholderPredicate<'db> {
|
|||
pub(crate) referenced_file: File,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for StarImportPlaceholderPredicate<'_> {}
|
||||
|
||||
impl<'db> StarImportPlaceholderPredicate<'db> {
|
||||
pub(crate) fn scope(self, db: &'db dyn Db) -> ScopeId<'db> {
|
||||
// See doc-comment above [`StarImportPlaceholderPredicate::symbol_id`]:
|
||||
|
|
|
@ -43,7 +43,7 @@ fn exports_cycle_initial(_db: &dyn Db, _file: File) -> Box<[Name]> {
|
|||
Box::default()
|
||||
}
|
||||
|
||||
#[salsa::tracked(returns(deref), cycle_fn=exports_cycle_recover, cycle_initial=exports_cycle_initial)]
|
||||
#[salsa::tracked(returns(deref), cycle_fn=exports_cycle_recover, cycle_initial=exports_cycle_initial, heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub(super) fn exported_names(db: &dyn Db, file: File) -> Box<[Name]> {
|
||||
let module = parsed_module(db.upcast(), file).load(db.upcast());
|
||||
let mut finder = ExportFinder::new(db, file);
|
||||
|
|
|
@ -226,7 +226,7 @@ use crate::types::{Truthiness, Type, infer_expression_type};
|
|||
///
|
||||
/// reachability constraints are normalized, so equivalent constraints are guaranteed to have equal
|
||||
/// IDs.
|
||||
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
|
||||
#[derive(Clone, Copy, Eq, Hash, PartialEq, get_size2::GetSize)]
|
||||
pub(crate) struct ScopedReachabilityConstraintId(u32);
|
||||
|
||||
impl std::fmt::Debug for ScopedReachabilityConstraintId {
|
||||
|
@ -255,7 +255,7 @@ impl std::fmt::Debug for ScopedReachabilityConstraintId {
|
|||
// _Interior nodes_ provide the TDD structure for the formula. Interior nodes are stored in an
|
||||
// arena Vec, with the constraint ID providing an index into the arena.
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, get_size2::GetSize)]
|
||||
struct InteriorNode {
|
||||
/// A "variable" that is evaluated as part of a TDD ternary function. For reachability
|
||||
/// constraints, this is a `Predicate` that represents some runtime property of the Python
|
||||
|
@ -306,7 +306,7 @@ const ALWAYS_FALSE: ScopedReachabilityConstraintId = ScopedReachabilityConstrain
|
|||
const SMALLEST_TERMINAL: ScopedReachabilityConstraintId = ALWAYS_FALSE;
|
||||
|
||||
/// A collection of reachability constraints for a given scope.
|
||||
#[derive(Debug, PartialEq, Eq, salsa::Update)]
|
||||
#[derive(Debug, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
|
||||
pub(crate) struct ReachabilityConstraints {
|
||||
interiors: IndexVec<ScopedReachabilityConstraintId, InteriorNode>,
|
||||
}
|
||||
|
|
|
@ -259,7 +259,7 @@ use crate::types::{IntersectionBuilder, Truthiness, Type, infer_narrowing_constr
|
|||
mod place_state;
|
||||
|
||||
/// Applicable definitions and constraints for every use of a name.
|
||||
#[derive(Debug, PartialEq, Eq, salsa::Update)]
|
||||
#[derive(Debug, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
|
||||
pub(crate) struct UseDefMap<'db> {
|
||||
/// Array of [`Definition`] in this scope. Only the first entry should be [`DefinitionState::Undefined`];
|
||||
/// this represents the implicit "unbound"/"undeclared" definition of every place.
|
||||
|
@ -549,9 +549,10 @@ impl<'db> UseDefMap<'db> {
|
|||
///
|
||||
/// There is a unique ID for each distinct [`EagerSnapshotKey`] in the file.
|
||||
#[newtype_index]
|
||||
#[derive(get_size2::GetSize)]
|
||||
pub(crate) struct ScopedEagerSnapshotId;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, get_size2::GetSize)]
|
||||
pub(crate) struct EagerSnapshotKey {
|
||||
/// The enclosing scope containing the bindings
|
||||
pub(crate) enclosing_scope: FileScopeId,
|
||||
|
@ -680,7 +681,7 @@ impl<'db> Iterator for DeclarationsIterator<'_, 'db> {
|
|||
|
||||
impl std::iter::FusedIterator for DeclarationsIterator<'_, '_> {}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, salsa::Update)]
|
||||
#[derive(Debug, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
|
||||
struct ReachableDefinitions {
|
||||
bindings: Bindings,
|
||||
declarations: Declarations,
|
||||
|
|
|
@ -55,7 +55,7 @@ use crate::semantic_index::reachability_constraints::{
|
|||
|
||||
/// A newtype-index for a definition in a particular scope.
|
||||
#[newtype_index]
|
||||
#[derive(Ord, PartialOrd)]
|
||||
#[derive(Ord, PartialOrd, get_size2::GetSize)]
|
||||
pub(super) struct ScopedDefinitionId;
|
||||
|
||||
impl ScopedDefinitionId {
|
||||
|
@ -77,14 +77,14 @@ const INLINE_DEFINITIONS_PER_PLACE: usize = 4;
|
|||
|
||||
/// Live declarations for a single place at some point in control flow, with their
|
||||
/// corresponding reachability constraints.
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, salsa::Update)]
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
|
||||
pub(super) struct Declarations {
|
||||
/// A list of live declarations for this place, sorted by their `ScopedDefinitionId`
|
||||
live_declarations: SmallVec<[LiveDeclaration; INLINE_DEFINITIONS_PER_PLACE]>,
|
||||
}
|
||||
|
||||
/// One of the live declarations for a single place at some point in control flow.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, get_size2::GetSize)]
|
||||
pub(super) struct LiveDeclaration {
|
||||
pub(super) declaration: ScopedDefinitionId,
|
||||
pub(super) reachability_constraint: ScopedReachabilityConstraintId,
|
||||
|
@ -183,7 +183,7 @@ impl Declarations {
|
|||
/// Even if it's a class scope (class variables are not visible to nested scopes) or there are no
|
||||
/// bindings, the current narrowing constraint is necessary for narrowing, so it's stored in
|
||||
/// `Constraint`.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, salsa::Update)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
|
||||
pub(super) enum EagerSnapshot {
|
||||
Constraint(ScopedNarrowingConstraint),
|
||||
Bindings(Bindings),
|
||||
|
@ -191,7 +191,7 @@ pub(super) enum EagerSnapshot {
|
|||
|
||||
/// Live bindings for a single place at some point in control flow. Each live binding comes
|
||||
/// with a set of narrowing constraints and a reachability constraint.
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, salsa::Update)]
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
|
||||
pub(super) struct Bindings {
|
||||
/// The narrowing constraint applicable to the "unbound" binding, if we need access to it even
|
||||
/// when it's not visible. This happens in class scopes, where local name bindings are not visible
|
||||
|
@ -210,7 +210,7 @@ impl Bindings {
|
|||
}
|
||||
|
||||
/// One of the live bindings for a single place at some point in control flow.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, get_size2::GetSize)]
|
||||
pub(super) struct LiveBinding {
|
||||
pub(super) binding: ScopedDefinitionId,
|
||||
pub(super) narrowing_constraint: ScopedNarrowingConstraint,
|
||||
|
@ -338,7 +338,7 @@ impl Bindings {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, get_size2::GetSize)]
|
||||
pub(in crate::semantic_index) struct PlaceState {
|
||||
declarations: Declarations,
|
||||
bindings: Bindings,
|
||||
|
|
|
@ -86,7 +86,7 @@ declare_lint! {
|
|||
}
|
||||
}
|
||||
|
||||
#[salsa::tracked(returns(ref))]
|
||||
#[salsa::tracked(returns(ref), heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub(crate) fn suppressions(db: &dyn Db, file: File) -> Suppressions {
|
||||
let parsed = parsed_module(db.upcast(), file).load(db.upcast());
|
||||
let source = source_text(db.upcast(), file);
|
||||
|
@ -331,7 +331,7 @@ impl<'a> CheckSuppressionsContext<'a> {
|
|||
}
|
||||
|
||||
/// The suppressions of a single file.
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
#[derive(Debug, Eq, PartialEq, get_size2::GetSize)]
|
||||
pub(crate) struct Suppressions {
|
||||
/// Suppressions that apply to the entire file.
|
||||
///
|
||||
|
@ -424,7 +424,7 @@ impl<'a> IntoIterator for &'a Suppressions {
|
|||
/// Suppression comments that suppress multiple codes
|
||||
/// create multiple suppressions: one for every code.
|
||||
/// They all share the same `comment_range`.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, get_size2::GetSize)]
|
||||
pub(crate) struct Suppression {
|
||||
target: SuppressionTarget,
|
||||
kind: SuppressionKind,
|
||||
|
@ -466,10 +466,10 @@ impl Suppression {
|
|||
/// The wrapped `TextRange` is the suppression's range.
|
||||
/// This is unique enough because it is its exact
|
||||
/// location in the source.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, get_size2::GetSize)]
|
||||
pub(crate) struct FileSuppressionId(TextRange);
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, get_size2::GetSize)]
|
||||
enum SuppressionTarget {
|
||||
/// Suppress all lints
|
||||
All,
|
||||
|
@ -628,7 +628,7 @@ impl<'a> SuppressionsBuilder<'a> {
|
|||
}
|
||||
|
||||
/// Suppression for an unknown lint rule.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[derive(Debug, PartialEq, Eq, get_size2::GetSize)]
|
||||
struct UnknownSuppression {
|
||||
/// The range of the code.
|
||||
range: TextRange,
|
||||
|
@ -639,7 +639,7 @@ struct UnknownSuppression {
|
|||
reason: GetLintError,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[derive(Debug, PartialEq, Eq, get_size2::GetSize)]
|
||||
struct InvalidSuppression {
|
||||
kind: SuppressionKind,
|
||||
error: ParseError,
|
||||
|
@ -843,7 +843,7 @@ struct SuppressionComment {
|
|||
codes: Option<SmallVec<[TextRange; 2]>>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, get_size2::GetSize)]
|
||||
enum SuppressionKind {
|
||||
TypeIgnore,
|
||||
Ty,
|
||||
|
@ -871,7 +871,7 @@ impl fmt::Display for SuppressionKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
#[derive(Debug, Eq, PartialEq, Clone, get_size2::GetSize)]
|
||||
struct ParseError {
|
||||
kind: ParseErrorKind,
|
||||
|
||||
|
@ -893,7 +893,7 @@ impl fmt::Display for ParseError {
|
|||
|
||||
impl Error for ParseError {}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Error)]
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Error, get_size2::GetSize)]
|
||||
enum ParseErrorKind {
|
||||
/// The comment isn't a suppression comment.
|
||||
#[error("not a suppression comment")]
|
||||
|
|
|
@ -85,7 +85,7 @@ mod definition;
|
|||
#[cfg(test)]
|
||||
mod property_tests;
|
||||
|
||||
#[salsa::tracked(returns(ref))]
|
||||
#[salsa::tracked(returns(ref), heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub fn check_types(db: &dyn Db, file: File) -> TypeCheckDiagnostics {
|
||||
let _span = tracing::trace_span!("check_types", ?file).entered();
|
||||
|
||||
|
@ -160,7 +160,7 @@ fn definition_expression_type<'db>(
|
|||
/// define a `__get__` method, while data descriptors additionally define a `__set__`
|
||||
/// method or a `__delete__` method. This enum is used to categorize attributes into two
|
||||
/// groups: (1) data descriptors and (2) normal attributes or non-data descriptors.
|
||||
#[derive(Clone, Debug, Copy, PartialEq, Eq, Hash, salsa::Update)]
|
||||
#[derive(Clone, Debug, Copy, PartialEq, Eq, Hash, salsa::Update, get_size2::GetSize)]
|
||||
pub(crate) enum AttributeKind {
|
||||
DataDescriptor,
|
||||
NormalOrNonDataDescriptor,
|
||||
|
@ -284,7 +284,7 @@ fn class_lookup_cycle_initial<'db>(
|
|||
|
||||
/// Meta data for `Type::Todo`, which represents a known limitation in ty.
|
||||
#[cfg(debug_assertions)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, get_size2::GetSize)]
|
||||
pub struct TodoType(pub &'static str);
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
|
@ -295,7 +295,7 @@ impl std::fmt::Display for TodoType {
|
|||
}
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, get_size2::GetSize)]
|
||||
pub struct TodoType;
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
|
@ -370,6 +370,9 @@ pub struct PropertyInstanceType<'db> {
|
|||
setter: Option<Type<'db>>,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for PropertyInstanceType<'_> {}
|
||||
|
||||
impl<'db> PropertyInstanceType<'db> {
|
||||
fn apply_type_mapping<'a>(self, db: &'db dyn Db, type_mapping: &TypeMapping<'a, 'db>) -> Self {
|
||||
let getter = self
|
||||
|
@ -423,6 +426,8 @@ bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
impl get_size2::GetSize for DataclassParams {}
|
||||
|
||||
impl Default for DataclassParams {
|
||||
fn default() -> Self {
|
||||
Self::INIT | Self::REPR | Self::EQ | Self::MATCH_ARGS
|
||||
|
@ -456,7 +461,7 @@ impl From<DataclassTransformerParams> for DataclassParams {
|
|||
|
||||
/// Representation of a type: a set of possible values at runtime.
|
||||
///
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, salsa::Update)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, salsa::Update, get_size2::GetSize)]
|
||||
pub enum Type<'db> {
|
||||
/// The dynamic type: a statically unknown set of values
|
||||
Dynamic(DynamicType),
|
||||
|
@ -2483,7 +2488,7 @@ impl<'db> Type<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
#[salsa::tracked(heap_size=get_size2::GetSize::get_heap_size)]
|
||||
#[allow(unused_variables)]
|
||||
// If we choose name `_unit`, the macro will generate code that uses `_unit`, causing clippy to fail.
|
||||
fn lookup_dunder_new(self, db: &'db dyn Db, unit: ()) -> Option<PlaceAndQualifiers<'db>> {
|
||||
|
@ -2504,7 +2509,7 @@ impl<'db> Type<'db> {
|
|||
self.class_member_with_policy(db, name, MemberLookupPolicy::default())
|
||||
}
|
||||
|
||||
#[salsa::tracked(cycle_fn=class_lookup_cycle_recover, cycle_initial=class_lookup_cycle_initial)]
|
||||
#[salsa::tracked(cycle_fn=class_lookup_cycle_recover, cycle_initial=class_lookup_cycle_initial, heap_size=get_size2::GetSize::get_heap_size)]
|
||||
fn class_member_with_policy(
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
|
@ -2657,7 +2662,7 @@ impl<'db> Type<'db> {
|
|||
/// that `self` represents: (1) a data descriptor or (2) a non-data descriptor / normal attribute.
|
||||
///
|
||||
/// If `__get__` is not defined on the meta-type, this method returns `None`.
|
||||
#[salsa::tracked]
|
||||
#[salsa::tracked(heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub(crate) fn try_call_dunder_get(
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
|
@ -2950,7 +2955,7 @@ impl<'db> Type<'db> {
|
|||
|
||||
/// Similar to [`Type::member`], but allows the caller to specify what policy should be used
|
||||
/// when looking up attributes. See [`MemberLookupPolicy`] for more information.
|
||||
#[salsa::tracked(cycle_fn=member_lookup_cycle_recover, cycle_initial=member_lookup_cycle_initial)]
|
||||
#[salsa::tracked(cycle_fn=member_lookup_cycle_recover, cycle_initial=member_lookup_cycle_initial, heap_size=get_size2::GetSize::get_heap_size)]
|
||||
fn member_lookup_with_policy(
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
|
@ -5209,7 +5214,7 @@ impl<'db> Type<'db> {
|
|||
/// Note that this does not specialize generic classes, functions, or type aliases! That is a
|
||||
/// different operation that is performed explicitly (via a subscript operation), or implicitly
|
||||
/// via a call to the generic object.
|
||||
#[salsa::tracked]
|
||||
#[salsa::tracked(heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub fn apply_specialization(
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
|
@ -5701,7 +5706,9 @@ impl<'db> TypeMapping<'_, 'db> {
|
|||
/// Ordering between variants is stable and should be the same between runs.
|
||||
/// Ordering within variants is based on the wrapped data's salsa-assigned id and not on its values.
|
||||
/// The id may change between runs, or when e.g. a `TypeVarInstance` was garbage-collected and recreated.
|
||||
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, salsa::Update, Ord, PartialOrd)]
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Eq, Hash, PartialEq, salsa::Update, Ord, PartialOrd, get_size2::GetSize,
|
||||
)]
|
||||
pub enum KnownInstanceType<'db> {
|
||||
/// The type of `Protocol[T]`, `Protocol[U, S]`, etc -- usually only found in a class's bases list.
|
||||
///
|
||||
|
@ -5790,7 +5797,7 @@ impl<'db> KnownInstanceType<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, get_size2::GetSize)]
|
||||
pub enum DynamicType {
|
||||
/// An explicitly annotated `typing.Any`
|
||||
Any,
|
||||
|
@ -5848,6 +5855,8 @@ bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
impl get_size2::GetSize for TypeQualifiers {}
|
||||
|
||||
/// When inferring the type of an annotation expression, we can also encounter type qualifiers
|
||||
/// such as `ClassVar` or `Final`. These do not affect the inferred type itself, but rather
|
||||
/// control how a particular place can be accessed or modified. This struct holds a type and
|
||||
|
@ -5855,7 +5864,7 @@ bitflags! {
|
|||
///
|
||||
/// Example: `Annotated[ClassVar[tuple[int]], "metadata"]` would have type `tuple[int]` and the
|
||||
/// qualifier `ClassVar`.
|
||||
#[derive(Clone, Debug, Copy, Eq, PartialEq, salsa::Update)]
|
||||
#[derive(Clone, Debug, Copy, Eq, PartialEq, salsa::Update, get_size2::GetSize)]
|
||||
pub(crate) struct TypeAndQualifiers<'db> {
|
||||
inner: Type<'db>,
|
||||
qualifiers: TypeQualifiers,
|
||||
|
@ -6081,6 +6090,9 @@ pub struct TypeVarInstance<'db> {
|
|||
pub kind: TypeVarKind,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for TypeVarInstance<'_> {}
|
||||
|
||||
impl<'db> TypeVarInstance<'db> {
|
||||
pub(crate) fn is_legacy(self, db: &'db dyn Db) -> bool {
|
||||
matches!(self.kind(db), TypeVarKind::Legacy)
|
||||
|
@ -7057,6 +7069,9 @@ pub struct BoundMethodType<'db> {
|
|||
self_instance: Type<'db>,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for BoundMethodType<'_> {}
|
||||
|
||||
impl<'db> BoundMethodType<'db> {
|
||||
pub(crate) fn into_callable_type(self, db: &'db dyn Db) -> Type<'db> {
|
||||
Type::Callable(CallableType::new(
|
||||
|
@ -7122,6 +7137,9 @@ pub struct CallableType<'db> {
|
|||
is_function_like: bool,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for CallableType<'_> {}
|
||||
|
||||
impl<'db> CallableType<'db> {
|
||||
/// Create a callable type with a single non-overloaded signature.
|
||||
pub(crate) fn single(db: &'db dyn Db, signature: Signature<'db>) -> Type<'db> {
|
||||
|
@ -7232,7 +7250,9 @@ impl<'db> CallableType<'db> {
|
|||
}
|
||||
|
||||
/// Represents a specific instance of `types.MethodWrapperType`
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, salsa::Update)]
|
||||
#[derive(
|
||||
Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, salsa::Update, get_size2::GetSize,
|
||||
)]
|
||||
pub enum MethodWrapperKind<'db> {
|
||||
/// Method wrapper for `some_function.__get__`
|
||||
FunctionTypeDunderGet(FunctionType<'db>),
|
||||
|
@ -7337,7 +7357,9 @@ impl<'db> MethodWrapperKind<'db> {
|
|||
}
|
||||
|
||||
/// Represents a specific instance of `types.WrapperDescriptorType`
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, salsa::Update)]
|
||||
#[derive(
|
||||
Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, salsa::Update, get_size2::GetSize,
|
||||
)]
|
||||
pub enum WrapperDescriptorKind {
|
||||
/// `FunctionType.__get__`
|
||||
FunctionTypeDunderGet,
|
||||
|
@ -7363,6 +7385,9 @@ pub struct ModuleLiteralType<'db> {
|
|||
pub module: Module,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for ModuleLiteralType<'_> {}
|
||||
|
||||
impl<'db> ModuleLiteralType<'db> {
|
||||
fn static_member(self, db: &'db dyn Db, name: &str) -> Place<'db> {
|
||||
// `__dict__` is a very special member that is never overridden by module globals;
|
||||
|
@ -7416,6 +7441,9 @@ pub struct PEP695TypeAliasType<'db> {
|
|||
rhs_scope: ScopeId<'db>,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for PEP695TypeAliasType<'_> {}
|
||||
|
||||
#[salsa::tracked]
|
||||
impl<'db> PEP695TypeAliasType<'db> {
|
||||
pub(crate) fn definition(self, db: &'db dyn Db) -> Definition<'db> {
|
||||
|
@ -7426,7 +7454,7 @@ impl<'db> PEP695TypeAliasType<'db> {
|
|||
semantic_index(db, scope.file(db)).expect_single_definition(type_alias_stmt_node)
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
#[salsa::tracked(heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub(crate) fn value_type(self, db: &'db dyn Db) -> Type<'db> {
|
||||
let scope = self.rhs_scope(db);
|
||||
let module = parsed_module(db.upcast(), scope.file(db)).load(db.upcast());
|
||||
|
@ -7452,6 +7480,9 @@ pub struct BareTypeAliasType<'db> {
|
|||
pub value: Type<'db>,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for BareTypeAliasType<'_> {}
|
||||
|
||||
impl<'db> BareTypeAliasType<'db> {
|
||||
fn normalized(self, db: &'db dyn Db) -> Self {
|
||||
Self::new(
|
||||
|
@ -7463,7 +7494,9 @@ impl<'db> BareTypeAliasType<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, salsa::Update)]
|
||||
#[derive(
|
||||
Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, salsa::Update, get_size2::GetSize,
|
||||
)]
|
||||
pub enum TypeAliasType<'db> {
|
||||
PEP695(PEP695TypeAliasType<'db>),
|
||||
Bare(BareTypeAliasType<'db>),
|
||||
|
@ -7500,7 +7533,7 @@ impl<'db> TypeAliasType<'db> {
|
|||
}
|
||||
|
||||
/// Either the explicit `metaclass=` keyword of the class, or the inferred metaclass of one of its base classes.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, salsa::Update)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
|
||||
pub(super) struct MetaclassCandidate<'db> {
|
||||
metaclass: ClassType<'db>,
|
||||
explicit_metaclass_of: ClassLiteral<'db>,
|
||||
|
@ -7513,6 +7546,9 @@ pub struct UnionType<'db> {
|
|||
pub elements: Box<[Type<'db>]>,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for UnionType<'_> {}
|
||||
|
||||
impl<'db> UnionType<'db> {
|
||||
/// Create a union from a list of elements
|
||||
/// (which may be eagerly simplified into a different variant of [`Type`] altogether).
|
||||
|
@ -7726,6 +7762,9 @@ pub struct IntersectionType<'db> {
|
|||
negative: FxOrderSet<Type<'db>>,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for IntersectionType<'_> {}
|
||||
|
||||
impl<'db> IntersectionType<'db> {
|
||||
/// Return a new `IntersectionType` instance with the positive and negative types sorted
|
||||
/// according to a canonical ordering, and other normalizations applied to each element as applicable.
|
||||
|
@ -7895,6 +7934,9 @@ pub struct StringLiteralType<'db> {
|
|||
value: Box<str>,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for StringLiteralType<'_> {}
|
||||
|
||||
impl<'db> StringLiteralType<'db> {
|
||||
/// The length of the string, as would be returned by Python's `len()`.
|
||||
pub(crate) fn python_len(self, db: &'db dyn Db) -> usize {
|
||||
|
@ -7920,6 +7962,9 @@ pub struct BytesLiteralType<'db> {
|
|||
value: Box<[u8]>,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for BytesLiteralType<'_> {}
|
||||
|
||||
impl<'db> BytesLiteralType<'db> {
|
||||
pub(crate) fn python_len(self, db: &'db dyn Db) -> usize {
|
||||
self.value(db).len()
|
||||
|
@ -8061,6 +8106,9 @@ pub struct BoundSuperType<'db> {
|
|||
pub owner: SuperOwnerKind<'db>,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for BoundSuperType<'_> {}
|
||||
|
||||
impl<'db> BoundSuperType<'db> {
|
||||
/// Attempts to build a `Type::BoundSuper` based on the given `pivot_class` and `owner`.
|
||||
///
|
||||
|
@ -8239,6 +8287,9 @@ pub struct TypeIsType<'db> {
|
|||
place_info: Option<(ScopeId<'db>, ScopedPlaceId)>,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for TypeIsType<'_> {}
|
||||
|
||||
impl<'db> TypeIsType<'db> {
|
||||
pub fn place_name(self, db: &'db dyn Db) -> Option<String> {
|
||||
let (scope, place) = self.place_info(db)?;
|
||||
|
|
|
@ -178,6 +178,9 @@ pub struct GenericAlias<'db> {
|
|||
pub(crate) specialization: Specialization<'db>,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for GenericAlias<'_> {}
|
||||
|
||||
impl<'db> GenericAlias<'db> {
|
||||
pub(super) fn normalized(self, db: &'db dyn Db) -> Self {
|
||||
Self::new(db, self.origin(db), self.specialization(db).normalized(db))
|
||||
|
@ -227,7 +230,17 @@ impl<'db> From<GenericAlias<'db>> for Type<'db> {
|
|||
/// Represents a class type, which might be a non-generic class, or a specialization of a generic
|
||||
/// class.
|
||||
#[derive(
|
||||
Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, salsa::Supertype, salsa::Update,
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
Eq,
|
||||
Hash,
|
||||
Ord,
|
||||
PartialEq,
|
||||
PartialOrd,
|
||||
salsa::Supertype,
|
||||
salsa::Update,
|
||||
get_size2::GetSize,
|
||||
)]
|
||||
pub enum ClassType<'db> {
|
||||
NonGeneric(ClassLiteral<'db>),
|
||||
|
@ -749,6 +762,9 @@ pub struct ClassLiteral<'db> {
|
|||
pub(crate) dataclass_transformer_params: Option<DataclassTransformerParams>,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for ClassLiteral<'_> {}
|
||||
|
||||
#[expect(clippy::trivially_copy_pass_by_ref, clippy::ref_option)]
|
||||
fn pep695_generic_context_cycle_recover<'db>(
|
||||
_db: &'db dyn Db,
|
||||
|
@ -795,7 +811,7 @@ impl<'db> ClassLiteral<'db> {
|
|||
self.pep695_generic_context(db).is_some()
|
||||
}
|
||||
|
||||
#[salsa::tracked(cycle_fn=pep695_generic_context_cycle_recover, cycle_initial=pep695_generic_context_cycle_initial)]
|
||||
#[salsa::tracked(cycle_fn=pep695_generic_context_cycle_recover, cycle_initial=pep695_generic_context_cycle_initial, heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub(crate) fn pep695_generic_context(self, db: &'db dyn Db) -> Option<GenericContext<'db>> {
|
||||
let scope = self.body_scope(db);
|
||||
let parsed = parsed_module(db.upcast(), scope.file(db)).load(db.upcast());
|
||||
|
@ -905,7 +921,7 @@ impl<'db> ClassLiteral<'db> {
|
|||
///
|
||||
/// Were this not a salsa query, then the calling query
|
||||
/// would depend on the class's AST and rerun for every change in that file.
|
||||
#[salsa::tracked(returns(deref), cycle_fn=explicit_bases_cycle_recover, cycle_initial=explicit_bases_cycle_initial)]
|
||||
#[salsa::tracked(returns(deref), cycle_fn=explicit_bases_cycle_recover, cycle_initial=explicit_bases_cycle_initial, heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub(super) fn explicit_bases(self, db: &'db dyn Db) -> Box<[Type<'db>]> {
|
||||
tracing::trace!("ClassLiteral::explicit_bases_query: {}", self.name(db));
|
||||
|
||||
|
@ -981,7 +997,7 @@ impl<'db> ClassLiteral<'db> {
|
|||
}
|
||||
|
||||
/// Return the types of the decorators on this class
|
||||
#[salsa::tracked(returns(deref))]
|
||||
#[salsa::tracked(returns(deref), heap_size=get_size2::GetSize::get_heap_size)]
|
||||
fn decorators(self, db: &'db dyn Db) -> Box<[Type<'db>]> {
|
||||
tracing::trace!("ClassLiteral::decorators: {}", self.name(db));
|
||||
|
||||
|
@ -1029,7 +1045,7 @@ impl<'db> ClassLiteral<'db> {
|
|||
/// attribute on a class at runtime.
|
||||
///
|
||||
/// [method resolution order]: https://docs.python.org/3/glossary.html#term-method-resolution-order
|
||||
#[salsa::tracked(returns(as_ref), cycle_fn=try_mro_cycle_recover, cycle_initial=try_mro_cycle_initial)]
|
||||
#[salsa::tracked(returns(as_ref), cycle_fn=try_mro_cycle_recover, cycle_initial=try_mro_cycle_initial, heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub(super) fn try_mro(
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
|
@ -1109,6 +1125,7 @@ impl<'db> ClassLiteral<'db> {
|
|||
#[salsa::tracked(
|
||||
cycle_fn=try_metaclass_cycle_recover,
|
||||
cycle_initial=try_metaclass_cycle_initial,
|
||||
heap_size=get_size2::GetSize::get_heap_size,
|
||||
)]
|
||||
pub(super) fn try_metaclass(
|
||||
self,
|
||||
|
@ -2097,7 +2114,7 @@ impl<'db> ClassLiteral<'db> {
|
|||
///
|
||||
/// A class definition like this will fail at runtime,
|
||||
/// but we must be resilient to it or we could panic.
|
||||
#[salsa::tracked(cycle_fn=inheritance_cycle_recover, cycle_initial=inheritance_cycle_initial)]
|
||||
#[salsa::tracked(cycle_fn=inheritance_cycle_recover, cycle_initial=inheritance_cycle_initial, heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub(super) fn inheritance_cycle(self, db: &'db dyn Db) -> Option<InheritanceCycle> {
|
||||
/// Return `true` if the class is cyclically defined.
|
||||
///
|
||||
|
@ -2181,7 +2198,7 @@ impl<'db> From<ClassLiteral<'db>> for Type<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, get_size2::GetSize)]
|
||||
pub(super) enum InheritanceCycle {
|
||||
/// The class is cyclically defined and is a participant in the cycle.
|
||||
/// i.e., it inherits either directly or indirectly from itself.
|
||||
|
@ -3554,7 +3571,7 @@ impl<'db> Type<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, salsa::Update)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
|
||||
pub(super) struct MetaclassError<'db> {
|
||||
kind: MetaclassErrorKind<'db>,
|
||||
}
|
||||
|
@ -3566,7 +3583,7 @@ impl<'db> MetaclassError<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, salsa::Update)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
|
||||
pub(super) enum MetaclassErrorKind<'db> {
|
||||
/// The class has incompatible metaclasses in its inheritance hierarchy.
|
||||
///
|
||||
|
|
|
@ -13,7 +13,7 @@ use crate::types::{
|
|||
/// Note that a non-specialized generic class _cannot_ be a class base. When we see a
|
||||
/// non-specialized generic class in any type expression (including the list of base classes), we
|
||||
/// automatically construct the default specialization for that class.
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, salsa::Update)]
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
|
||||
pub enum ClassBase<'db> {
|
||||
Dynamic(DynamicType),
|
||||
Class(ClassType<'db>),
|
||||
|
|
|
@ -1561,7 +1561,7 @@ declare_lint! {
|
|||
}
|
||||
|
||||
/// A collection of type check diagnostics.
|
||||
#[derive(Default, Eq, PartialEq)]
|
||||
#[derive(Default, Eq, PartialEq, get_size2::GetSize)]
|
||||
pub struct TypeCheckDiagnostics {
|
||||
diagnostics: Vec<Diagnostic>,
|
||||
used_suppressions: FxHashSet<FileSuppressionId>,
|
||||
|
|
|
@ -131,6 +131,8 @@ bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
impl get_size2::GetSize for DataclassTransformerParams {}
|
||||
|
||||
impl Default for DataclassTransformerParams {
|
||||
fn default() -> Self {
|
||||
Self::EQ_DEFAULT
|
||||
|
@ -168,6 +170,9 @@ pub struct OverloadLiteral<'db> {
|
|||
pub(crate) dataclass_transformer_params: Option<DataclassTransformerParams>,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for OverloadLiteral<'_> {}
|
||||
|
||||
#[salsa::tracked]
|
||||
impl<'db> OverloadLiteral<'db> {
|
||||
fn with_dataclass_transformer_params(
|
||||
|
@ -432,7 +437,7 @@ impl<'db> FunctionLiteral<'db> {
|
|||
self.last_definition(db).spans(db)
|
||||
}
|
||||
|
||||
#[salsa::tracked(returns(ref))]
|
||||
#[salsa::tracked(returns(ref), heap_size=get_size2::GetSize::get_heap_size)]
|
||||
fn overloads_and_implementation(
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
|
@ -530,6 +535,9 @@ pub struct FunctionType<'db> {
|
|||
type_mappings: Box<[TypeMapping<'db, 'db>]>,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for FunctionType<'_> {}
|
||||
|
||||
#[salsa::tracked]
|
||||
impl<'db> FunctionType<'db> {
|
||||
pub(crate) fn with_inherited_generic_context(
|
||||
|
@ -699,7 +707,7 @@ impl<'db> FunctionType<'db> {
|
|||
///
|
||||
/// Were this not a salsa query, then the calling query
|
||||
/// would depend on the function's AST and rerun for every change in that file.
|
||||
#[salsa::tracked(returns(ref), cycle_fn=signature_cycle_recover, cycle_initial=signature_cycle_initial)]
|
||||
#[salsa::tracked(returns(ref), cycle_fn=signature_cycle_recover, cycle_initial=signature_cycle_initial, heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub(crate) fn signature(self, db: &'db dyn Db) -> CallableSignature<'db> {
|
||||
self.literal(db).signature(db, self.type_mappings(db))
|
||||
}
|
||||
|
|
|
@ -30,6 +30,9 @@ pub struct GenericContext<'db> {
|
|||
pub(crate) variables: FxOrderSet<TypeVarInstance<'db>>,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for GenericContext<'_> {}
|
||||
|
||||
impl<'db> GenericContext<'db> {
|
||||
/// Creates a generic context from a list of PEP-695 type parameters.
|
||||
pub(crate) fn from_type_params(
|
||||
|
|
|
@ -129,7 +129,7 @@ use super::{ClassBase, NominalInstanceType, add_inferred_python_version_hint_to_
|
|||
/// Infer all types for a [`ScopeId`], including all definitions and expressions in that scope.
|
||||
/// Use when checking a scope, or needing to provide a type for an arbitrary expression in the
|
||||
/// scope.
|
||||
#[salsa::tracked(returns(ref), cycle_fn=scope_cycle_recover, cycle_initial=scope_cycle_initial)]
|
||||
#[salsa::tracked(returns(ref), cycle_fn=scope_cycle_recover, cycle_initial=scope_cycle_initial, heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub(crate) fn infer_scope_types<'db>(db: &'db dyn Db, scope: ScopeId<'db>) -> TypeInference<'db> {
|
||||
let file = scope.file(db);
|
||||
let _span = tracing::trace_span!("infer_scope_types", scope=?scope.as_id(), ?file).entered();
|
||||
|
@ -158,7 +158,7 @@ fn scope_cycle_initial<'db>(_db: &'db dyn Db, scope: ScopeId<'db>) -> TypeInfere
|
|||
|
||||
/// Infer all types for a [`Definition`] (including sub-expressions).
|
||||
/// Use when resolving a place use or public type of a place.
|
||||
#[salsa::tracked(returns(ref), cycle_fn=definition_cycle_recover, cycle_initial=definition_cycle_initial)]
|
||||
#[salsa::tracked(returns(ref), cycle_fn=definition_cycle_recover, cycle_initial=definition_cycle_initial, heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub(crate) fn infer_definition_types<'db>(
|
||||
db: &'db dyn Db,
|
||||
definition: Definition<'db>,
|
||||
|
@ -197,7 +197,7 @@ fn definition_cycle_initial<'db>(
|
|||
///
|
||||
/// Deferred expressions are type expressions (annotations, base classes, aliases...) in a stub
|
||||
/// file, or in a file with `from __future__ import annotations`, or stringified annotations.
|
||||
#[salsa::tracked(returns(ref), cycle_fn=deferred_cycle_recover, cycle_initial=deferred_cycle_initial)]
|
||||
#[salsa::tracked(returns(ref), cycle_fn=deferred_cycle_recover, cycle_initial=deferred_cycle_initial, heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub(crate) fn infer_deferred_types<'db>(
|
||||
db: &'db dyn Db,
|
||||
definition: Definition<'db>,
|
||||
|
@ -234,7 +234,7 @@ fn deferred_cycle_initial<'db>(db: &'db dyn Db, definition: Definition<'db>) ->
|
|||
/// Use rarely; only for cases where we'd otherwise risk double-inferring an expression: RHS of an
|
||||
/// assignment, which might be unpacking/multi-target and thus part of multiple definitions, or a
|
||||
/// type narrowing guard expression (e.g. if statement test node).
|
||||
#[salsa::tracked(returns(ref), cycle_fn=expression_cycle_recover, cycle_initial=expression_cycle_initial)]
|
||||
#[salsa::tracked(returns(ref), cycle_fn=expression_cycle_recover, cycle_initial=expression_cycle_initial, heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub(crate) fn infer_expression_types<'db>(
|
||||
db: &'db dyn Db,
|
||||
expression: Expression<'db>,
|
||||
|
@ -296,7 +296,7 @@ pub(super) fn infer_same_file_expression_type<'db>(
|
|||
///
|
||||
/// Use [`infer_same_file_expression_type`] if it is guaranteed that `expression` is in the same
|
||||
/// to avoid unnecessary salsa ingredients. This is normally the case inside the `TypeInferenceBuilder`.
|
||||
#[salsa::tracked(cycle_fn=single_expression_cycle_recover, cycle_initial=single_expression_cycle_initial)]
|
||||
#[salsa::tracked(cycle_fn=single_expression_cycle_recover, cycle_initial=single_expression_cycle_initial, heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub(crate) fn infer_expression_type<'db>(
|
||||
db: &'db dyn Db,
|
||||
expression: Expression<'db>,
|
||||
|
@ -330,7 +330,7 @@ fn single_expression_cycle_initial<'db>(
|
|||
/// involved in an unpacking operation. It returns a result-like object that can be used to get the
|
||||
/// type of the variables involved in this unpacking along with any violations that are detected
|
||||
/// during this unpacking.
|
||||
#[salsa::tracked(returns(ref), cycle_fn=unpack_cycle_recover, cycle_initial=unpack_cycle_initial)]
|
||||
#[salsa::tracked(returns(ref), cycle_fn=unpack_cycle_recover, cycle_initial=unpack_cycle_initial, heap_size=get_size2::GetSize::get_heap_size)]
|
||||
pub(super) fn infer_unpack_types<'db>(db: &'db dyn Db, unpack: Unpack<'db>) -> UnpackResult<'db> {
|
||||
let file = unpack.file(db);
|
||||
let module = parsed_module(db.upcast(), file).load(db.upcast());
|
||||
|
@ -414,7 +414,7 @@ struct TypeAndRange<'db> {
|
|||
}
|
||||
|
||||
/// The inferred types for a single region.
|
||||
#[derive(Debug, Eq, PartialEq, salsa::Update)]
|
||||
#[derive(Debug, Eq, PartialEq, salsa::Update, get_size2::GetSize)]
|
||||
pub(crate) struct TypeInference<'db> {
|
||||
/// The types of every expression in this region.
|
||||
expressions: FxHashMap<ScopedExpressionId, Type<'db>>,
|
||||
|
|
|
@ -64,7 +64,7 @@ impl<'db> Type<'db> {
|
|||
}
|
||||
|
||||
/// A type representing the set of runtime objects which are instances of a certain nominal class.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, salsa::Update)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, salsa::Update, get_size2::GetSize)]
|
||||
pub struct NominalInstanceType<'db> {
|
||||
pub(super) class: ClassType<'db>,
|
||||
|
||||
|
@ -147,7 +147,9 @@ impl<'db> From<NominalInstanceType<'db>> for Type<'db> {
|
|||
|
||||
/// A `ProtocolInstanceType` represents the set of all possible runtime objects
|
||||
/// that conform to the interface described by a certain protocol.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, salsa::Update, PartialOrd, Ord)]
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Eq, PartialEq, Hash, salsa::Update, PartialOrd, Ord, get_size2::GetSize,
|
||||
)]
|
||||
pub struct ProtocolInstanceType<'db> {
|
||||
pub(super) inner: Protocol<'db>,
|
||||
|
||||
|
@ -324,7 +326,9 @@ impl<'db> ProtocolInstanceType<'db> {
|
|||
|
||||
/// An enumeration of the two kinds of protocol types: those that originate from a class
|
||||
/// definition in source code, and those that are synthesized from a set of members.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, salsa::Update, PartialOrd, Ord)]
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Eq, PartialEq, Hash, salsa::Update, PartialOrd, Ord, get_size2::GetSize,
|
||||
)]
|
||||
pub(super) enum Protocol<'db> {
|
||||
FromClass(ClassType<'db>),
|
||||
Synthesized(SynthesizedProtocolType<'db>),
|
||||
|
@ -359,7 +363,9 @@ mod synthesized_protocol {
|
|||
///
|
||||
/// The constructor method of this type maintains the invariant that a synthesized protocol type
|
||||
/// is always constructed from a *normalized* protocol interface.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, salsa::Update, PartialOrd, Ord)]
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Eq, PartialEq, Hash, salsa::Update, PartialOrd, Ord, get_size2::GetSize,
|
||||
)]
|
||||
pub(in crate::types) struct SynthesizedProtocolType<'db>(ProtocolInterface<'db>);
|
||||
|
||||
impl<'db> SynthesizedProtocolType<'db> {
|
||||
|
|
|
@ -28,7 +28,7 @@ use crate::types::{ClassLiteral, ClassType, KnownInstanceType, SpecialFormType,
|
|||
/// ```
|
||||
///
|
||||
/// See [`ClassType::iter_mro`] for more details.
|
||||
#[derive(PartialEq, Eq, Clone, Debug, salsa::Update)]
|
||||
#[derive(PartialEq, Eq, Clone, Debug, salsa::Update, get_size2::GetSize)]
|
||||
pub(super) struct Mro<'db>(Box<[ClassBase<'db>]>);
|
||||
|
||||
impl<'db> Mro<'db> {
|
||||
|
@ -413,7 +413,7 @@ impl<'db> Iterator for MroIterator<'db> {
|
|||
|
||||
impl std::iter::FusedIterator for MroIterator<'_> {}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, salsa::Update)]
|
||||
#[derive(Debug, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
|
||||
pub(super) struct MroError<'db> {
|
||||
kind: MroErrorKind<'db>,
|
||||
fallback_mro: Mro<'db>,
|
||||
|
@ -442,7 +442,7 @@ impl<'db> MroError<'db> {
|
|||
}
|
||||
|
||||
/// Possible ways in which attempting to resolve the MRO of a class might fail.
|
||||
#[derive(Debug, PartialEq, Eq, salsa::Update)]
|
||||
#[derive(Debug, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
|
||||
pub(super) enum MroErrorKind<'db> {
|
||||
/// The class inherits from one or more invalid bases.
|
||||
///
|
||||
|
@ -483,7 +483,7 @@ impl<'db> MroErrorKind<'db> {
|
|||
}
|
||||
|
||||
/// Error recording the fact that a class definition was found to have duplicate bases.
|
||||
#[derive(Debug, PartialEq, Eq, salsa::Update)]
|
||||
#[derive(Debug, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
|
||||
pub(super) struct DuplicateBaseError<'db> {
|
||||
/// The base that is duplicated in the class's bases list.
|
||||
pub(super) duplicate_base: ClassBase<'db>,
|
||||
|
|
|
@ -69,7 +69,7 @@ pub(crate) fn infer_narrowing_constraint<'db>(
|
|||
}
|
||||
}
|
||||
|
||||
#[salsa::tracked(returns(as_ref))]
|
||||
#[salsa::tracked(returns(as_ref), heap_size=get_size2::GetSize::get_heap_size)]
|
||||
fn all_narrowing_constraints_for_pattern<'db>(
|
||||
db: &'db dyn Db,
|
||||
pattern: PatternPredicate<'db>,
|
||||
|
@ -82,6 +82,7 @@ fn all_narrowing_constraints_for_pattern<'db>(
|
|||
returns(as_ref),
|
||||
cycle_fn=constraints_for_expression_cycle_recover,
|
||||
cycle_initial=constraints_for_expression_cycle_initial,
|
||||
heap_size=get_size2::GetSize::get_heap_size,
|
||||
)]
|
||||
fn all_narrowing_constraints_for_expression<'db>(
|
||||
db: &'db dyn Db,
|
||||
|
@ -96,6 +97,7 @@ fn all_narrowing_constraints_for_expression<'db>(
|
|||
returns(as_ref),
|
||||
cycle_fn=negative_constraints_for_expression_cycle_recover,
|
||||
cycle_initial=negative_constraints_for_expression_cycle_initial,
|
||||
heap_size=get_size2::GetSize::get_heap_size,
|
||||
)]
|
||||
fn all_negative_narrowing_constraints_for_expression<'db>(
|
||||
db: &'db dyn Db,
|
||||
|
@ -106,7 +108,7 @@ fn all_negative_narrowing_constraints_for_expression<'db>(
|
|||
.finish()
|
||||
}
|
||||
|
||||
#[salsa::tracked(returns(as_ref))]
|
||||
#[salsa::tracked(returns(as_ref), heap_size=get_size2::GetSize::get_heap_size)]
|
||||
fn all_negative_narrowing_constraints_for_pattern<'db>(
|
||||
db: &'db dyn Db,
|
||||
pattern: PatternPredicate<'db>,
|
||||
|
|
|
@ -106,7 +106,7 @@ enum ParamKind {
|
|||
KeywordVariadic,
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
#[salsa::tracked(heap_size=get_size2::GetSize::get_heap_size)]
|
||||
fn create_bound_method<'db>(
|
||||
db: &'db dyn Db,
|
||||
function: Type<'db>,
|
||||
|
|
|
@ -70,8 +70,12 @@ pub(super) struct ProtocolInterfaceMembers<'db> {
|
|||
inner: BTreeMap<Name, ProtocolMemberData<'db>>,
|
||||
}
|
||||
|
||||
impl get_size2::GetSize for ProtocolInterfaceMembers<'_> {}
|
||||
|
||||
/// The interface of a protocol: the members of that protocol, and the types of those members.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, salsa::Update, PartialOrd, Ord)]
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Eq, PartialEq, Hash, salsa::Update, PartialOrd, Ord, get_size2::GetSize,
|
||||
)]
|
||||
pub(super) enum ProtocolInterface<'db> {
|
||||
Members(ProtocolInterfaceMembers<'db>),
|
||||
SelfReference,
|
||||
|
@ -327,7 +331,7 @@ fn excluded_from_proto_members(member: &str) -> bool {
|
|||
}
|
||||
|
||||
/// Inner Salsa query for [`ProtocolClassLiteral::interface`].
|
||||
#[salsa::tracked(cycle_fn=proto_interface_cycle_recover, cycle_initial=proto_interface_cycle_initial)]
|
||||
#[salsa::tracked(cycle_fn=proto_interface_cycle_recover, cycle_initial=proto_interface_cycle_initial, heap_size=get_size2::GetSize::get_heap_size)]
|
||||
fn cached_protocol_interface<'db>(
|
||||
db: &'db dyn Db,
|
||||
class: ClassLiteral<'db>,
|
||||
|
|
|
@ -24,7 +24,7 @@ use ruff_python_ast::{self as ast, name::Name};
|
|||
|
||||
/// The signature of a single callable. If the callable is overloaded, there is a separate
|
||||
/// [`Signature`] for each overload.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, salsa::Update)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, salsa::Update, get_size2::GetSize)]
|
||||
pub struct CallableSignature<'db> {
|
||||
/// The signatures of each overload of this callable. Will be empty if the type is not
|
||||
/// callable.
|
||||
|
@ -220,7 +220,7 @@ impl<'a, 'db> IntoIterator for &'a CallableSignature<'db> {
|
|||
}
|
||||
|
||||
/// The signature of one of the overloads of a callable.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, salsa::Update)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, salsa::Update, get_size2::GetSize)]
|
||||
pub struct Signature<'db> {
|
||||
/// The generic context for this overload, if it is generic.
|
||||
pub(crate) generic_context: Option<GenericContext<'db>>,
|
||||
|
@ -897,7 +897,7 @@ impl<'db> Signature<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, salsa::Update)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, salsa::Update, get_size2::GetSize)]
|
||||
pub(crate) struct Parameters<'db> {
|
||||
// TODO: use SmallVec here once invariance bug is fixed
|
||||
value: Vec<Parameter<'db>>,
|
||||
|
@ -1196,7 +1196,7 @@ impl<'db> std::ops::Index<usize> for Parameters<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, salsa::Update)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, salsa::Update, get_size2::GetSize)]
|
||||
pub(crate) struct Parameter<'db> {
|
||||
/// Annotated type of the parameter.
|
||||
annotated_type: Option<Type<'db>>,
|
||||
|
@ -1454,7 +1454,7 @@ impl<'db> Parameter<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, salsa::Update)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, salsa::Update, get_size2::GetSize)]
|
||||
pub(crate) enum ParameterKind<'db> {
|
||||
/// Positional-only parameter, e.g. `def f(x, /): ...`
|
||||
PositionalOnly {
|
||||
|
@ -1520,7 +1520,7 @@ impl<'db> ParameterKind<'db> {
|
|||
}
|
||||
|
||||
/// Whether a parameter is used as a value or a type form.
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, get_size2::GetSize)]
|
||||
pub(crate) enum ParameterForm {
|
||||
Value,
|
||||
Type,
|
||||
|
|
|
@ -24,6 +24,7 @@ use std::str::FromStr;
|
|||
PartialOrd,
|
||||
Ord,
|
||||
strum_macros::EnumString,
|
||||
get_size2::GetSize,
|
||||
)]
|
||||
pub enum SpecialFormType {
|
||||
/// The symbol `typing.Annotated` (which can also be found as `typing_extensions.Annotated`)
|
||||
|
|
|
@ -10,7 +10,7 @@ use crate::{Db, FxOrderSet};
|
|||
use super::{TypeVarBoundOrConstraints, TypeVarKind, TypeVarVariance};
|
||||
|
||||
/// A type that represents `type[C]`, i.e. the class object `C` and class objects that are subclasses of `C`.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Update)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Update, get_size2::GetSize)]
|
||||
pub struct SubclassOfType<'db> {
|
||||
// Keep this field private, so that the only way of constructing the struct is through the `from` method.
|
||||
subclass_of: SubclassOfInner<'db>,
|
||||
|
@ -199,7 +199,7 @@ impl<'db> SubclassOfType<'db> {
|
|||
/// Note that this enum is similar to the [`super::ClassBase`] enum,
|
||||
/// but does not include the `ClassBase::Protocol` and `ClassBase::Generic` variants
|
||||
/// (`type[Protocol]` and `type[Generic]` are not valid types).
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Update)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Update, get_size2::GetSize)]
|
||||
pub(crate) enum SubclassOfInner<'db> {
|
||||
Class(ClassType<'db>),
|
||||
Dynamic(DynamicType),
|
||||
|
|
|
@ -33,6 +33,9 @@ pub struct TupleType<'db> {
|
|||
pub(crate) tuple: TupleSpec<'db>,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for TupleType<'_> {}
|
||||
|
||||
impl<'db> Type<'db> {
|
||||
pub(crate) fn tuple(db: &'db dyn Db, tuple: TupleType<'db>) -> Self {
|
||||
// If a fixed-length (i.e., mandatory) element of the tuple is `Never`, then it's not
|
||||
|
|
|
@ -343,7 +343,7 @@ impl<'db, 'ast> Unpacker<'db, 'ast> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Eq, salsa::Update)]
|
||||
#[derive(Debug, Default, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
|
||||
pub(crate) struct UnpackResult<'db> {
|
||||
targets: FxHashMap<ScopedExpressionId, Type<'db>>,
|
||||
diagnostics: TypeCheckDiagnostics,
|
||||
|
|
15
crates/ty_python_semantic/src/util/get_size.rs
Normal file
15
crates/ty_python_semantic/src/util/get_size.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use get_size2::GetSize;
|
||||
|
||||
/// By default, `Arc<T>: GetSize` requires `T: 'static` to enable tracking references
|
||||
/// of the `Arc` and avoid double-counting. This method opts out of that behavior and
|
||||
/// removes the `'static` requirement.
|
||||
///
|
||||
/// This method will just return the heap-size of the inner `T`.
|
||||
pub(crate) fn untracked_arc_size<T>(arc: &Arc<T>) -> usize
|
||||
where
|
||||
T: GetSize,
|
||||
{
|
||||
T::get_heap_size(&**arc)
|
||||
}
|
|
@ -1,2 +1,3 @@
|
|||
pub(crate) mod diagnostics;
|
||||
pub(crate) mod get_size;
|
||||
pub(crate) mod subscript;
|
||||
|
|
|
@ -30,7 +30,7 @@ ty_python_semantic = { path = "../crates/ty_python_semantic" }
|
|||
ty_vendored = { path = "../crates/ty_vendored" }
|
||||
|
||||
libfuzzer-sys = { git = "https://github.com/rust-fuzz/libfuzzer", default-features = false }
|
||||
salsa = { git = "https://github.com/salsa-rs/salsa.git", rev = "09627e450566f894956710a3fd923dc80462ae6d" }
|
||||
salsa = { git = "https://github.com/salsa-rs/salsa", rev = "0666e2018bc35376b1ac4f98906f2d04d11e5fe4" }
|
||||
similar = { version = "2.5.0" }
|
||||
tracing = { version = "0.1.40" }
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue