migrate ra_hir to rowan 2.0

This commit is contained in:
Aleksey Kladov 2019-01-08 11:28:42 +03:00
parent d6020f516f
commit da0b348ae9
20 changed files with 238 additions and 197 deletions

10
Cargo.lock generated
View file

@ -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"

View file

@ -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()

View file

@ -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)
} }
} }

View file

@ -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))

View file

@ -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;
} }

View file

@ -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"),

View file

@ -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() {

View file

@ -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()));

View file

@ -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.

View file

@ -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());

View file

@ -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)

View file

@ -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| {

View file

@ -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())
} }

View file

@ -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();

View file

@ -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 {

View file

@ -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())
} }
} }

View file

@ -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) {

View file

@ -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 {

View file

@ -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 {

View file

@ -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>>,