migrate ra_editor to rowan 0.2

This commit is contained in:
Aleksey Kladov 2019-01-07 16:53:24 +03:00
parent b73c51ff9b
commit b88775af7f
11 changed files with 83 additions and 96 deletions

View File

@ -12,7 +12,7 @@ mod split_import;
use ra_text_edit::{TextEdit, TextEditBuilder}; use ra_text_edit::{TextEdit, TextEditBuilder};
use ra_syntax::{ use ra_syntax::{
Direction, SyntaxNodeRef, TextUnit, TextRange,SourceFileNode, AstNode, Direction, SyntaxNode, TextUnit, TextRange, SourceFile, AstNode,
algo::{find_leaf_at_offset, find_covering_node, LeafAtOffset}, algo::{find_leaf_at_offset, find_covering_node, LeafAtOffset},
}; };
@ -28,7 +28,7 @@ pub use self::{
}; };
/// Return all the assists applicable at the given position. /// Return all the assists applicable at the given position.
pub fn assists(file: &SourceFileNode, range: TextRange) -> Vec<LocalEdit> { pub fn assists(file: &SourceFile, range: TextRange) -> Vec<LocalEdit> {
let ctx = AssistCtx::new(file, range); let ctx = AssistCtx::new(file, range);
[ [
flip_comma, flip_comma,
@ -50,7 +50,7 @@ pub struct LocalEdit {
pub cursor_position: Option<TextUnit>, pub cursor_position: Option<TextUnit>,
} }
fn non_trivia_sibling(node: SyntaxNodeRef, direction: Direction) -> Option<SyntaxNodeRef> { fn non_trivia_sibling(node: &SyntaxNode, direction: Direction) -> Option<&SyntaxNode> {
node.siblings(direction) node.siblings(direction)
.skip(1) .skip(1)
.find(|node| !node.kind().is_trivia()) .find(|node| !node.kind().is_trivia())
@ -88,7 +88,7 @@ fn non_trivia_sibling(node: SyntaxNodeRef, direction: Direction) -> Option<Synta
/// easier to just compute the edit eagarly :-) /// easier to just compute the edit eagarly :-)
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct AssistCtx<'a> { pub struct AssistCtx<'a> {
source_file: &'a SourceFileNode, source_file: &'a SourceFile,
range: TextRange, range: TextRange,
should_compute_edit: bool, should_compute_edit: bool,
} }
@ -106,7 +106,7 @@ struct AssistBuilder {
} }
impl<'a> AssistCtx<'a> { impl<'a> AssistCtx<'a> {
pub fn new(source_file: &'a SourceFileNode, range: TextRange) -> AssistCtx { pub fn new(source_file: &'a SourceFile, range: TextRange) -> AssistCtx {
AssistCtx { AssistCtx {
source_file, source_file,
range, range,
@ -145,13 +145,13 @@ impl<'a> AssistCtx<'a> {
})) }))
} }
pub(crate) fn leaf_at_offset(&self) -> LeafAtOffset<SyntaxNodeRef<'a>> { pub(crate) fn leaf_at_offset(&self) -> LeafAtOffset<&'a SyntaxNode> {
find_leaf_at_offset(self.source_file.syntax(), self.range.start()) find_leaf_at_offset(self.source_file.syntax(), self.range.start())
} }
pub(crate) fn node_at_offset<N: AstNode<'a>>(&self) -> Option<N> { pub(crate) fn node_at_offset<N: AstNode>(&self) -> Option<&'a N> {
find_node_at_offset(self.source_file.syntax(), self.range.start()) find_node_at_offset(self.source_file.syntax(), self.range.start())
} }
pub(crate) fn covering_node(&self) -> SyntaxNodeRef<'a> { pub(crate) fn covering_node(&self) -> &'a SyntaxNode {
find_covering_node(self.source_file.syntax(), self.range) find_covering_node(self.source_file.syntax(), self.range)
} }
} }

View File

@ -28,7 +28,7 @@ pub fn add_derive(ctx: AssistCtx) -> Option<Assist> {
} }
// Insert `derive` after doc comments. // Insert `derive` after doc comments.
fn derive_insertion_offset(nominal: ast::NominalDef) -> Option<TextUnit> { fn derive_insertion_offset(nominal: &ast::NominalDef) -> Option<TextUnit> {
let non_ws_child = nominal let non_ws_child = nominal
.syntax() .syntax()
.children() .children()

View File

@ -46,7 +46,7 @@ fn add_vis(ctx: AssistCtx) -> Option<Assist> {
}) })
} }
fn change_vis(ctx: AssistCtx, vis: ast::Visibility) -> Option<Assist> { fn change_vis(ctx: AssistCtx, vis: &ast::Visibility) -> Option<Assist> {
if vis.syntax().text() != "pub" { if vis.syntax().text() != "pub" {
return None; return None;
} }

View File

@ -1,7 +1,7 @@
use ra_syntax::{ use ra_syntax::{
ast::{self, AstNode}, ast::{self, AstNode},
SyntaxKind::WHITESPACE, SyntaxKind::WHITESPACE,
SyntaxNodeRef, TextUnit, SyntaxNode, TextUnit,
}; };
use crate::assists::{AssistCtx, Assist}; use crate::assists::{AssistCtx, Assist};
@ -39,7 +39,7 @@ pub fn introduce_variable<'a>(ctx: AssistCtx) -> Option<Assist> {
/// Statement or last in the block expression, which will follow /// Statement or last in the block expression, which will follow
/// the freshly introduced var. /// the freshly introduced var.
fn anchor_stmt(expr: ast::Expr) -> Option<SyntaxNodeRef> { fn anchor_stmt(expr: &ast::Expr) -> Option<&SyntaxNode> {
expr.syntax().ancestors().find(|&node| { expr.syntax().ancestors().find(|&node| {
if ast::Stmt::cast(node).is_some() { if ast::Stmt::cast(node).is_some() {
return true; return true;

View File

@ -1,25 +1,15 @@
use itertools::Itertools; use itertools::Itertools;
use ra_syntax::{ use ra_syntax::{
Location, SourceFile, SyntaxKind, TextRange, SyntaxNode,
ast::{self, AstNode}, ast::{self, AstNode},
Location,
SourceFileNode,
SyntaxKind,
TextRange,
};
use ra_syntax::SyntaxNodeRef;
use ra_text_edit::{
TextEdit,
TextEditBuilder,
};
use crate::{
Diagnostic,
LocalEdit,
Severity,
}; };
use ra_text_edit::{TextEdit, TextEditBuilder};
pub fn diagnostics(file: &SourceFileNode) -> Vec<Diagnostic> { use crate::{Diagnostic, LocalEdit, Severity};
pub fn diagnostics(file: &SourceFile) -> Vec<Diagnostic> {
fn location_to_range(location: Location) -> TextRange { fn location_to_range(location: Location) -> TextRange {
match location { match location {
Location::Offset(offset) => TextRange::offset_len(offset, 1.into()), Location::Offset(offset) => TextRange::offset_len(offset, 1.into()),
@ -48,7 +38,7 @@ pub fn diagnostics(file: &SourceFileNode) -> Vec<Diagnostic> {
fn check_unnecessary_braces_in_use_statement( fn check_unnecessary_braces_in_use_statement(
acc: &mut Vec<Diagnostic>, acc: &mut Vec<Diagnostic>,
node: SyntaxNodeRef, node: &SyntaxNode,
) -> Option<()> { ) -> Option<()> {
let use_tree_list = ast::UseTreeList::cast(node)?; let use_tree_list = ast::UseTreeList::cast(node)?;
if let Some((single_use_tree,)) = use_tree_list.use_trees().collect_tuple() { if let Some((single_use_tree,)) = use_tree_list.use_trees().collect_tuple() {
@ -79,7 +69,7 @@ fn check_unnecessary_braces_in_use_statement(
} }
fn text_edit_for_remove_unnecessary_braces_with_self_in_use_statement( fn text_edit_for_remove_unnecessary_braces_with_self_in_use_statement(
single_use_tree: ast::UseTree, single_use_tree: &ast::UseTree,
) -> Option<TextEdit> { ) -> Option<TextEdit> {
let use_tree_list_node = single_use_tree.syntax().parent()?; let use_tree_list_node = single_use_tree.syntax().parent()?;
if single_use_tree if single_use_tree
@ -102,7 +92,7 @@ fn text_edit_for_remove_unnecessary_braces_with_self_in_use_statement(
fn check_struct_shorthand_initialization( fn check_struct_shorthand_initialization(
acc: &mut Vec<Diagnostic>, acc: &mut Vec<Diagnostic>,
node: SyntaxNodeRef, node: &SyntaxNode,
) -> Option<()> { ) -> Option<()> {
let struct_lit = ast::StructLit::cast(node)?; let struct_lit = ast::StructLit::cast(node)?;
let named_field_list = struct_lit.named_field_list()?; let named_field_list = struct_lit.named_field_list()?;
@ -138,10 +128,10 @@ mod tests {
use super::*; use super::*;
type DiagnosticChecker = fn(&mut Vec<Diagnostic>, SyntaxNodeRef) -> Option<()>; type DiagnosticChecker = fn(&mut Vec<Diagnostic>, &SyntaxNode) -> Option<()>;
fn check_not_applicable(code: &str, func: DiagnosticChecker) { fn check_not_applicable(code: &str, func: DiagnosticChecker) {
let file = SourceFileNode::parse(code); let file = SourceFile::parse(code);
let mut diagnostics = Vec::new(); let mut diagnostics = Vec::new();
for node in file.syntax().descendants() { for node in file.syntax().descendants() {
func(&mut diagnostics, node); func(&mut diagnostics, node);
@ -150,7 +140,7 @@ mod tests {
} }
fn check_apply(before: &str, after: &str, func: DiagnosticChecker) { fn check_apply(before: &str, after: &str, func: DiagnosticChecker) {
let file = SourceFileNode::parse(before); let file = SourceFile::parse(before);
let mut diagnostics = Vec::new(); let mut diagnostics = Vec::new();
for node in file.syntax().descendants() { for node in file.syntax().descendants() {
func(&mut diagnostics, node); func(&mut diagnostics, node);

View File

@ -1,11 +1,10 @@
use ra_syntax::{ use ra_syntax::{
Direction, SyntaxNode, TextRange, TextUnit,
algo::{find_covering_node, find_leaf_at_offset, LeafAtOffset}, algo::{find_covering_node, find_leaf_at_offset, LeafAtOffset},
Direction,
SyntaxKind::*, SyntaxKind::*,
SyntaxNodeRef, TextRange, TextUnit,
}; };
pub fn extend_selection(root: SyntaxNodeRef, range: TextRange) -> Option<TextRange> { pub fn extend_selection(root: &SyntaxNode, range: TextRange) -> Option<TextRange> {
let string_kinds = [COMMENT, STRING, RAW_STRING, BYTE_STRING, RAW_BYTE_STRING]; let string_kinds = [COMMENT, STRING, RAW_STRING, BYTE_STRING, RAW_BYTE_STRING];
if range.is_empty() { if range.is_empty() {
let offset = range.start(); let offset = range.start();
@ -40,7 +39,7 @@ pub fn extend_selection(root: SyntaxNodeRef, range: TextRange) -> Option<TextRan
} }
fn extend_single_word_in_comment_or_string( fn extend_single_word_in_comment_or_string(
leaf: SyntaxNodeRef, leaf: &SyntaxNode,
offset: TextUnit, offset: TextUnit,
) -> Option<TextRange> { ) -> Option<TextRange> {
let text: &str = leaf.leaf_text()?; let text: &str = leaf.leaf_text()?;
@ -66,7 +65,7 @@ fn extend_single_word_in_comment_or_string(
} }
} }
fn extend_ws(root: SyntaxNodeRef, ws: SyntaxNodeRef, offset: TextUnit) -> TextRange { fn extend_ws(root: &SyntaxNode, ws: &SyntaxNode, offset: TextUnit) -> TextRange {
let ws_text = ws.leaf_text().unwrap(); let ws_text = ws.leaf_text().unwrap();
let suffix = TextRange::from_to(offset, ws.range().end()) - ws.range().start(); let suffix = TextRange::from_to(offset, ws.range().end()) - ws.range().start();
let prefix = TextRange::from_to(ws.range().start(), offset) - ws.range().start(); let prefix = TextRange::from_to(ws.range().start(), offset) - ws.range().start();
@ -89,9 +88,9 @@ fn extend_ws(root: SyntaxNodeRef, ws: SyntaxNodeRef, offset: TextUnit) -> TextRa
ws.range() ws.range()
} }
fn pick_best<'a>(l: SyntaxNodeRef<'a>, r: SyntaxNodeRef<'a>) -> SyntaxNodeRef<'a> { fn pick_best<'a>(l: &'a SyntaxNode, r: &'a SyntaxNode) -> &'a SyntaxNode {
return if priority(r) > priority(l) { r } else { l }; return if priority(r) > priority(l) { r } else { l };
fn priority(n: SyntaxNodeRef) -> usize { fn priority(n: &SyntaxNode) -> usize {
match n.kind() { match n.kind() {
WHITESPACE => 0, WHITESPACE => 0,
IDENT | SELF_KW | SUPER_KW | CRATE_KW | LIFETIME => 2, IDENT | SELF_KW | SUPER_KW | CRATE_KW | LIFETIME => 2,
@ -100,7 +99,7 @@ fn pick_best<'a>(l: SyntaxNodeRef<'a>, r: SyntaxNodeRef<'a>) -> SyntaxNodeRef<'a
} }
} }
fn extend_comments(node: SyntaxNodeRef) -> Option<TextRange> { fn extend_comments(node: &SyntaxNode) -> Option<TextRange> {
let prev = adj_comments(node, Direction::Prev); let prev = adj_comments(node, Direction::Prev);
let next = adj_comments(node, Direction::Next); let next = adj_comments(node, Direction::Next);
if prev != next { if prev != next {
@ -110,7 +109,7 @@ fn extend_comments(node: SyntaxNodeRef) -> Option<TextRange> {
} }
} }
fn adj_comments(node: SyntaxNodeRef, dir: Direction) -> SyntaxNodeRef { fn adj_comments(node: &SyntaxNode, dir: Direction) -> &SyntaxNode {
let mut res = node; let mut res = node;
for node in node.siblings(dir) { for node in node.siblings(dir) {
match node.kind() { match node.kind() {
@ -124,13 +123,14 @@ fn adj_comments(node: SyntaxNodeRef, dir: Direction) -> SyntaxNodeRef {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use ra_syntax::{SourceFile, AstNode};
use ra_syntax::SourceFileNode;
use test_utils::extract_offset; use test_utils::extract_offset;
use super::*;
fn do_check(before: &str, afters: &[&str]) { fn do_check(before: &str, afters: &[&str]) {
let (cursor, before) = extract_offset(before); let (cursor, before) = extract_offset(before);
let file = SourceFileNode::parse(&before); let file = SourceFile::parse(&before);
let mut range = TextRange::offset_len(cursor, 0.into()); let mut range = TextRange::offset_len(cursor, 0.into());
for &after in afters { for &after in afters {
range = extend_selection(file.syntax(), range).unwrap(); range = extend_selection(file.syntax(), range).unwrap();

View File

@ -1,9 +1,8 @@
use rustc_hash::FxHashSet; use rustc_hash::FxHashSet;
use ra_syntax::{ use ra_syntax::{
ast, AstNode, Direction, SourceFileNode, ast, AstNode, Direction, SourceFile, SyntaxNode, TextRange,
SyntaxKind::{self, *}, SyntaxKind::{self, *},
SyntaxNodeRef, TextRange,
}; };
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
@ -19,7 +18,7 @@ pub struct Fold {
pub kind: FoldKind, pub kind: FoldKind,
} }
pub fn folding_ranges(file: &SourceFileNode) -> Vec<Fold> { pub fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
let mut res = vec![]; let mut res = vec![];
let mut visited_comments = FxHashSet::default(); let mut visited_comments = FxHashSet::default();
let mut visited_imports = FxHashSet::default(); let mut visited_imports = FxHashSet::default();
@ -69,7 +68,7 @@ fn fold_kind(kind: SyntaxKind) -> Option<FoldKind> {
} }
} }
fn has_newline(node: SyntaxNodeRef) -> bool { fn has_newline(node: &SyntaxNode) -> bool {
for descendant in node.descendants() { for descendant in node.descendants() {
if let Some(ws) = ast::Whitespace::cast(descendant) { if let Some(ws) = ast::Whitespace::cast(descendant) {
if ws.has_newlines() { if ws.has_newlines() {
@ -86,8 +85,8 @@ fn has_newline(node: SyntaxNodeRef) -> bool {
} }
fn contiguous_range_for_group<'a>( fn contiguous_range_for_group<'a>(
first: SyntaxNodeRef<'a>, first: &'a SyntaxNode,
visited: &mut FxHashSet<SyntaxNodeRef<'a>>, visited: &mut FxHashSet<&'a SyntaxNode>,
) -> Option<TextRange> { ) -> Option<TextRange> {
visited.insert(first); visited.insert(first);
@ -124,8 +123,8 @@ fn contiguous_range_for_group<'a>(
} }
fn contiguous_range_for_comment<'a>( fn contiguous_range_for_comment<'a>(
first: SyntaxNodeRef<'a>, first: &'a SyntaxNode,
visited: &mut FxHashSet<SyntaxNodeRef<'a>>, visited: &mut FxHashSet<&'a SyntaxNode>,
) -> Option<TextRange> { ) -> Option<TextRange> {
visited.insert(first); visited.insert(first);
@ -174,7 +173,7 @@ mod tests {
fn do_check(text: &str, fold_kinds: &[FoldKind]) { fn do_check(text: &str, fold_kinds: &[FoldKind]) {
let (ranges, text) = extract_ranges(text, "fold"); let (ranges, text) = extract_ranges(text, "fold");
let file = SourceFileNode::parse(&text); let file = SourceFile::parse(&text);
let folds = folding_ranges(&file); let folds = folding_ranges(&file);
assert_eq!( assert_eq!(

View File

@ -21,11 +21,10 @@ pub use self::{
}; };
use ra_text_edit::TextEditBuilder; use ra_text_edit::TextEditBuilder;
use ra_syntax::{ use ra_syntax::{
algo::find_leaf_at_offset, SourceFile, SyntaxNode, TextRange, TextUnit, Direction,
ast::{self, AstNode},
SourceFileNode,
SyntaxKind::{self, *}, SyntaxKind::{self, *},
SyntaxNodeRef, TextRange, TextUnit, Direction, ast::{self, AstNode},
algo::find_leaf_at_offset,
}; };
use rustc_hash::FxHashSet; use rustc_hash::FxHashSet;
@ -49,7 +48,7 @@ pub struct Diagnostic {
pub fix: Option<LocalEdit>, pub fix: Option<LocalEdit>,
} }
pub fn matching_brace(file: &SourceFileNode, offset: TextUnit) -> Option<TextUnit> { pub fn matching_brace(file: &SourceFile, offset: TextUnit) -> Option<TextUnit> {
const BRACES: &[SyntaxKind] = &[ const BRACES: &[SyntaxKind] = &[
L_CURLY, R_CURLY, L_BRACK, R_BRACK, L_PAREN, R_PAREN, L_ANGLE, R_ANGLE, L_CURLY, R_CURLY, L_BRACK, R_BRACK, L_PAREN, R_PAREN, L_ANGLE, R_ANGLE,
]; ];
@ -67,7 +66,7 @@ pub fn matching_brace(file: &SourceFileNode, offset: TextUnit) -> Option<TextUni
Some(matching_node.range().start()) Some(matching_node.range().start())
} }
pub fn highlight(root: SyntaxNodeRef) -> Vec<HighlightedRange> { pub fn highlight(root: &SyntaxNode) -> Vec<HighlightedRange> {
// Visited nodes to handle highlighting priorities // Visited nodes to handle highlighting priorities
let mut highlighted = FxHashSet::default(); let mut highlighted = FxHashSet::default();
let mut res = Vec::new(); let mut res = Vec::new();
@ -117,26 +116,25 @@ pub fn highlight(root: SyntaxNodeRef) -> Vec<HighlightedRange> {
res res
} }
pub fn syntax_tree(file: &SourceFileNode) -> String { pub fn syntax_tree(file: &SourceFile) -> String {
::ra_syntax::utils::dump_tree(file.syntax()) ::ra_syntax::utils::dump_tree(file.syntax())
} }
pub fn find_node_at_offset<'a, N: AstNode<'a>>( pub fn find_node_at_offset<N: AstNode>(syntax: &SyntaxNode, offset: TextUnit) -> Option<&N> {
syntax: SyntaxNodeRef<'a>,
offset: TextUnit,
) -> Option<N> {
find_leaf_at_offset(syntax, offset).find_map(|leaf| leaf.ancestors().find_map(N::cast)) find_leaf_at_offset(syntax, offset).find_map(|leaf| leaf.ancestors().find_map(N::cast))
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use ra_syntax::AstNode;
use crate::test_utils::{add_cursor, assert_eq_dbg, assert_eq_text, extract_offset}; use crate::test_utils::{add_cursor, assert_eq_dbg, assert_eq_text, extract_offset};
use super::*; use super::*;
#[test] #[test]
fn test_highlighting() { fn test_highlighting() {
let file = SourceFileNode::parse( let file = SourceFile::parse(
r#" r#"
// comment // comment
fn main() {} fn main() {}
@ -159,7 +157,7 @@ fn main() {}
fn test_matching_brace() { fn test_matching_brace() {
fn do_check(before: &str, after: &str) { fn do_check(before: &str, after: &str) {
let (pos, before) = extract_offset(before); let (pos, before) = extract_offset(before);
let file = SourceFileNode::parse(&before); let file = SourceFile::parse(&before);
let new_pos = match matching_brace(&file, pos) { let new_pos = match matching_brace(&file, pos) {
None => pos, None => pos,
Some(pos) => pos, Some(pos) => pos,

View File

@ -3,7 +3,7 @@ use crate::TextRange;
use ra_syntax::{ use ra_syntax::{
algo::visit::{visitor, Visitor}, algo::visit::{visitor, Visitor},
ast::{self, NameOwner}, ast::{self, NameOwner},
AstNode, SourceFileNode, SyntaxKind, SyntaxNodeRef, WalkEvent, AstNode, SourceFile, SyntaxKind, SyntaxNode, WalkEvent,
}; };
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -15,7 +15,7 @@ pub struct StructureNode {
pub kind: SyntaxKind, pub kind: SyntaxKind,
} }
pub fn file_structure(file: &SourceFileNode) -> Vec<StructureNode> { pub fn file_structure(file: &SourceFile) -> Vec<StructureNode> {
let mut res = Vec::new(); let mut res = Vec::new();
let mut stack = Vec::new(); let mut stack = Vec::new();
@ -38,8 +38,8 @@ pub fn file_structure(file: &SourceFileNode) -> Vec<StructureNode> {
res res
} }
fn structure_node(node: SyntaxNodeRef) -> Option<StructureNode> { fn structure_node(node: &SyntaxNode) -> Option<StructureNode> {
fn decl<'a, N: NameOwner<'a>>(node: N) -> Option<StructureNode> { fn decl<N: NameOwner>(node: &N) -> Option<StructureNode> {
let name = node.name()?; let name = node.name()?;
Some(StructureNode { Some(StructureNode {
parent: None, parent: None,
@ -60,7 +60,7 @@ fn structure_node(node: SyntaxNodeRef) -> Option<StructureNode> {
.visit(decl::<ast::TypeDef>) .visit(decl::<ast::TypeDef>)
.visit(decl::<ast::ConstDef>) .visit(decl::<ast::ConstDef>)
.visit(decl::<ast::StaticDef>) .visit(decl::<ast::StaticDef>)
.visit(|im: ast::ImplBlock| { .visit(|im: &ast::ImplBlock| {
let target_type = im.target_type()?; let target_type = im.target_type()?;
let target_trait = im.target_trait(); let target_trait = im.target_trait();
let label = match target_trait { let label = match target_trait {
@ -91,7 +91,7 @@ mod tests {
#[test] #[test]
fn test_file_structure() { fn test_file_structure() {
let file = SourceFileNode::parse( let file = SourceFile::parse(
r#" r#"
struct Foo { struct Foo {
x: i32 x: i32

View File

@ -1,15 +1,15 @@
use ra_syntax::{SourceFileNode, TextRange, TextUnit}; use ra_syntax::{SourceFile, TextRange, TextUnit};
use crate::LocalEdit; use crate::LocalEdit;
pub use test_utils::*; pub use test_utils::*;
pub fn check_action<F: Fn(&SourceFileNode, TextUnit) -> Option<LocalEdit>>( pub fn check_action<F: Fn(&SourceFile, TextUnit) -> Option<LocalEdit>>(
before: &str, before: &str,
after: &str, after: &str,
f: F, f: F,
) { ) {
let (before_cursor_pos, before) = extract_offset(before); let (before_cursor_pos, before) = extract_offset(before);
let file = SourceFileNode::parse(&before); let file = SourceFile::parse(&before);
let result = f(&file, before_cursor_pos).expect("code action is not applicable"); let result = f(&file, before_cursor_pos).expect("code action is not applicable");
let actual = result.edit.apply(&before); let actual = result.edit.apply(&before);
let actual_cursor_pos = match result.cursor_position { let actual_cursor_pos = match result.cursor_position {
@ -20,13 +20,13 @@ pub fn check_action<F: Fn(&SourceFileNode, TextUnit) -> Option<LocalEdit>>(
assert_eq_text!(after, &actual); assert_eq_text!(after, &actual);
} }
pub fn check_action_range<F: Fn(&SourceFileNode, TextRange) -> Option<LocalEdit>>( pub fn check_action_range<F: Fn(&SourceFile, TextRange) -> Option<LocalEdit>>(
before: &str, before: &str,
after: &str, after: &str,
f: F, f: F,
) { ) {
let (range, before) = extract_range(before); let (range, before) = extract_range(before);
let file = SourceFileNode::parse(&before); let file = SourceFile::parse(&before);
let result = f(&file, range).expect("code action is not applicable"); let result = f(&file, range).expect("code action is not applicable");
let actual = result.edit.apply(&before); let actual = result.edit.apply(&before);
let actual_cursor_pos = match result.cursor_position { let actual_cursor_pos = match result.cursor_position {

View File

@ -5,15 +5,15 @@ use ra_syntax::{
algo::{find_covering_node, find_leaf_at_offset, LeafAtOffset}, algo::{find_covering_node, find_leaf_at_offset, LeafAtOffset},
ast, ast,
text_utils::intersect, text_utils::intersect,
AstNode, Direction, SourceFileNode, SyntaxKind, AstNode, Direction, SourceFile, SyntaxKind,
SyntaxKind::*, SyntaxKind::*,
SyntaxNodeRef, TextRange, TextUnit, SyntaxNode, TextRange, TextUnit,
}; };
use ra_text_edit::text_utils::contains_offset_nonstrict; use ra_text_edit::text_utils::contains_offset_nonstrict;
use crate::{find_node_at_offset, LocalEdit, TextEditBuilder}; use crate::{find_node_at_offset, LocalEdit, TextEditBuilder};
pub fn join_lines(file: &SourceFileNode, range: TextRange) -> LocalEdit { pub fn join_lines(file: &SourceFile, range: TextRange) -> LocalEdit {
let range = if range.is_empty() { let range = if range.is_empty() {
let syntax = file.syntax(); let syntax = file.syntax();
let text = syntax.text().slice(range.start()..); let text = syntax.text().slice(range.start()..);
@ -59,7 +59,7 @@ pub fn join_lines(file: &SourceFileNode, range: TextRange) -> LocalEdit {
} }
} }
pub fn on_enter(file: &SourceFileNode, offset: TextUnit) -> Option<LocalEdit> { pub fn on_enter(file: &SourceFile, offset: TextUnit) -> Option<LocalEdit> {
let comment = find_leaf_at_offset(file.syntax(), offset) let comment = find_leaf_at_offset(file.syntax(), offset)
.left_biased() .left_biased()
.and_then(ast::Comment::cast)?; .and_then(ast::Comment::cast)?;
@ -85,7 +85,7 @@ pub fn on_enter(file: &SourceFileNode, offset: TextUnit) -> Option<LocalEdit> {
}) })
} }
fn node_indent<'a>(file: &'a SourceFileNode, node: SyntaxNodeRef) -> Option<&'a str> { fn node_indent<'a>(file: &'a SourceFile, node: &SyntaxNode) -> Option<&'a str> {
let ws = match find_leaf_at_offset(file.syntax(), node.range().start()) { let ws = match find_leaf_at_offset(file.syntax(), node.range().start()) {
LeafAtOffset::Between(l, r) => { LeafAtOffset::Between(l, r) => {
assert!(r == node); assert!(r == node);
@ -105,8 +105,8 @@ fn node_indent<'a>(file: &'a SourceFileNode, node: SyntaxNodeRef) -> Option<&'a
Some(&text[pos..]) Some(&text[pos..])
} }
pub fn on_eq_typed(file: &SourceFileNode, offset: TextUnit) -> Option<LocalEdit> { pub fn on_eq_typed(file: &SourceFile, offset: TextUnit) -> Option<LocalEdit> {
let let_stmt: ast::LetStmt = find_node_at_offset(file.syntax(), offset)?; let let_stmt: &ast::LetStmt = find_node_at_offset(file.syntax(), offset)?;
if let_stmt.has_semi() { if let_stmt.has_semi() {
return None; return None;
} }
@ -136,7 +136,7 @@ pub fn on_eq_typed(file: &SourceFileNode, offset: TextUnit) -> Option<LocalEdit>
}) })
} }
pub fn on_dot_typed(file: &SourceFileNode, offset: TextUnit) -> Option<LocalEdit> { pub fn on_dot_typed(file: &SourceFile, offset: TextUnit) -> Option<LocalEdit> {
let before_dot_offset = offset - TextUnit::of_char('.'); let before_dot_offset = offset - TextUnit::of_char('.');
let whitespace = find_leaf_at_offset(file.syntax(), before_dot_offset).left_biased()?; let whitespace = find_leaf_at_offset(file.syntax(), before_dot_offset).left_biased()?;
@ -151,7 +151,7 @@ pub fn on_dot_typed(file: &SourceFileNode, offset: TextUnit) -> Option<LocalEdit
.skip(1) .skip(1)
.next()?; .next()?;
ast::MethodCallExprNode::cast(method_call)?; ast::MethodCallExpr::cast(method_call)?;
// find how much the _method call is indented // find how much the _method call is indented
let method_chain_indent = method_call let method_chain_indent = method_call
@ -188,7 +188,7 @@ fn last_line_indent_in_whitespace(ws: &str) -> &str {
fn remove_newline( fn remove_newline(
edit: &mut TextEditBuilder, edit: &mut TextEditBuilder,
node: SyntaxNodeRef, node: &SyntaxNode,
node_text: &str, node_text: &str,
offset: TextUnit, offset: TextUnit,
) { ) {
@ -266,7 +266,7 @@ fn is_trailing_comma(left: SyntaxKind, right: SyntaxKind) -> bool {
} }
} }
fn join_single_expr_block(edit: &mut TextEditBuilder, node: SyntaxNodeRef) -> Option<()> { fn join_single_expr_block(edit: &mut TextEditBuilder, node: &SyntaxNode) -> Option<()> {
let block = ast::Block::cast(node.parent()?)?; let block = ast::Block::cast(node.parent()?)?;
let block_expr = ast::BlockExpr::cast(block.syntax().parent()?)?; let block_expr = ast::BlockExpr::cast(block.syntax().parent()?)?;
let expr = single_expr(block)?; let expr = single_expr(block)?;
@ -277,7 +277,7 @@ fn join_single_expr_block(edit: &mut TextEditBuilder, node: SyntaxNodeRef) -> Op
Some(()) Some(())
} }
fn single_expr(block: ast::Block) -> Option<ast::Expr> { fn single_expr(block: &ast::Block) -> Option<&ast::Expr> {
let mut res = None; let mut res = None;
for child in block.syntax().children() { for child in block.syntax().children() {
if let Some(expr) = ast::Expr::cast(child) { if let Some(expr) = ast::Expr::cast(child) {
@ -297,7 +297,7 @@ fn single_expr(block: ast::Block) -> Option<ast::Expr> {
res res
} }
fn join_single_use_tree(edit: &mut TextEditBuilder, node: SyntaxNodeRef) -> Option<()> { fn join_single_use_tree(edit: &mut TextEditBuilder, node: &SyntaxNode) -> Option<()> {
let use_tree_list = ast::UseTreeList::cast(node.parent()?)?; let use_tree_list = ast::UseTreeList::cast(node.parent()?)?;
let (tree,) = use_tree_list.use_trees().collect_tuple()?; let (tree,) = use_tree_list.use_trees().collect_tuple()?;
edit.replace( edit.replace(
@ -307,7 +307,7 @@ fn join_single_use_tree(edit: &mut TextEditBuilder, node: SyntaxNodeRef) -> Opti
Some(()) Some(())
} }
fn compute_ws(left: SyntaxNodeRef, right: SyntaxNodeRef) -> &'static str { fn compute_ws(left: &SyntaxNode, right: &SyntaxNode) -> &'static str {
match left.kind() { match left.kind() {
L_PAREN | L_BRACK => return "", L_PAREN | L_BRACK => return "",
L_CURLY => { L_CURLY => {
@ -547,7 +547,7 @@ fn foo() {
fn check_join_lines_sel(before: &str, after: &str) { fn check_join_lines_sel(before: &str, after: &str) {
let (sel, before) = extract_range(before); let (sel, before) = extract_range(before);
let file = SourceFileNode::parse(&before); let file = SourceFile::parse(&before);
let result = join_lines(&file, sel); let result = join_lines(&file, sel);
let actual = result.edit.apply(&before); let actual = result.edit.apply(&before);
assert_eq_text!(after, &actual); assert_eq_text!(after, &actual);
@ -626,7 +626,7 @@ pub fn handle_find_matching_brace() {
fn test_on_eq_typed() { fn test_on_eq_typed() {
fn do_check(before: &str, after: &str) { fn do_check(before: &str, after: &str) {
let (offset, before) = extract_offset(before); let (offset, before) = extract_offset(before);
let file = SourceFileNode::parse(&before); let file = SourceFile::parse(&before);
let result = on_eq_typed(&file, offset).unwrap(); let result = on_eq_typed(&file, offset).unwrap();
let actual = result.edit.apply(&before); let actual = result.edit.apply(&before);
assert_eq_text!(after, &actual); assert_eq_text!(after, &actual);
@ -670,7 +670,7 @@ fn foo() {
fn test_on_dot_typed() { fn test_on_dot_typed() {
fn do_check(before: &str, after: &str) { fn do_check(before: &str, after: &str) {
let (offset, before) = extract_offset(before); let (offset, before) = extract_offset(before);
let file = SourceFileNode::parse(&before); let file = SourceFile::parse(&before);
if let Some(result) = on_eq_typed(&file, offset) { if let Some(result) = on_eq_typed(&file, offset) {
let actual = result.edit.apply(&before); let actual = result.edit.apply(&before);
assert_eq_text!(after, &actual); assert_eq_text!(after, &actual);
@ -779,7 +779,7 @@ fn foo() {
fn test_on_enter() { fn test_on_enter() {
fn apply_on_enter(before: &str) -> Option<String> { fn apply_on_enter(before: &str) -> Option<String> {
let (offset, before) = extract_offset(before); let (offset, before) = extract_offset(before);
let file = SourceFileNode::parse(&before); let file = SourceFile::parse(&before);
let result = on_enter(&file, offset)?; let result = on_enter(&file, offset)?;
let actual = result.edit.apply(&before); let actual = result.edit.apply(&before);
let actual = add_cursor(&actual, result.cursor_position.unwrap()); let actual = add_cursor(&actual, result.cursor_position.unwrap());