Skip to content

Commit 3a95cd9

Browse files
committed
separate lambda parameters from function parameter definitions
1 parent fc94581 commit 3a95cd9

7 files changed

Lines changed: 349 additions & 79 deletions

File tree

crates/ty_python_semantic/src/semantic_index.rs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -865,7 +865,9 @@ mod tests {
865865
use crate::Db;
866866
use crate::db::tests::{TestDb, TestDbBuilder};
867867
use crate::semantic_index::ast_ids::{HasScopedUseId, ScopedUseId};
868-
use crate::semantic_index::definition::{Definition, DefinitionKind};
868+
use crate::semantic_index::definition::{
869+
Definition, DefinitionKind, LambdaParameterDefinitionNodeKind, ParameterDefinitionNodeKind,
870+
};
869871
use crate::semantic_index::place::PlaceTable;
870872
use crate::semantic_index::scope::{FileScopeId, Scope, ScopeKind};
871873
use crate::semantic_index::symbol::ScopedSymbolId;
@@ -1156,14 +1158,14 @@ def f(a: str, /, b: str, c: int = 1, *args, d: int = 2, **kwargs):
11561158
.unwrap();
11571159
assert!(matches!(
11581160
args_binding.kind(&db),
1159-
DefinitionKind::VariadicPositionalParameter(_)
1161+
DefinitionKind::Parameter(ParameterDefinitionNodeKind::VariadicPositionalParameter(_))
11601162
));
11611163
let kwargs_binding = use_def
11621164
.first_public_binding(function_table.symbol_id("kwargs").expect("symbol exists"))
11631165
.unwrap();
11641166
assert!(matches!(
11651167
kwargs_binding.kind(&db),
1166-
DefinitionKind::VariadicKeywordParameter(_)
1168+
DefinitionKind::Parameter(ParameterDefinitionNodeKind::VariadicKeywordParameter(_))
11671169
));
11681170
}
11691171

@@ -1186,29 +1188,44 @@ def f(a: str, /, b: str, c: int = 1, *args, d: int = 2, **kwargs):
11861188
let lambda_table = index.place_table(lambda_scope_id);
11871189
assert_eq!(
11881190
names(lambda_table),
1189-
vec!["a", "b", "c", "d", "args", "kwargs"],
1191+
vec!["a", "b", "c", "args", "d", "kwargs"],
11901192
);
11911193

11921194
let use_def = index.use_def_map(lambda_scope_id);
11931195
for name in ["a", "b", "c", "d"] {
11941196
let binding = use_def
11951197
.first_public_binding(lambda_table.symbol_id(name).expect("symbol exists"))
11961198
.unwrap();
1197-
assert!(matches!(binding.kind(&db), DefinitionKind::Parameter(_)));
1199+
assert!(matches!(
1200+
binding.kind(&db),
1201+
DefinitionKind::LambdaParameter(LambdaParameterDefinitionNodeKind {
1202+
index: _,
1203+
lambda: _,
1204+
parameter: ParameterDefinitionNodeKind::Parameter(_)
1205+
})
1206+
));
11981207
}
11991208
let args_binding = use_def
12001209
.first_public_binding(lambda_table.symbol_id("args").expect("symbol exists"))
12011210
.unwrap();
12021211
assert!(matches!(
12031212
args_binding.kind(&db),
1204-
DefinitionKind::VariadicPositionalParameter(_)
1213+
DefinitionKind::LambdaParameter(LambdaParameterDefinitionNodeKind {
1214+
index: 3,
1215+
lambda: _,
1216+
parameter: ParameterDefinitionNodeKind::VariadicPositionalParameter(_)
1217+
})
12051218
));
12061219
let kwargs_binding = use_def
12071220
.first_public_binding(lambda_table.symbol_id("kwargs").expect("symbol exists"))
12081221
.unwrap();
12091222
assert!(matches!(
12101223
kwargs_binding.kind(&db),
1211-
DefinitionKind::VariadicKeywordParameter(_)
1224+
DefinitionKind::LambdaParameter(LambdaParameterDefinitionNodeKind {
1225+
index: 5,
1226+
lambda: _,
1227+
parameter: ParameterDefinitionNodeKind::VariadicKeywordParameter(_)
1228+
})
12121229
));
12131230
}
12141231

crates/ty_python_semantic/src/semantic_index/builder.rs

Lines changed: 82 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ use crate::semantic_index::definition::{
2727
ComprehensionDefinitionNodeRef, Definition, DefinitionCategory, DefinitionNodeKey,
2828
DefinitionNodeRef, Definitions, DictKeyAssignmentNodeRef, ExceptHandlerDefinitionNodeRef,
2929
ForStmtDefinitionNodeRef, ImportDefinitionNodeRef, ImportFromDefinitionNodeRef,
30-
ImportFromSubmoduleDefinitionNodeRef, LoopHeaderDefinitionNodeRef, LoopStmtRef,
31-
MatchPatternDefinitionNodeRef, StarImportDefinitionNodeRef, WithItemDefinitionNodeRef,
30+
ImportFromSubmoduleDefinitionNodeRef, LambdaParameterDefinitionNodeRef,
31+
LoopHeaderDefinitionNodeRef, LoopStmtRef, MatchPatternDefinitionNodeRef,
32+
ParameterDefinitionNodeRef, StarImportDefinitionNodeRef, WithItemDefinitionNodeRef,
3233
};
3334
use crate::semantic_index::expression::{Expression, ExpressionKind};
3435
use crate::semantic_index::member::MemberExprBuilder;
@@ -1635,7 +1636,7 @@ impl<'db, 'ast> SemanticIndexBuilder<'db, 'ast> {
16351636
.mark_parameter();
16361637
self.add_definition(
16371638
symbol.into(),
1638-
DefinitionNodeRef::VariadicPositionalParameter(vararg),
1639+
ParameterDefinitionNodeRef::VariadicPositionalParameter(vararg),
16391640
);
16401641
}
16411642
if let Some(kwarg) = parameters.kwarg.as_ref() {
@@ -1645,15 +1646,90 @@ impl<'db, 'ast> SemanticIndexBuilder<'db, 'ast> {
16451646
.mark_parameter();
16461647
self.add_definition(
16471648
symbol.into(),
1648-
DefinitionNodeRef::VariadicKeywordParameter(kwarg),
1649+
ParameterDefinitionNodeRef::VariadicKeywordParameter(kwarg),
16491650
);
16501651
}
16511652
}
16521653

16531654
fn declare_parameter(&mut self, parameter: &'ast ast::ParameterWithDefault) {
16541655
let symbol = self.add_symbol(parameter.name().id().clone());
16551656

1656-
let definition = self.add_definition(symbol.into(), parameter);
1657+
let definition = self.add_definition(
1658+
symbol.into(),
1659+
ParameterDefinitionNodeRef::Parameter(parameter),
1660+
);
1661+
1662+
self.current_place_table_mut()
1663+
.symbol_mut(symbol)
1664+
.mark_parameter();
1665+
1666+
// Insert a mapping from the inner Parameter node to the same definition. This
1667+
// ensures that calling `HasType::inferred_type` on the inner parameter returns
1668+
// a valid type (and doesn't panic)
1669+
let existing_definition = self.definitions_by_node.insert(
1670+
(&parameter.parameter).into(),
1671+
Definitions::single(definition),
1672+
);
1673+
debug_assert_eq!(existing_definition, None);
1674+
}
1675+
1676+
fn declare_lambda_parameters(&mut self, parameters: &'ast ast::Parameters) {
1677+
let mut index = 0;
1678+
for parameter in &parameters.posonlyargs {
1679+
self.declare_lambda_parameter(index, parameter);
1680+
index += 1;
1681+
}
1682+
for parameter in &parameters.args {
1683+
self.declare_lambda_parameter(index, parameter);
1684+
index += 1;
1685+
}
1686+
if let Some(vararg) = parameters.vararg.as_ref() {
1687+
let symbol = self.add_symbol(vararg.name.id().clone());
1688+
self.current_place_table_mut()
1689+
.symbol_mut(symbol)
1690+
.mark_parameter();
1691+
self.add_definition(
1692+
symbol.into(),
1693+
LambdaParameterDefinitionNodeRef {
1694+
index,
1695+
parameter: ParameterDefinitionNodeRef::VariadicPositionalParameter(vararg),
1696+
},
1697+
);
1698+
index += 1;
1699+
}
1700+
for parameter in &parameters.kwonlyargs {
1701+
self.declare_lambda_parameter(index, parameter);
1702+
index += 1;
1703+
}
1704+
if let Some(kwarg) = parameters.kwarg.as_ref() {
1705+
let symbol = self.add_symbol(kwarg.name.id().clone());
1706+
self.current_place_table_mut()
1707+
.symbol_mut(symbol)
1708+
.mark_parameter();
1709+
self.add_definition(
1710+
symbol.into(),
1711+
LambdaParameterDefinitionNodeRef {
1712+
index,
1713+
parameter: ParameterDefinitionNodeRef::VariadicKeywordParameter(kwarg),
1714+
},
1715+
);
1716+
}
1717+
}
1718+
1719+
fn declare_lambda_parameter(
1720+
&mut self,
1721+
index: usize,
1722+
parameter: &'ast ast::ParameterWithDefault,
1723+
) {
1724+
let symbol = self.add_symbol(parameter.name().id().clone());
1725+
1726+
let definition = self.add_definition(
1727+
symbol.into(),
1728+
LambdaParameterDefinitionNodeRef {
1729+
index,
1730+
parameter: ParameterDefinitionNodeRef::Parameter(parameter),
1731+
},
1732+
);
16571733

16581734
self.current_place_table_mut()
16591735
.symbol_mut(symbol)
@@ -3168,7 +3244,7 @@ impl<'ast> Visitor<'ast> for SemanticIndexBuilder<'_, 'ast> {
31683244

31693245
// Add symbols and definitions for the parameters to the lambda scope.
31703246
if let Some(parameters) = lambda.parameters.as_ref() {
3171-
self.declare_parameters(parameters);
3247+
self.declare_lambda_parameters(parameters);
31723248
}
31733249

31743250
self.visit_expr(lambda.body.as_ref());

0 commit comments

Comments
 (0)