Fix ordering problem between qualifying paths and substituting params

This commit is contained in:
Florian Diebold 2020-01-10 18:26:18 +01:00 committed by Florian Diebold
parent 12905e5b58
commit 15fc643e05
7 changed files with 206 additions and 126 deletions

View file

@ -184,17 +184,17 @@ pub fn replace_children(
/// to create a type-safe abstraction on top of it instead.
pub fn replace_descendants(
parent: &SyntaxNode,
map: &FxHashMap<SyntaxElement, SyntaxElement>,
map: &impl Fn(&SyntaxElement) -> Option<SyntaxElement>,
) -> SyntaxNode {
// FIXME: this could be made much faster.
let new_children = parent.children_with_tokens().map(|it| go(map, it)).collect::<Vec<_>>();
return with_children(parent, new_children);
fn go(
map: &FxHashMap<SyntaxElement, SyntaxElement>,
map: &impl Fn(&SyntaxElement) -> Option<SyntaxElement>,
element: SyntaxElement,
) -> NodeOrToken<rowan::GreenNode, rowan::GreenToken> {
if let Some(replacement) = map.get(&element) {
if let Some(replacement) = map(&element) {
return match replacement {
NodeOrToken::Node(it) => NodeOrToken::Node(it.green().clone()),
NodeOrToken::Token(it) => NodeOrToken::Token(it.green().clone()),

View file

@ -236,8 +236,8 @@ pub fn replace_descendants<N: AstNode, D: AstNode>(
) -> N {
let map = replacement_map
.map(|(from, to)| (from.syntax().clone().into(), to.syntax().clone().into()))
.collect::<FxHashMap<_, _>>();
let new_syntax = algo::replace_descendants(parent.syntax(), &map);
.collect::<FxHashMap<SyntaxElement, _>>();
let new_syntax = algo::replace_descendants(parent.syntax(), &|n| map.get(n).cloned());
N::cast(new_syntax).unwrap()
}
@ -292,7 +292,7 @@ impl IndentLevel {
)
})
.collect();
algo::replace_descendants(&node, &replacements)
algo::replace_descendants(&node, &|n| replacements.get(n).cloned())
}
pub fn decrease_indent<N: AstNode>(self, node: N) -> N {
@ -320,7 +320,7 @@ impl IndentLevel {
)
})
.collect();
algo::replace_descendants(&node, &replacements)
algo::replace_descendants(&node, &|n| replacements.get(n).cloned())
}
}

View file

@ -2,7 +2,7 @@
//! of smaller pieces.
use itertools::Itertools;
use crate::{ast, AstNode, SourceFile};
use crate::{algo, ast, AstNode, SourceFile};
pub fn name(text: &str) -> ast::Name {
ast_from_text(&format!("mod {};", text))
@ -23,7 +23,14 @@ fn path_from_text(text: &str) -> ast::Path {
}
pub fn path_with_type_arg_list(path: ast::Path, args: Option<ast::TypeArgList>) -> ast::Path {
if let Some(args) = args {
ast_from_text(&format!("const X: {}{}", path.syntax(), args.syntax()))
let syntax = path.syntax();
// FIXME: remove existing type args
let new_syntax = algo::insert_children(
syntax,
crate::algo::InsertPosition::Last,
&mut Some(args).into_iter().map(|n| n.syntax().clone().into()),
);
ast::Path::cast(new_syntax).unwrap()
} else {
path
}