introduced better typed AstPtr

This commit is contained in:
Aleksey Kladov 2019-01-23 18:26:02 +03:00
parent e22b6edae5
commit d4ed25d86f
3 changed files with 40 additions and 9 deletions

View File

@ -1,10 +1,10 @@
use std::sync::Arc; use std::sync::Arc;
use ra_syntax::{ use ra_syntax::{
SyntaxKind, AstNode, SourceFile, TreeArc, SyntaxNodePtr, SyntaxKind, AstNode, SourceFile, TreeArc, AstPtr,
ast::{self, ModuleItemOwner}, ast::{self, ModuleItemOwner},
}; };
use ra_db::{SourceRootId}; 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,12 @@ pub struct LoweredModule {
#[derive(Debug, Default, PartialEq, Eq)] #[derive(Debug, Default, PartialEq, Eq)]
pub struct ImportSourceMap { pub struct ImportSourceMap {
map: ArenaMap<ImportId, SyntaxNodePtr>, map: ArenaMap<ImportId, AstPtr<ast::PathSegment>>,
} }
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, AstPtr::new(segment))
.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,9 +86,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].to_node(file)) self.map[import].to_node(file).to_owned()
.unwrap()
.to_owned()
} }
} }

View File

@ -43,7 +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, ptr::{SyntaxNodePtr, AstPtr},
}; };
use ra_text_edit::AtomTextEdit; use ra_text_edit::AtomTextEdit;

View File

@ -1,3 +1,5 @@
use std::marker::PhantomData;
use crate::{ use crate::{
AstNode, SourceFile, SyntaxKind, SyntaxNode, TextRange, AstNode, SourceFile, SyntaxKind, SyntaxNode, TextRange,
algo::generate, algo::generate,
@ -37,6 +39,38 @@ impl SyntaxNodePtr {
} }
} }
/// Like `SyntaxNodePtr`, but remembers the type of node
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct AstPtr<N: AstNode> {
ptr: SyntaxNodePtr,
_ty: PhantomData<N>,
}
impl<N: AstNode> Copy for AstPtr<N> {}
impl<N: AstNode> Clone for AstPtr<N> {
fn clone(&self) -> AstPtr<N> {
*self
}
}
impl<N: AstNode> AstPtr<N> {
pub fn new(node: &N) -> AstPtr<N> {
AstPtr {
ptr: SyntaxNodePtr::new(node.syntax()),
_ty: PhantomData,
}
}
pub fn to_node(self, source_file: &SourceFile) -> &N {
let syntax_node = self.ptr.to_node(source_file);
N::cast(syntax_node).unwrap()
}
pub fn syntax_node_ptr(self) -> SyntaxNodePtr {
self.ptr
}
}
#[test] #[test]
fn test_local_syntax_ptr() { fn test_local_syntax_ptr() {
use crate::{ast, AstNode}; use crate::{ast, AstNode};