Refactor ast_ids traits to take ScopeId instead of VfsFile plus FileScopeId. (#12139)

This commit is contained in:
Micha Reiser
2024-07-01 15:50:07 +02:00
committed by GitHub
parent 5677614079
commit 955138b74a
3 changed files with 38 additions and 58 deletions

View File

@@ -74,10 +74,7 @@ pub trait HasScopedAstId {
type Id: Copy;
/// Returns the ID that uniquely identifies the node in `scope`.
///
/// ## Panics
/// Panics if the node doesn't belong to `file` or is outside `scope`.
fn scoped_ast_id(&self, db: &dyn Db, file: VfsFile, scope: FileScopeId) -> Self::Id;
fn scoped_ast_id(&self, db: &dyn Db, scope: ScopeId) -> Self::Id;
}
/// Node that can be uniquely identified by an id in a [`FileScopeId`].
@@ -85,8 +82,8 @@ pub trait ScopedAstIdNode: HasScopedAstId {
/// Looks up the AST node by its ID.
///
/// ## Panics
/// May panic if the `id` does not belong to the AST of `file`, or is outside `scope`.
fn lookup_in_scope(db: &dyn Db, file: VfsFile, scope: FileScopeId, id: Self::Id) -> &Self
/// May panic if the `id` does not belong to the AST of `scope`.
fn lookup_in_scope<'db>(db: &'db dyn Db, scope: ScopeId<'db>, id: Self::Id) -> &'db Self
where
Self: Sized;
}
@@ -98,9 +95,9 @@ pub trait AstIdNode {
/// Resolves the AST id of the node.
///
/// ## Panics
/// May panic if the node does not belongs to `file`'s AST or is outside of `scope`. It may also
/// May panic if the node does not belong to `scope`. It may also
/// return an incorrect node if that's the case.
fn ast_id(&self, db: &dyn Db, file: VfsFile, scope: FileScopeId) -> AstId<Self::ScopeId>;
fn ast_id(&self, db: &dyn Db, scope: ScopeId) -> AstId<Self::ScopeId>;
/// Resolves the AST node for `id`.
///
@@ -118,17 +115,21 @@ where
{
type ScopeId = T::Id;
fn ast_id(&self, db: &dyn Db, file: VfsFile, scope: FileScopeId) -> AstId<Self::ScopeId> {
let in_scope_id = self.scoped_ast_id(db, file, scope);
AstId { scope, in_scope_id }
fn ast_id(&self, db: &dyn Db, scope: ScopeId) -> AstId<Self::ScopeId> {
let in_scope_id = self.scoped_ast_id(db, scope);
AstId {
scope: scope.file_scope_id(db),
in_scope_id,
}
}
fn lookup(db: &dyn Db, file: VfsFile, id: AstId<Self::ScopeId>) -> &Self
where
Self: Sized,
{
let scope = id.scope;
Self::lookup_in_scope(db, file, scope, id.in_scope_id)
let scope = id.scope.to_scope_id(db, file);
Self::lookup_in_scope(db, scope, id.in_scope_id)
}
}
@@ -161,14 +162,9 @@ macro_rules! impl_has_scoped_expression_id {
impl HasScopedAstId for $ty {
type Id = ScopedExpressionId;
fn scoped_ast_id(
&self,
db: &dyn Db,
file: VfsFile,
file_scope: FileScopeId,
) -> Self::Id {
fn scoped_ast_id(&self, db: &dyn Db, scope: ScopeId) -> Self::Id {
let expression_ref = ExpressionRef::from(self);
expression_ref.scoped_ast_id(db, file, file_scope)
expression_ref.scoped_ast_id(db, scope)
}
}
};
@@ -211,16 +207,14 @@ impl_has_scoped_expression_id!(ast::Expr);
impl HasScopedAstId for ast::ExpressionRef<'_> {
type Id = ScopedExpressionId;
fn scoped_ast_id(&self, db: &dyn Db, file: VfsFile, file_scope: FileScopeId) -> Self::Id {
let scope = file_scope.to_scope_id(db, file);
fn scoped_ast_id(&self, db: &dyn Db, scope: ScopeId) -> Self::Id {
let ast_ids = ast_ids(db, scope);
ast_ids.expression_id(*self)
}
}
impl ScopedAstIdNode for ast::Expr {
fn lookup_in_scope(db: &dyn Db, file: VfsFile, file_scope: FileScopeId, id: Self::Id) -> &Self {
let scope = file_scope.to_scope_id(db, file);
fn lookup_in_scope<'db>(db: &'db dyn Db, scope: ScopeId<'db>, id: Self::Id) -> &'db Self {
let ast_ids = ast_ids(db, scope);
ast_ids.expressions[id].node()
}
@@ -235,13 +229,7 @@ macro_rules! impl_has_scoped_statement_id {
impl HasScopedAstId for $ty {
type Id = ScopedStatementId;
fn scoped_ast_id(
&self,
db: &dyn Db,
file: VfsFile,
file_scope: FileScopeId,
) -> Self::Id {
let scope = file_scope.to_scope_id(db, file);
fn scoped_ast_id(&self, db: &dyn Db, scope: ScopeId) -> Self::Id {
let ast_ids = ast_ids(db, scope);
ast_ids.statement_id(self)
}
@@ -252,8 +240,7 @@ macro_rules! impl_has_scoped_statement_id {
impl_has_scoped_statement_id!(ast::Stmt);
impl ScopedAstIdNode for ast::Stmt {
fn lookup_in_scope(db: &dyn Db, file: VfsFile, file_scope: FileScopeId, id: Self::Id) -> &Self {
let scope = file_scope.to_scope_id(db, file);
fn lookup_in_scope<'db>(db: &'db dyn Db, scope: ScopeId<'db>, id: Self::Id) -> &'db Self {
let ast_ids = ast_ids(db, scope);
ast_ids.statements[id].node()
@@ -266,16 +253,15 @@ pub struct ScopedFunctionId(pub(super) ScopedStatementId);
impl HasScopedAstId for ast::StmtFunctionDef {
type Id = ScopedFunctionId;
fn scoped_ast_id(&self, db: &dyn Db, file: VfsFile, file_scope: FileScopeId) -> Self::Id {
let scope = file_scope.to_scope_id(db, file);
fn scoped_ast_id(&self, db: &dyn Db, scope: ScopeId) -> Self::Id {
let ast_ids = ast_ids(db, scope);
ScopedFunctionId(ast_ids.statement_id(self))
}
}
impl ScopedAstIdNode for ast::StmtFunctionDef {
fn lookup_in_scope(db: &dyn Db, file: VfsFile, scope: FileScopeId, id: Self::Id) -> &Self {
ast::Stmt::lookup_in_scope(db, file, scope, id.0)
fn lookup_in_scope<'db>(db: &'db dyn Db, scope: ScopeId<'db>, id: Self::Id) -> &'db Self {
ast::Stmt::lookup_in_scope(db, scope, id.0)
.as_function_def_stmt()
.unwrap()
}
@@ -287,16 +273,15 @@ pub struct ScopedClassId(pub(super) ScopedStatementId);
impl HasScopedAstId for ast::StmtClassDef {
type Id = ScopedClassId;
fn scoped_ast_id(&self, db: &dyn Db, file: VfsFile, file_scope: FileScopeId) -> Self::Id {
let scope = file_scope.to_scope_id(db, file);
fn scoped_ast_id(&self, db: &dyn Db, scope: ScopeId) -> Self::Id {
let ast_ids = ast_ids(db, scope);
ScopedClassId(ast_ids.statement_id(self))
}
}
impl ScopedAstIdNode for ast::StmtClassDef {
fn lookup_in_scope(db: &dyn Db, file: VfsFile, scope: FileScopeId, id: Self::Id) -> &Self {
let statement = ast::Stmt::lookup_in_scope(db, file, scope, id.0);
fn lookup_in_scope<'db>(db: &'db dyn Db, scope: ScopeId<'db>, id: Self::Id) -> &'db Self {
let statement = ast::Stmt::lookup_in_scope(db, scope, id.0);
statement.as_class_def_stmt().unwrap()
}
}

View File

@@ -45,9 +45,10 @@ impl HasTy for ast::ExpressionRef<'_> {
fn ty<'db>(&self, model: &SemanticModel<'db>) -> Type<'db> {
let index = semantic_index(model.db, model.file);
let file_scope = index.expression_scope_id(*self);
let expression_id = self.scoped_ast_id(model.db, model.file, file_scope);
let scope = file_scope.to_scope_id(model.db, model.file);
let expression_id = self.scoped_ast_id(model.db, scope);
infer_types(model.db, scope).expression_ty(expression_id)
}
}
@@ -152,8 +153,7 @@ impl HasTy for ast::StmtFunctionDef {
let scope = parent_scope_id.to_scope_id(model.db, model.file);
let types = infer_types(model.db, scope);
let definition =
Definition::FunctionDef(self.scoped_ast_id(model.db, model.file, parent_scope_id));
let definition = Definition::FunctionDef(self.scoped_ast_id(model.db, scope));
types.definition_ty(definition)
}
@@ -175,8 +175,7 @@ impl HasTy for StmtClassDef {
let scope = parent_scope_id.to_scope_id(model.db, model.file);
let types = infer_types(model.db, scope);
let definition =
Definition::ClassDef(self.scoped_ast_id(model.db, model.file, parent_scope_id));
let definition = Definition::ClassDef(self.scoped_ast_id(model.db, scope));
types.definition_ty(definition)
}

View File

@@ -191,7 +191,7 @@ impl<'db> TypeInferenceBuilder<'db> {
decorator_list,
} = function;
let function_id = function.scoped_ast_id(self.db, self.file_id, self.file_scope_id);
let function_id = function.scoped_ast_id(self.db, self.scope);
let decorator_tys = decorator_list
.iter()
.map(|decorator| self.infer_decorator(decorator))
@@ -231,7 +231,7 @@ impl<'db> TypeInferenceBuilder<'db> {
body: _,
} = class;
let class_id = class.scoped_ast_id(self.db, self.file_id, self.file_scope_id);
let class_id = class.scoped_ast_id(self.db, self.scope);
for decorator in decorator_list {
self.infer_decorator(decorator);
@@ -303,7 +303,7 @@ impl<'db> TypeInferenceBuilder<'db> {
self.infer_expression(target);
}
let assign_id = assignment.scoped_ast_id(self.db, self.file_id, self.file_scope_id);
let assign_id = assignment.scoped_ast_id(self.db, self.scope);
// TODO: Handle multiple targets.
self.types
@@ -328,11 +328,7 @@ impl<'db> TypeInferenceBuilder<'db> {
self.infer_expression(target);
self.types.definition_tys.insert(
Definition::AnnotatedAssignment(assignment.scoped_ast_id(
self.db,
self.file_id,
self.file_scope_id,
)),
Definition::AnnotatedAssignment(assignment.scoped_ast_id(self.db, self.scope)),
annotation_ty,
);
}
@@ -356,7 +352,7 @@ impl<'db> TypeInferenceBuilder<'db> {
fn infer_import_statement(&mut self, import: &ast::StmtImport) {
let ast::StmtImport { range: _, names } = import;
let import_id = import.scoped_ast_id(self.db, self.file_id, self.file_scope_id);
let import_id = import.scoped_ast_id(self.db, self.scope);
for (i, alias) in names.iter().enumerate() {
let ast::Alias {
@@ -389,7 +385,7 @@ impl<'db> TypeInferenceBuilder<'db> {
level: _,
} = import;
let import_id = import.scoped_ast_id(self.db, self.file_id, self.file_scope_id);
let import_id = import.scoped_ast_id(self.db, self.scope);
let module_name = ModuleName::new(module.as_deref().expect("Support relative imports"));
let module =
@@ -492,7 +488,7 @@ impl<'db> TypeInferenceBuilder<'db> {
self.infer_expression(target);
self.types.definition_tys.insert(
Definition::NamedExpr(named.scoped_ast_id(self.db, self.file_id, self.file_scope_id)),
Definition::NamedExpr(named.scoped_ast_id(self.db, self.scope)),
value_ty,
);