Refactor ast_ids traits to take ScopeId instead of VfsFile plus FileScopeId. (#12139)
This commit is contained in:
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user