mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-10 14:57:14 +00:00
Merge #610
610: move SyntaxPtr to ra_syntax r=matklad a=matklad Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
a583070b7d
@ -1,6 +1,5 @@
|
|||||||
//! ra_db defines basic database traits. The concrete DB is defined by ra_ide_api.
|
//! ra_db defines basic database traits. The concrete DB is defined by ra_ide_api.
|
||||||
mod cancellation;
|
mod cancellation;
|
||||||
mod syntax_ptr;
|
|
||||||
mod input;
|
mod input;
|
||||||
mod loc2id;
|
mod loc2id;
|
||||||
pub mod mock;
|
pub mod mock;
|
||||||
@ -12,7 +11,6 @@ use ra_syntax::{TextUnit, TextRange, SourceFile, TreeArc};
|
|||||||
pub use ::salsa as salsa;
|
pub use ::salsa as salsa;
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
cancellation::Canceled,
|
cancellation::Canceled,
|
||||||
syntax_ptr::LocalSyntaxPtr,
|
|
||||||
input::{
|
input::{
|
||||||
FilesDatabase, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, Dependency,
|
FilesDatabase, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, Dependency,
|
||||||
FileTextQuery, FileSourceRootQuery, SourceRootQuery, LocalRootsQuery, LibraryRootsQuery, CrateGraphQuery,
|
FileTextQuery, FileSourceRootQuery, SourceRootQuery, LocalRootsQuery, LibraryRootsQuery, CrateGraphQuery,
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
use ra_syntax::{AstNode, SourceFile, SyntaxKind, SyntaxNode, TextRange, TreeArc};
|
|
||||||
|
|
||||||
/// A pointer to a syntax node inside a file.
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
||||||
pub struct LocalSyntaxPtr {
|
|
||||||
range: TextRange,
|
|
||||||
kind: SyntaxKind,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LocalSyntaxPtr {
|
|
||||||
pub fn new(node: &SyntaxNode) -> LocalSyntaxPtr {
|
|
||||||
LocalSyntaxPtr {
|
|
||||||
range: node.range(),
|
|
||||||
kind: node.kind(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn resolve(self, file: &SourceFile) -> TreeArc<SyntaxNode> {
|
|
||||||
let mut curr = file.syntax();
|
|
||||||
loop {
|
|
||||||
if curr.range() == self.range && curr.kind() == self.kind {
|
|
||||||
return curr.to_owned();
|
|
||||||
}
|
|
||||||
curr = curr
|
|
||||||
.children()
|
|
||||||
.find(|it| self.range.is_subrange(&it.range()))
|
|
||||||
.unwrap_or_else(|| panic!("can't resolve local ptr to SyntaxNode: {:?}", self))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn range(self) -> TextRange {
|
|
||||||
self.range
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn kind(self) -> SyntaxKind {
|
|
||||||
self.kind
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_local_syntax_ptr() {
|
|
||||||
use ra_syntax::{ast, AstNode};
|
|
||||||
let file = SourceFile::parse("struct Foo { f: u32, }");
|
|
||||||
let field = file
|
|
||||||
.syntax()
|
|
||||||
.descendants()
|
|
||||||
.find_map(ast::NamedFieldDef::cast)
|
|
||||||
.unwrap();
|
|
||||||
let ptr = LocalSyntaxPtr::new(field.syntax());
|
|
||||||
let field_syntax = ptr.resolve(&file);
|
|
||||||
assert_eq!(field.syntax(), &*field_syntax);
|
|
||||||
}
|
|
@ -3,12 +3,11 @@ use std::sync::Arc;
|
|||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
|
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
AstNode, SyntaxNode, TextUnit, TextRange,
|
AstNode, SyntaxNode, TextUnit, TextRange, SyntaxNodePtr,
|
||||||
algo::generate,
|
algo::generate,
|
||||||
ast,
|
ast,
|
||||||
};
|
};
|
||||||
use ra_arena::{Arena, RawId, impl_arena_id};
|
use ra_arena::{Arena, RawId, impl_arena_id};
|
||||||
use ra_db::LocalSyntaxPtr;
|
|
||||||
|
|
||||||
use crate::{Name, AsName, expr::{PatId, ExprId, Pat, Expr, Body, Statement, BodySyntaxMapping}};
|
use crate::{Name, AsName, expr::{PatId, ExprId, Pat, Expr, Body, Statement, BodySyntaxMapping}};
|
||||||
|
|
||||||
@ -126,7 +125,7 @@ pub struct ScopesWithSyntaxMapping {
|
|||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct ScopeEntryWithSyntax {
|
pub struct ScopeEntryWithSyntax {
|
||||||
name: Name,
|
name: Name,
|
||||||
ptr: LocalSyntaxPtr,
|
ptr: SyntaxNodePtr,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScopeEntryWithSyntax {
|
impl ScopeEntryWithSyntax {
|
||||||
@ -134,7 +133,7 @@ impl ScopeEntryWithSyntax {
|
|||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ptr(&self) -> LocalSyntaxPtr {
|
pub fn ptr(&self) -> SyntaxNodePtr {
|
||||||
self.ptr
|
self.ptr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -169,7 +168,7 @@ impl ScopesWithSyntaxMapping {
|
|||||||
|
|
||||||
// XXX: during completion, cursor might be outside of any particular
|
// XXX: during completion, cursor might be outside of any particular
|
||||||
// expression. Try to figure out the correct scope...
|
// expression. Try to figure out the correct scope...
|
||||||
fn adjust(&self, ptr: LocalSyntaxPtr, original_scope: ScopeId, offset: TextUnit) -> ScopeId {
|
fn adjust(&self, ptr: SyntaxNodePtr, original_scope: ScopeId, offset: TextUnit) -> ScopeId {
|
||||||
let r = ptr.range();
|
let r = ptr.range();
|
||||||
let child_scopes = self
|
let child_scopes = self
|
||||||
.scopes
|
.scopes
|
||||||
@ -212,7 +211,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 = SyntaxNodePtr::new(pat.syntax());
|
||||||
fn_def
|
fn_def
|
||||||
.syntax()
|
.syntax()
|
||||||
.descendants()
|
.descendants()
|
||||||
@ -230,7 +229,7 @@ impl ScopesWithSyntaxMapping {
|
|||||||
|
|
||||||
fn scope_for(&self, node: &SyntaxNode) -> Option<ScopeId> {
|
fn scope_for(&self, node: &SyntaxNode) -> Option<ScopeId> {
|
||||||
node.ancestors()
|
node.ancestors()
|
||||||
.map(LocalSyntaxPtr::new)
|
.map(SyntaxNodePtr::new)
|
||||||
.filter_map(|ptr| self.syntax_mapping.syntax_expr(ptr))
|
.filter_map(|ptr| self.syntax_mapping.syntax_expr(ptr))
|
||||||
.find_map(|it| self.scopes.scope_for(it))
|
.find_map(|it| self.scopes.scope_for(it))
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,10 @@ use std::sync::Arc;
|
|||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap};
|
use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap};
|
||||||
use ra_db::LocalSyntaxPtr;
|
use ra_syntax::{
|
||||||
use ra_syntax::ast::{self, AstNode, LoopBodyOwner, ArgListOwner, NameOwner, LiteralFlavor};
|
SyntaxNodePtr, AstNode,
|
||||||
|
ast::{self, LoopBodyOwner, ArgListOwner, NameOwner, LiteralFlavor}
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{Path, type_ref::{Mutability, TypeRef}, Name, HirDatabase, DefId, Def, name::AsName};
|
use crate::{Path, type_ref::{Mutability, TypeRef}, Name, HirDatabase, DefId, Def, name::AsName};
|
||||||
use crate::ty::primitive::{UintTy, UncertainIntTy, UncertainFloatTy};
|
use crate::ty::primitive::{UintTy, UncertainIntTy, UncertainFloatTy};
|
||||||
@ -38,10 +40,10 @@ pub struct Body {
|
|||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct BodySyntaxMapping {
|
pub struct BodySyntaxMapping {
|
||||||
body: Arc<Body>,
|
body: Arc<Body>,
|
||||||
expr_syntax_mapping: FxHashMap<LocalSyntaxPtr, ExprId>,
|
expr_syntax_mapping: FxHashMap<SyntaxNodePtr, ExprId>,
|
||||||
expr_syntax_mapping_back: ArenaMap<ExprId, LocalSyntaxPtr>,
|
expr_syntax_mapping_back: ArenaMap<ExprId, SyntaxNodePtr>,
|
||||||
pat_syntax_mapping: FxHashMap<LocalSyntaxPtr, PatId>,
|
pat_syntax_mapping: FxHashMap<SyntaxNodePtr, PatId>,
|
||||||
pat_syntax_mapping_back: ArenaMap<PatId, LocalSyntaxPtr>,
|
pat_syntax_mapping_back: ArenaMap<PatId, SyntaxNodePtr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Body {
|
impl Body {
|
||||||
@ -71,31 +73,31 @@ impl Index<PatId> for Body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl BodySyntaxMapping {
|
impl BodySyntaxMapping {
|
||||||
pub fn expr_syntax(&self, expr: ExprId) -> Option<LocalSyntaxPtr> {
|
pub fn expr_syntax(&self, expr: ExprId) -> Option<SyntaxNodePtr> {
|
||||||
self.expr_syntax_mapping_back.get(expr).cloned()
|
self.expr_syntax_mapping_back.get(expr).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn syntax_expr(&self, ptr: LocalSyntaxPtr) -> Option<ExprId> {
|
pub fn syntax_expr(&self, ptr: SyntaxNodePtr) -> Option<ExprId> {
|
||||||
self.expr_syntax_mapping.get(&ptr).cloned()
|
self.expr_syntax_mapping.get(&ptr).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn node_expr(&self, node: &ast::Expr) -> Option<ExprId> {
|
pub fn node_expr(&self, node: &ast::Expr) -> Option<ExprId> {
|
||||||
self.expr_syntax_mapping
|
self.expr_syntax_mapping
|
||||||
.get(&LocalSyntaxPtr::new(node.syntax()))
|
.get(&SyntaxNodePtr::new(node.syntax()))
|
||||||
.cloned()
|
.cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pat_syntax(&self, pat: PatId) -> Option<LocalSyntaxPtr> {
|
pub fn pat_syntax(&self, pat: PatId) -> Option<SyntaxNodePtr> {
|
||||||
self.pat_syntax_mapping_back.get(pat).cloned()
|
self.pat_syntax_mapping_back.get(pat).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn syntax_pat(&self, ptr: LocalSyntaxPtr) -> Option<PatId> {
|
pub fn syntax_pat(&self, ptr: SyntaxNodePtr) -> Option<PatId> {
|
||||||
self.pat_syntax_mapping.get(&ptr).cloned()
|
self.pat_syntax_mapping.get(&ptr).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn node_pat(&self, node: &ast::Pat) -> Option<PatId> {
|
pub fn node_pat(&self, node: &ast::Pat) -> Option<PatId> {
|
||||||
self.pat_syntax_mapping
|
self.pat_syntax_mapping
|
||||||
.get(&LocalSyntaxPtr::new(node.syntax()))
|
.get(&SyntaxNodePtr::new(node.syntax()))
|
||||||
.cloned()
|
.cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,10 +442,10 @@ pub(crate) fn body_hir(db: &impl HirDatabase, def_id: DefId) -> Arc<Body> {
|
|||||||
struct ExprCollector {
|
struct ExprCollector {
|
||||||
exprs: Arena<ExprId, Expr>,
|
exprs: Arena<ExprId, Expr>,
|
||||||
pats: Arena<PatId, Pat>,
|
pats: Arena<PatId, Pat>,
|
||||||
expr_syntax_mapping: FxHashMap<LocalSyntaxPtr, ExprId>,
|
expr_syntax_mapping: FxHashMap<SyntaxNodePtr, ExprId>,
|
||||||
expr_syntax_mapping_back: ArenaMap<ExprId, LocalSyntaxPtr>,
|
expr_syntax_mapping_back: ArenaMap<ExprId, SyntaxNodePtr>,
|
||||||
pat_syntax_mapping: FxHashMap<LocalSyntaxPtr, PatId>,
|
pat_syntax_mapping: FxHashMap<SyntaxNodePtr, PatId>,
|
||||||
pat_syntax_mapping_back: ArenaMap<PatId, LocalSyntaxPtr>,
|
pat_syntax_mapping_back: ArenaMap<PatId, SyntaxNodePtr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExprCollector {
|
impl ExprCollector {
|
||||||
@ -458,14 +460,14 @@ impl ExprCollector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alloc_expr(&mut self, expr: Expr, syntax_ptr: LocalSyntaxPtr) -> ExprId {
|
fn alloc_expr(&mut self, expr: Expr, syntax_ptr: SyntaxNodePtr) -> ExprId {
|
||||||
let id = self.exprs.alloc(expr);
|
let id = self.exprs.alloc(expr);
|
||||||
self.expr_syntax_mapping.insert(syntax_ptr, id);
|
self.expr_syntax_mapping.insert(syntax_ptr, id);
|
||||||
self.expr_syntax_mapping_back.insert(id, syntax_ptr);
|
self.expr_syntax_mapping_back.insert(id, syntax_ptr);
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alloc_pat(&mut self, pat: Pat, syntax_ptr: LocalSyntaxPtr) -> PatId {
|
fn alloc_pat(&mut self, pat: Pat, syntax_ptr: SyntaxNodePtr) -> PatId {
|
||||||
let id = self.pats.alloc(pat);
|
let id = self.pats.alloc(pat);
|
||||||
self.pat_syntax_mapping.insert(syntax_ptr, id);
|
self.pat_syntax_mapping.insert(syntax_ptr, id);
|
||||||
self.pat_syntax_mapping_back.insert(id, syntax_ptr);
|
self.pat_syntax_mapping_back.insert(id, syntax_ptr);
|
||||||
@ -481,7 +483,7 @@ impl ExprCollector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 = SyntaxNodePtr::new(expr.syntax());
|
||||||
match expr.kind() {
|
match expr.kind() {
|
||||||
ast::ExprKind::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()) {
|
||||||
@ -643,9 +645,9 @@ impl ExprCollector {
|
|||||||
// field shorthand
|
// field shorthand
|
||||||
let id = self.exprs.alloc(Expr::Path(Path::from_name_ref(nr)));
|
let id = self.exprs.alloc(Expr::Path(Path::from_name_ref(nr)));
|
||||||
self.expr_syntax_mapping
|
self.expr_syntax_mapping
|
||||||
.insert(LocalSyntaxPtr::new(nr.syntax()), id);
|
.insert(SyntaxNodePtr::new(nr.syntax()), id);
|
||||||
self.expr_syntax_mapping_back
|
self.expr_syntax_mapping_back
|
||||||
.insert(id, LocalSyntaxPtr::new(nr.syntax()));
|
.insert(id, SyntaxNodePtr::new(nr.syntax()));
|
||||||
id
|
id
|
||||||
} else {
|
} else {
|
||||||
self.exprs.alloc(Expr::Missing)
|
self.exprs.alloc(Expr::Missing)
|
||||||
@ -806,7 +808,7 @@ impl ExprCollector {
|
|||||||
let tail = block.expr().map(|e| self.collect_expr(e));
|
let tail = block.expr().map(|e| self.collect_expr(e));
|
||||||
self.alloc_expr(
|
self.alloc_expr(
|
||||||
Expr::Block { statements, tail },
|
Expr::Block { statements, tail },
|
||||||
LocalSyntaxPtr::new(block.syntax()),
|
SyntaxNodePtr::new(block.syntax()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -883,7 +885,7 @@ impl ExprCollector {
|
|||||||
// TODO: implement
|
// TODO: implement
|
||||||
ast::PatKind::SlicePat(_) | ast::PatKind::RangePat(_) => Pat::Missing,
|
ast::PatKind::SlicePat(_) | ast::PatKind::RangePat(_) => Pat::Missing,
|
||||||
};
|
};
|
||||||
let syntax_ptr = LocalSyntaxPtr::new(pat.syntax());
|
let syntax_ptr = SyntaxNodePtr::new(pat.syntax());
|
||||||
self.alloc_pat(pattern, syntax_ptr)
|
self.alloc_pat(pattern, syntax_ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -919,7 +921,7 @@ pub(crate) fn collect_fn_body_syntax(node: &ast::FnDef) -> BodySyntaxMapping {
|
|||||||
let mut params = Vec::new();
|
let mut params = Vec::new();
|
||||||
|
|
||||||
if let Some(self_param) = param_list.self_param() {
|
if let Some(self_param) = param_list.self_param() {
|
||||||
let self_param = LocalSyntaxPtr::new(
|
let self_param = SyntaxNodePtr::new(
|
||||||
self_param
|
self_param
|
||||||
.self_kw()
|
.self_kw()
|
||||||
.expect("self param without self keyword")
|
.expect("self param without self keyword")
|
||||||
|
@ -9,9 +9,8 @@
|
|||||||
/// those yet, so all macros are string based at the moment!
|
/// those yet, so all macros are string based at the moment!
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use ra_db::LocalSyntaxPtr;
|
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
TextRange, TextUnit, SourceFile, AstNode, SyntaxNode, TreeArc,
|
TextRange, TextUnit, SourceFile, AstNode, SyntaxNode, TreeArc, SyntaxNodePtr,
|
||||||
ast::{self, NameOwner},
|
ast::{self, NameOwner},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -80,7 +79,7 @@ impl MacroDef {
|
|||||||
let file = SourceFile::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 = SyntaxNodePtr::new(match_arg.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));
|
||||||
let ranges_map = vec![(src_range, match_arg.syntax().range())];
|
let ranges_map = vec![(src_range, match_arg.syntax().range())];
|
||||||
let res = MacroExpansion {
|
let res = MacroExpansion {
|
||||||
@ -94,7 +93,7 @@ impl MacroDef {
|
|||||||
let text = format!(r"fn dummy() {{ {}; }}", input.text);
|
let text = format!(r"fn dummy() {{ {}; }}", input.text);
|
||||||
let file = SourceFile::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 = SyntaxNodePtr::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));
|
||||||
let ranges_map = vec![(src_range, array_expr.syntax().range())];
|
let ranges_map = vec![(src_range, array_expr.syntax().range())];
|
||||||
let res = MacroExpansion {
|
let res = MacroExpansion {
|
||||||
@ -119,7 +118,7 @@ impl MacroDef {
|
|||||||
let file = SourceFile::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 = SyntaxNodePtr::new(trait_def.syntax());
|
||||||
let ranges_map = vec![(src_range, name.syntax().range())];
|
let ranges_map = vec![(src_range, name.syntax().range())];
|
||||||
let res = MacroExpansion {
|
let res = MacroExpansion {
|
||||||
text,
|
text,
|
||||||
@ -146,7 +145,7 @@ pub struct MacroExpansion {
|
|||||||
/// Implementation detail: internally, a macro is expanded to the whole file,
|
/// Implementation detail: internally, a macro is expanded to the whole file,
|
||||||
/// even if it is an expression. This `ptr` selects the actual expansion from
|
/// even if it is an expression. This `ptr` selects the actual expansion from
|
||||||
/// the expanded file.
|
/// the expanded file.
|
||||||
ptr: LocalSyntaxPtr,
|
ptr: SyntaxNodePtr,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MacroExpansion {
|
impl MacroExpansion {
|
||||||
@ -157,7 +156,7 @@ impl MacroExpansion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn syntax(&self) -> TreeArc<SyntaxNode> {
|
pub fn syntax(&self) -> TreeArc<SyntaxNode> {
|
||||||
self.ptr.resolve(&self.file())
|
self.ptr.to_node(&self.file()).to_owned()
|
||||||
}
|
}
|
||||||
/// 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.
|
||||||
pub fn map_range_forward(&self, src_range: TextRange) -> Option<TextRange> {
|
pub fn map_range_forward(&self, src_range: TextRange) -> Option<TextRange> {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
SyntaxKind, AstNode, SourceFile, TreeArc,
|
SyntaxKind, AstNode, SourceFile, TreeArc, SyntaxNodePtr,
|
||||||
ast::{self, ModuleItemOwner},
|
ast::{self, ModuleItemOwner},
|
||||||
};
|
};
|
||||||
use ra_db::{SourceRootId, LocalSyntaxPtr};
|
use ra_db::{SourceRootId};
|
||||||
use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap};
|
use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -72,13 +72,13 @@ pub struct LoweredModule {
|
|||||||
|
|
||||||
#[derive(Debug, Default, PartialEq, Eq)]
|
#[derive(Debug, Default, PartialEq, Eq)]
|
||||||
pub struct ImportSourceMap {
|
pub struct ImportSourceMap {
|
||||||
map: ArenaMap<ImportId, LocalSyntaxPtr>,
|
map: ArenaMap<ImportId, SyntaxNodePtr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ImportSourceMap {
|
impl ImportSourceMap {
|
||||||
fn insert(&mut self, import: ImportId, segment: &ast::PathSegment) {
|
fn insert(&mut self, import: ImportId, segment: &ast::PathSegment) {
|
||||||
self.map
|
self.map
|
||||||
.insert(import, LocalSyntaxPtr::new(segment.syntax()))
|
.insert(import, SyntaxNodePtr::new(segment.syntax()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, source: &ModuleSource, import: ImportId) -> TreeArc<ast::PathSegment> {
|
pub fn get(&self, source: &ModuleSource, import: ImportId) -> TreeArc<ast::PathSegment> {
|
||||||
@ -87,7 +87,7 @@ impl ImportSourceMap {
|
|||||||
ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(),
|
ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(),
|
||||||
};
|
};
|
||||||
|
|
||||||
ast::PathSegment::cast(&self.map[import].resolve(file))
|
ast::PathSegment::cast(self.map[import].to_node(file))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_owned()
|
.to_owned()
|
||||||
}
|
}
|
||||||
|
@ -562,7 +562,7 @@ fn infer(content: &str) -> String {
|
|||||||
// sort ranges for consistency
|
// sort ranges for consistency
|
||||||
types.sort_by_key(|(ptr, _)| (ptr.range().start(), ptr.range().end()));
|
types.sort_by_key(|(ptr, _)| (ptr.range().start(), ptr.range().end()));
|
||||||
for (syntax_ptr, ty) in &types {
|
for (syntax_ptr, ty) in &types {
|
||||||
let node = syntax_ptr.resolve(&source_file);
|
let node = syntax_ptr.to_node(&source_file);
|
||||||
write!(
|
write!(
|
||||||
acc,
|
acc,
|
||||||
"{} '{}': {}\n",
|
"{} '{}': {}\n",
|
||||||
|
@ -23,8 +23,8 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.find(|it| it.ptr.kind() == FN_DEF)?;
|
.find(|it| it.ptr.kind() == FN_DEF)?;
|
||||||
let fn_file = db.source_file(symbol.file_id);
|
let fn_file = db.source_file(symbol.file_id);
|
||||||
let fn_def = symbol.ptr.resolve(&fn_file);
|
let fn_def = symbol.ptr.to_node(&fn_file);
|
||||||
let fn_def = ast::FnDef::cast(&fn_def).unwrap();
|
let fn_def = ast::FnDef::cast(fn_def).unwrap();
|
||||||
let mut call_info = CallInfo::new(fn_def)?;
|
let mut call_info = CallInfo::new(fn_def)?;
|
||||||
// If we have a calling expression let's find which argument we are on
|
// If we have a calling expression let's find which argument we are on
|
||||||
let num_params = call_info.parameters.len();
|
let num_params = call_info.parameters.len();
|
||||||
|
@ -153,7 +153,7 @@ impl db::RootDatabase {
|
|||||||
source_binder::function_from_child_node(db, position.file_id, name_ref.syntax())?;
|
source_binder::function_from_child_node(db, position.file_id, name_ref.syntax())?;
|
||||||
let scope = descr.scopes(db);
|
let scope = descr.scopes(db);
|
||||||
let resolved = scope.resolve_local_name(name_ref)?;
|
let resolved = scope.resolve_local_name(name_ref)?;
|
||||||
let resolved = resolved.ptr().resolve(source_file);
|
let resolved = resolved.ptr().to_node(source_file);
|
||||||
let binding = find_node_at_offset::<ast::BindPat>(syntax, resolved.range().end())?;
|
let binding = find_node_at_offset::<ast::BindPat>(syntax, resolved.range().end())?;
|
||||||
Some((binding, descr))
|
Some((binding, descr))
|
||||||
}
|
}
|
||||||
|
@ -27,13 +27,13 @@ use std::{
|
|||||||
|
|
||||||
use fst::{self, Streamer};
|
use fst::{self, Streamer};
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
SyntaxNode, SourceFile, SmolStr, TreeArc, AstNode,
|
SyntaxNode, SyntaxNodePtr, SourceFile, SmolStr, TreeArc, AstNode,
|
||||||
algo::{visit::{visitor, Visitor}, find_covering_node},
|
algo::{visit::{visitor, Visitor}, find_covering_node},
|
||||||
SyntaxKind::{self, *},
|
SyntaxKind::{self, *},
|
||||||
ast::{self, NameOwner},
|
ast::{self, NameOwner},
|
||||||
};
|
};
|
||||||
use ra_db::{
|
use ra_db::{
|
||||||
SourceRootId, FilesDatabase, LocalSyntaxPtr,
|
SourceRootId, FilesDatabase,
|
||||||
salsa::{self, ParallelDatabase},
|
salsa::{self, ParallelDatabase},
|
||||||
};
|
};
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
@ -62,7 +62,7 @@ fn file_symbols(db: &impl SymbolsDatabase, file_id: FileId) -> Arc<SymbolIndex>
|
|||||||
|
|
||||||
for (name, text_range) in hir::source_binder::macro_symbols(db, file_id) {
|
for (name, text_range) in hir::source_binder::macro_symbols(db, file_id) {
|
||||||
let node = find_covering_node(source_file.syntax(), text_range);
|
let node = find_covering_node(source_file.syntax(), text_range);
|
||||||
let ptr = LocalSyntaxPtr::new(node);
|
let ptr = SyntaxNodePtr::new(node);
|
||||||
symbols.push(FileSymbol { file_id, name, ptr })
|
symbols.push(FileSymbol { file_id, name, ptr })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,13 +196,13 @@ fn is_type(kind: SyntaxKind) -> bool {
|
|||||||
pub(crate) struct FileSymbol {
|
pub(crate) struct FileSymbol {
|
||||||
pub(crate) file_id: FileId,
|
pub(crate) file_id: FileId,
|
||||||
pub(crate) name: SmolStr,
|
pub(crate) name: SmolStr,
|
||||||
pub(crate) ptr: LocalSyntaxPtr,
|
pub(crate) ptr: SyntaxNodePtr,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_symbol(node: &SyntaxNode) -> Option<(SmolStr, LocalSyntaxPtr)> {
|
fn to_symbol(node: &SyntaxNode) -> Option<(SmolStr, SyntaxNodePtr)> {
|
||||||
fn decl<N: NameOwner>(node: &N) -> Option<(SmolStr, LocalSyntaxPtr)> {
|
fn decl<N: NameOwner>(node: &N) -> Option<(SmolStr, SyntaxNodePtr)> {
|
||||||
let name = node.name()?.text().clone();
|
let name = node.name()?.text().clone();
|
||||||
let ptr = LocalSyntaxPtr::new(node.syntax());
|
let ptr = SyntaxNodePtr::new(node.syntax());
|
||||||
Some((name, ptr))
|
Some((name, ptr))
|
||||||
}
|
}
|
||||||
visitor()
|
visitor()
|
||||||
|
@ -35,6 +35,7 @@ mod syntax_kinds;
|
|||||||
pub mod utils;
|
pub mod utils;
|
||||||
mod validation;
|
mod validation;
|
||||||
mod yellow;
|
mod yellow;
|
||||||
|
mod ptr;
|
||||||
|
|
||||||
pub use rowan::{SmolStr, TextRange, TextUnit};
|
pub use rowan::{SmolStr, TextRange, TextUnit};
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
@ -42,6 +43,7 @@ pub use crate::{
|
|||||||
lexer::{tokenize, Token},
|
lexer::{tokenize, Token},
|
||||||
syntax_kinds::SyntaxKind,
|
syntax_kinds::SyntaxKind,
|
||||||
yellow::{Direction, SyntaxError, SyntaxNode, WalkEvent, Location, TreeArc},
|
yellow::{Direction, SyntaxError, SyntaxNode, WalkEvent, Location, TreeArc},
|
||||||
|
ptr::SyntaxNodePtr,
|
||||||
};
|
};
|
||||||
|
|
||||||
use ra_text_edit::AtomTextEdit;
|
use ra_text_edit::AtomTextEdit;
|
||||||
|
53
crates/ra_syntax/src/ptr.rs
Normal file
53
crates/ra_syntax/src/ptr.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use crate::{
|
||||||
|
AstNode, SourceFile, SyntaxKind, SyntaxNode, TextRange,
|
||||||
|
algo::generate,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A pointer to a syntax node inside a file. It can be used to remember a
|
||||||
|
/// specific node across reparses of the same file.
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub struct SyntaxNodePtr {
|
||||||
|
range: TextRange,
|
||||||
|
kind: SyntaxKind,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SyntaxNodePtr {
|
||||||
|
pub fn new(node: &SyntaxNode) -> SyntaxNodePtr {
|
||||||
|
SyntaxNodePtr {
|
||||||
|
range: node.range(),
|
||||||
|
kind: node.kind(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_node(self, source_file: &SourceFile) -> &SyntaxNode {
|
||||||
|
generate(Some(source_file.syntax()), |&node| {
|
||||||
|
node.children()
|
||||||
|
.find(|it| self.range.is_subrange(&it.range()))
|
||||||
|
})
|
||||||
|
.find(|it| it.range() == self.range && it.kind() == self.kind)
|
||||||
|
.unwrap_or_else(|| panic!("can't resolve local ptr to SyntaxNode: {:?}", self))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn range(self) -> TextRange {
|
||||||
|
self.range
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn kind(self) -> SyntaxKind {
|
||||||
|
self.kind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_local_syntax_ptr() {
|
||||||
|
use crate::{ast, AstNode};
|
||||||
|
|
||||||
|
let file = SourceFile::parse("struct Foo { f: u32, }");
|
||||||
|
let field = file
|
||||||
|
.syntax()
|
||||||
|
.descendants()
|
||||||
|
.find_map(ast::NamedFieldDef::cast)
|
||||||
|
.unwrap();
|
||||||
|
let ptr = SyntaxNodePtr::new(field.syntax());
|
||||||
|
let field_syntax = ptr.to_node(&file);
|
||||||
|
assert_eq!(field.syntax(), &*field_syntax);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user