mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-27 20:35:09 +00:00
migrate ra_hir to rowan 2.0
This commit is contained in:
parent
d6020f516f
commit
da0b348ae9
20 changed files with 238 additions and 197 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -295,7 +295,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flexi_logger"
|
name = "flexi_logger"
|
||||||
version = "0.10.3"
|
version = "0.10.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -706,7 +706,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ena 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ena 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"flexi_logger 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"flexi_logger 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ra_arena 0.1.0",
|
"ra_arena 0.1.0",
|
||||||
|
@ -728,7 +728,7 @@ dependencies = [
|
||||||
"drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"flexi_logger 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"flexi_logger 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gen_lsp_server 0.1.0",
|
"gen_lsp_server 0.1.0",
|
||||||
"im 12.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"im 12.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"languageserver-types 0.53.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"languageserver-types 0.53.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -970,7 +970,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rowan"
|
name = "rowan"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/rust-analyzer/rowan.git?branch=new-impl#6b50db0f68a989c512e3bbebfbc8ede70ca7f221"
|
source = "git+https://github.com/rust-analyzer/rowan.git?branch=new-impl#c921101ffb102cfa5bd27ff3a746dc12cf56af5e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smol_str 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smol_str 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1510,7 +1510,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
|
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
|
||||||
"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
|
"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
|
||||||
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||||
"checksum flexi_logger 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4dda06444ccc8b0a6da19d939989b4a4e83f328710ada449eedaed48c8b903cd"
|
"checksum flexi_logger 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7d3681306880a7ce87740ceb3d1ce98ca92ae636ff30a629494488cbbcf85ff8"
|
||||||
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
|
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
|
||||||
"checksum fst 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "db72126ca7dff566cdbbdd54af44668c544897d9d3862b198141f176f1238bdf"
|
"checksum fst 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "db72126ca7dff566cdbbdd54af44668c544897d9d3862b198141f176f1238bdf"
|
||||||
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
||||||
|
|
|
@ -42,7 +42,7 @@ pub struct StructData {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StructData {
|
impl StructData {
|
||||||
pub(crate) fn new(struct_def: ast::StructDef) -> StructData {
|
pub(crate) fn new(struct_def: &ast::StructDef) -> StructData {
|
||||||
let name = struct_def.name().map(|n| n.as_name());
|
let name = struct_def.name().map(|n| n.as_name());
|
||||||
let variant_data = VariantData::new(struct_def.flavor());
|
let variant_data = VariantData::new(struct_def.flavor());
|
||||||
let variant_data = Arc::new(variant_data);
|
let variant_data = Arc::new(variant_data);
|
||||||
|
@ -87,7 +87,7 @@ pub struct EnumData {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EnumData {
|
impl EnumData {
|
||||||
pub(crate) fn new(enum_def: ast::EnumDef) -> Self {
|
pub(crate) fn new(enum_def: &ast::EnumDef) -> Self {
|
||||||
let name = enum_def.name().map(|n| n.as_name());
|
let name = enum_def.name().map(|n| n.as_name());
|
||||||
let variants = if let Some(evl) = enum_def.variant_list() {
|
let variants = if let Some(evl) = enum_def.variant_list() {
|
||||||
evl.variants()
|
evl.variants()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use relative_path::RelativePathBuf;
|
use relative_path::RelativePathBuf;
|
||||||
use ra_db::{CrateId, Cancelable, FileId};
|
use ra_db::{CrateId, Cancelable, FileId};
|
||||||
use ra_syntax::{ast, SyntaxNode};
|
use ra_syntax::{ast, TreePtr, SyntaxNode};
|
||||||
|
|
||||||
use crate::{Name, db::HirDatabase, DefId, Path, PerNs, nameres::ModuleScope};
|
use crate::{Name, db::HirDatabase, DefId, Path, PerNs, nameres::ModuleScope};
|
||||||
|
|
||||||
|
@ -36,8 +36,8 @@ pub struct Module {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum ModuleSource {
|
pub enum ModuleSource {
|
||||||
SourceFile(ast::SourceFileNode),
|
SourceFile(TreePtr<ast::SourceFile>),
|
||||||
Module(ast::ModuleNode),
|
Module(TreePtr<ast::Module>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
||||||
|
@ -66,7 +66,7 @@ impl Module {
|
||||||
pub fn declaration_source(
|
pub fn declaration_source(
|
||||||
&self,
|
&self,
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
) -> Cancelable<Option<(FileId, ast::ModuleNode)>> {
|
) -> Cancelable<Option<(FileId, TreePtr<ast::Module>)>> {
|
||||||
self.declaration_source_impl(db)
|
self.declaration_source_impl(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +104,10 @@ impl Module {
|
||||||
pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> Cancelable<PerNs<DefId>> {
|
pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> Cancelable<PerNs<DefId>> {
|
||||||
self.resolve_path_impl(db, path)
|
self.resolve_path_impl(db, path)
|
||||||
}
|
}
|
||||||
pub fn problems(&self, db: &impl HirDatabase) -> Cancelable<Vec<(SyntaxNode, Problem)>> {
|
pub fn problems(
|
||||||
|
&self,
|
||||||
|
db: &impl HirDatabase,
|
||||||
|
) -> Cancelable<Vec<(TreePtr<SyntaxNode>, Problem)>> {
|
||||||
self.problems_impl(db)
|
self.problems_impl(db)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use ra_db::{Cancelable, SourceRootId, FileId};
|
use ra_db::{Cancelable, SourceRootId, FileId};
|
||||||
use ra_syntax::{ast, SyntaxNode, AstNode};
|
use ra_syntax::{ast, SyntaxNode, AstNode, TreePtr};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Module, ModuleSource, Problem,
|
Module, ModuleSource, Problem,
|
||||||
|
@ -43,12 +43,11 @@ impl Module {
|
||||||
let loc = self.def_id.loc(db);
|
let loc = self.def_id.loc(db);
|
||||||
let file_id = loc.source_item_id.file_id.as_original_file();
|
let file_id = loc.source_item_id.file_id.as_original_file();
|
||||||
let syntax_node = db.file_item(loc.source_item_id);
|
let syntax_node = db.file_item(loc.source_item_id);
|
||||||
let syntax_node = syntax_node.borrowed();
|
let module_source = if let Some(source_file) = ast::SourceFile::cast(&syntax_node) {
|
||||||
let module_source = if let Some(source_file) = ast::SourceFile::cast(syntax_node) {
|
ModuleSource::SourceFile(source_file.to_owned())
|
||||||
ModuleSource::SourceFile(source_file.owned())
|
|
||||||
} else {
|
} else {
|
||||||
let module = ast::Module::cast(syntax_node).unwrap();
|
let module = ast::Module::cast(&syntax_node).unwrap();
|
||||||
ModuleSource::Module(module.owned())
|
ModuleSource::Module(module.to_owned())
|
||||||
};
|
};
|
||||||
Ok((file_id, module_source))
|
Ok((file_id, module_source))
|
||||||
}
|
}
|
||||||
|
@ -56,7 +55,7 @@ impl Module {
|
||||||
pub fn declaration_source_impl(
|
pub fn declaration_source_impl(
|
||||||
&self,
|
&self,
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
) -> Cancelable<Option<(FileId, ast::ModuleNode)>> {
|
) -> Cancelable<Option<(FileId, TreePtr<ast::Module>)>> {
|
||||||
let loc = self.def_id.loc(db);
|
let loc = self.def_id.loc(db);
|
||||||
let module_tree = db.module_tree(loc.source_root_id)?;
|
let module_tree = db.module_tree(loc.source_root_id)?;
|
||||||
let link = ctry!(loc.module_id.parent_link(&module_tree));
|
let link = ctry!(loc.module_id.parent_link(&module_tree));
|
||||||
|
@ -146,7 +145,10 @@ impl Module {
|
||||||
}
|
}
|
||||||
Ok(curr_per_ns)
|
Ok(curr_per_ns)
|
||||||
}
|
}
|
||||||
pub fn problems_impl(&self, db: &impl HirDatabase) -> Cancelable<Vec<(SyntaxNode, Problem)>> {
|
pub fn problems_impl(
|
||||||
|
&self,
|
||||||
|
db: &impl HirDatabase,
|
||||||
|
) -> Cancelable<Vec<(TreePtr<SyntaxNode>, Problem)>> {
|
||||||
let loc = self.def_id.loc(db);
|
let loc = self.def_id.loc(db);
|
||||||
let module_tree = db.module_tree(loc.source_root_id)?;
|
let module_tree = db.module_tree(loc.source_root_id)?;
|
||||||
Ok(loc.module_id.problems(&module_tree, db))
|
Ok(loc.module_id.problems(&module_tree, db))
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use ra_syntax::{SyntaxNode, SourceFileNode};
|
use ra_syntax::{SyntaxNode, TreePtr, SourceFile};
|
||||||
use ra_db::{SourceRootId, LocationIntener, SyntaxDatabase, Cancelable};
|
use ra_db::{SourceRootId, LocationIntener, SyntaxDatabase, Cancelable};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -22,7 +22,7 @@ pub trait HirDatabase: SyntaxDatabase
|
||||||
+ AsRef<LocationIntener<DefLoc, DefId>>
|
+ AsRef<LocationIntener<DefLoc, DefId>>
|
||||||
+ AsRef<LocationIntener<MacroCallLoc, MacroCallId>>
|
+ AsRef<LocationIntener<MacroCallLoc, MacroCallId>>
|
||||||
{
|
{
|
||||||
fn hir_source_file(file_id: HirFileId) -> SourceFileNode {
|
fn hir_source_file(file_id: HirFileId) -> TreePtr<SourceFile> {
|
||||||
type HirSourceFileQuery;
|
type HirSourceFileQuery;
|
||||||
use fn HirFileId::hir_source_file;
|
use fn HirFileId::hir_source_file;
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ pub trait HirDatabase: SyntaxDatabase
|
||||||
use fn query_definitions::file_items;
|
use fn query_definitions::file_items;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn file_item(source_item_id: SourceItemId) -> SyntaxNode {
|
fn file_item(source_item_id: SourceItemId) -> TreePtr<SyntaxNode> {
|
||||||
type FileItemQuery;
|
type FileItemQuery;
|
||||||
use fn query_definitions::file_item;
|
use fn query_definitions::file_item;
|
||||||
}
|
}
|
||||||
|
|
|
@ -373,10 +373,10 @@ impl ExprCollector {
|
||||||
self.exprs.alloc(block)
|
self.exprs.alloc(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_expr(&mut self, expr: ast::Expr) -> ExprId {
|
fn collect_expr(&mut self, expr: &ast::Expr) -> ExprId {
|
||||||
let syntax_ptr = LocalSyntaxPtr::new(expr.syntax());
|
let syntax_ptr = LocalSyntaxPtr::new(expr.syntax());
|
||||||
match expr {
|
match expr.kind() {
|
||||||
ast::Expr::IfExpr(e) => {
|
ast::ExprKind::IfExpr(e) => {
|
||||||
if let Some(pat) = e.condition().and_then(|c| c.pat()) {
|
if let Some(pat) = e.condition().and_then(|c| c.pat()) {
|
||||||
// if let -- desugar to match
|
// if let -- desugar to match
|
||||||
let pat = self.collect_pat(pat);
|
let pat = self.collect_pat(pat);
|
||||||
|
@ -419,12 +419,12 @@ impl ExprCollector {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::Expr::BlockExpr(e) => self.collect_block_opt(e.block()),
|
ast::ExprKind::BlockExpr(e) => self.collect_block_opt(e.block()),
|
||||||
ast::Expr::LoopExpr(e) => {
|
ast::ExprKind::LoopExpr(e) => {
|
||||||
let body = self.collect_block_opt(e.loop_body());
|
let body = self.collect_block_opt(e.loop_body());
|
||||||
self.alloc_expr(Expr::Loop { body }, syntax_ptr)
|
self.alloc_expr(Expr::Loop { body }, syntax_ptr)
|
||||||
}
|
}
|
||||||
ast::Expr::WhileExpr(e) => {
|
ast::ExprKind::WhileExpr(e) => {
|
||||||
let condition = if let Some(condition) = e.condition() {
|
let condition = if let Some(condition) = e.condition() {
|
||||||
if condition.pat().is_none() {
|
if condition.pat().is_none() {
|
||||||
self.collect_expr_opt(condition.expr())
|
self.collect_expr_opt(condition.expr())
|
||||||
|
@ -438,7 +438,7 @@ impl ExprCollector {
|
||||||
let body = self.collect_block_opt(e.loop_body());
|
let body = self.collect_block_opt(e.loop_body());
|
||||||
self.alloc_expr(Expr::While { condition, body }, syntax_ptr)
|
self.alloc_expr(Expr::While { condition, body }, syntax_ptr)
|
||||||
}
|
}
|
||||||
ast::Expr::ForExpr(e) => {
|
ast::ExprKind::ForExpr(e) => {
|
||||||
let iterable = self.collect_expr_opt(e.iterable());
|
let iterable = self.collect_expr_opt(e.iterable());
|
||||||
let pat = self.collect_pat_opt(e.pat());
|
let pat = self.collect_pat_opt(e.pat());
|
||||||
let body = self.collect_block_opt(e.loop_body());
|
let body = self.collect_block_opt(e.loop_body());
|
||||||
|
@ -451,7 +451,7 @@ impl ExprCollector {
|
||||||
syntax_ptr,
|
syntax_ptr,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ast::Expr::CallExpr(e) => {
|
ast::ExprKind::CallExpr(e) => {
|
||||||
let callee = self.collect_expr_opt(e.expr());
|
let callee = self.collect_expr_opt(e.expr());
|
||||||
let args = if let Some(arg_list) = e.arg_list() {
|
let args = if let Some(arg_list) = e.arg_list() {
|
||||||
arg_list.args().map(|e| self.collect_expr(e)).collect()
|
arg_list.args().map(|e| self.collect_expr(e)).collect()
|
||||||
|
@ -460,7 +460,7 @@ impl ExprCollector {
|
||||||
};
|
};
|
||||||
self.alloc_expr(Expr::Call { callee, args }, syntax_ptr)
|
self.alloc_expr(Expr::Call { callee, args }, syntax_ptr)
|
||||||
}
|
}
|
||||||
ast::Expr::MethodCallExpr(e) => {
|
ast::ExprKind::MethodCallExpr(e) => {
|
||||||
let receiver = self.collect_expr_opt(e.expr());
|
let receiver = self.collect_expr_opt(e.expr());
|
||||||
let args = if let Some(arg_list) = e.arg_list() {
|
let args = if let Some(arg_list) = e.arg_list() {
|
||||||
arg_list.args().map(|e| self.collect_expr(e)).collect()
|
arg_list.args().map(|e| self.collect_expr(e)).collect()
|
||||||
|
@ -480,7 +480,7 @@ impl ExprCollector {
|
||||||
syntax_ptr,
|
syntax_ptr,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ast::Expr::MatchExpr(e) => {
|
ast::ExprKind::MatchExpr(e) => {
|
||||||
let expr = self.collect_expr_opt(e.expr());
|
let expr = self.collect_expr_opt(e.expr());
|
||||||
let arms = if let Some(match_arm_list) = e.match_arm_list() {
|
let arms = if let Some(match_arm_list) = e.match_arm_list() {
|
||||||
match_arm_list
|
match_arm_list
|
||||||
|
@ -495,7 +495,7 @@ impl ExprCollector {
|
||||||
};
|
};
|
||||||
self.alloc_expr(Expr::Match { expr, arms }, syntax_ptr)
|
self.alloc_expr(Expr::Match { expr, arms }, syntax_ptr)
|
||||||
}
|
}
|
||||||
ast::Expr::PathExpr(e) => {
|
ast::ExprKind::PathExpr(e) => {
|
||||||
let path = e
|
let path = e
|
||||||
.path()
|
.path()
|
||||||
.and_then(Path::from_ast)
|
.and_then(Path::from_ast)
|
||||||
|
@ -503,25 +503,25 @@ impl ExprCollector {
|
||||||
.unwrap_or(Expr::Missing);
|
.unwrap_or(Expr::Missing);
|
||||||
self.alloc_expr(path, syntax_ptr)
|
self.alloc_expr(path, syntax_ptr)
|
||||||
}
|
}
|
||||||
ast::Expr::ContinueExpr(_e) => {
|
ast::ExprKind::ContinueExpr(_e) => {
|
||||||
// TODO: labels
|
// TODO: labels
|
||||||
self.alloc_expr(Expr::Continue, syntax_ptr)
|
self.alloc_expr(Expr::Continue, syntax_ptr)
|
||||||
}
|
}
|
||||||
ast::Expr::BreakExpr(e) => {
|
ast::ExprKind::BreakExpr(e) => {
|
||||||
let expr = e.expr().map(|e| self.collect_expr(e));
|
let expr = e.expr().map(|e| self.collect_expr(e));
|
||||||
self.alloc_expr(Expr::Break { expr }, syntax_ptr)
|
self.alloc_expr(Expr::Break { expr }, syntax_ptr)
|
||||||
}
|
}
|
||||||
ast::Expr::ParenExpr(e) => {
|
ast::ExprKind::ParenExpr(e) => {
|
||||||
let inner = self.collect_expr_opt(e.expr());
|
let inner = self.collect_expr_opt(e.expr());
|
||||||
// make the paren expr point to the inner expression as well
|
// make the paren expr point to the inner expression as well
|
||||||
self.expr_syntax_mapping.insert(syntax_ptr, inner);
|
self.expr_syntax_mapping.insert(syntax_ptr, inner);
|
||||||
inner
|
inner
|
||||||
}
|
}
|
||||||
ast::Expr::ReturnExpr(e) => {
|
ast::ExprKind::ReturnExpr(e) => {
|
||||||
let expr = e.expr().map(|e| self.collect_expr(e));
|
let expr = e.expr().map(|e| self.collect_expr(e));
|
||||||
self.alloc_expr(Expr::Return { expr }, syntax_ptr)
|
self.alloc_expr(Expr::Return { expr }, syntax_ptr)
|
||||||
}
|
}
|
||||||
ast::Expr::StructLit(e) => {
|
ast::ExprKind::StructLit(e) => {
|
||||||
let path = e.path().and_then(Path::from_ast);
|
let path = e.path().and_then(Path::from_ast);
|
||||||
let fields = if let Some(nfl) = e.named_field_list() {
|
let fields = if let Some(nfl) = e.named_field_list() {
|
||||||
nfl.fields()
|
nfl.fields()
|
||||||
|
@ -558,7 +558,7 @@ impl ExprCollector {
|
||||||
syntax_ptr,
|
syntax_ptr,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ast::Expr::FieldExpr(e) => {
|
ast::ExprKind::FieldExpr(e) => {
|
||||||
let expr = self.collect_expr_opt(e.expr());
|
let expr = self.collect_expr_opt(e.expr());
|
||||||
let name = e
|
let name = e
|
||||||
.name_ref()
|
.name_ref()
|
||||||
|
@ -566,26 +566,26 @@ impl ExprCollector {
|
||||||
.unwrap_or_else(Name::missing);
|
.unwrap_or_else(Name::missing);
|
||||||
self.alloc_expr(Expr::Field { expr, name }, syntax_ptr)
|
self.alloc_expr(Expr::Field { expr, name }, syntax_ptr)
|
||||||
}
|
}
|
||||||
ast::Expr::TryExpr(e) => {
|
ast::ExprKind::TryExpr(e) => {
|
||||||
let expr = self.collect_expr_opt(e.expr());
|
let expr = self.collect_expr_opt(e.expr());
|
||||||
self.alloc_expr(Expr::Try { expr }, syntax_ptr)
|
self.alloc_expr(Expr::Try { expr }, syntax_ptr)
|
||||||
}
|
}
|
||||||
ast::Expr::CastExpr(e) => {
|
ast::ExprKind::CastExpr(e) => {
|
||||||
let expr = self.collect_expr_opt(e.expr());
|
let expr = self.collect_expr_opt(e.expr());
|
||||||
let type_ref = TypeRef::from_ast_opt(e.type_ref());
|
let type_ref = TypeRef::from_ast_opt(e.type_ref());
|
||||||
self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr)
|
self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr)
|
||||||
}
|
}
|
||||||
ast::Expr::RefExpr(e) => {
|
ast::ExprKind::RefExpr(e) => {
|
||||||
let expr = self.collect_expr_opt(e.expr());
|
let expr = self.collect_expr_opt(e.expr());
|
||||||
let mutability = Mutability::from_mutable(e.is_mut());
|
let mutability = Mutability::from_mutable(e.is_mut());
|
||||||
self.alloc_expr(Expr::Ref { expr, mutability }, syntax_ptr)
|
self.alloc_expr(Expr::Ref { expr, mutability }, syntax_ptr)
|
||||||
}
|
}
|
||||||
ast::Expr::PrefixExpr(e) => {
|
ast::ExprKind::PrefixExpr(e) => {
|
||||||
let expr = self.collect_expr_opt(e.expr());
|
let expr = self.collect_expr_opt(e.expr());
|
||||||
let op = e.op();
|
let op = e.op();
|
||||||
self.alloc_expr(Expr::UnaryOp { expr, op }, syntax_ptr)
|
self.alloc_expr(Expr::UnaryOp { expr, op }, syntax_ptr)
|
||||||
}
|
}
|
||||||
ast::Expr::LambdaExpr(e) => {
|
ast::ExprKind::LambdaExpr(e) => {
|
||||||
let mut args = Vec::new();
|
let mut args = Vec::new();
|
||||||
let mut arg_types = Vec::new();
|
let mut arg_types = Vec::new();
|
||||||
if let Some(pl) = e.param_list() {
|
if let Some(pl) = e.param_list() {
|
||||||
|
@ -606,7 +606,7 @@ impl ExprCollector {
|
||||||
syntax_ptr,
|
syntax_ptr,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ast::Expr::BinExpr(e) => {
|
ast::ExprKind::BinExpr(e) => {
|
||||||
let lhs = self.collect_expr_opt(e.lhs());
|
let lhs = self.collect_expr_opt(e.lhs());
|
||||||
let rhs = self.collect_expr_opt(e.rhs());
|
let rhs = self.collect_expr_opt(e.rhs());
|
||||||
let op = e.op();
|
let op = e.op();
|
||||||
|
@ -614,16 +614,16 @@ impl ExprCollector {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO implement HIR for these:
|
// TODO implement HIR for these:
|
||||||
ast::Expr::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
||||||
ast::Expr::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
||||||
ast::Expr::TupleExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
ast::ExprKind::TupleExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
||||||
ast::Expr::ArrayExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
ast::ExprKind::ArrayExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
||||||
ast::Expr::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
||||||
ast::Expr::Literal(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
ast::ExprKind::Literal(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_expr_opt(&mut self, expr: Option<ast::Expr>) -> ExprId {
|
fn collect_expr_opt(&mut self, expr: Option<&ast::Expr>) -> ExprId {
|
||||||
if let Some(expr) = expr {
|
if let Some(expr) = expr {
|
||||||
self.collect_expr(expr)
|
self.collect_expr(expr)
|
||||||
} else {
|
} else {
|
||||||
|
@ -631,11 +631,11 @@ impl ExprCollector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_block(&mut self, block: ast::Block) -> ExprId {
|
fn collect_block(&mut self, block: &ast::Block) -> ExprId {
|
||||||
let statements = block
|
let statements = block
|
||||||
.statements()
|
.statements()
|
||||||
.map(|s| match s {
|
.map(|s| match s.kind() {
|
||||||
ast::Stmt::LetStmt(stmt) => {
|
ast::StmtKind::LetStmt(stmt) => {
|
||||||
let pat = self.collect_pat_opt(stmt.pat());
|
let pat = self.collect_pat_opt(stmt.pat());
|
||||||
let type_ref = stmt.type_ref().map(TypeRef::from_ast);
|
let type_ref = stmt.type_ref().map(TypeRef::from_ast);
|
||||||
let initializer = stmt.initializer().map(|e| self.collect_expr(e));
|
let initializer = stmt.initializer().map(|e| self.collect_expr(e));
|
||||||
|
@ -645,7 +645,9 @@ impl ExprCollector {
|
||||||
initializer,
|
initializer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::Stmt::ExprStmt(stmt) => Statement::Expr(self.collect_expr_opt(stmt.expr())),
|
ast::StmtKind::ExprStmt(stmt) => {
|
||||||
|
Statement::Expr(self.collect_expr_opt(stmt.expr()))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let tail = block.expr().map(|e| self.collect_expr(e));
|
let tail = block.expr().map(|e| self.collect_expr(e));
|
||||||
|
@ -655,7 +657,7 @@ impl ExprCollector {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_block_opt(&mut self, block: Option<ast::Block>) -> ExprId {
|
fn collect_block_opt(&mut self, block: Option<&ast::Block>) -> ExprId {
|
||||||
if let Some(block) = block {
|
if let Some(block) = block {
|
||||||
self.collect_block(block)
|
self.collect_block(block)
|
||||||
} else {
|
} else {
|
||||||
|
@ -663,17 +665,17 @@ impl ExprCollector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_pat(&mut self, pat: ast::Pat) -> PatId {
|
fn collect_pat(&mut self, pat: &ast::Pat) -> PatId {
|
||||||
let syntax_ptr = LocalSyntaxPtr::new(pat.syntax());
|
let syntax_ptr = LocalSyntaxPtr::new(pat.syntax());
|
||||||
match pat {
|
match pat.kind() {
|
||||||
ast::Pat::BindPat(bp) => {
|
ast::PatKind::BindPat(bp) => {
|
||||||
let name = bp
|
let name = bp
|
||||||
.name()
|
.name()
|
||||||
.map(|nr| nr.as_name())
|
.map(|nr| nr.as_name())
|
||||||
.unwrap_or_else(Name::missing);
|
.unwrap_or_else(Name::missing);
|
||||||
self.alloc_pat(Pat::Bind { name }, syntax_ptr)
|
self.alloc_pat(Pat::Bind { name }, syntax_ptr)
|
||||||
}
|
}
|
||||||
ast::Pat::TupleStructPat(p) => {
|
ast::PatKind::TupleStructPat(p) => {
|
||||||
let path = p.path().and_then(Path::from_ast);
|
let path = p.path().and_then(Path::from_ast);
|
||||||
let args = p.args().map(|p| self.collect_pat(p)).collect();
|
let args = p.args().map(|p| self.collect_pat(p)).collect();
|
||||||
self.alloc_pat(Pat::TupleStruct { path, args }, syntax_ptr)
|
self.alloc_pat(Pat::TupleStruct { path, args }, syntax_ptr)
|
||||||
|
@ -685,7 +687,7 @@ impl ExprCollector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_pat_opt(&mut self, pat: Option<ast::Pat>) -> PatId {
|
fn collect_pat_opt(&mut self, pat: Option<&ast::Pat>) -> PatId {
|
||||||
if let Some(pat) = pat {
|
if let Some(pat) = pat {
|
||||||
self.collect_pat(pat)
|
self.collect_pat(pat)
|
||||||
} else {
|
} else {
|
||||||
|
@ -710,7 +712,7 @@ impl ExprCollector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn collect_fn_body_syntax(node: ast::FnDef) -> BodySyntaxMapping {
|
pub(crate) fn collect_fn_body_syntax(node: &ast::FnDef) -> BodySyntaxMapping {
|
||||||
let mut collector = ExprCollector::new();
|
let mut collector = ExprCollector::new();
|
||||||
|
|
||||||
let args = if let Some(param_list) = node.param_list() {
|
let args = if let Some(param_list) = node.param_list() {
|
||||||
|
@ -758,9 +760,7 @@ pub(crate) fn body_syntax_mapping(
|
||||||
let body_syntax_mapping = match def {
|
let body_syntax_mapping = match def {
|
||||||
Def::Function(f) => {
|
Def::Function(f) => {
|
||||||
let node = f.syntax(db);
|
let node = f.syntax(db);
|
||||||
let node = node.borrowed();
|
collect_fn_body_syntax(&node)
|
||||||
|
|
||||||
collect_fn_body_syntax(node)
|
|
||||||
}
|
}
|
||||||
// TODO: consts, etc.
|
// TODO: consts, etc.
|
||||||
_ => panic!("Trying to get body for item type without body"),
|
_ => panic!("Trying to get body for item type without body"),
|
||||||
|
|
|
@ -7,7 +7,7 @@ use std::{
|
||||||
|
|
||||||
use ra_db::Cancelable;
|
use ra_db::Cancelable;
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
TextRange, TextUnit,
|
TextRange, TextUnit, TreePtr,
|
||||||
ast::{self, AstNode, DocCommentsOwner, NameOwner},
|
ast::{self, AstNode, DocCommentsOwner, NameOwner},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -29,11 +29,11 @@ impl Function {
|
||||||
self.def_id
|
self.def_id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn syntax(&self, db: &impl HirDatabase) -> ast::FnDefNode {
|
pub fn syntax(&self, db: &impl HirDatabase) -> TreePtr<ast::FnDef> {
|
||||||
let def_loc = self.def_id.loc(db);
|
let def_loc = self.def_id.loc(db);
|
||||||
assert!(def_loc.kind == DefKind::Function);
|
assert!(def_loc.kind == DefKind::Function);
|
||||||
let syntax = db.file_item(def_loc.source_item_id);
|
let syntax = db.file_item(def_loc.source_item_id);
|
||||||
ast::FnDef::cast(syntax.borrowed()).unwrap().owned()
|
ast::FnDef::cast(&syntax).unwrap().to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn body(&self, db: &impl HirDatabase) -> Cancelable<Arc<Body>> {
|
pub fn body(&self, db: &impl HirDatabase) -> Cancelable<Arc<Body>> {
|
||||||
|
@ -59,7 +59,7 @@ impl Function {
|
||||||
|
|
||||||
pub fn signature_info(&self, db: &impl HirDatabase) -> Option<FnSignatureInfo> {
|
pub fn signature_info(&self, db: &impl HirDatabase) -> Option<FnSignatureInfo> {
|
||||||
let syntax = self.syntax(db);
|
let syntax = self.syntax(db);
|
||||||
FnSignatureInfo::new(syntax.borrowed())
|
FnSignatureInfo::new(&syntax)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn infer(&self, db: &impl HirDatabase) -> Cancelable<Arc<InferenceResult>> {
|
pub fn infer(&self, db: &impl HirDatabase) -> Cancelable<Arc<InferenceResult>> {
|
||||||
|
@ -99,8 +99,7 @@ impl FnSignature {
|
||||||
|
|
||||||
pub(crate) fn fn_signature(db: &impl HirDatabase, def_id: DefId) -> Arc<FnSignature> {
|
pub(crate) fn fn_signature(db: &impl HirDatabase, def_id: DefId) -> Arc<FnSignature> {
|
||||||
let func = Function::new(def_id);
|
let func = Function::new(def_id);
|
||||||
let syntax = func.syntax(db);
|
let node = func.syntax(db);
|
||||||
let node = syntax.borrowed();
|
|
||||||
let mut args = Vec::new();
|
let mut args = Vec::new();
|
||||||
if let Some(param_list) = node.param_list() {
|
if let Some(param_list) = node.param_list() {
|
||||||
if let Some(self_param) = param_list.self_param() {
|
if let Some(self_param) = param_list.self_param() {
|
||||||
|
@ -144,7 +143,7 @@ pub struct FnSignatureInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FnSignatureInfo {
|
impl FnSignatureInfo {
|
||||||
fn new(node: ast::FnDef) -> Option<Self> {
|
fn new(node: &ast::FnDef) -> Option<Self> {
|
||||||
let name = node.name()?.text().to_string();
|
let name = node.name()?.text().to_string();
|
||||||
|
|
||||||
let mut doc = None;
|
let mut doc = None;
|
||||||
|
@ -207,7 +206,7 @@ impl FnSignatureInfo {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract_doc_comments(node: ast::FnDef) -> Option<(TextRange, String)> {
|
fn extract_doc_comments(node: &ast::FnDef) -> Option<(TextRange, String)> {
|
||||||
if node.doc_comments().count() == 0 {
|
if node.doc_comments().count() == 0 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -227,7 +226,7 @@ impl FnSignatureInfo {
|
||||||
Some((range, comment_text))
|
Some((range, comment_text))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn param_list(node: ast::FnDef) -> Vec<String> {
|
fn param_list(node: &ast::FnDef) -> Vec<String> {
|
||||||
let mut res = vec![];
|
let mut res = vec![];
|
||||||
if let Some(param_list) = node.param_list() {
|
if let Some(param_list) = node.param_list() {
|
||||||
if let Some(self_param) = param_list.self_param() {
|
if let Some(self_param) = param_list.self_param() {
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::sync::Arc;
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
|
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
AstNode, SyntaxNodeRef, TextUnit, TextRange,
|
AstNode, SyntaxNode, TextUnit, TextRange,
|
||||||
algo::generate,
|
algo::generate,
|
||||||
ast,
|
ast,
|
||||||
};
|
};
|
||||||
|
@ -127,7 +127,7 @@ impl ScopeEntryWithSyntax {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScopesWithSyntaxMapping {
|
impl ScopesWithSyntaxMapping {
|
||||||
pub fn scope_chain<'a>(&'a self, node: SyntaxNodeRef) -> impl Iterator<Item = ScopeId> + 'a {
|
pub fn scope_chain<'a>(&'a self, node: &SyntaxNode) -> impl Iterator<Item = ScopeId> + 'a {
|
||||||
generate(self.scope_for(node), move |&scope| {
|
generate(self.scope_for(node), move |&scope| {
|
||||||
self.scopes.scopes[scope].parent
|
self.scopes.scopes[scope].parent
|
||||||
})
|
})
|
||||||
|
@ -178,7 +178,7 @@ impl ScopesWithSyntaxMapping {
|
||||||
.unwrap_or(original_scope)
|
.unwrap_or(original_scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_local_name(&self, name_ref: ast::NameRef) -> Option<ScopeEntryWithSyntax> {
|
pub fn resolve_local_name(&self, name_ref: &ast::NameRef) -> Option<ScopeEntryWithSyntax> {
|
||||||
let mut shadowed = FxHashSet::default();
|
let mut shadowed = FxHashSet::default();
|
||||||
let name = name_ref.as_name();
|
let name = name_ref.as_name();
|
||||||
let ret = self
|
let ret = self
|
||||||
|
@ -195,7 +195,7 @@ impl ScopesWithSyntaxMapping {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_all_refs(&self, pat: ast::BindPat) -> Vec<ReferenceDescriptor> {
|
pub fn find_all_refs(&self, pat: &ast::BindPat) -> Vec<ReferenceDescriptor> {
|
||||||
let fn_def = pat.syntax().ancestors().find_map(ast::FnDef::cast).unwrap();
|
let fn_def = pat.syntax().ancestors().find_map(ast::FnDef::cast).unwrap();
|
||||||
let name_ptr = LocalSyntaxPtr::new(pat.syntax());
|
let name_ptr = LocalSyntaxPtr::new(pat.syntax());
|
||||||
fn_def
|
fn_def
|
||||||
|
@ -213,7 +213,7 @@ impl ScopesWithSyntaxMapping {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scope_for(&self, node: SyntaxNodeRef) -> Option<ScopeId> {
|
fn scope_for(&self, node: &SyntaxNode) -> Option<ScopeId> {
|
||||||
node.ancestors()
|
node.ancestors()
|
||||||
.map(LocalSyntaxPtr::new)
|
.map(LocalSyntaxPtr::new)
|
||||||
.filter_map(|ptr| self.syntax_mapping.syntax_expr(ptr))
|
.filter_map(|ptr| self.syntax_mapping.syntax_expr(ptr))
|
||||||
|
@ -309,7 +309,7 @@ pub struct ReferenceDescriptor {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use ra_editor::find_node_at_offset;
|
use ra_editor::find_node_at_offset;
|
||||||
use ra_syntax::SourceFileNode;
|
use ra_syntax::SourceFile;
|
||||||
use test_utils::{extract_offset, assert_eq_text};
|
use test_utils::{extract_offset, assert_eq_text};
|
||||||
|
|
||||||
use crate::expr;
|
use crate::expr;
|
||||||
|
@ -326,9 +326,9 @@ mod tests {
|
||||||
buf.push_str(&code[off..]);
|
buf.push_str(&code[off..]);
|
||||||
buf
|
buf
|
||||||
};
|
};
|
||||||
let file = SourceFileNode::parse(&code);
|
let file = SourceFile::parse(&code);
|
||||||
let marker: ast::PathExpr = find_node_at_offset(file.syntax(), off).unwrap();
|
let marker: &ast::PathExpr = find_node_at_offset(file.syntax(), off).unwrap();
|
||||||
let fn_def: ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap();
|
let fn_def: &ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap();
|
||||||
let body_hir = expr::collect_fn_body_syntax(fn_def);
|
let body_hir = expr::collect_fn_body_syntax(fn_def);
|
||||||
let scopes = FnScopes::new(Arc::clone(body_hir.body()));
|
let scopes = FnScopes::new(Arc::clone(body_hir.body()));
|
||||||
let scopes = ScopesWithSyntaxMapping {
|
let scopes = ScopesWithSyntaxMapping {
|
||||||
|
@ -422,9 +422,9 @@ mod tests {
|
||||||
|
|
||||||
fn do_check_local_name(code: &str, expected_offset: u32) {
|
fn do_check_local_name(code: &str, expected_offset: u32) {
|
||||||
let (off, code) = extract_offset(code);
|
let (off, code) = extract_offset(code);
|
||||||
let file = SourceFileNode::parse(&code);
|
let file = SourceFile::parse(&code);
|
||||||
let fn_def: ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap();
|
let fn_def: &ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap();
|
||||||
let name_ref: ast::NameRef = find_node_at_offset(file.syntax(), off).unwrap();
|
let name_ref: &ast::NameRef = find_node_at_offset(file.syntax(), off).unwrap();
|
||||||
|
|
||||||
let body_hir = expr::collect_fn_body_syntax(fn_def);
|
let body_hir = expr::collect_fn_body_syntax(fn_def);
|
||||||
let scopes = FnScopes::new(Arc::clone(body_hir.body()));
|
let scopes = FnScopes::new(Arc::clone(body_hir.body()));
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use ra_db::{SourceRootId, LocationIntener, Cancelable, FileId};
|
use ra_db::{SourceRootId, LocationIntener, Cancelable, FileId};
|
||||||
use ra_syntax::{SourceFileNode, SyntaxKind, SyntaxNode, SyntaxNodeRef, SourceFile, AstNode, ast};
|
use ra_syntax::{TreePtr, SyntaxKind, SyntaxNode, SourceFile, AstNode, ast};
|
||||||
use ra_arena::{Arena, RawId, impl_arena_id};
|
use ra_arena::{Arena, RawId, impl_arena_id};
|
||||||
|
|
||||||
use crate::{HirDatabase, PerNs, ModuleId, Def, Function, Struct, Enum, ImplBlock, Crate};
|
use crate::{HirDatabase, PerNs, ModuleId, Def, Function, Struct, Enum, ImplBlock, Crate};
|
||||||
|
@ -55,7 +55,10 @@ impl HirFileId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn hir_source_file(db: &impl HirDatabase, file_id: HirFileId) -> SourceFileNode {
|
pub(crate) fn hir_source_file(
|
||||||
|
db: &impl HirDatabase,
|
||||||
|
file_id: HirFileId,
|
||||||
|
) -> TreePtr<SourceFile> {
|
||||||
match file_id.0 {
|
match file_id.0 {
|
||||||
HirFileIdRepr::File(file_id) => db.source_file(file_id),
|
HirFileIdRepr::File(file_id) => db.source_file(file_id),
|
||||||
HirFileIdRepr::Macro(m) => {
|
HirFileIdRepr::Macro(m) => {
|
||||||
|
@ -63,7 +66,7 @@ impl HirFileId {
|
||||||
return exp.file();
|
return exp.file();
|
||||||
}
|
}
|
||||||
// returning an empty string looks fishy...
|
// returning an empty string looks fishy...
|
||||||
SourceFileNode::parse("")
|
SourceFile::parse("")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -233,11 +236,11 @@ pub struct SourceItemId {
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct SourceFileItems {
|
pub struct SourceFileItems {
|
||||||
file_id: HirFileId,
|
file_id: HirFileId,
|
||||||
arena: Arena<SourceFileItemId, SyntaxNode>,
|
arena: Arena<SourceFileItemId, TreePtr<SyntaxNode>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SourceFileItems {
|
impl SourceFileItems {
|
||||||
pub(crate) fn new(file_id: HirFileId, source_file: SourceFile) -> SourceFileItems {
|
pub(crate) fn new(file_id: HirFileId, source_file: &SourceFile) -> SourceFileItems {
|
||||||
let mut res = SourceFileItems {
|
let mut res = SourceFileItems {
|
||||||
file_id,
|
file_id,
|
||||||
arena: Arena::default(),
|
arena: Arena::default(),
|
||||||
|
@ -246,20 +249,20 @@ impl SourceFileItems {
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(&mut self, source_file: SourceFile) {
|
fn init(&mut self, source_file: &SourceFile) {
|
||||||
source_file.syntax().descendants().for_each(|it| {
|
source_file.syntax().descendants().for_each(|it| {
|
||||||
if let Some(module_item) = ast::ModuleItem::cast(it) {
|
if let Some(module_item) = ast::ModuleItem::cast(it) {
|
||||||
self.alloc(module_item.syntax().owned());
|
self.alloc(module_item.syntax().to_owned());
|
||||||
} else if let Some(macro_call) = ast::MacroCall::cast(it) {
|
} else if let Some(macro_call) = ast::MacroCall::cast(it) {
|
||||||
self.alloc(macro_call.syntax().owned());
|
self.alloc(macro_call.syntax().to_owned());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alloc(&mut self, item: SyntaxNode) -> SourceFileItemId {
|
fn alloc(&mut self, item: TreePtr<SyntaxNode>) -> SourceFileItemId {
|
||||||
self.arena.alloc(item)
|
self.arena.alloc(item)
|
||||||
}
|
}
|
||||||
pub(crate) fn id_of(&self, file_id: HirFileId, item: SyntaxNodeRef) -> SourceFileItemId {
|
pub(crate) fn id_of(&self, file_id: HirFileId, item: &SyntaxNode) -> SourceFileItemId {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
self.file_id, file_id,
|
self.file_id, file_id,
|
||||||
"SourceFileItems: wrong file, expected {:?}, got {:?}",
|
"SourceFileItems: wrong file, expected {:?}, got {:?}",
|
||||||
|
@ -267,8 +270,8 @@ impl SourceFileItems {
|
||||||
);
|
);
|
||||||
self.id_of_unchecked(item)
|
self.id_of_unchecked(item)
|
||||||
}
|
}
|
||||||
pub(crate) fn id_of_unchecked(&self, item: SyntaxNodeRef) -> SourceFileItemId {
|
pub(crate) fn id_of_unchecked(&self, item: &SyntaxNode) -> SourceFileItemId {
|
||||||
if let Some((id, _)) = self.arena.iter().find(|(_id, i)| i.borrowed() == item) {
|
if let Some((id, _)) = self.arena.iter().find(|(_id, i)| *i == item) {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
// This should not happen. Let's try to give a sensible diagnostics.
|
// This should not happen. Let's try to give a sensible diagnostics.
|
||||||
|
|
|
@ -62,7 +62,7 @@ impl ImplData {
|
||||||
db: &impl AsRef<LocationIntener<DefLoc, DefId>>,
|
db: &impl AsRef<LocationIntener<DefLoc, DefId>>,
|
||||||
file_items: &SourceFileItems,
|
file_items: &SourceFileItems,
|
||||||
module: &Module,
|
module: &Module,
|
||||||
node: ast::ImplBlock,
|
node: &ast::ImplBlock,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let target_trait = node.target_type().map(TypeRef::from_ast);
|
let target_trait = node.target_type().map(TypeRef::from_ast);
|
||||||
let target_type = TypeRef::from_ast_opt(node.target_type());
|
let target_type = TypeRef::from_ast_opt(node.target_type());
|
||||||
|
@ -71,10 +71,10 @@ impl ImplData {
|
||||||
item_list
|
item_list
|
||||||
.impl_items()
|
.impl_items()
|
||||||
.map(|item_node| {
|
.map(|item_node| {
|
||||||
let kind = match item_node {
|
let kind = match item_node.kind() {
|
||||||
ast::ImplItem::FnDef(..) => DefKind::Function,
|
ast::ImplItemKind::FnDef(..) => DefKind::Function,
|
||||||
ast::ImplItem::ConstDef(..) => DefKind::Item,
|
ast::ImplItemKind::ConstDef(..) => DefKind::Item,
|
||||||
ast::ImplItem::TypeDef(..) => DefKind::Item,
|
ast::ImplItemKind::TypeDef(..) => DefKind::Item,
|
||||||
};
|
};
|
||||||
let item_id = file_items.id_of_unchecked(item_node.syntax());
|
let item_id = file_items.id_of_unchecked(item_node.syntax());
|
||||||
let source_item_id = SourceItemId {
|
let source_item_id = SourceItemId {
|
||||||
|
@ -87,10 +87,10 @@ impl ImplData {
|
||||||
..module_loc
|
..module_loc
|
||||||
};
|
};
|
||||||
let def_id = def_loc.id(db);
|
let def_id = def_loc.id(db);
|
||||||
match item_node {
|
match item_node.kind() {
|
||||||
ast::ImplItem::FnDef(..) => ImplItem::Method(Function::new(def_id)),
|
ast::ImplItemKind::FnDef(..) => ImplItem::Method(Function::new(def_id)),
|
||||||
ast::ImplItem::ConstDef(..) => ImplItem::Const(def_id),
|
ast::ImplItemKind::ConstDef(..) => ImplItem::Const(def_id),
|
||||||
ast::ImplItem::TypeDef(..) => ImplItem::Type(def_id),
|
ast::ImplItemKind::TypeDef(..) => ImplItem::Type(def_id),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
|
@ -152,8 +152,8 @@ impl ModuleImplBlocks {
|
||||||
fn collect(&mut self, db: &impl HirDatabase, module: Module) -> Cancelable<()> {
|
fn collect(&mut self, db: &impl HirDatabase, module: Module) -> Cancelable<()> {
|
||||||
let (file_id, module_source) = module.defenition_source(db)?;
|
let (file_id, module_source) = module.defenition_source(db)?;
|
||||||
let node = match &module_source {
|
let node = match &module_source {
|
||||||
ModuleSource::SourceFile(node) => node.borrowed().syntax(),
|
ModuleSource::SourceFile(node) => node.syntax(),
|
||||||
ModuleSource::Module(node) => node.borrowed().syntax(),
|
ModuleSource::Module(node) => node.syntax(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let source_file_items = db.file_items(file_id.into());
|
let source_file_items = db.file_items(file_id.into());
|
||||||
|
|
|
@ -11,7 +11,7 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use ra_db::LocalSyntaxPtr;
|
use ra_db::LocalSyntaxPtr;
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
TextRange, TextUnit, SourceFileNode, AstNode, SyntaxNode,
|
TextRange, TextUnit, SourceFile, AstNode, SyntaxNode, TreePtr,
|
||||||
ast::{self, NameOwner},
|
ast::{self, NameOwner},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -28,14 +28,14 @@ pub enum MacroDef {
|
||||||
impl MacroDef {
|
impl MacroDef {
|
||||||
/// Expands macro call, returning the expansion and offset to be used to
|
/// Expands macro call, returning the expansion and offset to be used to
|
||||||
/// convert ranges between expansion and original source.
|
/// convert ranges between expansion and original source.
|
||||||
pub fn ast_expand(macro_call: ast::MacroCall) -> Option<(TextUnit, MacroExpansion)> {
|
pub fn ast_expand(macro_call: &ast::MacroCall) -> Option<(TextUnit, MacroExpansion)> {
|
||||||
let (def, input) = MacroDef::from_call(macro_call)?;
|
let (def, input) = MacroDef::from_call(macro_call)?;
|
||||||
let exp = def.expand(input)?;
|
let exp = def.expand(input)?;
|
||||||
let off = macro_call.token_tree()?.syntax().range().start();
|
let off = macro_call.token_tree()?.syntax().range().start();
|
||||||
Some((off, exp))
|
Some((off, exp))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_call(macro_call: ast::MacroCall) -> Option<(MacroDef, MacroInput)> {
|
fn from_call(macro_call: &ast::MacroCall) -> Option<(MacroDef, MacroInput)> {
|
||||||
let def = {
|
let def = {
|
||||||
let path = macro_call.path()?;
|
let path = macro_call.path()?;
|
||||||
let name_ref = path.segment()?.name_ref()?;
|
let name_ref = path.segment()?.name_ref()?;
|
||||||
|
@ -77,7 +77,7 @@ impl MacroDef {
|
||||||
}}",
|
}}",
|
||||||
input.text
|
input.text
|
||||||
);
|
);
|
||||||
let file = SourceFileNode::parse(&text);
|
let file = SourceFile::parse(&text);
|
||||||
let match_expr = file.syntax().descendants().find_map(ast::MatchExpr::cast)?;
|
let match_expr = file.syntax().descendants().find_map(ast::MatchExpr::cast)?;
|
||||||
let match_arg = match_expr.expr()?;
|
let match_arg = match_expr.expr()?;
|
||||||
let ptr = LocalSyntaxPtr::new(match_arg.syntax());
|
let ptr = LocalSyntaxPtr::new(match_arg.syntax());
|
||||||
|
@ -92,7 +92,7 @@ impl MacroDef {
|
||||||
}
|
}
|
||||||
fn expand_vec(self, input: MacroInput) -> Option<MacroExpansion> {
|
fn expand_vec(self, input: MacroInput) -> Option<MacroExpansion> {
|
||||||
let text = format!(r"fn dummy() {{ {}; }}", input.text);
|
let text = format!(r"fn dummy() {{ {}; }}", input.text);
|
||||||
let file = SourceFileNode::parse(&text);
|
let file = SourceFile::parse(&text);
|
||||||
let array_expr = file.syntax().descendants().find_map(ast::ArrayExpr::cast)?;
|
let array_expr = file.syntax().descendants().find_map(ast::ArrayExpr::cast)?;
|
||||||
let ptr = LocalSyntaxPtr::new(array_expr.syntax());
|
let ptr = LocalSyntaxPtr::new(array_expr.syntax());
|
||||||
let src_range = TextRange::offset_len(0.into(), TextUnit::of_str(&input.text));
|
let src_range = TextRange::offset_len(0.into(), TextUnit::of_str(&input.text));
|
||||||
|
@ -116,7 +116,7 @@ impl MacroDef {
|
||||||
}
|
}
|
||||||
let src_range = TextRange::offset_len((pos as u32).into(), TextUnit::of_str(&trait_name));
|
let src_range = TextRange::offset_len((pos as u32).into(), TextUnit::of_str(&trait_name));
|
||||||
let text = format!(r"trait {} {{ }}", trait_name);
|
let text = format!(r"trait {} {{ }}", trait_name);
|
||||||
let file = SourceFileNode::parse(&text);
|
let file = SourceFile::parse(&text);
|
||||||
let trait_def = file.syntax().descendants().find_map(ast::TraitDef::cast)?;
|
let trait_def = file.syntax().descendants().find_map(ast::TraitDef::cast)?;
|
||||||
let name = trait_def.name()?;
|
let name = trait_def.name()?;
|
||||||
let ptr = LocalSyntaxPtr::new(trait_def.syntax());
|
let ptr = LocalSyntaxPtr::new(trait_def.syntax());
|
||||||
|
@ -152,11 +152,11 @@ pub struct MacroExpansion {
|
||||||
impl MacroExpansion {
|
impl MacroExpansion {
|
||||||
// FIXME: does not really make sense, macro expansion is not neccessary a
|
// FIXME: does not really make sense, macro expansion is not neccessary a
|
||||||
// whole file. See `MacroExpansion::ptr` as well.
|
// whole file. See `MacroExpansion::ptr` as well.
|
||||||
pub(crate) fn file(&self) -> SourceFileNode {
|
pub(crate) fn file(&self) -> TreePtr<SourceFile> {
|
||||||
SourceFileNode::parse(&self.text)
|
SourceFile::parse(&self.text)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn syntax(&self) -> SyntaxNode {
|
pub fn syntax(&self) -> TreePtr<SyntaxNode> {
|
||||||
self.ptr.resolve(&self.file())
|
self.ptr.resolve(&self.file())
|
||||||
}
|
}
|
||||||
/// Maps range in the source code to the range in the expanded code.
|
/// Maps range in the source code to the range in the expanded code.
|
||||||
|
@ -191,8 +191,7 @@ pub(crate) fn expand_macro_invocation(
|
||||||
) -> Option<Arc<MacroExpansion>> {
|
) -> Option<Arc<MacroExpansion>> {
|
||||||
let loc = invoc.loc(db);
|
let loc = invoc.loc(db);
|
||||||
let syntax = db.file_item(loc.source_item_id);
|
let syntax = db.file_item(loc.source_item_id);
|
||||||
let syntax = syntax.borrowed();
|
let macro_call = ast::MacroCall::cast(&syntax).unwrap();
|
||||||
let macro_call = ast::MacroCall::cast(syntax).unwrap();
|
|
||||||
|
|
||||||
let (def, input) = MacroDef::from_call(macro_call)?;
|
let (def, input) = MacroDef::from_call(macro_call)?;
|
||||||
def.expand(input).map(Arc::new)
|
def.expand(input).map(Arc::new)
|
||||||
|
|
|
@ -5,9 +5,9 @@ use arrayvec::ArrayVec;
|
||||||
use relative_path::RelativePathBuf;
|
use relative_path::RelativePathBuf;
|
||||||
use ra_db::{FileId, SourceRootId, Cancelable, SourceRoot};
|
use ra_db::{FileId, SourceRootId, Cancelable, SourceRoot};
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
|
SyntaxNode, TreePtr,
|
||||||
algo::generate,
|
algo::generate,
|
||||||
ast::{self, AstNode, NameOwner},
|
ast::{self, AstNode, NameOwner},
|
||||||
SyntaxNode,
|
|
||||||
};
|
};
|
||||||
use ra_arena::{Arena, RawId, impl_arena_id};
|
use ra_arena::{Arena, RawId, impl_arena_id};
|
||||||
|
|
||||||
|
@ -19,12 +19,11 @@ impl ModuleSource {
|
||||||
source_item_id: SourceItemId,
|
source_item_id: SourceItemId,
|
||||||
) -> ModuleSource {
|
) -> ModuleSource {
|
||||||
let module_syntax = db.file_item(source_item_id);
|
let module_syntax = db.file_item(source_item_id);
|
||||||
let module_syntax = module_syntax.borrowed();
|
if let Some(source_file) = ast::SourceFile::cast(&module_syntax) {
|
||||||
if let Some(source_file) = ast::SourceFile::cast(module_syntax) {
|
ModuleSource::SourceFile(source_file.to_owned())
|
||||||
ModuleSource::SourceFile(source_file.owned())
|
} else if let Some(module) = ast::Module::cast(&module_syntax) {
|
||||||
} else if let Some(module) = ast::Module::cast(module_syntax) {
|
|
||||||
assert!(module.item_list().is_some(), "expected inline module");
|
assert!(module.item_list().is_some(), "expected inline module");
|
||||||
ModuleSource::Module(module.owned())
|
ModuleSource::Module(module.to_owned())
|
||||||
} else {
|
} else {
|
||||||
panic!("expected file or inline module")
|
panic!("expected file or inline module")
|
||||||
}
|
}
|
||||||
|
@ -49,19 +48,18 @@ impl Submodule {
|
||||||
let module_source = ModuleSource::from_source_item_id(db, source);
|
let module_source = ModuleSource::from_source_item_id(db, source);
|
||||||
let submodules = match module_source {
|
let submodules = match module_source {
|
||||||
ModuleSource::SourceFile(source_file) => {
|
ModuleSource::SourceFile(source_file) => {
|
||||||
collect_submodules(file_id, &file_items, source_file.borrowed())
|
collect_submodules(file_id, &file_items, &*source_file)
|
||||||
}
|
}
|
||||||
ModuleSource::Module(module) => {
|
ModuleSource::Module(module) => {
|
||||||
let module = module.borrowed();
|
|
||||||
collect_submodules(file_id, &file_items, module.item_list().unwrap())
|
collect_submodules(file_id, &file_items, module.item_list().unwrap())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return Ok(Arc::new(submodules));
|
return Ok(Arc::new(submodules));
|
||||||
|
|
||||||
fn collect_submodules<'a>(
|
fn collect_submodules(
|
||||||
file_id: HirFileId,
|
file_id: HirFileId,
|
||||||
file_items: &SourceFileItems,
|
file_items: &SourceFileItems,
|
||||||
root: impl ast::ModuleItemOwner<'a>,
|
root: &impl ast::ModuleItemOwner,
|
||||||
) -> Vec<Submodule> {
|
) -> Vec<Submodule> {
|
||||||
modules(root)
|
modules(root)
|
||||||
.map(|(name, m)| Submodule {
|
.map(|(name, m)| Submodule {
|
||||||
|
@ -120,8 +118,8 @@ impl ModuleTree {
|
||||||
source_root: SourceRootId,
|
source_root: SourceRootId,
|
||||||
) -> Cancelable<Arc<ModuleTree>> {
|
) -> Cancelable<Arc<ModuleTree>> {
|
||||||
db.check_canceled()?;
|
db.check_canceled()?;
|
||||||
let res = create_module_tree(db, source_root)?;
|
let res = create_module_tree(db, source_root);
|
||||||
Ok(Arc::new(res))
|
Ok(Arc::new(res?))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn modules<'a>(&'a self) -> impl Iterator<Item = ModuleId> + 'a {
|
pub(crate) fn modules<'a>(&'a self) -> impl Iterator<Item = ModuleId> + 'a {
|
||||||
|
@ -172,14 +170,14 @@ impl ModuleId {
|
||||||
self,
|
self,
|
||||||
tree: &ModuleTree,
|
tree: &ModuleTree,
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
) -> Vec<(SyntaxNode, Problem)> {
|
) -> Vec<(TreePtr<SyntaxNode>, Problem)> {
|
||||||
tree.mods[self]
|
tree.mods[self]
|
||||||
.children
|
.children
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|&link| {
|
.filter_map(|&link| {
|
||||||
let p = tree.links[link].problem.clone()?;
|
let p = tree.links[link].problem.clone()?;
|
||||||
let s = link.source(tree, db);
|
let s = link.source(tree, db);
|
||||||
let s = s.borrowed().name().unwrap().syntax().owned();
|
let s = s.name().unwrap().syntax().to_owned();
|
||||||
Some((s, p))
|
Some((s, p))
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
|
@ -193,11 +191,9 @@ impl LinkId {
|
||||||
pub(crate) fn name(self, tree: &ModuleTree) -> &Name {
|
pub(crate) fn name(self, tree: &ModuleTree) -> &Name {
|
||||||
&tree.links[self].name
|
&tree.links[self].name
|
||||||
}
|
}
|
||||||
pub(crate) fn source(self, tree: &ModuleTree, db: &impl HirDatabase) -> ast::ModuleNode {
|
pub(crate) fn source(self, tree: &ModuleTree, db: &impl HirDatabase) -> TreePtr<ast::Module> {
|
||||||
let syntax_node = db.file_item(tree.links[self].source);
|
let syntax_node = db.file_item(tree.links[self].source);
|
||||||
ast::ModuleNode::cast(syntax_node.borrowed())
|
ast::Module::cast(&syntax_node).unwrap().to_owned()
|
||||||
.unwrap()
|
|
||||||
.owned()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,12 +209,10 @@ impl ModuleTree {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn modules<'a>(
|
fn modules(root: &impl ast::ModuleItemOwner) -> impl Iterator<Item = (Name, &ast::Module)> {
|
||||||
root: impl ast::ModuleItemOwner<'a>,
|
|
||||||
) -> impl Iterator<Item = (Name, ast::Module<'a>)> {
|
|
||||||
root.items()
|
root.items()
|
||||||
.filter_map(|item| match item {
|
.filter_map(|item| match item.kind() {
|
||||||
ast::ModuleItem::Module(m) => Some(m),
|
ast::ModuleItemKind::Module(m) => Some(m),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.filter_map(|module| {
|
.filter_map(|module| {
|
||||||
|
|
|
@ -74,13 +74,13 @@ pub(crate) trait AsName {
|
||||||
fn as_name(&self) -> Name;
|
fn as_name(&self) -> Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsName for ast::NameRef<'_> {
|
impl AsName for ast::NameRef {
|
||||||
fn as_name(&self) -> Name {
|
fn as_name(&self) -> Name {
|
||||||
Name::new(self.text())
|
Name::new(self.text())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsName for ast::Name<'_> {
|
impl AsName for ast::Name {
|
||||||
fn as_name(&self) -> Name {
|
fn as_name(&self) -> Name {
|
||||||
Name::new(self.text())
|
Name::new(self.text())
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,7 @@ impl NamedImport {
|
||||||
item_id: Some(self.file_item_id),
|
item_id: Some(self.file_item_id),
|
||||||
};
|
};
|
||||||
let syntax = db.file_item(source_item_id);
|
let syntax = db.file_item(source_item_id);
|
||||||
let offset = syntax.borrowed().range().start();
|
let offset = syntax.range().start();
|
||||||
self.relative_range + offset
|
self.relative_range + offset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -215,45 +215,45 @@ impl InputModuleItems {
|
||||||
&mut self,
|
&mut self,
|
||||||
file_id: HirFileId,
|
file_id: HirFileId,
|
||||||
file_items: &SourceFileItems,
|
file_items: &SourceFileItems,
|
||||||
item: ast::ModuleItem,
|
item: &ast::ModuleItem,
|
||||||
) -> Option<()> {
|
) -> Option<()> {
|
||||||
match item {
|
match item.kind() {
|
||||||
ast::ModuleItem::StructDef(it) => {
|
ast::ModuleItemKind::StructDef(it) => {
|
||||||
self.items.push(ModuleItem::new(file_id, file_items, it)?)
|
self.items.push(ModuleItem::new(file_id, file_items, it)?)
|
||||||
}
|
}
|
||||||
ast::ModuleItem::EnumDef(it) => {
|
ast::ModuleItemKind::EnumDef(it) => {
|
||||||
self.items.push(ModuleItem::new(file_id, file_items, it)?)
|
self.items.push(ModuleItem::new(file_id, file_items, it)?)
|
||||||
}
|
}
|
||||||
ast::ModuleItem::FnDef(it) => {
|
ast::ModuleItemKind::FnDef(it) => {
|
||||||
self.items.push(ModuleItem::new(file_id, file_items, it)?)
|
self.items.push(ModuleItem::new(file_id, file_items, it)?)
|
||||||
}
|
}
|
||||||
ast::ModuleItem::TraitDef(it) => {
|
ast::ModuleItemKind::TraitDef(it) => {
|
||||||
self.items.push(ModuleItem::new(file_id, file_items, it)?)
|
self.items.push(ModuleItem::new(file_id, file_items, it)?)
|
||||||
}
|
}
|
||||||
ast::ModuleItem::TypeDef(it) => {
|
ast::ModuleItemKind::TypeDef(it) => {
|
||||||
self.items.push(ModuleItem::new(file_id, file_items, it)?)
|
self.items.push(ModuleItem::new(file_id, file_items, it)?)
|
||||||
}
|
}
|
||||||
ast::ModuleItem::ImplBlock(_) => {
|
ast::ModuleItemKind::ImplBlock(_) => {
|
||||||
// impls don't define items
|
// impls don't define items
|
||||||
}
|
}
|
||||||
ast::ModuleItem::UseItem(it) => self.add_use_item(file_items, it),
|
ast::ModuleItemKind::UseItem(it) => self.add_use_item(file_items, it),
|
||||||
ast::ModuleItem::ExternCrateItem(_) => {
|
ast::ModuleItemKind::ExternCrateItem(_) => {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
ast::ModuleItem::ConstDef(it) => {
|
ast::ModuleItemKind::ConstDef(it) => {
|
||||||
self.items.push(ModuleItem::new(file_id, file_items, it)?)
|
self.items.push(ModuleItem::new(file_id, file_items, it)?)
|
||||||
}
|
}
|
||||||
ast::ModuleItem::StaticDef(it) => {
|
ast::ModuleItemKind::StaticDef(it) => {
|
||||||
self.items.push(ModuleItem::new(file_id, file_items, it)?)
|
self.items.push(ModuleItem::new(file_id, file_items, it)?)
|
||||||
}
|
}
|
||||||
ast::ModuleItem::Module(it) => {
|
ast::ModuleItemKind::Module(it) => {
|
||||||
self.items.push(ModuleItem::new(file_id, file_items, it)?)
|
self.items.push(ModuleItem::new(file_id, file_items, it)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_use_item(&mut self, file_items: &SourceFileItems, item: ast::UseItem) {
|
fn add_use_item(&mut self, file_items: &SourceFileItems, item: &ast::UseItem) {
|
||||||
let file_item_id = file_items.id_of_unchecked(item.syntax());
|
let file_item_id = file_items.id_of_unchecked(item.syntax());
|
||||||
let start_offset = item.syntax().range().start();
|
let start_offset = item.syntax().range().start();
|
||||||
Path::expand_use_item(item, |path, range| {
|
Path::expand_use_item(item, |path, range| {
|
||||||
|
@ -270,10 +270,10 @@ impl InputModuleItems {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleItem {
|
impl ModuleItem {
|
||||||
fn new<'a>(
|
fn new(
|
||||||
file_id: HirFileId,
|
file_id: HirFileId,
|
||||||
file_items: &SourceFileItems,
|
file_items: &SourceFileItems,
|
||||||
item: impl ast::NameOwner<'a>,
|
item: &impl ast::NameOwner,
|
||||||
) -> Option<ModuleItem> {
|
) -> Option<ModuleItem> {
|
||||||
let name = item.name()?.as_name();
|
let name = item.name()?.as_name();
|
||||||
let kind = item.syntax().kind();
|
let kind = item.syntax().kind();
|
||||||
|
|
|
@ -18,14 +18,14 @@ pub enum PathKind {
|
||||||
|
|
||||||
impl Path {
|
impl Path {
|
||||||
/// Calls `cb` with all paths, represented by this use item.
|
/// Calls `cb` with all paths, represented by this use item.
|
||||||
pub fn expand_use_item(item: ast::UseItem, mut cb: impl FnMut(Path, Option<TextRange>)) {
|
pub fn expand_use_item(item: &ast::UseItem, mut cb: impl FnMut(Path, Option<TextRange>)) {
|
||||||
if let Some(tree) = item.use_tree() {
|
if let Some(tree) = item.use_tree() {
|
||||||
expand_use_tree(None, tree, &mut cb);
|
expand_use_tree(None, tree, &mut cb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts an `ast::Path` to `Path`. Works with use trees.
|
/// Converts an `ast::Path` to `Path`. Works with use trees.
|
||||||
pub fn from_ast(mut path: ast::Path) -> Option<Path> {
|
pub fn from_ast(mut path: &ast::Path) -> Option<Path> {
|
||||||
let mut kind = PathKind::Plain;
|
let mut kind = PathKind::Plain;
|
||||||
let mut segments = Vec::new();
|
let mut segments = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
|
@ -53,7 +53,7 @@ impl Path {
|
||||||
segments.reverse();
|
segments.reverse();
|
||||||
return Some(Path { kind, segments });
|
return Some(Path { kind, segments });
|
||||||
|
|
||||||
fn qualifier(path: ast::Path) -> Option<ast::Path> {
|
fn qualifier(path: &ast::Path) -> Option<&ast::Path> {
|
||||||
if let Some(q) = path.qualifier() {
|
if let Some(q) = path.qualifier() {
|
||||||
return Some(q);
|
return Some(q);
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ impl Path {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts an `ast::NameRef` into a single-identifier `Path`.
|
/// Converts an `ast::NameRef` into a single-identifier `Path`.
|
||||||
pub fn from_name_ref(name_ref: ast::NameRef) -> Path {
|
pub fn from_name_ref(name_ref: &ast::NameRef) -> Path {
|
||||||
name_ref.as_name().into()
|
name_ref.as_name().into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ impl From<Name> for Path {
|
||||||
|
|
||||||
fn expand_use_tree(
|
fn expand_use_tree(
|
||||||
prefix: Option<Path>,
|
prefix: Option<Path>,
|
||||||
tree: ast::UseTree,
|
tree: &ast::UseTree,
|
||||||
cb: &mut impl FnMut(Path, Option<TextRange>),
|
cb: &mut impl FnMut(Path, Option<TextRange>),
|
||||||
) {
|
) {
|
||||||
if let Some(use_tree_list) = tree.use_tree_list() {
|
if let Some(use_tree_list) = tree.use_tree_list() {
|
||||||
|
@ -146,7 +146,7 @@ fn expand_use_tree(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_path(prefix: Option<Path>, path: ast::Path) -> Option<Path> {
|
fn convert_path(prefix: Option<Path>, path: &ast::Path) -> Option<Path> {
|
||||||
let prefix = if let Some(qual) = path.qualifier() {
|
let prefix = if let Some(qual) = path.qualifier() {
|
||||||
Some(convert_path(prefix, qual)?)
|
Some(convert_path(prefix, qual)?)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::{
|
||||||
|
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
AstNode, SyntaxNode,
|
AstNode, SyntaxNode, TreePtr,
|
||||||
ast::{self, ModuleItemOwner}
|
ast::{self, ModuleItemOwner}
|
||||||
};
|
};
|
||||||
use ra_db::{SourceRootId, Cancelable,};
|
use ra_db::{SourceRootId, Cancelable,};
|
||||||
|
@ -31,30 +31,34 @@ pub(super) fn struct_data(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Ar
|
||||||
assert!(def_loc.kind == DefKind::Struct);
|
assert!(def_loc.kind == DefKind::Struct);
|
||||||
let syntax = db.file_item(def_loc.source_item_id);
|
let syntax = db.file_item(def_loc.source_item_id);
|
||||||
let struct_def =
|
let struct_def =
|
||||||
ast::StructDef::cast(syntax.borrowed()).expect("struct def should point to StructDef node");
|
ast::StructDef::cast(&syntax).expect("struct def should point to StructDef node");
|
||||||
Ok(Arc::new(StructData::new(struct_def.borrowed())))
|
Ok(Arc::new(StructData::new(struct_def)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn enum_data(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<EnumData>> {
|
pub(super) fn enum_data(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<EnumData>> {
|
||||||
let def_loc = def_id.loc(db);
|
let def_loc = def_id.loc(db);
|
||||||
assert!(def_loc.kind == DefKind::Enum);
|
assert!(def_loc.kind == DefKind::Enum);
|
||||||
let syntax = db.file_item(def_loc.source_item_id);
|
let syntax = db.file_item(def_loc.source_item_id);
|
||||||
let enum_def =
|
let enum_def = ast::EnumDef::cast(&syntax).expect("enum def should point to EnumDef node");
|
||||||
ast::EnumDef::cast(syntax.borrowed()).expect("enum def should point to EnumDef node");
|
Ok(Arc::new(EnumData::new(enum_def)))
|
||||||
Ok(Arc::new(EnumData::new(enum_def.borrowed())))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn file_items(db: &impl HirDatabase, file_id: HirFileId) -> Arc<SourceFileItems> {
|
pub(super) fn file_items(db: &impl HirDatabase, file_id: HirFileId) -> Arc<SourceFileItems> {
|
||||||
let source_file = db.hir_source_file(file_id);
|
let source_file = db.hir_source_file(file_id);
|
||||||
let source_file = source_file.borrowed();
|
let res = SourceFileItems::new(file_id, &source_file);
|
||||||
let res = SourceFileItems::new(file_id, source_file);
|
|
||||||
Arc::new(res)
|
Arc::new(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn file_item(db: &impl HirDatabase, source_item_id: SourceItemId) -> SyntaxNode {
|
pub(super) fn file_item(
|
||||||
|
db: &impl HirDatabase,
|
||||||
|
source_item_id: SourceItemId,
|
||||||
|
) -> TreePtr<SyntaxNode> {
|
||||||
match source_item_id.item_id {
|
match source_item_id.item_id {
|
||||||
Some(id) => db.file_items(source_item_id.file_id)[id].clone(),
|
Some(id) => db.file_items(source_item_id.file_id)[id].to_owned(),
|
||||||
None => db.hir_source_file(source_item_id.file_id).syntax().owned(),
|
None => db
|
||||||
|
.hir_source_file(source_item_id.file_id)
|
||||||
|
.syntax()
|
||||||
|
.to_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +92,7 @@ pub(super) fn input_module_items(
|
||||||
let file_id = HirFileId::from(id);
|
let file_id = HirFileId::from(id);
|
||||||
let file_items = db.file_items(file_id);
|
let file_items = db.file_items(file_id);
|
||||||
//FIXME: expand recursively
|
//FIXME: expand recursively
|
||||||
for item in db.hir_source_file(file_id).borrowed().items() {
|
for item in db.hir_source_file(file_id).items() {
|
||||||
acc.add_item(file_id, &file_items, item);
|
acc.add_item(file_id, &file_items, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,9 +102,9 @@ pub(super) fn input_module_items(
|
||||||
|
|
||||||
let mut res = InputModuleItems::default();
|
let mut res = InputModuleItems::default();
|
||||||
match source {
|
match source {
|
||||||
ModuleSource::SourceFile(it) => fill(&mut res, &mut it.borrowed().items_with_macros()),
|
ModuleSource::SourceFile(it) => fill(&mut res, &mut it.items_with_macros()),
|
||||||
ModuleSource::Module(it) => {
|
ModuleSource::Module(it) => {
|
||||||
if let Some(item_list) = it.borrowed().item_list() {
|
if let Some(item_list) = it.item_list() {
|
||||||
fill(&mut res, &mut item_list.items_with_macros())
|
fill(&mut res, &mut item_list.items_with_macros())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
use ra_db::{FileId, FilePosition, Cancelable};
|
use ra_db::{FileId, FilePosition, Cancelable};
|
||||||
use ra_editor::find_node_at_offset;
|
use ra_editor::find_node_at_offset;
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
SmolStr, TextRange, SyntaxNodeRef,
|
SmolStr, TextRange, SyntaxNode,
|
||||||
ast::{self, AstNode, NameOwner},
|
ast::{self, AstNode, NameOwner},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ pub fn module_from_file_id(db: &impl HirDatabase, file_id: FileId) -> Cancelable
|
||||||
pub fn module_from_declaration(
|
pub fn module_from_declaration(
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
file_id: FileId,
|
file_id: FileId,
|
||||||
decl: ast::Module,
|
decl: &ast::Module,
|
||||||
) -> Cancelable<Option<Module>> {
|
) -> Cancelable<Option<Module>> {
|
||||||
let parent_module = module_from_file_id(db, file_id)?;
|
let parent_module = module_from_file_id(db, file_id)?;
|
||||||
let child_name = decl.name();
|
let child_name = decl.name();
|
||||||
|
@ -60,7 +60,7 @@ pub fn module_from_position(
|
||||||
fn module_from_inline(
|
fn module_from_inline(
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
file_id: FileId,
|
file_id: FileId,
|
||||||
module: ast::Module,
|
module: &ast::Module,
|
||||||
) -> Cancelable<Option<Module>> {
|
) -> Cancelable<Option<Module>> {
|
||||||
assert!(!module.has_semi());
|
assert!(!module.has_semi());
|
||||||
let file_id = file_id.into();
|
let file_id = file_id.into();
|
||||||
|
@ -77,7 +77,7 @@ fn module_from_inline(
|
||||||
pub fn module_from_child_node(
|
pub fn module_from_child_node(
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
file_id: FileId,
|
file_id: FileId,
|
||||||
child: SyntaxNodeRef,
|
child: &SyntaxNode,
|
||||||
) -> Cancelable<Option<Module>> {
|
) -> Cancelable<Option<Module>> {
|
||||||
if let Some(m) = child
|
if let Some(m) = child
|
||||||
.ancestors()
|
.ancestors()
|
||||||
|
@ -112,7 +112,7 @@ pub fn function_from_position(
|
||||||
pub fn function_from_source(
|
pub fn function_from_source(
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
file_id: FileId,
|
file_id: FileId,
|
||||||
fn_def: ast::FnDef,
|
fn_def: &ast::FnDef,
|
||||||
) -> Cancelable<Option<Function>> {
|
) -> Cancelable<Option<Function>> {
|
||||||
let module = ctry!(module_from_child_node(db, file_id, fn_def.syntax())?);
|
let module = ctry!(module_from_child_node(db, file_id, fn_def.syntax())?);
|
||||||
let res = function_from_module(db, &module, fn_def);
|
let res = function_from_module(db, &module, fn_def);
|
||||||
|
@ -122,7 +122,7 @@ pub fn function_from_source(
|
||||||
pub fn function_from_module(
|
pub fn function_from_module(
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
module: &Module,
|
module: &Module,
|
||||||
fn_def: ast::FnDef,
|
fn_def: &ast::FnDef,
|
||||||
) -> Function {
|
) -> Function {
|
||||||
let loc = module.def_id.loc(db);
|
let loc = module.def_id.loc(db);
|
||||||
let file_id = loc.source_item_id.file_id;
|
let file_id = loc.source_item_id.file_id;
|
||||||
|
@ -144,7 +144,7 @@ pub fn function_from_module(
|
||||||
pub fn function_from_child_node(
|
pub fn function_from_child_node(
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
file_id: FileId,
|
file_id: FileId,
|
||||||
node: SyntaxNodeRef,
|
node: &SyntaxNode,
|
||||||
) -> Cancelable<Option<Function>> {
|
) -> Cancelable<Option<Function>> {
|
||||||
let fn_def = ctry!(node.ancestors().find_map(ast::FnDef::cast));
|
let fn_def = ctry!(node.ancestors().find_map(ast::FnDef::cast));
|
||||||
function_from_source(db, file_id, fn_def)
|
function_from_source(db, file_id, fn_def)
|
||||||
|
@ -170,8 +170,7 @@ pub fn macro_symbols(
|
||||||
if let Some(exp) = db.expand_macro_invocation(macro_call_id) {
|
if let Some(exp) = db.expand_macro_invocation(macro_call_id) {
|
||||||
let loc = macro_call_id.loc(db);
|
let loc = macro_call_id.loc(db);
|
||||||
let syntax = db.file_item(loc.source_item_id);
|
let syntax = db.file_item(loc.source_item_id);
|
||||||
let syntax = syntax.borrowed();
|
let macro_call = ast::MacroCall::cast(&syntax).unwrap();
|
||||||
let macro_call = ast::MacroCall::cast(syntax).unwrap();
|
|
||||||
let off = macro_call.token_tree().unwrap().syntax().range().start();
|
let off = macro_call.token_tree().unwrap().syntax().range().start();
|
||||||
let file = exp.file();
|
let file = exp.file();
|
||||||
for trait_def in file.syntax().descendants().filter_map(ast::TraitDef::cast) {
|
for trait_def in file.syntax().descendants().filter_map(ast::TraitDef::cast) {
|
||||||
|
|
|
@ -56,9 +56,9 @@ pub enum TypeRef {
|
||||||
|
|
||||||
impl TypeRef {
|
impl TypeRef {
|
||||||
/// Converts an `ast::TypeRef` to a `hir::TypeRef`.
|
/// Converts an `ast::TypeRef` to a `hir::TypeRef`.
|
||||||
pub(crate) fn from_ast(node: ast::TypeRef) -> Self {
|
pub(crate) fn from_ast(node: &ast::TypeRef) -> Self {
|
||||||
use ra_syntax::ast::TypeRef::*;
|
use ra_syntax::ast::TypeRefKind::*;
|
||||||
match node {
|
match node.kind() {
|
||||||
ParenType(inner) => TypeRef::from_ast_opt(inner.type_ref()),
|
ParenType(inner) => TypeRef::from_ast_opt(inner.type_ref()),
|
||||||
TupleType(inner) => TypeRef::Tuple(inner.fields().map(TypeRef::from_ast).collect()),
|
TupleType(inner) => TypeRef::Tuple(inner.fields().map(TypeRef::from_ast).collect()),
|
||||||
NeverType(..) => TypeRef::Never,
|
NeverType(..) => TypeRef::Never,
|
||||||
|
@ -100,7 +100,7 @@ impl TypeRef {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_ast_opt(node: Option<ast::TypeRef>) -> Self {
|
pub(crate) fn from_ast_opt(node: Option<&ast::TypeRef>) -> Self {
|
||||||
if let Some(node) = node {
|
if let Some(node) = node {
|
||||||
TypeRef::from_ast(node)
|
TypeRef::from_ast(node)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -53,10 +53,37 @@ pub trait FnDefOwner: AstNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum ItemOrMacro<'a> {
|
||||||
|
Item(&'a ModuleItem),
|
||||||
|
Macro(&'a MacroCall),
|
||||||
|
}
|
||||||
|
|
||||||
pub trait ModuleItemOwner: AstNode {
|
pub trait ModuleItemOwner: AstNode {
|
||||||
fn items(&self) -> AstChildren<ModuleItem> {
|
fn items(&self) -> AstChildren<ModuleItem> {
|
||||||
children(self)
|
children(self)
|
||||||
}
|
}
|
||||||
|
fn items_with_macros(&self) -> ItemOrMacroIter {
|
||||||
|
ItemOrMacroIter(self.syntax().children())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ItemOrMacroIter<'a>(SyntaxNodeChildren<'a>);
|
||||||
|
|
||||||
|
impl<'a> Iterator for ItemOrMacroIter<'a> {
|
||||||
|
type Item = ItemOrMacro<'a>;
|
||||||
|
fn next(&mut self) -> Option<ItemOrMacro<'a>> {
|
||||||
|
loop {
|
||||||
|
let n = self.0.next()?;
|
||||||
|
if let Some(item) = ModuleItem::cast(n) {
|
||||||
|
return Some(ItemOrMacro::Item(item));
|
||||||
|
}
|
||||||
|
if let Some(call) = MacroCall::cast(n) {
|
||||||
|
return Some(ItemOrMacro::Macro(call));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TypeParamsOwner: AstNode {
|
pub trait TypeParamsOwner: AstNode {
|
||||||
|
|
|
@ -47,6 +47,17 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> PartialEq<T> for TreePtr<T>
|
||||||
|
where
|
||||||
|
T: TransparentNewType<Repr = rowan::SyntaxNode<RaTypes>>,
|
||||||
|
T: PartialEq<T>,
|
||||||
|
{
|
||||||
|
fn eq(&self, other: &T) -> bool {
|
||||||
|
let t: &T = self;
|
||||||
|
t == other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> Clone for TreePtr<T>
|
impl<T> Clone for TreePtr<T>
|
||||||
where
|
where
|
||||||
T: TransparentNewType<Repr = rowan::SyntaxNode<RaTypes>>,
|
T: TransparentNewType<Repr = rowan::SyntaxNode<RaTypes>>,
|
||||||
|
|
Loading…
Reference in a new issue