mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 04:53:34 +00:00
Convert code to text-size
This commit is contained in:
parent
27a7718880
commit
b1d5817dd1
75 changed files with 438 additions and 456 deletions
16
Cargo.lock
generated
16
Cargo.lock
generated
|
@ -1180,7 +1180,7 @@ dependencies = [
|
||||||
name = "ra_text_edit"
|
name = "ra_text_edit"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"text_unit",
|
"text-size",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1322,13 +1322,11 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rowan"
|
name = "rowan"
|
||||||
version = "0.9.1"
|
version = "0.10.0-pre.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1ea7cadf87a9d8432e85cb4eb86bd2e765ace60c24ef86e79084dcae5d1c5a19"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"smol_str",
|
"smol_str",
|
||||||
"text_unit",
|
"text-size",
|
||||||
"thin-dst",
|
"thin-dst",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1620,14 +1618,12 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"difference",
|
"difference",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"text_unit",
|
"text-size",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "text_unit"
|
name = "text-size"
|
||||||
version = "0.1.10"
|
version = "1.0.0-pre.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "20431e104bfecc1a40872578dbc390e10290a0e9c35fffe3ce6f73c15a9dbfc2"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thin-dst"
|
name = "thin-dst"
|
||||||
|
|
|
@ -5,7 +5,7 @@ use ra_fmt::{leading_indent, reindent};
|
||||||
use ra_ide_db::RootDatabase;
|
use ra_ide_db::RootDatabase;
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
algo::{self, find_covering_element, find_node_at_offset},
|
algo::{self, find_covering_element, find_node_at_offset},
|
||||||
AstNode, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, TextUnit,
|
AstNode, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, TextSize,
|
||||||
TokenAtOffset,
|
TokenAtOffset,
|
||||||
};
|
};
|
||||||
use ra_text_edit::TextEditBuilder;
|
use ra_text_edit::TextEditBuilder;
|
||||||
|
@ -178,7 +178,7 @@ impl<'a> AssistGroup<'a> {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub(crate) struct ActionBuilder {
|
pub(crate) struct ActionBuilder {
|
||||||
edit: TextEditBuilder,
|
edit: TextEditBuilder,
|
||||||
cursor_position: Option<TextUnit>,
|
cursor_position: Option<TextSize>,
|
||||||
target: Option<TextRange>,
|
target: Option<TextRange>,
|
||||||
file: AssistFile,
|
file: AssistFile,
|
||||||
}
|
}
|
||||||
|
@ -211,12 +211,12 @@ impl ActionBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Append specified `text` at the given `offset`
|
/// Append specified `text` at the given `offset`
|
||||||
pub(crate) fn insert(&mut self, offset: TextUnit, text: impl Into<String>) {
|
pub(crate) fn insert(&mut self, offset: TextSize, text: impl Into<String>) {
|
||||||
self.edit.insert(offset, text.into())
|
self.edit.insert(offset, text.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Specify desired position of the cursor after the assist is applied.
|
/// Specify desired position of the cursor after the assist is applied.
|
||||||
pub(crate) fn set_cursor(&mut self, offset: TextUnit) {
|
pub(crate) fn set_cursor(&mut self, offset: TextSize) {
|
||||||
self.cursor_position = Some(offset)
|
self.cursor_position = Some(offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ use ra_syntax::{
|
||||||
ast::{self, AstNode},
|
ast::{self, AstNode},
|
||||||
Direction, SmolStr,
|
Direction, SmolStr,
|
||||||
SyntaxKind::{IDENT, WHITESPACE},
|
SyntaxKind::{IDENT, WHITESPACE},
|
||||||
TextRange, TextUnit,
|
TextRange, TextSize,
|
||||||
};
|
};
|
||||||
use stdx::SepBy;
|
use stdx::SepBy;
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ pub(crate) fn add_custom_impl(ctx: AssistCtx) -> Option<Assist> {
|
||||||
|
|
||||||
let cursor_delta = if has_more_derives {
|
let cursor_delta = if has_more_derives {
|
||||||
edit.replace(input.syntax().text_range(), new_attr_input);
|
edit.replace(input.syntax().text_range(), new_attr_input);
|
||||||
input.syntax().text_range().len() - TextUnit::from_usize(new_attr_input_len)
|
input.syntax().text_range().len() - TextSize::from_usize(new_attr_input_len)
|
||||||
} else {
|
} else {
|
||||||
let attr_range = attr.syntax().text_range();
|
let attr_range = attr.syntax().text_range();
|
||||||
edit.delete(attr_range);
|
edit.delete(attr_range);
|
||||||
|
@ -81,13 +81,13 @@ pub(crate) fn add_custom_impl(ctx: AssistCtx) -> Option<Assist> {
|
||||||
.next_sibling_or_token()
|
.next_sibling_or_token()
|
||||||
.filter(|t| t.kind() == WHITESPACE)
|
.filter(|t| t.kind() == WHITESPACE)
|
||||||
.map(|t| t.text_range())
|
.map(|t| t.text_range())
|
||||||
.unwrap_or_else(|| TextRange::from_to(TextUnit::from(0), TextUnit::from(0)));
|
.unwrap_or_else(|| TextRange::new(TextSize::from(0), TextSize::from(0)));
|
||||||
edit.delete(line_break_range);
|
edit.delete(line_break_range);
|
||||||
|
|
||||||
attr_range.len() + line_break_range.len()
|
attr_range.len() + line_break_range.len()
|
||||||
};
|
};
|
||||||
|
|
||||||
edit.set_cursor(start_offset + TextUnit::of_str(&buf) - cursor_delta);
|
edit.set_cursor(start_offset + TextSize::of(&buf) - cursor_delta);
|
||||||
buf.push_str("\n}");
|
buf.push_str("\n}");
|
||||||
edit.insert(start_offset, buf);
|
edit.insert(start_offset, buf);
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
ast::{self, AstNode, AttrsOwner},
|
ast::{self, AstNode, AttrsOwner},
|
||||||
SyntaxKind::{COMMENT, WHITESPACE},
|
SyntaxKind::{COMMENT, WHITESPACE},
|
||||||
TextUnit,
|
TextSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Assist, AssistCtx, AssistId};
|
use crate::{Assist, AssistCtx, AssistId};
|
||||||
|
@ -37,9 +37,9 @@ pub(crate) fn add_derive(ctx: AssistCtx) -> Option<Assist> {
|
||||||
let offset = match derive_attr {
|
let offset = match derive_attr {
|
||||||
None => {
|
None => {
|
||||||
edit.insert(node_start, "#[derive()]\n");
|
edit.insert(node_start, "#[derive()]\n");
|
||||||
node_start + TextUnit::of_str("#[derive(")
|
node_start + TextSize::of("#[derive(")
|
||||||
}
|
}
|
||||||
Some(tt) => tt.syntax().text_range().end() - TextUnit::of_char(')'),
|
Some(tt) => tt.syntax().text_range().end() - TextSize::of(')'),
|
||||||
};
|
};
|
||||||
edit.target(nominal.syntax().text_range());
|
edit.target(nominal.syntax().text_range());
|
||||||
edit.set_cursor(offset)
|
edit.set_cursor(offset)
|
||||||
|
@ -47,7 +47,7 @@ pub(crate) 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<TextSize> {
|
||||||
let non_ws_child = nominal
|
let non_ws_child = nominal
|
||||||
.syntax()
|
.syntax()
|
||||||
.children_with_tokens()
|
.children_with_tokens()
|
||||||
|
|
|
@ -37,8 +37,8 @@ pub(crate) fn add_explicit_type(ctx: AssistCtx) -> Option<Assist> {
|
||||||
let stmt_range = stmt.syntax().text_range();
|
let stmt_range = stmt.syntax().text_range();
|
||||||
let eq_range = stmt.eq_token()?.text_range();
|
let eq_range = stmt.eq_token()?.text_range();
|
||||||
// Assist should only be applicable if cursor is between 'let' and '='
|
// Assist should only be applicable if cursor is between 'let' and '='
|
||||||
let let_range = TextRange::from_to(stmt_range.start(), eq_range.start());
|
let let_range = TextRange::new(stmt_range.start(), eq_range.start());
|
||||||
let cursor_in_range = ctx.frange.range.is_subrange(&let_range);
|
let cursor_in_range = let_range.contains_range(ctx.frange.range);
|
||||||
if !cursor_in_range {
|
if !cursor_in_range {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
ast::{self, AstNode, NameOwner},
|
ast::{self, AstNode, NameOwner},
|
||||||
TextUnit,
|
TextSize,
|
||||||
};
|
};
|
||||||
use stdx::format_to;
|
use stdx::format_to;
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ impl From<{0}> for {1} {{
|
||||||
variant_name
|
variant_name
|
||||||
);
|
);
|
||||||
edit.insert(start_offset, buf);
|
edit.insert(start_offset, buf);
|
||||||
edit.set_cursor(start_offset + TextUnit::of_str("\n\n"));
|
edit.set_cursor(start_offset + TextSize::of("\n\n"));
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
ast::{self, AstNode},
|
ast::{self, AstNode},
|
||||||
SyntaxKind, SyntaxNode, TextUnit,
|
SyntaxKind, SyntaxNode, TextSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Assist, AssistCtx, AssistFile, AssistId};
|
use crate::{Assist, AssistCtx, AssistFile, AssistId};
|
||||||
|
@ -69,8 +69,8 @@ pub(crate) fn add_function(ctx: AssistCtx) -> Option<Assist> {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FunctionTemplate {
|
struct FunctionTemplate {
|
||||||
insert_offset: TextUnit,
|
insert_offset: TextSize,
|
||||||
cursor_offset: TextUnit,
|
cursor_offset: TextSize,
|
||||||
fn_def: ast::SourceFile,
|
fn_def: ast::SourceFile,
|
||||||
file: AssistFile,
|
file: AssistFile,
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ impl FunctionBuilder {
|
||||||
let fn_def = indent_once.increase_indent(fn_def);
|
let fn_def = indent_once.increase_indent(fn_def);
|
||||||
let fn_def = ast::make::add_trailing_newlines(1, fn_def);
|
let fn_def = ast::make::add_trailing_newlines(1, fn_def);
|
||||||
let fn_def = indent.increase_indent(fn_def);
|
let fn_def = indent.increase_indent(fn_def);
|
||||||
(fn_def, it.syntax().text_range().start() + TextUnit::from_usize(1))
|
(fn_def, it.syntax().text_range().start() + TextSize::from_usize(1))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
ast::{self, AstNode, NameOwner, TypeParamsOwner},
|
ast::{self, AstNode, NameOwner, TypeParamsOwner},
|
||||||
TextUnit,
|
TextSize,
|
||||||
};
|
};
|
||||||
use stdx::{format_to, SepBy};
|
use stdx::{format_to, SepBy};
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ pub(crate) fn add_impl(ctx: AssistCtx) -> Option<Assist> {
|
||||||
format_to!(buf, "<{}>", generic_params)
|
format_to!(buf, "<{}>", generic_params)
|
||||||
}
|
}
|
||||||
buf.push_str(" {\n");
|
buf.push_str(" {\n");
|
||||||
edit.set_cursor(start_offset + TextUnit::of_str(&buf));
|
edit.set_cursor(start_offset + TextSize::of(&buf));
|
||||||
buf.push_str("\n}");
|
buf.push_str("\n}");
|
||||||
edit.insert(start_offset, buf);
|
edit.insert(start_offset, buf);
|
||||||
})
|
})
|
||||||
|
|
|
@ -3,7 +3,7 @@ use ra_syntax::{
|
||||||
ast::{
|
ast::{
|
||||||
self, AstNode, NameOwner, StructKind, TypeAscriptionOwner, TypeParamsOwner, VisibilityOwner,
|
self, AstNode, NameOwner, StructKind, TypeAscriptionOwner, TypeParamsOwner, VisibilityOwner,
|
||||||
},
|
},
|
||||||
TextUnit, T,
|
TextSize, T,
|
||||||
};
|
};
|
||||||
use stdx::{format_to, SepBy};
|
use stdx::{format_to, SepBy};
|
||||||
|
|
||||||
|
@ -77,16 +77,16 @@ pub(crate) fn add_new(ctx: AssistCtx) -> Option<Assist> {
|
||||||
.text_range()
|
.text_range()
|
||||||
.end();
|
.end();
|
||||||
|
|
||||||
Some((start, TextUnit::from_usize(1)))
|
Some((start, TextSize::from_usize(1)))
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
buf = generate_impl_text(&strukt, &buf);
|
buf = generate_impl_text(&strukt, &buf);
|
||||||
let start = strukt.syntax().text_range().end();
|
let start = strukt.syntax().text_range().end();
|
||||||
|
|
||||||
(start, TextUnit::from_usize(3))
|
(start, TextSize::from_usize(3))
|
||||||
});
|
});
|
||||||
|
|
||||||
edit.set_cursor(start_offset + TextUnit::of_str(&buf) - end_offset);
|
edit.set_cursor(start_offset + TextSize::of(&buf) - end_offset);
|
||||||
edit.insert(start_offset, buf);
|
edit.insert(start_offset, buf);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ pub(crate) fn apply_demorgan(ctx: AssistCtx) -> Option<Assist> {
|
||||||
let op = expr.op_kind()?;
|
let op = expr.op_kind()?;
|
||||||
let op_range = expr.op_token()?.text_range();
|
let op_range = expr.op_token()?.text_range();
|
||||||
let opposite_op = opposite_logic_op(op)?;
|
let opposite_op = opposite_logic_op(op)?;
|
||||||
let cursor_in_range = ctx.frange.range.is_subrange(&op_range);
|
let cursor_in_range = op_range.contains_range(ctx.frange.range);
|
||||||
if !cursor_in_range {
|
if !cursor_in_range {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use ra_syntax::{
|
||||||
ATTR, COMMENT, CONST_DEF, ENUM_DEF, FN_DEF, MODULE, STRUCT_DEF, TRAIT_DEF, VISIBILITY,
|
ATTR, COMMENT, CONST_DEF, ENUM_DEF, FN_DEF, MODULE, STRUCT_DEF, TRAIT_DEF, VISIBILITY,
|
||||||
WHITESPACE,
|
WHITESPACE,
|
||||||
},
|
},
|
||||||
SyntaxNode, TextUnit, T,
|
SyntaxNode, TextSize, T,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Assist, AssistCtx, AssistId};
|
use crate::{Assist, AssistCtx, AssistId};
|
||||||
|
@ -67,7 +67,7 @@ fn add_vis(ctx: AssistCtx) -> Option<Assist> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vis_offset(node: &SyntaxNode) -> TextUnit {
|
fn vis_offset(node: &SyntaxNode) -> TextSize {
|
||||||
node.children_with_tokens()
|
node.children_with_tokens()
|
||||||
.skip_while(|it| match it.kind() {
|
.skip_while(|it| match it.kind() {
|
||||||
WHITESPACE | COMMENT | ATTR => true,
|
WHITESPACE | COMMENT | ATTR => true,
|
||||||
|
|
|
@ -23,7 +23,7 @@ pub(crate) fn flip_binexpr(ctx: AssistCtx) -> Option<Assist> {
|
||||||
let rhs = expr.rhs()?.syntax().clone();
|
let rhs = expr.rhs()?.syntax().clone();
|
||||||
let op_range = expr.op_token()?.text_range();
|
let op_range = expr.op_token()?.text_range();
|
||||||
// The assist should be applied only if the cursor is on the operator
|
// The assist should be applied only if the cursor is on the operator
|
||||||
let cursor_in_range = ctx.frange.range.is_subrange(&op_range);
|
let cursor_in_range = op_range.contains_range(ctx.frange.range);
|
||||||
if !cursor_in_range {
|
if !cursor_in_range {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ pub(crate) fn inline_local_variable(ctx: AssistCtx) -> Option<Assist> {
|
||||||
.next_sibling_or_token()
|
.next_sibling_or_token()
|
||||||
.and_then(|it| ast::Whitespace::cast(it.as_token()?.clone()))
|
.and_then(|it| ast::Whitespace::cast(it.as_token()?.clone()))
|
||||||
{
|
{
|
||||||
TextRange::from_to(
|
TextRange::new(
|
||||||
let_stmt.syntax().text_range().start(),
|
let_stmt.syntax().text_range().start(),
|
||||||
whitespace.syntax().text_range().end(),
|
whitespace.syntax().text_range().end(),
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,7 +4,7 @@ use ra_syntax::{
|
||||||
BLOCK_EXPR, BREAK_EXPR, COMMENT, LAMBDA_EXPR, LOOP_EXPR, MATCH_ARM, PATH_EXPR, RETURN_EXPR,
|
BLOCK_EXPR, BREAK_EXPR, COMMENT, LAMBDA_EXPR, LOOP_EXPR, MATCH_ARM, PATH_EXPR, RETURN_EXPR,
|
||||||
WHITESPACE,
|
WHITESPACE,
|
||||||
},
|
},
|
||||||
SyntaxNode, TextUnit,
|
SyntaxNode, TextSize,
|
||||||
};
|
};
|
||||||
use stdx::format_to;
|
use stdx::format_to;
|
||||||
use test_utils::tested_by;
|
use test_utils::tested_by;
|
||||||
|
@ -47,10 +47,10 @@ pub(crate) fn introduce_variable(ctx: AssistCtx) -> Option<Assist> {
|
||||||
|
|
||||||
let cursor_offset = if wrap_in_block {
|
let cursor_offset = if wrap_in_block {
|
||||||
buf.push_str("{ let var_name = ");
|
buf.push_str("{ let var_name = ");
|
||||||
TextUnit::of_str("{ let ")
|
TextSize::of("{ let ")
|
||||||
} else {
|
} else {
|
||||||
buf.push_str("let var_name = ");
|
buf.push_str("let var_name = ");
|
||||||
TextUnit::of_str("let ")
|
TextSize::of("let ")
|
||||||
};
|
};
|
||||||
format_to!(buf, "{}", expr.syntax());
|
format_to!(buf, "{}", expr.syntax());
|
||||||
let full_stmt = ast::ExprStmt::cast(anchor_stmt.clone());
|
let full_stmt = ast::ExprStmt::cast(anchor_stmt.clone());
|
||||||
|
|
|
@ -28,7 +28,7 @@ pub(crate) fn invert_if(ctx: AssistCtx) -> Option<Assist> {
|
||||||
let if_keyword = ctx.find_token_at_offset(T![if])?;
|
let if_keyword = ctx.find_token_at_offset(T![if])?;
|
||||||
let expr = ast::IfExpr::cast(if_keyword.parent())?;
|
let expr = ast::IfExpr::cast(if_keyword.parent())?;
|
||||||
let if_range = if_keyword.text_range();
|
let if_range = if_keyword.text_range();
|
||||||
let cursor_in_range = ctx.frange.range.is_subrange(&if_range);
|
let cursor_in_range = if_range.contains_range(ctx.frange.range);
|
||||||
if !cursor_in_range {
|
if !cursor_in_range {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::iter::successors;
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
algo::neighbor,
|
algo::neighbor,
|
||||||
ast::{self, AstNode},
|
ast::{self, AstNode},
|
||||||
Direction, TextUnit,
|
Direction, TextSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Assist, AssistCtx, AssistId, TextRange};
|
use crate::{Assist, AssistCtx, AssistId, TextRange};
|
||||||
|
@ -42,8 +42,8 @@ pub(crate) fn merge_match_arms(ctx: AssistCtx) -> Option<Assist> {
|
||||||
let current_text_range = current_arm.syntax().text_range();
|
let current_text_range = current_arm.syntax().text_range();
|
||||||
|
|
||||||
enum CursorPos {
|
enum CursorPos {
|
||||||
InExpr(TextUnit),
|
InExpr(TextSize),
|
||||||
InPat(TextUnit),
|
InPat(TextSize),
|
||||||
}
|
}
|
||||||
let cursor_pos = ctx.frange.range.start();
|
let cursor_pos = ctx.frange.range.start();
|
||||||
let cursor_pos = if current_expr.syntax().text_range().contains(cursor_pos) {
|
let cursor_pos = if current_expr.syntax().text_range().contains(cursor_pos) {
|
||||||
|
@ -89,10 +89,10 @@ pub(crate) fn merge_match_arms(ctx: AssistCtx) -> Option<Assist> {
|
||||||
|
|
||||||
edit.target(current_text_range);
|
edit.target(current_text_range);
|
||||||
edit.set_cursor(match cursor_pos {
|
edit.set_cursor(match cursor_pos {
|
||||||
CursorPos::InExpr(back_offset) => start + TextUnit::from_usize(arm.len()) - back_offset,
|
CursorPos::InExpr(back_offset) => start + TextSize::from_usize(arm.len()) - back_offset,
|
||||||
CursorPos::InPat(offset) => offset,
|
CursorPos::InPat(offset) => offset,
|
||||||
});
|
});
|
||||||
edit.replace(TextRange::from_to(start, end), arm);
|
edit.replace(TextRange::new(start, end), arm);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
ast,
|
ast,
|
||||||
ast::{AstNode, AstToken, IfExpr, MatchArm},
|
ast::{AstNode, AstToken, IfExpr, MatchArm},
|
||||||
TextUnit,
|
TextSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Assist, AssistCtx, AssistId};
|
use crate::{Assist, AssistCtx, AssistId};
|
||||||
|
@ -49,16 +49,16 @@ pub(crate) fn move_guard_to_arm_body(ctx: AssistCtx) -> Option<Assist> {
|
||||||
edit.delete(ele);
|
edit.delete(ele);
|
||||||
ele.len()
|
ele.len()
|
||||||
} else {
|
} else {
|
||||||
TextUnit::from(0)
|
TextSize::from(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => TextUnit::from(0),
|
_ => TextSize::from(0),
|
||||||
};
|
};
|
||||||
|
|
||||||
edit.delete(guard.syntax().text_range());
|
edit.delete(guard.syntax().text_range());
|
||||||
edit.replace_node_and_indent(arm_expr.syntax(), buf);
|
edit.replace_node_and_indent(arm_expr.syntax(), buf);
|
||||||
edit.set_cursor(
|
edit.set_cursor(
|
||||||
arm_expr.syntax().text_range().start() + TextUnit::from(3) - offseting_amount,
|
arm_expr.syntax().text_range().start() + TextSize::from(3) - offseting_amount,
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ pub(crate) fn move_arm_cond_to_match_guard(ctx: AssistCtx) -> Option<Assist> {
|
||||||
}
|
}
|
||||||
|
|
||||||
edit.insert(match_pat.syntax().text_range().end(), buf);
|
edit.insert(match_pat.syntax().text_range().end(), buf);
|
||||||
edit.set_cursor(match_pat.syntax().text_range().end() + TextUnit::from(1));
|
edit.set_cursor(match_pat.syntax().text_range().end() + TextSize::from(1));
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ use ra_syntax::{
|
||||||
ast::{self, HasStringValue},
|
ast::{self, HasStringValue},
|
||||||
AstToken,
|
AstToken,
|
||||||
SyntaxKind::{RAW_STRING, STRING},
|
SyntaxKind::{RAW_STRING, STRING},
|
||||||
TextUnit,
|
TextSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Assist, AssistCtx, AssistId};
|
use crate::{Assist, AssistCtx, AssistId};
|
||||||
|
@ -81,7 +81,7 @@ pub(crate) fn add_hash(ctx: AssistCtx) -> Option<Assist> {
|
||||||
let token = ctx.find_token_at_offset(RAW_STRING)?;
|
let token = ctx.find_token_at_offset(RAW_STRING)?;
|
||||||
ctx.add_assist(AssistId("add_hash"), "Add # to raw string", |edit| {
|
ctx.add_assist(AssistId("add_hash"), "Add # to raw string", |edit| {
|
||||||
edit.target(token.text_range());
|
edit.target(token.text_range());
|
||||||
edit.insert(token.text_range().start() + TextUnit::of_char('r'), "#");
|
edit.insert(token.text_range().start() + TextSize::of('r'), "#");
|
||||||
edit.insert(token.text_range().end(), "#");
|
edit.insert(token.text_range().end(), "#");
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
ast::{self, AstNode},
|
ast::{self, AstNode},
|
||||||
TextUnit, T,
|
TextSize, T,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Assist, AssistCtx, AssistId};
|
use crate::{Assist, AssistCtx, AssistId};
|
||||||
|
@ -38,9 +38,9 @@ pub(crate) fn remove_dbg(ctx: AssistCtx) -> Option<Assist> {
|
||||||
let offset_start = file_range
|
let offset_start = file_range
|
||||||
.start()
|
.start()
|
||||||
.checked_sub(macro_range.start())
|
.checked_sub(macro_range.start())
|
||||||
.unwrap_or_else(|| TextUnit::from(0));
|
.unwrap_or_else(|| TextSize::from(0));
|
||||||
|
|
||||||
let dbg_size = TextUnit::of_str("dbg!(");
|
let dbg_size = TextSize::of("dbg!(");
|
||||||
|
|
||||||
if offset_start > dbg_size {
|
if offset_start > dbg_size {
|
||||||
file_range.start() - dbg_size
|
file_range.start() - dbg_size
|
||||||
|
@ -53,7 +53,7 @@ pub(crate) fn remove_dbg(ctx: AssistCtx) -> Option<Assist> {
|
||||||
let macro_args = macro_call.token_tree()?.syntax().clone();
|
let macro_args = macro_call.token_tree()?.syntax().clone();
|
||||||
|
|
||||||
let text = macro_args.text();
|
let text = macro_args.text();
|
||||||
let without_parens = TextUnit::of_char('(')..text.len() - TextUnit::of_char(')');
|
let without_parens = TextSize::of('(')..text.len() - TextSize::of(')');
|
||||||
text.slice(without_parens).to_string()
|
text.slice(without_parens).to_string()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,6 @@ pub(crate) fn remove_mut(ctx: AssistCtx) -> Option<Assist> {
|
||||||
|
|
||||||
ctx.add_assist(AssistId("remove_mut"), "Remove `mut` keyword", |edit| {
|
ctx.add_assist(AssistId("remove_mut"), "Remove `mut` keyword", |edit| {
|
||||||
edit.set_cursor(delete_from);
|
edit.set_cursor(delete_from);
|
||||||
edit.delete(TextRange::from_to(delete_from, delete_to));
|
edit.delete(TextRange::new(delete_from, delete_to));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ pub(crate) fn replace_qualified_name_with_use(ctx: AssistCtx) -> Option<Assist>
|
||||||
if let Some(last) = path.segment() {
|
if let Some(last) = path.segment() {
|
||||||
// Here we are assuming the assist will provide a correct use statement
|
// Here we are assuming the assist will provide a correct use statement
|
||||||
// so we can delete the path qualifier
|
// so we can delete the path qualifier
|
||||||
edit.delete(TextRange::from_to(
|
edit.delete(TextRange::new(
|
||||||
path.syntax().text_range().start(),
|
path.syntax().text_range().start(),
|
||||||
last.syntax().text_range().start(),
|
last.syntax().text_range().start(),
|
||||||
));
|
));
|
||||||
|
|
|
@ -19,7 +19,7 @@ pub mod ast_transform;
|
||||||
|
|
||||||
use ra_db::{FileId, FileRange};
|
use ra_db::{FileId, FileRange};
|
||||||
use ra_ide_db::RootDatabase;
|
use ra_ide_db::RootDatabase;
|
||||||
use ra_syntax::{TextRange, TextUnit};
|
use ra_syntax::{TextRange, TextSize};
|
||||||
use ra_text_edit::TextEdit;
|
use ra_text_edit::TextEdit;
|
||||||
|
|
||||||
pub(crate) use crate::assist_ctx::{Assist, AssistCtx, AssistHandler};
|
pub(crate) use crate::assist_ctx::{Assist, AssistCtx, AssistHandler};
|
||||||
|
@ -51,7 +51,7 @@ impl AssistLabel {
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct AssistAction {
|
pub struct AssistAction {
|
||||||
pub edit: TextEdit,
|
pub edit: TextEdit,
|
||||||
pub cursor_position: Option<TextUnit>,
|
pub cursor_position: Option<TextSize>,
|
||||||
// FIXME: This belongs to `AssistLabel`
|
// FIXME: This belongs to `AssistLabel`
|
||||||
pub target: Option<TextRange>,
|
pub target: Option<TextRange>,
|
||||||
pub file: AssistFile,
|
pub file: AssistFile,
|
||||||
|
@ -104,7 +104,7 @@ pub fn resolved_assists(db: &RootDatabase, range: FileRange) -> Vec<ResolvedAssi
|
||||||
.flat_map(|it| it.0)
|
.flat_map(|it| it.0)
|
||||||
.map(|it| it.into_resolved().unwrap())
|
.map(|it| it.into_resolved().unwrap())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
a.sort_by_key(|it| it.action.target.map_or(TextUnit::from(!0u32), |it| it.len()));
|
a.sort_by_key(|it| it.action.target.map_or(TextSize::from(!0u32), |it| it.len()));
|
||||||
a
|
a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ pub mod fixture;
|
||||||
use std::{panic, sync::Arc};
|
use std::{panic, sync::Arc};
|
||||||
|
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
use ra_syntax::{ast, Parse, SourceFile, TextRange, TextUnit};
|
use ra_syntax::{ast, Parse, SourceFile, TextRange, TextSize};
|
||||||
|
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
cancellation::Canceled,
|
cancellation::Canceled,
|
||||||
|
@ -75,7 +75,7 @@ impl<T: salsa::Database> CheckCanceled for T {
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct FilePosition {
|
pub struct FilePosition {
|
||||||
pub file_id: FileId,
|
pub file_id: FileId,
|
||||||
pub offset: TextUnit,
|
pub offset: TextSize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
|
|
@ -14,7 +14,7 @@ use ra_db::{FileId, FileRange};
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
algo::{find_node_at_offset, skip_trivia_token},
|
algo::{find_node_at_offset, skip_trivia_token},
|
||||||
ast, AstNode, Direction, SyntaxNode, SyntaxToken, TextRange, TextUnit,
|
ast, AstNode, Direction, SyntaxNode, SyntaxToken, TextRange, TextSize,
|
||||||
};
|
};
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
|
||||||
let token = successors(Some(parent.with_value(token)), |token| {
|
let token = successors(Some(parent.with_value(token)), |token| {
|
||||||
let macro_call = token.value.ancestors().find_map(ast::MacroCall::cast)?;
|
let macro_call = token.value.ancestors().find_map(ast::MacroCall::cast)?;
|
||||||
let tt = macro_call.token_tree()?;
|
let tt = macro_call.token_tree()?;
|
||||||
if !token.value.text_range().is_subrange(&tt.syntax().text_range()) {
|
if !tt.syntax().text_range().contains_range(token.value.text_range()) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let file_id = sa.expand(self.db, token.with_value(¯o_call))?;
|
let file_id = sa.expand(self.db, token.with_value(¯o_call))?;
|
||||||
|
@ -114,7 +114,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
|
||||||
pub fn descend_node_at_offset<N: ast::AstNode>(
|
pub fn descend_node_at_offset<N: ast::AstNode>(
|
||||||
&self,
|
&self,
|
||||||
node: &SyntaxNode,
|
node: &SyntaxNode,
|
||||||
offset: TextUnit,
|
offset: TextSize,
|
||||||
) -> Option<N> {
|
) -> Option<N> {
|
||||||
// Handle macro token cases
|
// Handle macro token cases
|
||||||
node.token_at_offset(offset)
|
node.token_at_offset(offset)
|
||||||
|
@ -142,7 +142,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
|
||||||
pub fn ancestors_at_offset_with_macros(
|
pub fn ancestors_at_offset_with_macros(
|
||||||
&self,
|
&self,
|
||||||
node: &SyntaxNode,
|
node: &SyntaxNode,
|
||||||
offset: TextUnit,
|
offset: TextSize,
|
||||||
) -> impl Iterator<Item = SyntaxNode> + '_ {
|
) -> impl Iterator<Item = SyntaxNode> + '_ {
|
||||||
node.token_at_offset(offset)
|
node.token_at_offset(offset)
|
||||||
.map(|token| self.ancestors_with_macros(token.parent()))
|
.map(|token| self.ancestors_with_macros(token.parent()))
|
||||||
|
@ -154,7 +154,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
|
||||||
pub fn find_node_at_offset_with_macros<N: AstNode>(
|
pub fn find_node_at_offset_with_macros<N: AstNode>(
|
||||||
&self,
|
&self,
|
||||||
node: &SyntaxNode,
|
node: &SyntaxNode,
|
||||||
offset: TextUnit,
|
offset: TextSize,
|
||||||
) -> Option<N> {
|
) -> Option<N> {
|
||||||
self.ancestors_at_offset_with_macros(node, offset).find_map(N::cast)
|
self.ancestors_at_offset_with_macros(node, offset).find_map(N::cast)
|
||||||
}
|
}
|
||||||
|
@ -164,7 +164,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
|
||||||
pub fn find_node_at_offset_with_descend<N: AstNode>(
|
pub fn find_node_at_offset_with_descend<N: AstNode>(
|
||||||
&self,
|
&self,
|
||||||
node: &SyntaxNode,
|
node: &SyntaxNode,
|
||||||
offset: TextUnit,
|
offset: TextSize,
|
||||||
) -> Option<N> {
|
) -> Option<N> {
|
||||||
if let Some(it) = find_node_at_offset(&node, offset) {
|
if let Some(it) = find_node_at_offset(&node, offset) {
|
||||||
return Some(it);
|
return Some(it);
|
||||||
|
@ -255,7 +255,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
|
||||||
SemanticsScope { db: self.db, resolver }
|
SemanticsScope { db: self.db, resolver }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scope_at_offset(&self, node: &SyntaxNode, offset: TextUnit) -> SemanticsScope<'db, DB> {
|
pub fn scope_at_offset(&self, node: &SyntaxNode, offset: TextSize) -> SemanticsScope<'db, DB> {
|
||||||
let node = self.find_file(node.clone());
|
let node = self.find_file(node.clone());
|
||||||
let resolver = self.analyze2(node.as_ref(), Some(offset)).resolver;
|
let resolver = self.analyze2(node.as_ref(), Some(offset)).resolver;
|
||||||
SemanticsScope { db: self.db, resolver }
|
SemanticsScope { db: self.db, resolver }
|
||||||
|
@ -271,7 +271,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
|
||||||
self.analyze2(src.as_ref(), None)
|
self.analyze2(src.as_ref(), None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn analyze2(&self, src: InFile<&SyntaxNode>, offset: Option<TextUnit>) -> SourceAnalyzer {
|
fn analyze2(&self, src: InFile<&SyntaxNode>, offset: Option<TextSize>) -> SourceAnalyzer {
|
||||||
let _p = profile("Semantics::analyze2");
|
let _p = profile("Semantics::analyze2");
|
||||||
|
|
||||||
let container = match self.with_ctx(|ctx| ctx.find_container(src)) {
|
let container = match self.with_ctx(|ctx| ctx.find_container(src)) {
|
||||||
|
@ -463,7 +463,7 @@ fn original_range_opt(
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(first.with_value(first.value.text_range().extend_to(&last.value.text_range())))
|
Some(first.with_value(first.value.text_range().cover(last.value.text_range())))
|
||||||
})?)
|
})?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ use hir_ty::{
|
||||||
};
|
};
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
ast::{self, AstNode},
|
ast::{self, AstNode},
|
||||||
SyntaxNode, TextRange, TextUnit,
|
SyntaxNode, TextRange, TextSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -50,7 +50,7 @@ impl SourceAnalyzer {
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
def: DefWithBodyId,
|
def: DefWithBodyId,
|
||||||
node: InFile<&SyntaxNode>,
|
node: InFile<&SyntaxNode>,
|
||||||
offset: Option<TextUnit>,
|
offset: Option<TextSize>,
|
||||||
) -> SourceAnalyzer {
|
) -> SourceAnalyzer {
|
||||||
let (body, source_map) = db.body_with_source_map(def);
|
let (body, source_map) = db.body_with_source_map(def);
|
||||||
let scopes = db.expr_scopes(def);
|
let scopes = db.expr_scopes(def);
|
||||||
|
@ -318,7 +318,7 @@ fn scope_for_offset(
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
scopes: &ExprScopes,
|
scopes: &ExprScopes,
|
||||||
source_map: &BodySourceMap,
|
source_map: &BodySourceMap,
|
||||||
offset: InFile<TextUnit>,
|
offset: InFile<TextSize>,
|
||||||
) -> Option<ScopeId> {
|
) -> Option<ScopeId> {
|
||||||
scopes
|
scopes
|
||||||
.scope_by_expr()
|
.scope_by_expr()
|
||||||
|
@ -354,7 +354,7 @@ fn adjust(
|
||||||
source_map: &BodySourceMap,
|
source_map: &BodySourceMap,
|
||||||
expr_range: TextRange,
|
expr_range: TextRange,
|
||||||
file_id: HirFileId,
|
file_id: HirFileId,
|
||||||
offset: TextUnit,
|
offset: TextSize,
|
||||||
) -> Option<ScopeId> {
|
) -> Option<ScopeId> {
|
||||||
let child_scopes = scopes
|
let child_scopes = scopes
|
||||||
.scope_by_expr()
|
.scope_by_expr()
|
||||||
|
@ -369,15 +369,15 @@ fn adjust(
|
||||||
let node = source.value.to_node(&root);
|
let node = source.value.to_node(&root);
|
||||||
Some((node.syntax().text_range(), scope))
|
Some((node.syntax().text_range(), scope))
|
||||||
})
|
})
|
||||||
.filter(|(range, _)| {
|
.filter(|&(range, _)| {
|
||||||
range.start() <= offset && range.is_subrange(&expr_range) && *range != expr_range
|
range.start() <= offset && expr_range.contains_range(range) && range != expr_range
|
||||||
});
|
});
|
||||||
|
|
||||||
child_scopes
|
child_scopes
|
||||||
.max_by(|(r1, _), (r2, _)| {
|
.max_by(|&(r1, _), &(r2, _)| {
|
||||||
if r2.is_subrange(&r1) {
|
if r1.contains_range(r2) {
|
||||||
std::cmp::Ordering::Greater
|
std::cmp::Ordering::Greater
|
||||||
} else if r1.is_subrange(&r2) {
|
} else if r2.contains_range(r1) {
|
||||||
std::cmp::Ordering::Less
|
std::cmp::Ordering::Less
|
||||||
} else {
|
} else {
|
||||||
r1.start().cmp(&r2.start())
|
r1.start().cmp(&r2.start())
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use crate::db::AstDatabase;
|
use crate::db::AstDatabase;
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{self, AstToken, HasStringValue},
|
ast::{self, AstToken, HasStringValue},
|
||||||
name, AstId, CrateId, MacroDefId, MacroDefKind, TextUnit,
|
name, AstId, CrateId, MacroDefId, MacroDefKind, TextSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{quote, EagerMacroId, LazyMacroId, MacroCallId};
|
use crate::{quote, EagerMacroId, LazyMacroId, MacroCallId};
|
||||||
|
@ -127,7 +127,7 @@ fn stringify_expand(
|
||||||
let arg = loc.kind.arg(db).ok_or_else(|| mbe::ExpandError::UnexpectedToken)?;
|
let arg = loc.kind.arg(db).ok_or_else(|| mbe::ExpandError::UnexpectedToken)?;
|
||||||
let macro_args = arg;
|
let macro_args = arg;
|
||||||
let text = macro_args.text();
|
let text = macro_args.text();
|
||||||
let without_parens = TextUnit::of_char('(')..text.len() - TextUnit::of_char(')');
|
let without_parens = TextSize::of('(')..text.len() - TextSize::of(')');
|
||||||
text.slice(without_parens).to_string()
|
text.slice(without_parens).to_string()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ use ra_db::{impl_intern_key, salsa, CrateId, FileId};
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
algo,
|
algo,
|
||||||
ast::{self, AstNode},
|
ast::{self, AstNode},
|
||||||
SyntaxNode, SyntaxToken, TextUnit,
|
SyntaxNode, SyntaxToken, TextSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::ast_id_map::FileAstId;
|
use crate::ast_id_map::FileAstId;
|
||||||
|
@ -348,7 +348,7 @@ impl<N: AstNode> AstId<N> {
|
||||||
///
|
///
|
||||||
/// * `InFile<SyntaxNode>` -- syntax node in a file
|
/// * `InFile<SyntaxNode>` -- syntax node in a file
|
||||||
/// * `InFile<ast::FnDef>` -- ast node in a file
|
/// * `InFile<ast::FnDef>` -- ast node in a file
|
||||||
/// * `InFile<TextUnit>` -- offset in a file
|
/// * `InFile<TextSize>` -- offset in a file
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
|
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
|
||||||
pub struct InFile<T> {
|
pub struct InFile<T> {
|
||||||
pub file_id: HirFileId,
|
pub file_id: HirFileId,
|
||||||
|
|
|
@ -117,7 +117,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
|
||||||
let macro_prefix = if node.file_id != file_id.into() { "!" } else { "" };
|
let macro_prefix = if node.file_id != file_id.into() { "!" } else { "" };
|
||||||
format_to!(
|
format_to!(
|
||||||
buf,
|
buf,
|
||||||
"{}{} '{}': {}\n",
|
"{}{:?} '{}': {}\n",
|
||||||
macro_prefix,
|
macro_prefix,
|
||||||
range,
|
range,
|
||||||
ellipsize(text, 15),
|
ellipsize(text, 15),
|
||||||
|
@ -134,7 +134,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
|
||||||
let macro_prefix = if src_ptr.file_id != file_id.into() { "!" } else { "" };
|
let macro_prefix = if src_ptr.file_id != file_id.into() { "!" } else { "" };
|
||||||
format_to!(
|
format_to!(
|
||||||
buf,
|
buf,
|
||||||
"{}{}: expected {}, got {}\n",
|
"{}{:?}: expected {}, got {}\n",
|
||||||
macro_prefix,
|
macro_prefix,
|
||||||
range,
|
range,
|
||||||
mismatch.expected.display(&db),
|
mismatch.expected.display(&db),
|
||||||
|
|
|
@ -126,7 +126,7 @@ impl FnCallNode {
|
||||||
ast::CallExpr(it) => Some(FnCallNode::CallExpr(it)),
|
ast::CallExpr(it) => Some(FnCallNode::CallExpr(it)),
|
||||||
ast::MethodCallExpr(it) => {
|
ast::MethodCallExpr(it) => {
|
||||||
let arg_list = it.arg_list()?;
|
let arg_list = it.arg_list()?;
|
||||||
if !syntax.text_range().is_subrange(&arg_list.syntax().text_range()) {
|
if !arg_list.syntax().text_range().contains_range(syntax.text_range()) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
Some(FnCallNode::MethodCallExpr(it))
|
Some(FnCallNode::MethodCallExpr(it))
|
||||||
|
|
|
@ -97,7 +97,7 @@ fn is_in_loop_body(leaf: &SyntaxToken) -> bool {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if let Some(body) = loop_body {
|
if let Some(body) = loop_body {
|
||||||
if leaf.text_range().is_subrange(&body.syntax().text_range()) {
|
if body.syntax().text_range().contains_range(leaf.text_range()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
ast::{self, AstNode},
|
ast::{self, AstNode},
|
||||||
TextRange, TextUnit,
|
TextRange, TextSize,
|
||||||
};
|
};
|
||||||
use ra_text_edit::TextEdit;
|
use ra_text_edit::TextEdit;
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
|
||||||
fn get_receiver_text(receiver: &ast::Expr, receiver_is_ambiguous_float_literal: bool) -> String {
|
fn get_receiver_text(receiver: &ast::Expr, receiver_is_ambiguous_float_literal: bool) -> String {
|
||||||
if receiver_is_ambiguous_float_literal {
|
if receiver_is_ambiguous_float_literal {
|
||||||
let text = receiver.syntax().text();
|
let text = receiver.syntax().text();
|
||||||
let without_dot = ..text.len() - TextUnit::of_char('.');
|
let without_dot = ..text.len() - TextSize::of('.');
|
||||||
text.slice(without_dot).to_string()
|
text.slice(without_dot).to_string()
|
||||||
} else {
|
} else {
|
||||||
receiver.to_string()
|
receiver.to_string()
|
||||||
|
@ -143,7 +143,7 @@ fn postfix_snippet(
|
||||||
let edit = {
|
let edit = {
|
||||||
let receiver_syntax = receiver.syntax();
|
let receiver_syntax = receiver.syntax();
|
||||||
let receiver_range = ctx.sema.original_range(receiver_syntax).range;
|
let receiver_range = ctx.sema.original_range(receiver_syntax).range;
|
||||||
let delete_range = TextRange::from_to(receiver_range.start(), ctx.source_range().end());
|
let delete_range = TextRange::new(receiver_range.start(), ctx.source_range().end());
|
||||||
TextEdit::replace(delete_range, snippet.to_string())
|
TextEdit::replace(delete_range, snippet.to_string())
|
||||||
};
|
};
|
||||||
CompletionItem::new(CompletionKind::Postfix, ctx.source_range(), label)
|
CompletionItem::new(CompletionKind::Postfix, ctx.source_range(), label)
|
||||||
|
|
|
@ -141,7 +141,7 @@ fn add_function_impl(
|
||||||
} else {
|
} else {
|
||||||
CompletionItemKind::Function
|
CompletionItemKind::Function
|
||||||
};
|
};
|
||||||
let range = TextRange::from_to(fn_def_node.text_range().start(), ctx.source_range().end());
|
let range = TextRange::new(fn_def_node.text_range().start(), ctx.source_range().end());
|
||||||
|
|
||||||
match ctx.config.snippet_cap {
|
match ctx.config.snippet_cap {
|
||||||
Some(cap) => {
|
Some(cap) => {
|
||||||
|
@ -167,7 +167,7 @@ fn add_type_alias_impl(
|
||||||
|
|
||||||
let snippet = format!("type {} = ", alias_name);
|
let snippet = format!("type {} = ", alias_name);
|
||||||
|
|
||||||
let range = TextRange::from_to(type_def_node.text_range().start(), ctx.source_range().end());
|
let range = TextRange::new(type_def_node.text_range().start(), ctx.source_range().end());
|
||||||
|
|
||||||
CompletionItem::new(CompletionKind::Magic, ctx.source_range(), snippet.clone())
|
CompletionItem::new(CompletionKind::Magic, ctx.source_range(), snippet.clone())
|
||||||
.text_edit(TextEdit::replace(range, snippet))
|
.text_edit(TextEdit::replace(range, snippet))
|
||||||
|
@ -189,7 +189,7 @@ fn add_const_impl(
|
||||||
let snippet = make_const_compl_syntax(&const_.source(ctx.db).value);
|
let snippet = make_const_compl_syntax(&const_.source(ctx.db).value);
|
||||||
|
|
||||||
let range =
|
let range =
|
||||||
TextRange::from_to(const_def_node.text_range().start(), ctx.source_range().end());
|
TextRange::new(const_def_node.text_range().start(), ctx.source_range().end());
|
||||||
|
|
||||||
CompletionItem::new(CompletionKind::Magic, ctx.source_range(), snippet.clone())
|
CompletionItem::new(CompletionKind::Magic, ctx.source_range(), snippet.clone())
|
||||||
.text_edit(TextEdit::replace(range, snippet))
|
.text_edit(TextEdit::replace(range, snippet))
|
||||||
|
@ -216,7 +216,7 @@ fn make_const_compl_syntax(const_: &ast::ConstDef) -> String {
|
||||||
.map_or(const_end, |f| f.text_range().start());
|
.map_or(const_end, |f| f.text_range().start());
|
||||||
|
|
||||||
let len = end - start;
|
let len = end - start;
|
||||||
let range = TextRange::from_to(0.into(), len);
|
let range = TextRange::new(0.into(), len);
|
||||||
|
|
||||||
let syntax = const_.syntax().text().slice(range).to_string();
|
let syntax = const_.syntax().text().slice(range).to_string();
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ use ra_syntax::{
|
||||||
algo::{find_covering_element, find_node_at_offset},
|
algo::{find_covering_element, find_node_at_offset},
|
||||||
ast, AstNode,
|
ast, AstNode,
|
||||||
SyntaxKind::*,
|
SyntaxKind::*,
|
||||||
SyntaxNode, SyntaxToken, TextRange, TextUnit,
|
SyntaxNode, SyntaxToken, TextRange, TextSize,
|
||||||
};
|
};
|
||||||
use ra_text_edit::AtomTextEdit;
|
use ra_text_edit::AtomTextEdit;
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ pub(crate) struct CompletionContext<'a> {
|
||||||
pub(super) sema: Semantics<'a, RootDatabase>,
|
pub(super) sema: Semantics<'a, RootDatabase>,
|
||||||
pub(super) db: &'a RootDatabase,
|
pub(super) db: &'a RootDatabase,
|
||||||
pub(super) config: &'a CompletionConfig,
|
pub(super) config: &'a CompletionConfig,
|
||||||
pub(super) offset: TextUnit,
|
pub(super) offset: TextSize,
|
||||||
/// The token before the cursor, in the original file.
|
/// The token before the cursor, in the original file.
|
||||||
pub(super) original_token: SyntaxToken,
|
pub(super) original_token: SyntaxToken,
|
||||||
/// The token before the cursor, in the macro-expanded file.
|
/// The token before the cursor, in the macro-expanded file.
|
||||||
|
@ -167,7 +167,7 @@ impl<'a> CompletionContext<'a> {
|
||||||
match self.token.kind() {
|
match self.token.kind() {
|
||||||
// workaroud when completion is triggered by trigger characters.
|
// workaroud when completion is triggered by trigger characters.
|
||||||
IDENT => self.original_token.text_range(),
|
IDENT => self.original_token.text_range(),
|
||||||
_ => TextRange::offset_len(self.offset, 0.into()),
|
_ => TextRange::empty(self.offset),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ impl<'a> CompletionContext<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
original_file: &SyntaxNode,
|
original_file: &SyntaxNode,
|
||||||
file_with_fake_ident: SyntaxNode,
|
file_with_fake_ident: SyntaxNode,
|
||||||
offset: TextUnit,
|
offset: TextSize,
|
||||||
) {
|
) {
|
||||||
// First, let's try to complete a reference to some declaration.
|
// First, let's try to complete a reference to some declaration.
|
||||||
if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(&file_with_fake_ident, offset) {
|
if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(&file_with_fake_ident, offset) {
|
||||||
|
@ -224,7 +224,8 @@ impl<'a> CompletionContext<'a> {
|
||||||
}
|
}
|
||||||
if let Some(let_stmt) = bind_pat.syntax().ancestors().find_map(ast::LetStmt::cast) {
|
if let Some(let_stmt) = bind_pat.syntax().ancestors().find_map(ast::LetStmt::cast) {
|
||||||
if let Some(pat) = let_stmt.pat() {
|
if let Some(pat) = let_stmt.pat() {
|
||||||
if bind_pat.syntax().text_range().is_subrange(&pat.syntax().text_range()) {
|
if pat.syntax().text_range().contains_range(bind_pat.syntax().text_range())
|
||||||
|
{
|
||||||
self.is_pat_binding_or_const = false;
|
self.is_pat_binding_or_const = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -246,7 +247,7 @@ impl<'a> CompletionContext<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
original_file: &SyntaxNode,
|
original_file: &SyntaxNode,
|
||||||
name_ref: ast::NameRef,
|
name_ref: ast::NameRef,
|
||||||
offset: TextUnit,
|
offset: TextSize,
|
||||||
) {
|
) {
|
||||||
self.name_ref_syntax =
|
self.name_ref_syntax =
|
||||||
find_node_at_offset(&original_file, name_ref.syntax().text_range().start());
|
find_node_at_offset(&original_file, name_ref.syntax().text_range().start());
|
||||||
|
|
|
@ -171,7 +171,7 @@ fn text_edit_for_remove_unnecessary_braces_with_self_in_use_statement(
|
||||||
if single_use_tree.path()?.segment()?.syntax().first_child_or_token()?.kind() == T![self] {
|
if single_use_tree.path()?.segment()?.syntax().first_child_or_token()?.kind() == T![self] {
|
||||||
let start = use_tree_list_node.prev_sibling_or_token()?.text_range().start();
|
let start = use_tree_list_node.prev_sibling_or_token()?.text_range().start();
|
||||||
let end = use_tree_list_node.text_range().end();
|
let end = use_tree_list_node.text_range().end();
|
||||||
let range = TextRange::from_to(start, end);
|
let range = TextRange::new(start, end);
|
||||||
return Some(TextEdit::delete(range));
|
return Some(TextEdit::delete(range));
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
|
|
|
@ -9,7 +9,7 @@ use ra_syntax::{
|
||||||
ast::{self, AstNode, AstToken},
|
ast::{self, AstNode, AstToken},
|
||||||
Direction, NodeOrToken,
|
Direction, NodeOrToken,
|
||||||
SyntaxKind::{self, *},
|
SyntaxKind::{self, *},
|
||||||
SyntaxNode, SyntaxToken, TextRange, TextUnit, TokenAtOffset, T,
|
SyntaxNode, SyntaxToken, TextRange, TextSize, TokenAtOffset, T,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::FileRange;
|
use crate::FileRange;
|
||||||
|
@ -121,10 +121,10 @@ fn extend_tokens_from_range(
|
||||||
let mut first_token = skip_trivia_token(first_token, Direction::Next)?;
|
let mut first_token = skip_trivia_token(first_token, Direction::Next)?;
|
||||||
let mut last_token = skip_trivia_token(last_token, Direction::Prev)?;
|
let mut last_token = skip_trivia_token(last_token, Direction::Prev)?;
|
||||||
|
|
||||||
while !first_token.text_range().is_subrange(&original_range) {
|
while !original_range.contains_range(first_token.text_range()) {
|
||||||
first_token = skip_trivia_token(first_token.next_token()?, Direction::Next)?;
|
first_token = skip_trivia_token(first_token.next_token()?, Direction::Next)?;
|
||||||
}
|
}
|
||||||
while !last_token.text_range().is_subrange(&original_range) {
|
while !original_range.contains_range(last_token.text_range()) {
|
||||||
last_token = skip_trivia_token(last_token.prev_token()?, Direction::Prev)?;
|
last_token = skip_trivia_token(last_token.prev_token()?, Direction::Prev)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,8 +161,8 @@ fn extend_tokens_from_range(
|
||||||
.take_while(validate)
|
.take_while(validate)
|
||||||
.last()?;
|
.last()?;
|
||||||
|
|
||||||
let range = first.text_range().extend_to(&last.text_range());
|
let range = first.text_range().cover(last.text_range());
|
||||||
if original_range.is_subrange(&range) && original_range != range {
|
if range.contains_range(original_range) && original_range != range {
|
||||||
Some(range)
|
Some(range)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -176,7 +176,7 @@ fn shallowest_node(node: &SyntaxNode) -> SyntaxNode {
|
||||||
|
|
||||||
fn extend_single_word_in_comment_or_string(
|
fn extend_single_word_in_comment_or_string(
|
||||||
leaf: &SyntaxToken,
|
leaf: &SyntaxToken,
|
||||||
offset: TextUnit,
|
offset: TextSize,
|
||||||
) -> Option<TextRange> {
|
) -> Option<TextRange> {
|
||||||
let text: &str = leaf.text();
|
let text: &str = leaf.text();
|
||||||
let cursor_position: u32 = (offset - leaf.text_range().start()).into();
|
let cursor_position: u32 = (offset - leaf.text_range().start()).into();
|
||||||
|
@ -190,10 +190,10 @@ fn extend_single_word_in_comment_or_string(
|
||||||
let start_idx = before.rfind(non_word_char)? as u32;
|
let start_idx = before.rfind(non_word_char)? as u32;
|
||||||
let end_idx = after.find(non_word_char).unwrap_or_else(|| after.len()) as u32;
|
let end_idx = after.find(non_word_char).unwrap_or_else(|| after.len()) as u32;
|
||||||
|
|
||||||
let from: TextUnit = (start_idx + 1).into();
|
let from: TextSize = (start_idx + 1).into();
|
||||||
let to: TextUnit = (cursor_position + end_idx).into();
|
let to: TextSize = (cursor_position + end_idx).into();
|
||||||
|
|
||||||
let range = TextRange::from_to(from, to);
|
let range = TextRange::new(from, to);
|
||||||
if range.is_empty() {
|
if range.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
@ -201,24 +201,24 @@ fn extend_single_word_in_comment_or_string(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extend_ws(root: &SyntaxNode, ws: SyntaxToken, offset: TextUnit) -> TextRange {
|
fn extend_ws(root: &SyntaxNode, ws: SyntaxToken, offset: TextSize) -> TextRange {
|
||||||
let ws_text = ws.text();
|
let ws_text = ws.text();
|
||||||
let suffix = TextRange::from_to(offset, ws.text_range().end()) - ws.text_range().start();
|
let suffix = TextRange::new(offset, ws.text_range().end()) - ws.text_range().start();
|
||||||
let prefix = TextRange::from_to(ws.text_range().start(), offset) - ws.text_range().start();
|
let prefix = TextRange::new(ws.text_range().start(), offset) - ws.text_range().start();
|
||||||
let ws_suffix = &ws_text.as_str()[suffix];
|
let ws_suffix = &ws_text.as_str()[suffix];
|
||||||
let ws_prefix = &ws_text.as_str()[prefix];
|
let ws_prefix = &ws_text.as_str()[prefix];
|
||||||
if ws_text.contains('\n') && !ws_suffix.contains('\n') {
|
if ws_text.contains('\n') && !ws_suffix.contains('\n') {
|
||||||
if let Some(node) = ws.next_sibling_or_token() {
|
if let Some(node) = ws.next_sibling_or_token() {
|
||||||
let start = match ws_prefix.rfind('\n') {
|
let start = match ws_prefix.rfind('\n') {
|
||||||
Some(idx) => ws.text_range().start() + TextUnit::from((idx + 1) as u32),
|
Some(idx) => ws.text_range().start() + TextSize::from((idx + 1) as u32),
|
||||||
None => node.text_range().start(),
|
None => node.text_range().start(),
|
||||||
};
|
};
|
||||||
let end = if root.text().char_at(node.text_range().end()) == Some('\n') {
|
let end = if root.text().char_at(node.text_range().end()) == Some('\n') {
|
||||||
node.text_range().end() + TextUnit::of_char('\n')
|
node.text_range().end() + TextSize::of('\n')
|
||||||
} else {
|
} else {
|
||||||
node.text_range().end()
|
node.text_range().end()
|
||||||
};
|
};
|
||||||
return TextRange::from_to(start, end);
|
return TextRange::new(start, end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ws.text_range()
|
ws.text_range()
|
||||||
|
@ -270,13 +270,10 @@ fn extend_list_item(node: &SyntaxNode) -> Option<TextRange> {
|
||||||
.filter(|node| is_single_line_ws(node))
|
.filter(|node| is_single_line_ws(node))
|
||||||
.unwrap_or(delimiter_node);
|
.unwrap_or(delimiter_node);
|
||||||
|
|
||||||
return Some(TextRange::from_to(node.text_range().start(), final_node.text_range().end()));
|
return Some(TextRange::new(node.text_range().start(), final_node.text_range().end()));
|
||||||
}
|
}
|
||||||
if let Some(delimiter_node) = nearby_delimiter(delimiter, node, Direction::Prev) {
|
if let Some(delimiter_node) = nearby_delimiter(delimiter, node, Direction::Prev) {
|
||||||
return Some(TextRange::from_to(
|
return Some(TextRange::new(delimiter_node.text_range().start(), node.text_range().end()));
|
||||||
delimiter_node.text_range().start(),
|
|
||||||
node.text_range().end(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
|
@ -286,10 +283,7 @@ fn extend_comments(comment: ast::Comment) -> Option<TextRange> {
|
||||||
let prev = adj_comments(&comment, Direction::Prev);
|
let prev = adj_comments(&comment, Direction::Prev);
|
||||||
let next = adj_comments(&comment, Direction::Next);
|
let next = adj_comments(&comment, Direction::Next);
|
||||||
if prev != next {
|
if prev != next {
|
||||||
Some(TextRange::from_to(
|
Some(TextRange::new(prev.syntax().text_range().start(), next.syntax().text_range().end()))
|
||||||
prev.syntax().text_range().start(),
|
|
||||||
next.syntax().text_range().end(),
|
|
||||||
))
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,7 +141,7 @@ fn contiguous_range_for_group_unless(
|
||||||
}
|
}
|
||||||
|
|
||||||
if first != &last {
|
if first != &last {
|
||||||
Some(TextRange::from_to(first.text_range().start(), last.text_range().end()))
|
Some(TextRange::new(first.text_range().start(), last.text_range().end()))
|
||||||
} else {
|
} else {
|
||||||
// The group consists of only one element, therefore it cannot be folded
|
// The group consists of only one element, therefore it cannot be folded
|
||||||
None
|
None
|
||||||
|
@ -187,7 +187,7 @@ fn contiguous_range_for_comment(
|
||||||
}
|
}
|
||||||
|
|
||||||
if first != last {
|
if first != last {
|
||||||
Some(TextRange::from_to(
|
Some(TextRange::new(
|
||||||
first.syntax().text_range().start(),
|
first.syntax().text_range().start(),
|
||||||
last.syntax().text_range().end(),
|
last.syntax().text_range().end(),
|
||||||
))
|
))
|
||||||
|
|
|
@ -275,7 +275,7 @@ mod tests {
|
||||||
",
|
",
|
||||||
);
|
);
|
||||||
let hover = analysis.hover(position).unwrap().unwrap();
|
let hover = analysis.hover(position).unwrap().unwrap();
|
||||||
assert_eq!(hover.range, TextRange::from_to(95.into(), 100.into()));
|
assert_eq!(hover.range, TextRange::new(95.into(), 100.into()));
|
||||||
assert_eq!(trim_markup_opt(hover.info.first()), Some("u32"));
|
assert_eq!(trim_markup_opt(hover.info.first()), Some("u32"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ use ra_syntax::{
|
||||||
ast::{self, AstNode, AstToken},
|
ast::{self, AstNode, AstToken},
|
||||||
Direction, NodeOrToken, SourceFile,
|
Direction, NodeOrToken, SourceFile,
|
||||||
SyntaxKind::{self, WHITESPACE},
|
SyntaxKind::{self, WHITESPACE},
|
||||||
SyntaxNode, SyntaxToken, TextRange, TextUnit, T,
|
SyntaxNode, SyntaxToken, TextRange, TextSize, T,
|
||||||
};
|
};
|
||||||
use ra_text_edit::{TextEdit, TextEditBuilder};
|
use ra_text_edit::{TextEdit, TextEditBuilder};
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ pub fn join_lines(file: &SourceFile, range: TextRange) -> TextEdit {
|
||||||
None => return TextEditBuilder::default().finish(),
|
None => return TextEditBuilder::default().finish(),
|
||||||
Some(pos) => pos,
|
Some(pos) => pos,
|
||||||
};
|
};
|
||||||
TextRange::offset_len(range.start() + pos, TextUnit::of_char('\n'))
|
TextRange::at(range.start() + pos, TextSize::of('\n'))
|
||||||
} else {
|
} else {
|
||||||
range
|
range
|
||||||
};
|
};
|
||||||
|
@ -30,13 +30,13 @@ pub fn join_lines(file: &SourceFile, range: TextRange) -> TextEdit {
|
||||||
};
|
};
|
||||||
let mut edit = TextEditBuilder::default();
|
let mut edit = TextEditBuilder::default();
|
||||||
for token in node.descendants_with_tokens().filter_map(|it| it.into_token()) {
|
for token in node.descendants_with_tokens().filter_map(|it| it.into_token()) {
|
||||||
let range = match range.intersection(&token.text_range()) {
|
let range = match range.intersect(token.text_range()) {
|
||||||
Some(range) => range,
|
Some(range) => range,
|
||||||
None => continue,
|
None => continue,
|
||||||
} - token.text_range().start();
|
} - token.text_range().start();
|
||||||
let text = token.text();
|
let text = token.text();
|
||||||
for (pos, _) in text[range].bytes().enumerate().filter(|&(_, b)| b == b'\n') {
|
for (pos, _) in text[range].bytes().enumerate().filter(|&(_, b)| b == b'\n') {
|
||||||
let pos: TextUnit = (pos as u32).into();
|
let pos: TextSize = (pos as u32).into();
|
||||||
let off = token.text_range().start() + range.start() + pos;
|
let off = token.text_range().start() + range.start() + pos;
|
||||||
if !edit.invalidates_offset(off) {
|
if !edit.invalidates_offset(off) {
|
||||||
remove_newline(&mut edit, &token, off);
|
remove_newline(&mut edit, &token, off);
|
||||||
|
@ -47,16 +47,16 @@ pub fn join_lines(file: &SourceFile, range: TextRange) -> TextEdit {
|
||||||
edit.finish()
|
edit.finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_newline(edit: &mut TextEditBuilder, token: &SyntaxToken, offset: TextUnit) {
|
fn remove_newline(edit: &mut TextEditBuilder, token: &SyntaxToken, offset: TextSize) {
|
||||||
if token.kind() != WHITESPACE || token.text().bytes().filter(|&b| b == b'\n').count() != 1 {
|
if token.kind() != WHITESPACE || token.text().bytes().filter(|&b| b == b'\n').count() != 1 {
|
||||||
// The node is either the first or the last in the file
|
// The node is either the first or the last in the file
|
||||||
let suff = &token.text()[TextRange::from_to(
|
let suff = &token.text()[TextRange::new(
|
||||||
offset - token.text_range().start() + TextUnit::of_char('\n'),
|
offset - token.text_range().start() + TextSize::of('\n'),
|
||||||
TextUnit::of_str(token.text()),
|
TextSize::of(token.text().as_str()),
|
||||||
)];
|
)];
|
||||||
let spaces = suff.bytes().take_while(|&b| b == b' ').count();
|
let spaces = suff.bytes().take_while(|&b| b == b' ').count();
|
||||||
|
|
||||||
edit.replace(TextRange::offset_len(offset, ((spaces + 1) as u32).into()), " ".to_string());
|
edit.replace(TextRange::at(offset, ((spaces + 1) as u32).into()), " ".to_string());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ fn remove_newline(edit: &mut TextEditBuilder, token: &SyntaxToken, offset: TextU
|
||||||
let next = token.next_sibling_or_token().unwrap();
|
let next = token.next_sibling_or_token().unwrap();
|
||||||
if is_trailing_comma(prev.kind(), next.kind()) {
|
if is_trailing_comma(prev.kind(), next.kind()) {
|
||||||
// Removes: trailing comma, newline (incl. surrounding whitespace)
|
// Removes: trailing comma, newline (incl. surrounding whitespace)
|
||||||
edit.delete(TextRange::from_to(prev.text_range().start(), token.text_range().end()));
|
edit.delete(TextRange::new(prev.text_range().start(), token.text_range().end()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if prev.kind() == T![,] && next.kind() == T!['}'] {
|
if prev.kind() == T![,] && next.kind() == T!['}'] {
|
||||||
|
@ -76,7 +76,7 @@ fn remove_newline(edit: &mut TextEditBuilder, token: &SyntaxToken, offset: TextU
|
||||||
" "
|
" "
|
||||||
};
|
};
|
||||||
edit.replace(
|
edit.replace(
|
||||||
TextRange::from_to(prev.text_range().start(), token.text_range().end()),
|
TextRange::new(prev.text_range().start(), token.text_range().end()),
|
||||||
space.to_string(),
|
space.to_string(),
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -87,9 +87,9 @@ fn remove_newline(edit: &mut TextEditBuilder, token: &SyntaxToken, offset: TextU
|
||||||
next.as_token().cloned().and_then(ast::Comment::cast),
|
next.as_token().cloned().and_then(ast::Comment::cast),
|
||||||
) {
|
) {
|
||||||
// Removes: newline (incl. surrounding whitespace), start of the next comment
|
// Removes: newline (incl. surrounding whitespace), start of the next comment
|
||||||
edit.delete(TextRange::from_to(
|
edit.delete(TextRange::new(
|
||||||
token.text_range().start(),
|
token.text_range().start(),
|
||||||
next.syntax().text_range().start() + TextUnit::of_str(next.prefix()),
|
next.syntax().text_range().start() + TextSize::of(next.prefix()),
|
||||||
));
|
));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -420,10 +420,10 @@ fn foo() {
|
||||||
check_join_lines(
|
check_join_lines(
|
||||||
r"
|
r"
|
||||||
<|>use ra_syntax::{
|
<|>use ra_syntax::{
|
||||||
TextUnit, TextRange,
|
TextSize, TextRange,
|
||||||
};",
|
};",
|
||||||
r"
|
r"
|
||||||
<|>use ra_syntax::{TextUnit, TextRange,
|
<|>use ra_syntax::{TextSize, TextRange,
|
||||||
};",
|
};",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -434,11 +434,11 @@ fn foo() {
|
||||||
check_join_lines(
|
check_join_lines(
|
||||||
r"
|
r"
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
<|> TextUnit, TextRange
|
<|> TextSize, TextRange
|
||||||
};",
|
};",
|
||||||
r"
|
r"
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
<|> TextUnit, TextRange};",
|
<|> TextSize, TextRange};",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -448,11 +448,11 @@ use ra_syntax::{
|
||||||
check_join_lines(
|
check_join_lines(
|
||||||
r"
|
r"
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
<|> TextUnit, TextRange,
|
<|> TextSize, TextRange,
|
||||||
};",
|
};",
|
||||||
r"
|
r"
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
<|> TextUnit, TextRange};",
|
<|> TextSize, TextRange};",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ use ra_ide_db::{
|
||||||
symbol_index::{self, FileSymbol},
|
symbol_index::{self, FileSymbol},
|
||||||
LineIndexDatabase,
|
LineIndexDatabase,
|
||||||
};
|
};
|
||||||
use ra_syntax::{SourceFile, TextRange, TextUnit};
|
use ra_syntax::{SourceFile, TextRange, TextSize};
|
||||||
|
|
||||||
use crate::display::ToNav;
|
use crate::display::ToNav;
|
||||||
|
|
||||||
|
@ -265,7 +265,7 @@ impl Analysis {
|
||||||
|
|
||||||
/// Returns position of the matching brace (all types of braces are
|
/// Returns position of the matching brace (all types of braces are
|
||||||
/// supported).
|
/// supported).
|
||||||
pub fn matching_brace(&self, position: FilePosition) -> Cancelable<Option<TextUnit>> {
|
pub fn matching_brace(&self, position: FilePosition) -> Cancelable<Option<TextSize>> {
|
||||||
self.with_db(|db| {
|
self.with_db(|db| {
|
||||||
let parse = db.parse(position.file_id);
|
let parse = db.parse(position.file_id);
|
||||||
let file = parse.tree();
|
let file = parse.tree();
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
//! FIXME: write short doc here
|
//! FIXME: write short doc here
|
||||||
|
|
||||||
use ra_syntax::{ast::AstNode, SourceFile, SyntaxKind, TextUnit, T};
|
use ra_syntax::{ast::AstNode, SourceFile, SyntaxKind, TextSize, T};
|
||||||
|
|
||||||
pub fn matching_brace(file: &SourceFile, offset: TextUnit) -> Option<TextUnit> {
|
pub fn matching_brace(file: &SourceFile, offset: TextSize) -> Option<TextSize> {
|
||||||
const BRACES: &[SyntaxKind] =
|
const BRACES: &[SyntaxKind] =
|
||||||
&[T!['{'], T!['}'], T!['['], T![']'], T!['('], T![')'], T![<], T![>]];
|
&[T!['{'], T!['}'], T!['['], T![']'], T!['('], T![')'], T![<], T![>]];
|
||||||
let (brace_node, brace_idx) = file
|
let (brace_node, brace_idx) = file
|
||||||
|
|
|
@ -54,7 +54,7 @@ fn source_edit_from_reference(reference: Reference, new_name: &str) -> SourceFil
|
||||||
ReferenceKind::StructFieldShorthandForField => {
|
ReferenceKind::StructFieldShorthandForField => {
|
||||||
replacement_text.push_str(new_name);
|
replacement_text.push_str(new_name);
|
||||||
replacement_text.push_str(": ");
|
replacement_text.push_str(": ");
|
||||||
TextRange::from_to(
|
TextRange::new(
|
||||||
reference.file_range.range.start(),
|
reference.file_range.range.start(),
|
||||||
reference.file_range.range.start(),
|
reference.file_range.range.start(),
|
||||||
)
|
)
|
||||||
|
@ -62,7 +62,7 @@ fn source_edit_from_reference(reference: Reference, new_name: &str) -> SourceFil
|
||||||
ReferenceKind::StructFieldShorthandForLocal => {
|
ReferenceKind::StructFieldShorthandForLocal => {
|
||||||
replacement_text.push_str(": ");
|
replacement_text.push_str(": ");
|
||||||
replacement_text.push_str(new_name);
|
replacement_text.push_str(new_name);
|
||||||
TextRange::from_to(reference.file_range.range.end(), reference.file_range.range.end())
|
TextRange::new(reference.file_range.range.end(), reference.file_range.range.end())
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
replacement_text.push_str(new_name);
|
replacement_text.push_str(new_name);
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
use ra_db::RelativePathBuf;
|
use ra_db::RelativePathBuf;
|
||||||
use ra_text_edit::TextEdit;
|
use ra_text_edit::TextEdit;
|
||||||
|
|
||||||
use crate::{FileId, FilePosition, SourceRootId, TextUnit};
|
use crate::{FileId, FilePosition, SourceRootId, TextSize};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SourceChange {
|
pub struct SourceChange {
|
||||||
|
@ -104,7 +104,7 @@ pub enum FileSystemEdit {
|
||||||
pub(crate) struct SingleFileChange {
|
pub(crate) struct SingleFileChange {
|
||||||
pub label: String,
|
pub label: String,
|
||||||
pub edit: TextEdit,
|
pub edit: TextEdit,
|
||||||
pub cursor_position: Option<TextUnit>,
|
pub cursor_position: Option<TextSize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SingleFileChange {
|
impl SingleFileChange {
|
||||||
|
|
|
@ -61,16 +61,16 @@ impl HighlightedRangeStack {
|
||||||
let prev = self.stack.last_mut().unwrap();
|
let prev = self.stack.last_mut().unwrap();
|
||||||
let needs_flattening = !children.is_empty()
|
let needs_flattening = !children.is_empty()
|
||||||
&& !prev.is_empty()
|
&& !prev.is_empty()
|
||||||
&& children.first().unwrap().range.is_subrange(&prev.last().unwrap().range);
|
&& prev.last().unwrap().range.contains_range(children.first().unwrap().range);
|
||||||
if !needs_flattening {
|
if !needs_flattening {
|
||||||
prev.extend(children);
|
prev.extend(children);
|
||||||
} else {
|
} else {
|
||||||
let mut parent = prev.pop().unwrap();
|
let mut parent = prev.pop().unwrap();
|
||||||
for ele in children {
|
for ele in children {
|
||||||
assert!(ele.range.is_subrange(&parent.range));
|
assert!(parent.range.contains_range(ele.range));
|
||||||
let mut cloned = parent.clone();
|
let mut cloned = parent.clone();
|
||||||
parent.range = TextRange::from_to(parent.range.start(), ele.range.start());
|
parent.range = TextRange::new(parent.range.start(), ele.range.start());
|
||||||
cloned.range = TextRange::from_to(ele.range.end(), cloned.range.end());
|
cloned.range = TextRange::new(ele.range.end(), cloned.range.end());
|
||||||
if !parent.range.is_empty() {
|
if !parent.range.is_empty() {
|
||||||
prev.push(parent);
|
prev.push(parent);
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ pub(crate) fn highlight(
|
||||||
};
|
};
|
||||||
|
|
||||||
// Element outside of the viewport, no need to highlight
|
// Element outside of the viewport, no need to highlight
|
||||||
if range_to_highlight.intersection(&event_range).is_none() {
|
if range_to_highlight.intersect(event_range).is_none() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,7 +309,7 @@ fn macro_call_range(macro_call: &ast::MacroCall) -> Option<TextRange> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(TextRange::from_to(range_start, range_end))
|
Some(TextRange::new(range_start, range_end))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn highlight_element(
|
fn highlight_element(
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! Renders a bit of code as HTML.
|
//! Renders a bit of code as HTML.
|
||||||
|
|
||||||
use ra_db::SourceDatabase;
|
use ra_db::SourceDatabase;
|
||||||
use ra_syntax::{AstNode, TextUnit};
|
use ra_syntax::{AstNode, TextSize};
|
||||||
|
|
||||||
use crate::{FileId, RootDatabase};
|
use crate::{FileId, RootDatabase};
|
||||||
|
|
||||||
|
@ -23,17 +23,18 @@ pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: boo
|
||||||
|
|
||||||
let ranges = highlight(db, file_id, None);
|
let ranges = highlight(db, file_id, None);
|
||||||
let text = parse.tree().syntax().to_string();
|
let text = parse.tree().syntax().to_string();
|
||||||
let mut prev_pos = TextUnit::from(0);
|
let mut prev_pos = TextSize::from(0);
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
buf.push_str(&STYLE);
|
buf.push_str(&STYLE);
|
||||||
buf.push_str("<pre><code>");
|
buf.push_str("<pre><code>");
|
||||||
|
// TODO: unusize
|
||||||
for range in &ranges {
|
for range in &ranges {
|
||||||
if range.range.start() > prev_pos {
|
if range.range.start() > prev_pos {
|
||||||
let curr = &text[prev_pos.to_usize()..range.range.start().to_usize()];
|
let curr = &text[usize::from(prev_pos)..usize::from(range.range.start())];
|
||||||
let text = html_escape(curr);
|
let text = html_escape(curr);
|
||||||
buf.push_str(&text);
|
buf.push_str(&text);
|
||||||
}
|
}
|
||||||
let curr = &text[range.range.start().to_usize()..range.range.end().to_usize()];
|
let curr = &text[usize::from(range.range.start())..usize::from(range.range.end())];
|
||||||
|
|
||||||
let class = range.highlight.to_string().replace('.', " ");
|
let class = range.highlight.to_string().replace('.', " ");
|
||||||
let color = match (rainbow, range.binding_hash) {
|
let color = match (rainbow, range.binding_hash) {
|
||||||
|
@ -47,7 +48,7 @@ pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: boo
|
||||||
prev_pos = range.range.end();
|
prev_pos = range.range.end();
|
||||||
}
|
}
|
||||||
// Add the remaining (non-highlighted) text
|
// Add the remaining (non-highlighted) text
|
||||||
let curr = &text[prev_pos.to_usize()..];
|
let curr = &text[usize::from(prev_pos)..];
|
||||||
let text = html_escape(curr);
|
let text = html_escape(curr);
|
||||||
buf.push_str(&text);
|
buf.push_str(&text);
|
||||||
buf.push_str("</code></pre>");
|
buf.push_str("</code></pre>");
|
||||||
|
|
|
@ -5,7 +5,7 @@ use ra_ide_db::RootDatabase;
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
algo, AstNode, NodeOrToken, SourceFile,
|
algo, AstNode, NodeOrToken, SourceFile,
|
||||||
SyntaxKind::{RAW_STRING, STRING},
|
SyntaxKind::{RAW_STRING, STRING},
|
||||||
SyntaxToken, TextRange, TextUnit,
|
SyntaxToken, TextRange, TextSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use ra_db::FileId;
|
pub use ra_db::FileId;
|
||||||
|
@ -66,13 +66,13 @@ fn syntax_tree_for_token(node: &SyntaxToken, text_range: TextRange) -> Option<St
|
||||||
let len = len.min(node_len);
|
let len = len.min(node_len);
|
||||||
|
|
||||||
// Ensure our slice is inside the actual string
|
// Ensure our slice is inside the actual string
|
||||||
let end = if start + len < TextUnit::of_str(&text) {
|
let end = if start + len < TextSize::of(&text) {
|
||||||
start + len
|
start + len
|
||||||
} else {
|
} else {
|
||||||
TextUnit::of_str(&text) - start
|
TextSize::of(&text) - start
|
||||||
};
|
};
|
||||||
|
|
||||||
let text = &text[TextRange::from_to(start, end)];
|
let text = &text[TextRange::new(start, end)];
|
||||||
|
|
||||||
// Remove possible extra string quotes from the start
|
// Remove possible extra string quotes from the start
|
||||||
// and the end of the string
|
// and the end of the string
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
//! FIXME: write short doc here
|
//! FIXME: write short doc here
|
||||||
|
|
||||||
use ra_syntax::{SourceFile, TextUnit};
|
use ra_syntax::{SourceFile, TextSize};
|
||||||
use ra_text_edit::TextEdit;
|
use ra_text_edit::TextEdit;
|
||||||
|
|
||||||
pub use test_utils::*;
|
pub use test_utils::*;
|
||||||
|
|
||||||
pub fn check_action<F: Fn(&SourceFile, TextUnit) -> Option<TextEdit>>(
|
pub fn check_action<F: Fn(&SourceFile, TextSize) -> Option<TextEdit>>(
|
||||||
before: &str,
|
before: &str,
|
||||||
after: &str,
|
after: &str,
|
||||||
f: F,
|
f: F,
|
||||||
|
|
|
@ -21,7 +21,7 @@ use ra_ide_db::RootDatabase;
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
algo::find_node_at_offset,
|
algo::find_node_at_offset,
|
||||||
ast::{self, AstToken},
|
ast::{self, AstToken},
|
||||||
AstNode, SourceFile, TextRange, TextUnit,
|
AstNode, SourceFile, TextRange, TextSize,
|
||||||
};
|
};
|
||||||
use ra_text_edit::TextEdit;
|
use ra_text_edit::TextEdit;
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ pub(crate) fn on_char_typed(
|
||||||
|
|
||||||
fn on_char_typed_inner(
|
fn on_char_typed_inner(
|
||||||
file: &SourceFile,
|
file: &SourceFile,
|
||||||
offset: TextUnit,
|
offset: TextSize,
|
||||||
char_typed: char,
|
char_typed: char,
|
||||||
) -> Option<SingleFileChange> {
|
) -> Option<SingleFileChange> {
|
||||||
assert!(TRIGGER_CHARS.contains(char_typed));
|
assert!(TRIGGER_CHARS.contains(char_typed));
|
||||||
|
@ -60,7 +60,7 @@ fn on_char_typed_inner(
|
||||||
/// Returns an edit which should be applied after `=` was typed. Primarily,
|
/// Returns an edit which should be applied after `=` was typed. Primarily,
|
||||||
/// this works when adding `let =`.
|
/// this works when adding `let =`.
|
||||||
// FIXME: use a snippet completion instead of this hack here.
|
// FIXME: use a snippet completion instead of this hack here.
|
||||||
fn on_eq_typed(file: &SourceFile, offset: TextUnit) -> Option<SingleFileChange> {
|
fn on_eq_typed(file: &SourceFile, offset: TextSize) -> Option<SingleFileChange> {
|
||||||
assert_eq!(file.syntax().text().char_at(offset), Some('='));
|
assert_eq!(file.syntax().text().char_at(offset), Some('='));
|
||||||
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.semicolon_token().is_some() {
|
if let_stmt.semicolon_token().is_some() {
|
||||||
|
@ -86,7 +86,7 @@ fn on_eq_typed(file: &SourceFile, offset: TextUnit) -> Option<SingleFileChange>
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an edit which should be applied when a dot ('.') is typed on a blank line, indenting the line appropriately.
|
/// Returns an edit which should be applied when a dot ('.') is typed on a blank line, indenting the line appropriately.
|
||||||
fn on_dot_typed(file: &SourceFile, offset: TextUnit) -> Option<SingleFileChange> {
|
fn on_dot_typed(file: &SourceFile, offset: TextSize) -> Option<SingleFileChange> {
|
||||||
assert_eq!(file.syntax().text().char_at(offset), Some('.'));
|
assert_eq!(file.syntax().text().char_at(offset), Some('.'));
|
||||||
let whitespace =
|
let whitespace =
|
||||||
file.syntax().token_at_offset(offset).left_biased().and_then(ast::Whitespace::cast)?;
|
file.syntax().token_at_offset(offset).left_biased().and_then(ast::Whitespace::cast)?;
|
||||||
|
@ -96,13 +96,13 @@ fn on_dot_typed(file: &SourceFile, offset: TextUnit) -> Option<SingleFileChange>
|
||||||
let newline = text.rfind('\n')?;
|
let newline = text.rfind('\n')?;
|
||||||
&text[newline + 1..]
|
&text[newline + 1..]
|
||||||
};
|
};
|
||||||
let current_indent_len = TextUnit::of_str(current_indent);
|
let current_indent_len = TextSize::of(current_indent);
|
||||||
|
|
||||||
// Make sure dot is a part of call chain
|
// Make sure dot is a part of call chain
|
||||||
let field_expr = ast::FieldExpr::cast(whitespace.syntax().parent())?;
|
let field_expr = ast::FieldExpr::cast(whitespace.syntax().parent())?;
|
||||||
let prev_indent = leading_indent(field_expr.syntax())?;
|
let prev_indent = leading_indent(field_expr.syntax())?;
|
||||||
let target_indent = format!(" {}", prev_indent);
|
let target_indent = format!(" {}", prev_indent);
|
||||||
let target_indent_len = TextUnit::of_str(&target_indent);
|
let target_indent_len = TextSize::of(&target_indent);
|
||||||
if current_indent_len == target_indent_len {
|
if current_indent_len == target_indent_len {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -110,20 +110,20 @@ fn on_dot_typed(file: &SourceFile, offset: TextUnit) -> Option<SingleFileChange>
|
||||||
Some(SingleFileChange {
|
Some(SingleFileChange {
|
||||||
label: "reindent dot".to_string(),
|
label: "reindent dot".to_string(),
|
||||||
edit: TextEdit::replace(
|
edit: TextEdit::replace(
|
||||||
TextRange::from_to(offset - current_indent_len, offset),
|
TextRange::new(offset - current_indent_len, offset),
|
||||||
target_indent,
|
target_indent,
|
||||||
),
|
),
|
||||||
cursor_position: Some(
|
cursor_position: Some(
|
||||||
offset + target_indent_len - current_indent_len + TextUnit::of_char('.'),
|
offset + target_indent_len - current_indent_len + TextSize::of('.'),
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a space after an arrow when `fn foo() { ... }` is turned into `fn foo() -> { ... }`
|
/// Adds a space after an arrow when `fn foo() { ... }` is turned into `fn foo() -> { ... }`
|
||||||
fn on_arrow_typed(file: &SourceFile, offset: TextUnit) -> Option<SingleFileChange> {
|
fn on_arrow_typed(file: &SourceFile, offset: TextSize) -> Option<SingleFileChange> {
|
||||||
let file_text = file.syntax().text();
|
let file_text = file.syntax().text();
|
||||||
assert_eq!(file_text.char_at(offset), Some('>'));
|
assert_eq!(file_text.char_at(offset), Some('>'));
|
||||||
let after_arrow = offset + TextUnit::of_char('>');
|
let after_arrow = offset + TextSize::of('>');
|
||||||
if file_text.char_at(after_arrow) != Some('{') {
|
if file_text.char_at(after_arrow) != Some('{') {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use ra_syntax::{
|
||||||
ast::{self, AstToken},
|
ast::{self, AstToken},
|
||||||
AstNode, SmolStr, SourceFile,
|
AstNode, SmolStr, SourceFile,
|
||||||
SyntaxKind::*,
|
SyntaxKind::*,
|
||||||
SyntaxToken, TextUnit, TokenAtOffset,
|
SyntaxToken, TextSize, TokenAtOffset,
|
||||||
};
|
};
|
||||||
use ra_text_edit::TextEdit;
|
use ra_text_edit::TextEdit;
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option<Sour
|
||||||
|
|
||||||
let prefix = comment.prefix();
|
let prefix = comment.prefix();
|
||||||
let comment_range = comment.syntax().text_range();
|
let comment_range = comment.syntax().text_range();
|
||||||
if position.offset < comment_range.start() + TextUnit::of_str(prefix) {
|
if position.offset < comment_range.start() + TextSize::of(prefix) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option<Sour
|
||||||
|
|
||||||
let indent = node_indent(&file, comment.syntax())?;
|
let indent = node_indent(&file, comment.syntax())?;
|
||||||
let inserted = format!("\n{}{} ", indent, prefix);
|
let inserted = format!("\n{}{} ", indent, prefix);
|
||||||
let cursor_position = position.offset + TextUnit::of_str(&inserted);
|
let cursor_position = position.offset + TextSize::of(&inserted);
|
||||||
let edit = TextEdit::insert(position.offset, inserted);
|
let edit = TextEdit::insert(position.offset, inserted);
|
||||||
|
|
||||||
Some(
|
Some(
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
//! `LineIndex` maps flat `TextUnit` offsets into `(Line, Column)`
|
//! `LineIndex` maps flat `TextSize` offsets into `(Line, Column)`
|
||||||
//! representation.
|
//! representation.
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
// TODO: un TextSize
|
||||||
use ra_syntax::{TextRange, TextUnit};
|
use ra_syntax::{TextRange, TextSize};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use superslice::Ext;
|
use superslice::Ext;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct LineIndex {
|
pub struct LineIndex {
|
||||||
pub(crate) newlines: Vec<TextUnit>,
|
pub(crate) newlines: Vec<TextSize>,
|
||||||
pub(crate) utf16_lines: FxHashMap<u32, Vec<Utf16Char>>,
|
pub(crate) utf16_lines: FxHashMap<u32, Vec<Utf16Char>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,12 +22,12 @@ pub struct LineCol {
|
||||||
|
|
||||||
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
||||||
pub(crate) struct Utf16Char {
|
pub(crate) struct Utf16Char {
|
||||||
pub(crate) start: TextUnit,
|
pub(crate) start: TextSize,
|
||||||
pub(crate) end: TextUnit,
|
pub(crate) end: TextSize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Utf16Char {
|
impl Utf16Char {
|
||||||
fn len(&self) -> TextUnit {
|
fn len(&self) -> TextSize {
|
||||||
self.end - self.start
|
self.end - self.start
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ impl LineIndex {
|
||||||
let mut curr_col = 0.into();
|
let mut curr_col = 0.into();
|
||||||
let mut line = 0;
|
let mut line = 0;
|
||||||
for c in text.chars() {
|
for c in text.chars() {
|
||||||
curr_row += TextUnit::of_char(c);
|
curr_row += TextSize::of(c);
|
||||||
if c == '\n' {
|
if c == '\n' {
|
||||||
newlines.push(curr_row);
|
newlines.push(curr_row);
|
||||||
|
|
||||||
|
@ -58,8 +58,8 @@ impl LineIndex {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let char_len = TextUnit::of_char(c);
|
let char_len = TextSize::of(c);
|
||||||
if char_len > TextUnit::from_usize(1) {
|
if char_len > TextSize::from_usize(1) {
|
||||||
utf16_chars.push(Utf16Char { start: curr_col, end: curr_col + char_len });
|
utf16_chars.push(Utf16Char { start: curr_col, end: curr_col + char_len });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ impl LineIndex {
|
||||||
LineIndex { newlines, utf16_lines }
|
LineIndex { newlines, utf16_lines }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn line_col(&self, offset: TextUnit) -> LineCol {
|
pub fn line_col(&self, offset: TextSize) -> LineCol {
|
||||||
let line = self.newlines.upper_bound(&offset) - 1;
|
let line = self.newlines.upper_bound(&offset) - 1;
|
||||||
let line_start_offset = self.newlines[line];
|
let line_start_offset = self.newlines[line];
|
||||||
let col = offset - line_start_offset;
|
let col = offset - line_start_offset;
|
||||||
|
@ -82,7 +82,7 @@ impl LineIndex {
|
||||||
LineCol { line: line as u32, col_utf16: self.utf8_to_utf16_col(line as u32, col) as u32 }
|
LineCol { line: line as u32, col_utf16: self.utf8_to_utf16_col(line as u32, col) as u32 }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn offset(&self, line_col: LineCol) -> TextUnit {
|
pub fn offset(&self, line_col: LineCol) -> TextSize {
|
||||||
//FIXME: return Result
|
//FIXME: return Result
|
||||||
let col = self.utf16_to_utf8_col(line_col.line, line_col.col_utf16);
|
let col = self.utf16_to_utf8_col(line_col.line, line_col.col_utf16);
|
||||||
self.newlines[line_col.line as usize] + col
|
self.newlines[line_col.line as usize] + col
|
||||||
|
@ -97,16 +97,16 @@ impl LineIndex {
|
||||||
|
|
||||||
all.clone()
|
all.clone()
|
||||||
.zip(all.skip(1))
|
.zip(all.skip(1))
|
||||||
.map(|(lo, hi)| TextRange::from_to(lo, hi))
|
.map(|(lo, hi)| TextRange::new(lo, hi))
|
||||||
.filter(|it| !it.is_empty())
|
.filter(|it| !it.is_empty())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn utf8_to_utf16_col(&self, line: u32, col: TextUnit) -> usize {
|
fn utf8_to_utf16_col(&self, line: u32, col: TextSize) -> usize {
|
||||||
if let Some(utf16_chars) = self.utf16_lines.get(&line) {
|
if let Some(utf16_chars) = self.utf16_lines.get(&line) {
|
||||||
let mut correction = 0;
|
let mut correction = 0;
|
||||||
for c in utf16_chars {
|
for c in utf16_chars {
|
||||||
if col >= c.end {
|
if col >= c.end {
|
||||||
correction += c.len().to_usize() - 1;
|
correction += usize::from(c.len()) - 1;
|
||||||
} else {
|
} else {
|
||||||
// From here on, all utf16 characters come *after* the character we are mapping,
|
// From here on, all utf16 characters come *after* the character we are mapping,
|
||||||
// so we don't need to take them into account
|
// so we don't need to take them into account
|
||||||
|
@ -114,18 +114,18 @@ impl LineIndex {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
col.to_usize() - correction
|
usize::from(col) - correction
|
||||||
} else {
|
} else {
|
||||||
col.to_usize()
|
usize::from(col)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn utf16_to_utf8_col(&self, line: u32, col: u32) -> TextUnit {
|
fn utf16_to_utf8_col(&self, line: u32, col: u32) -> TextSize {
|
||||||
let mut col: TextUnit = col.into();
|
let mut col: TextSize = col.into();
|
||||||
if let Some(utf16_chars) = self.utf16_lines.get(&line) {
|
if let Some(utf16_chars) = self.utf16_lines.get(&line) {
|
||||||
for c in utf16_chars {
|
for c in utf16_chars {
|
||||||
if col >= c.start {
|
if col >= c.start {
|
||||||
col += c.len() - TextUnit::from_usize(1);
|
col += c.len() - TextSize::from_usize(1);
|
||||||
} else {
|
} else {
|
||||||
// From here on, all utf16 characters come *after* the character we are mapping,
|
// From here on, all utf16 characters come *after* the character we are mapping,
|
||||||
// so we don't need to take them into account
|
// so we don't need to take them into account
|
||||||
|
@ -200,10 +200,10 @@ const C: char = 'メ';
|
||||||
assert_eq!(col_index.utf8_to_utf16_col(1, 22.into()), 20);
|
assert_eq!(col_index.utf8_to_utf16_col(1, 22.into()), 20);
|
||||||
|
|
||||||
// UTF-16 to UTF-8, no changes
|
// UTF-16 to UTF-8, no changes
|
||||||
assert_eq!(col_index.utf16_to_utf8_col(1, 15), TextUnit::from(15));
|
assert_eq!(col_index.utf16_to_utf8_col(1, 15), TextSize::from(15));
|
||||||
|
|
||||||
// UTF-16 to UTF-8
|
// UTF-16 to UTF-8
|
||||||
assert_eq!(col_index.utf16_to_utf8_col(1, 19), TextUnit::from(21));
|
assert_eq!(col_index.utf16_to_utf8_col(1, 19), TextSize::from(21));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -228,18 +228,18 @@ const C: char = \"メ メ\";
|
||||||
assert!(col_index.utf8_to_utf16_col(2, 15.into()) == 15);
|
assert!(col_index.utf8_to_utf16_col(2, 15.into()) == 15);
|
||||||
|
|
||||||
// UTF-16 to UTF-8
|
// UTF-16 to UTF-8
|
||||||
assert_eq!(col_index.utf16_to_utf8_col(1, 15), TextUnit::from_usize(15));
|
assert_eq!(col_index.utf16_to_utf8_col(1, 15), TextSize::from_usize(15));
|
||||||
|
|
||||||
assert_eq!(col_index.utf16_to_utf8_col(1, 18), TextUnit::from_usize(20));
|
assert_eq!(col_index.utf16_to_utf8_col(1, 18), TextSize::from_usize(20));
|
||||||
assert_eq!(col_index.utf16_to_utf8_col(1, 19), TextUnit::from_usize(23));
|
assert_eq!(col_index.utf16_to_utf8_col(1, 19), TextSize::from_usize(23));
|
||||||
|
|
||||||
assert_eq!(col_index.utf16_to_utf8_col(2, 15), TextUnit::from_usize(15));
|
assert_eq!(col_index.utf16_to_utf8_col(2, 15), TextSize::from_usize(15));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_splitlines() {
|
fn test_splitlines() {
|
||||||
fn r(lo: u32, hi: u32) -> TextRange {
|
fn r(lo: u32, hi: u32) -> TextRange {
|
||||||
TextRange::from_to(lo.into(), hi.into())
|
TextRange::new(lo.into(), hi.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
let text = "a\nbb\nccc\n";
|
let text = "a\nbb\nccc\n";
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
//! Code actions can specify desirable final position of the cursor.
|
//! Code actions can specify desirable final position of the cursor.
|
||||||
//!
|
//!
|
||||||
//! The position is specified as a `TextUnit` in the final file. We need to send
|
//! The position is specified as a `TextSize` in the final file. We need to send
|
||||||
//! it in `(Line, Column)` coordinate though. However, we only have a LineIndex
|
//! it in `(Line, Column)` coordinate though. However, we only have a LineIndex
|
||||||
//! for a file pre-edit!
|
//! for a file pre-edit!
|
||||||
//!
|
//!
|
||||||
//! Code in this module applies this "to (Line, Column) after edit"
|
//! Code in this module applies this "to (Line, Column) after edit"
|
||||||
//! transformation.
|
//! transformation.
|
||||||
|
|
||||||
use ra_syntax::{TextRange, TextUnit};
|
use ra_syntax::{TextRange, TextSize};
|
||||||
use ra_text_edit::{AtomTextEdit, TextEdit};
|
use ra_text_edit::{AtomTextEdit, TextEdit};
|
||||||
|
|
||||||
use crate::line_index::{LineCol, LineIndex, Utf16Char};
|
use crate::line_index::{LineCol, LineIndex, Utf16Char};
|
||||||
|
|
||||||
pub fn translate_offset_with_edit(
|
pub fn translate_offset_with_edit(
|
||||||
line_index: &LineIndex,
|
line_index: &LineIndex,
|
||||||
offset: TextUnit,
|
offset: TextSize,
|
||||||
text_edit: &TextEdit,
|
text_edit: &TextEdit,
|
||||||
) -> LineCol {
|
) -> LineCol {
|
||||||
let mut state = Edits::from_text_edit(&text_edit);
|
let mut state = Edits::from_text_edit(&text_edit);
|
||||||
|
@ -84,7 +84,7 @@ pub fn translate_offset_with_edit(
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
enum Step {
|
enum Step {
|
||||||
Newline(TextUnit),
|
Newline(TextSize),
|
||||||
Utf16Char(TextRange),
|
Utf16Char(TextRange),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ enum Step {
|
||||||
struct LineIndexStepIter<'a> {
|
struct LineIndexStepIter<'a> {
|
||||||
line_index: &'a LineIndex,
|
line_index: &'a LineIndex,
|
||||||
next_newline_idx: usize,
|
next_newline_idx: usize,
|
||||||
utf16_chars: Option<(TextUnit, std::slice::Iter<'a, Utf16Char>)>,
|
utf16_chars: Option<(TextSize, std::slice::Iter<'a, Utf16Char>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LineIndexStepIter<'_> {
|
impl LineIndexStepIter<'_> {
|
||||||
|
@ -111,7 +111,7 @@ impl Iterator for LineIndexStepIter<'_> {
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.and_then(|(newline, x)| {
|
.and_then(|(newline, x)| {
|
||||||
let x = x.next()?;
|
let x = x.next()?;
|
||||||
Some(Step::Utf16Char(TextRange::from_to(*newline + x.start, *newline + x.end)))
|
Some(Step::Utf16Char(TextRange::new(*newline + x.start, *newline + x.end)))
|
||||||
})
|
})
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
let next_newline = *self.line_index.newlines.get(self.next_newline_idx)?;
|
let next_newline = *self.line_index.newlines.get(self.next_newline_idx)?;
|
||||||
|
@ -129,7 +129,7 @@ impl Iterator for LineIndexStepIter<'_> {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct OffsetStepIter<'a> {
|
struct OffsetStepIter<'a> {
|
||||||
text: &'a str,
|
text: &'a str,
|
||||||
offset: TextUnit,
|
offset: TextSize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Iterator for OffsetStepIter<'_> {
|
impl Iterator for OffsetStepIter<'_> {
|
||||||
|
@ -140,15 +140,15 @@ impl Iterator for OffsetStepIter<'_> {
|
||||||
.char_indices()
|
.char_indices()
|
||||||
.filter_map(|(i, c)| {
|
.filter_map(|(i, c)| {
|
||||||
if c == '\n' {
|
if c == '\n' {
|
||||||
let next_offset = self.offset + TextUnit::from_usize(i + 1);
|
let next_offset = self.offset + TextSize::from_usize(i + 1);
|
||||||
let next = Step::Newline(next_offset);
|
let next = Step::Newline(next_offset);
|
||||||
Some((next, next_offset))
|
Some((next, next_offset))
|
||||||
} else {
|
} else {
|
||||||
let char_len = TextUnit::of_char(c);
|
let char_len = TextSize::of(c);
|
||||||
if char_len > TextUnit::from_usize(1) {
|
if char_len > TextSize::from_usize(1) {
|
||||||
let start = self.offset + TextUnit::from_usize(i);
|
let start = self.offset + TextSize::from_usize(i);
|
||||||
let end = start + char_len;
|
let end = start + char_len;
|
||||||
let next = Step::Utf16Char(TextRange::from_to(start, end));
|
let next = Step::Utf16Char(TextRange::new(start, end));
|
||||||
let next_offset = end;
|
let next_offset = end;
|
||||||
Some((next, next_offset))
|
Some((next, next_offset))
|
||||||
} else {
|
} else {
|
||||||
|
@ -157,7 +157,7 @@ impl Iterator for OffsetStepIter<'_> {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.next()?;
|
.next()?;
|
||||||
let next_idx = (next_offset - self.offset).to_usize();
|
let next_idx: usize = (next_offset - self.offset).into();
|
||||||
self.text = &self.text[next_idx..];
|
self.text = &self.text[next_idx..];
|
||||||
self.offset = next_offset;
|
self.offset = next_offset;
|
||||||
Some(next)
|
Some(next)
|
||||||
|
@ -195,7 +195,7 @@ impl<'a> Edits<'a> {
|
||||||
match self.edits.split_first() {
|
match self.edits.split_first() {
|
||||||
Some((next, rest)) => {
|
Some((next, rest)) => {
|
||||||
let delete = self.translate_range(next.delete);
|
let delete = self.translate_range(next.delete);
|
||||||
let diff = next.insert.len() as i64 - next.delete.len().to_usize() as i64;
|
let diff = next.insert.len() as i64 - usize::from(next.delete.len()) as i64;
|
||||||
self.current = Some(TranslatedEdit { delete, insert: &next.insert, diff });
|
self.current = Some(TranslatedEdit { delete, insert: &next.insert, diff });
|
||||||
self.edits = rest;
|
self.edits = rest;
|
||||||
}
|
}
|
||||||
|
@ -244,15 +244,15 @@ impl<'a> Edits<'a> {
|
||||||
} else {
|
} else {
|
||||||
let start = self.translate(range.start());
|
let start = self.translate(range.start());
|
||||||
let end = self.translate(range.end());
|
let end = self.translate(range.end());
|
||||||
TextRange::from_to(start, end)
|
TextRange::new(start, end)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn translate(&self, x: TextUnit) -> TextUnit {
|
fn translate(&self, x: TextSize) -> TextSize {
|
||||||
if self.acc_diff == 0 {
|
if self.acc_diff == 0 {
|
||||||
x
|
x
|
||||||
} else {
|
} else {
|
||||||
TextUnit::from((x.to_usize() as i64 + self.acc_diff) as u32)
|
TextSize::from((usize::from(x) as i64 + self.acc_diff) as u32)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,29 +271,29 @@ impl<'a> Edits<'a> {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct RunningLineCol {
|
struct RunningLineCol {
|
||||||
line: u32,
|
line: u32,
|
||||||
last_newline: TextUnit,
|
last_newline: TextSize,
|
||||||
col_adjust: TextUnit,
|
col_adjust: TextSize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RunningLineCol {
|
impl RunningLineCol {
|
||||||
fn new() -> RunningLineCol {
|
fn new() -> RunningLineCol {
|
||||||
RunningLineCol { line: 0, last_newline: TextUnit::from(0), col_adjust: TextUnit::from(0) }
|
RunningLineCol { line: 0, last_newline: TextSize::from(0), col_adjust: TextSize::from(0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_line_col(&self, offset: TextUnit) -> LineCol {
|
fn to_line_col(&self, offset: TextSize) -> LineCol {
|
||||||
LineCol {
|
LineCol {
|
||||||
line: self.line,
|
line: self.line,
|
||||||
col_utf16: ((offset - self.last_newline) - self.col_adjust).into(),
|
col_utf16: ((offset - self.last_newline) - self.col_adjust).into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_line(&mut self, newline: TextUnit) {
|
fn add_line(&mut self, newline: TextSize) {
|
||||||
self.line += 1;
|
self.line += 1;
|
||||||
self.last_newline = newline;
|
self.last_newline = newline;
|
||||||
self.col_adjust = TextUnit::from(0);
|
self.col_adjust = TextSize::from(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn adjust_col(&mut self, range: TextRange) {
|
fn adjust_col(&mut self, range: TextRange) {
|
||||||
self.col_adjust += range.len() - TextUnit::from(1);
|
self.col_adjust += range.len() - TextSize::from(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ use hir::{DefWithBody, HasSource, Module, ModuleSource, Semantics, Visibility};
|
||||||
use once_cell::unsync::Lazy;
|
use once_cell::unsync::Lazy;
|
||||||
use ra_db::{FileId, FileRange, SourceDatabaseExt};
|
use ra_db::{FileId, FileRange, SourceDatabaseExt};
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
use ra_syntax::{ast, match_ast, AstNode, TextRange, TextUnit};
|
use ra_syntax::{ast, match_ast, AstNode, TextRange, TextSize};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use test_utils::tested_by;
|
use test_utils::tested_by;
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ impl SearchScope {
|
||||||
match (r1, r2) {
|
match (r1, r2) {
|
||||||
(None, r) | (r, None) => Some(r),
|
(None, r) | (r, None) => Some(r),
|
||||||
(Some(r1), Some(r2)) => {
|
(Some(r1), Some(r2)) => {
|
||||||
let r = r1.intersection(&r2)?;
|
let r = r1.intersect(r2)?;
|
||||||
Some(Some(r))
|
Some(Some(r))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,14 +200,13 @@ impl Definition {
|
||||||
|
|
||||||
for (file_id, search_range) in search_scope {
|
for (file_id, search_range) in search_scope {
|
||||||
let text = db.file_text(file_id);
|
let text = db.file_text(file_id);
|
||||||
let search_range =
|
let search_range = search_range.unwrap_or(TextRange::up_to(TextSize::of(&text)));
|
||||||
search_range.unwrap_or(TextRange::offset_len(0.into(), TextUnit::of_str(&text)));
|
|
||||||
|
|
||||||
let sema = Semantics::new(db);
|
let sema = Semantics::new(db);
|
||||||
let tree = Lazy::new(|| sema.parse(file_id).syntax().clone());
|
let tree = Lazy::new(|| sema.parse(file_id).syntax().clone());
|
||||||
|
|
||||||
for (idx, _) in text.match_indices(pat) {
|
for (idx, _) in text.match_indices(pat) {
|
||||||
let offset = TextUnit::from_usize(idx);
|
let offset = TextSize::from_usize(idx);
|
||||||
if !search_range.contains_inclusive(offset) {
|
if !search_range.contains_inclusive(offset) {
|
||||||
tested_by!(search_filters_by_range; force);
|
tested_by!(search_filters_by_range; force);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -5,7 +5,7 @@ use ra_syntax::{
|
||||||
ast::{self, make::tokens::doc_comment},
|
ast::{self, make::tokens::doc_comment},
|
||||||
tokenize, AstToken, Parse, SmolStr, SyntaxKind,
|
tokenize, AstToken, Parse, SmolStr, SyntaxKind,
|
||||||
SyntaxKind::*,
|
SyntaxKind::*,
|
||||||
SyntaxNode, SyntaxToken, SyntaxTreeBuilder, TextRange, TextUnit, Token as RawToken, T,
|
SyntaxNode, SyntaxToken, SyntaxTreeBuilder, TextRange, TextSize, Token as RawToken, T,
|
||||||
};
|
};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use tt::buffer::{Cursor, TokenBuffer};
|
use tt::buffer::{Cursor, TokenBuffer};
|
||||||
|
@ -99,11 +99,11 @@ pub fn parse_to_token_tree(text: &str) -> Option<(tt::Subtree, TokenMap)> {
|
||||||
|
|
||||||
let mut conv = RawConvertor {
|
let mut conv = RawConvertor {
|
||||||
text,
|
text,
|
||||||
offset: TextUnit::default(),
|
offset: TextSize::default(),
|
||||||
inner: tokens.iter(),
|
inner: tokens.iter(),
|
||||||
id_alloc: TokenIdAlloc {
|
id_alloc: TokenIdAlloc {
|
||||||
map: Default::default(),
|
map: Default::default(),
|
||||||
global_offset: TextUnit::default(),
|
global_offset: TextSize::default(),
|
||||||
next_id: 0,
|
next_id: 0,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -227,7 +227,7 @@ fn convert_doc_comment(token: &ra_syntax::SyntaxToken) -> Option<Vec<tt::TokenTr
|
||||||
|
|
||||||
struct TokenIdAlloc {
|
struct TokenIdAlloc {
|
||||||
map: TokenMap,
|
map: TokenMap,
|
||||||
global_offset: TextUnit,
|
global_offset: TextSize,
|
||||||
next_id: u32,
|
next_id: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,7 +266,7 @@ impl TokenIdAlloc {
|
||||||
/// A Raw Token (straightly from lexer) convertor
|
/// A Raw Token (straightly from lexer) convertor
|
||||||
struct RawConvertor<'a> {
|
struct RawConvertor<'a> {
|
||||||
text: &'a str,
|
text: &'a str,
|
||||||
offset: TextUnit,
|
offset: TextSize,
|
||||||
id_alloc: TokenIdAlloc,
|
id_alloc: TokenIdAlloc,
|
||||||
inner: std::slice::Iter<'a, RawToken>,
|
inner: std::slice::Iter<'a, RawToken>,
|
||||||
}
|
}
|
||||||
|
@ -314,7 +314,7 @@ trait TokenConvertor {
|
||||||
}
|
}
|
||||||
|
|
||||||
result.push(if k.is_punct() {
|
result.push(if k.is_punct() {
|
||||||
assert_eq!(range.len().to_usize(), 1);
|
assert_eq!(range.len(), TextSize::of('.'));
|
||||||
let delim = match k {
|
let delim = match k {
|
||||||
T!['('] => Some((tt::DelimiterKind::Parenthesis, T![')'])),
|
T!['('] => Some((tt::DelimiterKind::Parenthesis, T![')'])),
|
||||||
T!['{'] => Some((tt::DelimiterKind::Brace, T!['}'])),
|
T!['{'] => Some((tt::DelimiterKind::Brace, T!['}'])),
|
||||||
|
@ -381,8 +381,8 @@ trait TokenConvertor {
|
||||||
k if k.is_keyword() => make_leaf!(Ident),
|
k if k.is_keyword() => make_leaf!(Ident),
|
||||||
k if k.is_literal() => make_leaf!(Literal),
|
k if k.is_literal() => make_leaf!(Literal),
|
||||||
LIFETIME => {
|
LIFETIME => {
|
||||||
let char_unit = TextUnit::from_usize(1);
|
let char_unit = TextSize::of('\'');
|
||||||
let r = TextRange::offset_len(range.start(), char_unit);
|
let r = TextRange::at(range.start(), char_unit);
|
||||||
let apostrophe = tt::Leaf::from(tt::Punct {
|
let apostrophe = tt::Leaf::from(tt::Punct {
|
||||||
char: '\'',
|
char: '\'',
|
||||||
spacing: tt::Spacing::Joint,
|
spacing: tt::Spacing::Joint,
|
||||||
|
@ -390,8 +390,7 @@ trait TokenConvertor {
|
||||||
});
|
});
|
||||||
result.push(apostrophe.into());
|
result.push(apostrophe.into());
|
||||||
|
|
||||||
let r =
|
let r = TextRange::at(range.start() + char_unit, range.len() - char_unit);
|
||||||
TextRange::offset_len(range.start() + char_unit, range.len() - char_unit);
|
|
||||||
let ident = tt::Leaf::from(tt::Ident {
|
let ident = tt::Leaf::from(tt::Ident {
|
||||||
text: SmolStr::new(&token.to_text()[1..]),
|
text: SmolStr::new(&token.to_text()[1..]),
|
||||||
id: self.id_alloc().alloc(r),
|
id: self.id_alloc().alloc(r),
|
||||||
|
@ -440,7 +439,7 @@ impl<'a> TokenConvertor for RawConvertor<'a> {
|
||||||
|
|
||||||
fn bump(&mut self) -> Option<(Self::Token, TextRange)> {
|
fn bump(&mut self) -> Option<(Self::Token, TextRange)> {
|
||||||
let token = self.inner.next()?;
|
let token = self.inner.next()?;
|
||||||
let range = TextRange::offset_len(self.offset, token.len);
|
let range = TextRange::at(self.offset, token.len);
|
||||||
self.offset += token.len;
|
self.offset += token.len;
|
||||||
|
|
||||||
Some(((*token, &self.text[range]), range))
|
Some(((*token, &self.text[range]), range))
|
||||||
|
@ -450,7 +449,7 @@ impl<'a> TokenConvertor for RawConvertor<'a> {
|
||||||
let token = self.inner.as_slice().get(0).cloned();
|
let token = self.inner.as_slice().get(0).cloned();
|
||||||
|
|
||||||
token.map(|it| {
|
token.map(|it| {
|
||||||
let range = TextRange::offset_len(self.offset, it.len);
|
let range = TextRange::at(self.offset, it.len);
|
||||||
(it, &self.text[range])
|
(it, &self.text[range])
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -464,11 +463,11 @@ struct Convertor {
|
||||||
id_alloc: TokenIdAlloc,
|
id_alloc: TokenIdAlloc,
|
||||||
current: Option<SyntaxToken>,
|
current: Option<SyntaxToken>,
|
||||||
range: TextRange,
|
range: TextRange,
|
||||||
punct_offset: Option<(SyntaxToken, TextUnit)>,
|
punct_offset: Option<(SyntaxToken, TextSize)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Convertor {
|
impl Convertor {
|
||||||
fn new(node: &SyntaxNode, global_offset: TextUnit) -> Convertor {
|
fn new(node: &SyntaxNode, global_offset: TextSize) -> Convertor {
|
||||||
Convertor {
|
Convertor {
|
||||||
id_alloc: { TokenIdAlloc { map: TokenMap::default(), global_offset, next_id: 0 } },
|
id_alloc: { TokenIdAlloc { map: TokenMap::default(), global_offset, next_id: 0 } },
|
||||||
current: node.first_token(),
|
current: node.first_token(),
|
||||||
|
@ -481,7 +480,7 @@ impl Convertor {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum SynToken {
|
enum SynToken {
|
||||||
Ordiniary(SyntaxToken),
|
Ordiniary(SyntaxToken),
|
||||||
Punch(SyntaxToken, TextUnit),
|
Punch(SyntaxToken, TextSize),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SynToken {
|
impl SynToken {
|
||||||
|
@ -500,7 +499,7 @@ impl SrcToken for SynToken {
|
||||||
fn to_char(&self) -> Option<char> {
|
fn to_char(&self) -> Option<char> {
|
||||||
match self {
|
match self {
|
||||||
SynToken::Ordiniary(_) => None,
|
SynToken::Ordiniary(_) => None,
|
||||||
SynToken::Punch(it, i) => it.text().chars().nth(i.to_usize()),
|
SynToken::Punch(it, i) => it.text().chars().nth((*i).into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn to_text(&self) -> SmolStr {
|
fn to_text(&self) -> SmolStr {
|
||||||
|
@ -516,26 +515,26 @@ impl TokenConvertor for Convertor {
|
||||||
|
|
||||||
fn bump(&mut self) -> Option<(Self::Token, TextRange)> {
|
fn bump(&mut self) -> Option<(Self::Token, TextRange)> {
|
||||||
if let Some((punct, offset)) = self.punct_offset.clone() {
|
if let Some((punct, offset)) = self.punct_offset.clone() {
|
||||||
if offset.to_usize() + 1 < punct.text().len() {
|
if usize::from(offset) + 1 < punct.text().len() {
|
||||||
let offset = offset + TextUnit::from_usize(1);
|
let offset = offset + TextSize::from_usize(1);
|
||||||
let range = punct.text_range();
|
let range = punct.text_range();
|
||||||
self.punct_offset = Some((punct.clone(), offset));
|
self.punct_offset = Some((punct.clone(), offset));
|
||||||
let range = TextRange::offset_len(range.start() + offset, TextUnit::from_usize(1));
|
let range = TextRange::at(range.start() + offset, TextSize::of('.'));
|
||||||
return Some((SynToken::Punch(punct, offset), range));
|
return Some((SynToken::Punch(punct, offset), range));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let curr = self.current.clone()?;
|
let curr = self.current.clone()?;
|
||||||
if !curr.text_range().is_subrange(&self.range) {
|
if !&self.range.contains_range(curr.text_range()) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
self.current = curr.next_token();
|
self.current = curr.next_token();
|
||||||
|
|
||||||
let token = if curr.kind().is_punct() {
|
let token = if curr.kind().is_punct() {
|
||||||
let range = curr.text_range();
|
let range = curr.text_range();
|
||||||
let range = TextRange::offset_len(range.start(), TextUnit::from_usize(1));
|
let range = TextRange::at(range.start(), TextSize::from_usize(1));
|
||||||
self.punct_offset = Some((curr.clone(), TextUnit::from_usize(0)));
|
self.punct_offset = Some((curr.clone(), TextSize::from_usize(0)));
|
||||||
(SynToken::Punch(curr, TextUnit::from_usize(0)), range)
|
(SynToken::Punch(curr, TextSize::from_usize(0)), range)
|
||||||
} else {
|
} else {
|
||||||
self.punct_offset = None;
|
self.punct_offset = None;
|
||||||
let range = curr.text_range();
|
let range = curr.text_range();
|
||||||
|
@ -547,19 +546,19 @@ impl TokenConvertor for Convertor {
|
||||||
|
|
||||||
fn peek(&self) -> Option<Self::Token> {
|
fn peek(&self) -> Option<Self::Token> {
|
||||||
if let Some((punct, mut offset)) = self.punct_offset.clone() {
|
if let Some((punct, mut offset)) = self.punct_offset.clone() {
|
||||||
offset = offset + TextUnit::from_usize(1);
|
offset = offset + TextSize::from_usize(1);
|
||||||
if offset.to_usize() < punct.text().len() {
|
if usize::from(offset) < punct.text().len() {
|
||||||
return Some(SynToken::Punch(punct, offset));
|
return Some(SynToken::Punch(punct, offset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let curr = self.current.clone()?;
|
let curr = self.current.clone()?;
|
||||||
if !curr.text_range().is_subrange(&self.range) {
|
if !self.range.contains_range(curr.text_range()) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let token = if curr.kind().is_punct() {
|
let token = if curr.kind().is_punct() {
|
||||||
SynToken::Punch(curr, TextUnit::from_usize(0))
|
SynToken::Punch(curr, TextSize::from_usize(0))
|
||||||
} else {
|
} else {
|
||||||
SynToken::Ordiniary(curr)
|
SynToken::Ordiniary(curr)
|
||||||
};
|
};
|
||||||
|
@ -574,8 +573,8 @@ impl TokenConvertor for Convertor {
|
||||||
struct TtTreeSink<'a> {
|
struct TtTreeSink<'a> {
|
||||||
buf: String,
|
buf: String,
|
||||||
cursor: Cursor<'a>,
|
cursor: Cursor<'a>,
|
||||||
open_delims: FxHashMap<tt::TokenId, TextUnit>,
|
open_delims: FxHashMap<tt::TokenId, TextSize>,
|
||||||
text_pos: TextUnit,
|
text_pos: TextSize,
|
||||||
inner: SyntaxTreeBuilder,
|
inner: SyntaxTreeBuilder,
|
||||||
token_map: TokenMap,
|
token_map: TokenMap,
|
||||||
|
|
||||||
|
@ -641,7 +640,7 @@ impl<'a> TreeSink for TtTreeSink<'a> {
|
||||||
}
|
}
|
||||||
tt::Leaf::Literal(lit) => (lit.text.clone(), lit.id),
|
tt::Leaf::Literal(lit) => (lit.text.clone(), lit.id),
|
||||||
};
|
};
|
||||||
let range = TextRange::offset_len(self.text_pos, TextUnit::of_str(&text));
|
let range = TextRange::at(self.text_pos, TextSize::of(text.as_str()));
|
||||||
self.token_map.insert(id, range);
|
self.token_map.insert(id, range);
|
||||||
self.cursor = self.cursor.bump();
|
self.cursor = self.cursor.bump();
|
||||||
text
|
text
|
||||||
|
@ -658,10 +657,8 @@ impl<'a> TreeSink for TtTreeSink<'a> {
|
||||||
self.cursor = self.cursor.bump();
|
self.cursor = self.cursor.bump();
|
||||||
if let Some(id) = parent.delimiter.map(|it| it.id) {
|
if let Some(id) = parent.delimiter.map(|it| it.id) {
|
||||||
if let Some(open_delim) = self.open_delims.get(&id) {
|
if let Some(open_delim) = self.open_delims.get(&id) {
|
||||||
let open_range =
|
let open_range = TextRange::at(*open_delim, TextSize::of('('));
|
||||||
TextRange::offset_len(*open_delim, TextUnit::from_usize(1));
|
let close_range = TextRange::at(self.text_pos, TextSize::of('('));
|
||||||
let close_range =
|
|
||||||
TextRange::offset_len(self.text_pos, TextUnit::from_usize(1));
|
|
||||||
self.token_map.insert_delim(id, open_range, close_range);
|
self.token_map.insert_delim(id, open_range, close_range);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -672,7 +669,7 @@ impl<'a> TreeSink for TtTreeSink<'a> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.buf += &text;
|
self.buf += &text;
|
||||||
self.text_pos += TextUnit::of_str(&text);
|
self.text_pos += TextSize::of(text.as_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
let text = SmolStr::new(self.buf.as_str());
|
let text = SmolStr::new(self.buf.as_str());
|
||||||
|
@ -690,7 +687,7 @@ impl<'a> TreeSink for TtTreeSink<'a> {
|
||||||
// other parts of RA such that we don't add whitespace here.
|
// other parts of RA such that we don't add whitespace here.
|
||||||
if curr.spacing == tt::Spacing::Alone && curr.char != ';' {
|
if curr.spacing == tt::Spacing::Alone && curr.char != ';' {
|
||||||
self.inner.token(WHITESPACE, " ".into());
|
self.inner.token(WHITESPACE, " ".into());
|
||||||
self.text_pos += TextUnit::of_char(' ');
|
self.text_pos += TextSize::of(' ');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ doctest = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
itertools = "0.9.0"
|
itertools = "0.9.0"
|
||||||
rowan = "0.9.1"
|
rowan = { path = "../../../rowan" }
|
||||||
rustc_lexer = { version = "652.0.0", package = "rustc-ap-rustc_lexer" }
|
rustc_lexer = { version = "652.0.0", package = "rustc-ap-rustc_lexer" }
|
||||||
rustc-hash = "1.1.0"
|
rustc-hash = "1.1.0"
|
||||||
arrayvec = "0.5.1"
|
arrayvec = "0.5.1"
|
||||||
|
|
|
@ -11,7 +11,7 @@ use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxNodePtr,
|
AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxNodePtr,
|
||||||
SyntaxToken, TextRange, TextUnit,
|
SyntaxToken, TextRange, TextSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Returns ancestors of the node at the offset, sorted by length. This should
|
/// Returns ancestors of the node at the offset, sorted by length. This should
|
||||||
|
@ -21,7 +21,7 @@ use crate::{
|
||||||
/// t.parent().ancestors())`.
|
/// t.parent().ancestors())`.
|
||||||
pub fn ancestors_at_offset(
|
pub fn ancestors_at_offset(
|
||||||
node: &SyntaxNode,
|
node: &SyntaxNode,
|
||||||
offset: TextUnit,
|
offset: TextSize,
|
||||||
) -> impl Iterator<Item = SyntaxNode> {
|
) -> impl Iterator<Item = SyntaxNode> {
|
||||||
node.token_at_offset(offset)
|
node.token_at_offset(offset)
|
||||||
.map(|token| token.parent().ancestors())
|
.map(|token| token.parent().ancestors())
|
||||||
|
@ -37,7 +37,7 @@ pub fn ancestors_at_offset(
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// then the shorter node will be silently preferred.
|
/// then the shorter node will be silently preferred.
|
||||||
pub fn find_node_at_offset<N: AstNode>(syntax: &SyntaxNode, offset: TextUnit) -> Option<N> {
|
pub fn find_node_at_offset<N: AstNode>(syntax: &SyntaxNode, offset: TextSize) -> Option<N> {
|
||||||
ancestors_at_offset(syntax, offset).find_map(N::cast)
|
ancestors_at_offset(syntax, offset).find_map(N::cast)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ fn _insert_children(
|
||||||
position: InsertPosition<SyntaxElement>,
|
position: InsertPosition<SyntaxElement>,
|
||||||
to_insert: &mut dyn Iterator<Item = SyntaxElement>,
|
to_insert: &mut dyn Iterator<Item = SyntaxElement>,
|
||||||
) -> SyntaxNode {
|
) -> SyntaxNode {
|
||||||
let mut delta = TextUnit::default();
|
let mut delta = TextSize::default();
|
||||||
let to_insert = to_insert.map(|element| {
|
let to_insert = to_insert.map(|element| {
|
||||||
delta += element.text_range().len();
|
delta += element.text_range().len();
|
||||||
to_green_element(element)
|
to_green_element(element)
|
||||||
|
@ -347,7 +347,7 @@ fn with_children(
|
||||||
parent: &SyntaxNode,
|
parent: &SyntaxNode,
|
||||||
new_children: Vec<NodeOrToken<rowan::GreenNode, rowan::GreenToken>>,
|
new_children: Vec<NodeOrToken<rowan::GreenNode, rowan::GreenToken>>,
|
||||||
) -> SyntaxNode {
|
) -> SyntaxNode {
|
||||||
let len = new_children.iter().map(|it| it.text_len()).sum::<TextUnit>();
|
let len = new_children.iter().map(|it| it.text_len()).sum::<TextSize>();
|
||||||
let new_node = rowan::GreenNode::new(rowan::SyntaxKind(parent.kind() as u16), new_children);
|
let new_node = rowan::GreenNode::new(rowan::SyntaxKind(parent.kind() as u16), new_children);
|
||||||
let new_root_node = parent.replace_with(new_node);
|
let new_root_node = parent.replace_with(new_node);
|
||||||
let new_root_node = SyntaxNode::new_root(new_root_node);
|
let new_root_node = SyntaxNode::new_root(new_root_node);
|
||||||
|
@ -355,7 +355,7 @@ fn with_children(
|
||||||
// FIXME: use a more elegant way to re-fetch the node (#1185), make
|
// FIXME: use a more elegant way to re-fetch the node (#1185), make
|
||||||
// `range` private afterwards
|
// `range` private afterwards
|
||||||
let mut ptr = SyntaxNodePtr::new(parent);
|
let mut ptr = SyntaxNodePtr::new(parent);
|
||||||
ptr.range = TextRange::offset_len(ptr.range.start(), len);
|
ptr.range = TextRange::at(ptr.range.start(), len);
|
||||||
ptr.to_node(&new_root_node)
|
ptr.to_node(&new_root_node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{AstToken, Comment, RawString, String, Whitespace},
|
ast::{AstToken, Comment, RawString, String, Whitespace},
|
||||||
TextRange, TextUnit,
|
TextRange, TextSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Comment {
|
impl Comment {
|
||||||
|
@ -94,14 +94,14 @@ impl QuoteOffsets {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let start = TextUnit::from(0);
|
let start = TextSize::from(0);
|
||||||
let left_quote = TextUnit::from_usize(left_quote) + TextUnit::of_char('"');
|
let left_quote = TextSize::from_usize(left_quote) + TextSize::of('"');
|
||||||
let right_quote = TextUnit::from_usize(right_quote);
|
let right_quote = TextSize::from_usize(right_quote);
|
||||||
let end = TextUnit::of_str(literal);
|
let end = TextSize::of(literal);
|
||||||
|
|
||||||
let res = QuoteOffsets {
|
let res = QuoteOffsets {
|
||||||
quotes: [TextRange::from_to(start, left_quote), TextRange::from_to(right_quote, end)],
|
quotes: [TextRange::new(start, left_quote), TextRange::new(right_quote, end)],
|
||||||
contents: TextRange::from_to(left_quote, right_quote),
|
contents: TextRange::new(left_quote, right_quote),
|
||||||
};
|
};
|
||||||
Some(res)
|
Some(res)
|
||||||
}
|
}
|
||||||
|
@ -168,7 +168,7 @@ impl HasStringValue for RawString {
|
||||||
impl RawString {
|
impl RawString {
|
||||||
pub fn map_range_up(&self, range: TextRange) -> Option<TextRange> {
|
pub fn map_range_up(&self, range: TextRange) -> Option<TextRange> {
|
||||||
let contents_range = self.text_range_between_quotes()?;
|
let contents_range = self.text_range_between_quotes()?;
|
||||||
assert!(range.is_subrange(&TextRange::offset_len(0.into(), contents_range.len())));
|
assert!(TextRange::up_to(contents_range.len()).contains_range(range));
|
||||||
Some(range + contents_range.start())
|
Some(range + contents_range.start())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -459,7 +459,7 @@ pub trait HasFormatSpecifier: AstToken {
|
||||||
while let Some((r, Ok(next_char))) = chars.peek() {
|
while let Some((r, Ok(next_char))) = chars.peek() {
|
||||||
if next_char.is_ascii_digit() {
|
if next_char.is_ascii_digit() {
|
||||||
chars.next();
|
chars.next();
|
||||||
range = range.extend_to(r);
|
range = range.cover(*r);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -477,7 +477,7 @@ pub trait HasFormatSpecifier: AstToken {
|
||||||
while let Some((r, Ok(next_char))) = chars.peek() {
|
while let Some((r, Ok(next_char))) = chars.peek() {
|
||||||
if *next_char == '_' || next_char.is_ascii_digit() || next_char.is_alphabetic() {
|
if *next_char == '_' || next_char.is_ascii_digit() || next_char.is_alphabetic() {
|
||||||
chars.next();
|
chars.next();
|
||||||
range = range.extend_to(r);
|
range = range.cover(*r);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -498,10 +498,8 @@ impl HasFormatSpecifier for String {
|
||||||
let mut res = Vec::with_capacity(text.len());
|
let mut res = Vec::with_capacity(text.len());
|
||||||
rustc_lexer::unescape::unescape_str(text, &mut |range, unescaped_char| {
|
rustc_lexer::unescape::unescape_str(text, &mut |range, unescaped_char| {
|
||||||
res.push((
|
res.push((
|
||||||
TextRange::from_to(
|
TextRange::new(TextSize::from_usize(range.start), TextSize::from_usize(range.end))
|
||||||
TextUnit::from_usize(range.start),
|
+ offset,
|
||||||
TextUnit::from_usize(range.end),
|
|
||||||
) + offset,
|
|
||||||
unescaped_char,
|
unescaped_char,
|
||||||
))
|
))
|
||||||
});
|
});
|
||||||
|
@ -521,10 +519,8 @@ impl HasFormatSpecifier for RawString {
|
||||||
let mut res = Vec::with_capacity(text.len());
|
let mut res = Vec::with_capacity(text.len());
|
||||||
for (idx, c) in text.char_indices() {
|
for (idx, c) in text.char_indices() {
|
||||||
res.push((
|
res.push((
|
||||||
TextRange::from_to(
|
TextRange::new(TextSize::from_usize(idx), TextSize::from_usize(idx + c.len_utf8()))
|
||||||
TextUnit::from_usize(idx),
|
+ offset,
|
||||||
TextUnit::from_usize(idx + c.len_utf8()),
|
|
||||||
) + offset,
|
|
||||||
Ok(c),
|
Ok(c),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! FIXME: write short doc here
|
//! FIXME: write short doc here
|
||||||
|
|
||||||
use crate::{validation, AstNode, SourceFile, TextRange, TextUnit};
|
use crate::{validation, AstNode, SourceFile, TextRange, TextSize};
|
||||||
use ra_text_edit::AtomTextEdit;
|
use ra_text_edit::AtomTextEdit;
|
||||||
use std::str::{self, FromStr};
|
use std::str::{self, FromStr};
|
||||||
|
|
||||||
|
@ -34,10 +34,8 @@ impl CheckReparse {
|
||||||
let text = lines.collect::<Vec<_>>().join("\n");
|
let text = lines.collect::<Vec<_>>().join("\n");
|
||||||
let text = format!("{}{}{}", PREFIX, text, SUFFIX);
|
let text = format!("{}{}{}", PREFIX, text, SUFFIX);
|
||||||
text.get(delete_start..delete_start.checked_add(delete_len)?)?; // make sure delete is a valid range
|
text.get(delete_start..delete_start.checked_add(delete_len)?)?; // make sure delete is a valid range
|
||||||
let delete = TextRange::offset_len(
|
let delete =
|
||||||
TextUnit::from_usize(delete_start),
|
TextRange::at(TextSize::from_usize(delete_start), TextSize::from_usize(delete_len));
|
||||||
TextUnit::from_usize(delete_len),
|
|
||||||
);
|
|
||||||
let edited_text =
|
let edited_text =
|
||||||
format!("{}{}{}", &text[..delete_start], &insert, &text[delete_start + delete_len..]);
|
format!("{}{}{}", &text[..delete_start], &insert, &text[delete_start + delete_len..]);
|
||||||
let edit = AtomTextEdit { delete, insert };
|
let edit = AtomTextEdit { delete, insert };
|
||||||
|
|
|
@ -55,7 +55,7 @@ pub use crate::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
pub use ra_parser::{SyntaxKind, T};
|
pub use ra_parser::{SyntaxKind, T};
|
||||||
pub use rowan::{SmolStr, SyntaxText, TextRange, TextUnit, TokenAtOffset, WalkEvent};
|
pub use rowan::{SmolStr, SyntaxText, TextRange, TextSize, TokenAtOffset, WalkEvent};
|
||||||
|
|
||||||
/// `Parse` is the result of the parsing: a syntax tree and a collection of
|
/// `Parse` is the result of the parsing: a syntax tree and a collection of
|
||||||
/// errors.
|
/// errors.
|
||||||
|
@ -266,7 +266,7 @@ fn api_walkthrough() {
|
||||||
assert_eq!(expr_syntax.kind(), SyntaxKind::BIN_EXPR);
|
assert_eq!(expr_syntax.kind(), SyntaxKind::BIN_EXPR);
|
||||||
|
|
||||||
// And text range:
|
// And text range:
|
||||||
assert_eq!(expr_syntax.text_range(), TextRange::from_to(32.into(), 37.into()));
|
assert_eq!(expr_syntax.text_range(), TextRange::new(32.into(), 37.into()));
|
||||||
|
|
||||||
// You can get node's text as a `SyntaxText` object, which will traverse the
|
// You can get node's text as a `SyntaxText` object, which will traverse the
|
||||||
// tree collecting token's text:
|
// tree collecting token's text:
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
SyntaxError,
|
SyntaxError,
|
||||||
SyntaxKind::{self, *},
|
SyntaxKind::{self, *},
|
||||||
TextRange, TextUnit, T,
|
TextRange, TextSize, T,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A token of Rust source.
|
/// A token of Rust source.
|
||||||
|
@ -13,7 +13,7 @@ pub struct Token {
|
||||||
/// The kind of token.
|
/// The kind of token.
|
||||||
pub kind: SyntaxKind,
|
pub kind: SyntaxKind,
|
||||||
/// The length of the token.
|
/// The length of the token.
|
||||||
pub len: TextUnit,
|
pub len: TextSize,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Break a string up into its component tokens.
|
/// Break a string up into its component tokens.
|
||||||
|
@ -30,7 +30,7 @@ pub fn tokenize(text: &str) -> (Vec<Token>, Vec<SyntaxError>) {
|
||||||
|
|
||||||
let mut offset: usize = rustc_lexer::strip_shebang(text)
|
let mut offset: usize = rustc_lexer::strip_shebang(text)
|
||||||
.map(|shebang_len| {
|
.map(|shebang_len| {
|
||||||
tokens.push(Token { kind: SHEBANG, len: TextUnit::from_usize(shebang_len) });
|
tokens.push(Token { kind: SHEBANG, len: TextSize::from_usize(shebang_len) });
|
||||||
shebang_len
|
shebang_len
|
||||||
})
|
})
|
||||||
.unwrap_or(0);
|
.unwrap_or(0);
|
||||||
|
@ -38,8 +38,8 @@ pub fn tokenize(text: &str) -> (Vec<Token>, Vec<SyntaxError>) {
|
||||||
let text_without_shebang = &text[offset..];
|
let text_without_shebang = &text[offset..];
|
||||||
|
|
||||||
for rustc_token in rustc_lexer::tokenize(text_without_shebang) {
|
for rustc_token in rustc_lexer::tokenize(text_without_shebang) {
|
||||||
let token_len = TextUnit::from_usize(rustc_token.len);
|
let token_len = TextSize::from_usize(rustc_token.len);
|
||||||
let token_range = TextRange::offset_len(TextUnit::from_usize(offset), token_len);
|
let token_range = TextRange::at(TextSize::from_usize(offset), token_len);
|
||||||
|
|
||||||
let (syntax_kind, err_message) =
|
let (syntax_kind, err_message) =
|
||||||
rustc_token_kind_to_syntax_kind(&rustc_token.kind, &text[token_range]);
|
rustc_token_kind_to_syntax_kind(&rustc_token.kind, &text[token_range]);
|
||||||
|
@ -65,7 +65,7 @@ pub fn tokenize(text: &str) -> (Vec<Token>, Vec<SyntaxError>) {
|
||||||
/// Beware that unescape errors are not checked at tokenization time.
|
/// Beware that unescape errors are not checked at tokenization time.
|
||||||
pub fn lex_single_syntax_kind(text: &str) -> Option<(SyntaxKind, Option<SyntaxError>)> {
|
pub fn lex_single_syntax_kind(text: &str) -> Option<(SyntaxKind, Option<SyntaxError>)> {
|
||||||
lex_first_token(text)
|
lex_first_token(text)
|
||||||
.filter(|(token, _)| token.len == TextUnit::of_str(text))
|
.filter(|(token, _)| token.len == TextSize::of(text))
|
||||||
.map(|(token, error)| (token.kind, error))
|
.map(|(token, error)| (token.kind, error))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ pub fn lex_single_syntax_kind(text: &str) -> Option<(SyntaxKind, Option<SyntaxEr
|
||||||
/// Beware that unescape errors are not checked at tokenization time.
|
/// Beware that unescape errors are not checked at tokenization time.
|
||||||
pub fn lex_single_valid_syntax_kind(text: &str) -> Option<SyntaxKind> {
|
pub fn lex_single_valid_syntax_kind(text: &str) -> Option<SyntaxKind> {
|
||||||
lex_first_token(text)
|
lex_first_token(text)
|
||||||
.filter(|(token, error)| !error.is_some() && token.len == TextUnit::of_str(text))
|
.filter(|(token, error)| !error.is_some() && token.len == TextSize::of(text))
|
||||||
.map(|(token, _error)| token.kind)
|
.map(|(token, _error)| token.kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,9 +96,9 @@ fn lex_first_token(text: &str) -> Option<(Token, Option<SyntaxError>)> {
|
||||||
let rustc_token = rustc_lexer::first_token(text);
|
let rustc_token = rustc_lexer::first_token(text);
|
||||||
let (syntax_kind, err_message) = rustc_token_kind_to_syntax_kind(&rustc_token.kind, text);
|
let (syntax_kind, err_message) = rustc_token_kind_to_syntax_kind(&rustc_token.kind, text);
|
||||||
|
|
||||||
let token = Token { kind: syntax_kind, len: TextUnit::from_usize(rustc_token.len) };
|
let token = Token { kind: syntax_kind, len: TextSize::from_usize(rustc_token.len) };
|
||||||
let optional_error = err_message.map(|err_message| {
|
let optional_error = err_message.map(|err_message| {
|
||||||
SyntaxError::new(err_message, TextRange::from_to(0.into(), TextUnit::of_str(text)))
|
SyntaxError::new(err_message, TextRange::new(0.into(), TextSize::of(text)))
|
||||||
});
|
});
|
||||||
|
|
||||||
Some((token, optional_error))
|
Some((token, optional_error))
|
||||||
|
|
|
@ -19,7 +19,7 @@ use crate::{
|
||||||
syntax_node::{GreenNode, GreenToken, NodeOrToken, SyntaxElement, SyntaxNode},
|
syntax_node::{GreenNode, GreenToken, NodeOrToken, SyntaxElement, SyntaxNode},
|
||||||
SyntaxError,
|
SyntaxError,
|
||||||
SyntaxKind::*,
|
SyntaxKind::*,
|
||||||
TextRange, TextUnit, T,
|
TextRange, TextSize, T,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) fn incremental_reparse(
|
pub(crate) fn incremental_reparse(
|
||||||
|
@ -176,7 +176,7 @@ fn merge_errors(
|
||||||
if old_err_range.end() <= range_before_reparse.start() {
|
if old_err_range.end() <= range_before_reparse.start() {
|
||||||
res.push(old_err);
|
res.push(old_err);
|
||||||
} else if old_err_range.start() >= range_before_reparse.end() {
|
} else if old_err_range.start() >= range_before_reparse.end() {
|
||||||
let inserted_len = TextUnit::of_str(&edit.insert);
|
let inserted_len = TextSize::of(&edit.insert);
|
||||||
res.push(old_err.with_range((old_err_range + inserted_len) - edit.delete.len()));
|
res.push(old_err.with_range((old_err_range + inserted_len) - edit.delete.len()));
|
||||||
// Note: extra parens are intentional to prevent uint underflow, HWAB (here was a bug)
|
// Note: extra parens are intentional to prevent uint underflow, HWAB (here was a bug)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use ra_parser::Token as PToken;
|
use ra_parser::Token as PToken;
|
||||||
use ra_parser::TokenSource;
|
use ra_parser::TokenSource;
|
||||||
|
|
||||||
use crate::{parsing::lexer::Token, SyntaxKind::EOF, TextRange, TextUnit};
|
use crate::{parsing::lexer::Token, SyntaxKind::EOF, TextRange, TextSize};
|
||||||
|
|
||||||
pub(crate) struct TextTokenSource<'t> {
|
pub(crate) struct TextTokenSource<'t> {
|
||||||
text: &'t str,
|
text: &'t str,
|
||||||
|
@ -15,7 +15,7 @@ pub(crate) struct TextTokenSource<'t> {
|
||||||
/// 0 7 10
|
/// 0 7 10
|
||||||
/// ```
|
/// ```
|
||||||
/// (token, start_offset): `[(struct, 0), (Foo, 7), (;, 10)]`
|
/// (token, start_offset): `[(struct, 0), (Foo, 7), (;, 10)]`
|
||||||
start_offsets: Vec<TextUnit>,
|
start_offsets: Vec<TextSize>,
|
||||||
/// non-whitespace/comment tokens
|
/// non-whitespace/comment tokens
|
||||||
/// ```non-rust
|
/// ```non-rust
|
||||||
/// struct Foo {}
|
/// struct Foo {}
|
||||||
|
@ -51,12 +51,12 @@ impl<'t> TokenSource for TextTokenSource<'t> {
|
||||||
if pos >= self.tokens.len() {
|
if pos >= self.tokens.len() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let range = TextRange::offset_len(self.start_offsets[pos], self.tokens[pos].len);
|
let range = TextRange::at(self.start_offsets[pos], self.tokens[pos].len);
|
||||||
self.text[range] == *kw
|
self.text[range] == *kw
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mk_token(pos: usize, start_offsets: &[TextUnit], tokens: &[Token]) -> PToken {
|
fn mk_token(pos: usize, start_offsets: &[TextSize], tokens: &[Token]) -> PToken {
|
||||||
let kind = tokens.get(pos).map(|t| t.kind).unwrap_or(EOF);
|
let kind = tokens.get(pos).map(|t| t.kind).unwrap_or(EOF);
|
||||||
let is_jointed_to_next = if pos + 1 < start_offsets.len() {
|
let is_jointed_to_next = if pos + 1 < start_offsets.len() {
|
||||||
start_offsets[pos] + tokens[pos].len == start_offsets[pos + 1]
|
start_offsets[pos] + tokens[pos].len == start_offsets[pos + 1]
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::{
|
||||||
syntax_node::GreenNode,
|
syntax_node::GreenNode,
|
||||||
SmolStr, SyntaxError,
|
SmolStr, SyntaxError,
|
||||||
SyntaxKind::{self, *},
|
SyntaxKind::{self, *},
|
||||||
SyntaxTreeBuilder, TextRange, TextUnit,
|
SyntaxTreeBuilder, TextRange, TextSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Bridges the parser with our specific syntax tree representation.
|
/// Bridges the parser with our specific syntax tree representation.
|
||||||
|
@ -18,7 +18,7 @@ use crate::{
|
||||||
pub(crate) struct TextTreeSink<'a> {
|
pub(crate) struct TextTreeSink<'a> {
|
||||||
text: &'a str,
|
text: &'a str,
|
||||||
tokens: &'a [Token],
|
tokens: &'a [Token],
|
||||||
text_pos: TextUnit,
|
text_pos: TextSize,
|
||||||
token_pos: usize,
|
token_pos: usize,
|
||||||
state: State,
|
state: State,
|
||||||
inner: SyntaxTreeBuilder,
|
inner: SyntaxTreeBuilder,
|
||||||
|
@ -42,7 +42,7 @@ impl<'a> TreeSink for TextTreeSink<'a> {
|
||||||
let len = self.tokens[self.token_pos..self.token_pos + n_tokens]
|
let len = self.tokens[self.token_pos..self.token_pos + n_tokens]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|it| it.len)
|
.map(|it| it.len)
|
||||||
.sum::<TextUnit>();
|
.sum::<TextSize>();
|
||||||
self.do_token(kind, len, n_tokens);
|
self.do_token(kind, len, n_tokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,12 +62,12 @@ impl<'a> TreeSink for TextTreeSink<'a> {
|
||||||
self.tokens[self.token_pos..].iter().take_while(|it| it.kind.is_trivia()).count();
|
self.tokens[self.token_pos..].iter().take_while(|it| it.kind.is_trivia()).count();
|
||||||
let leading_trivias = &self.tokens[self.token_pos..self.token_pos + n_trivias];
|
let leading_trivias = &self.tokens[self.token_pos..self.token_pos + n_trivias];
|
||||||
let mut trivia_end =
|
let mut trivia_end =
|
||||||
self.text_pos + leading_trivias.iter().map(|it| it.len).sum::<TextUnit>();
|
self.text_pos + leading_trivias.iter().map(|it| it.len).sum::<TextSize>();
|
||||||
|
|
||||||
let n_attached_trivias = {
|
let n_attached_trivias = {
|
||||||
let leading_trivias = leading_trivias.iter().rev().map(|it| {
|
let leading_trivias = leading_trivias.iter().rev().map(|it| {
|
||||||
let next_end = trivia_end - it.len;
|
let next_end = trivia_end - it.len;
|
||||||
let range = TextRange::from_to(next_end, trivia_end);
|
let range = TextRange::new(next_end, trivia_end);
|
||||||
trivia_end = next_end;
|
trivia_end = next_end;
|
||||||
(it.kind, &self.text[range])
|
(it.kind, &self.text[range])
|
||||||
});
|
});
|
||||||
|
@ -132,8 +132,8 @@ impl<'a> TextTreeSink<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_token(&mut self, kind: SyntaxKind, len: TextUnit, n_tokens: usize) {
|
fn do_token(&mut self, kind: SyntaxKind, len: TextSize, n_tokens: usize) {
|
||||||
let range = TextRange::offset_len(self.text_pos, len);
|
let range = TextRange::at(self.text_pos, len);
|
||||||
let text: SmolStr = self.text[range].into();
|
let text: SmolStr = self.text[range].into();
|
||||||
self.text_pos += len;
|
self.text_pos += len;
|
||||||
self.token_pos += n_tokens;
|
self.token_pos += n_tokens;
|
||||||
|
|
|
@ -24,7 +24,7 @@ impl SyntaxNodePtr {
|
||||||
pub fn to_node(&self, root: &SyntaxNode) -> SyntaxNode {
|
pub fn to_node(&self, root: &SyntaxNode) -> SyntaxNode {
|
||||||
assert!(root.parent().is_none());
|
assert!(root.parent().is_none());
|
||||||
successors(Some(root.clone()), |node| {
|
successors(Some(root.clone()), |node| {
|
||||||
node.children().find(|it| self.range.is_subrange(&it.text_range()))
|
node.children().find(|it| it.text_range().contains_range(self.range))
|
||||||
})
|
})
|
||||||
.find(|it| it.text_range() == self.range && it.kind() == self.kind)
|
.find(|it| it.text_range() == self.range && it.kind() == self.kind)
|
||||||
.unwrap_or_else(|| panic!("can't resolve local ptr to SyntaxNode: {:?}", self))
|
.unwrap_or_else(|| panic!("can't resolve local ptr to SyntaxNode: {:?}", self))
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use crate::{TextRange, TextUnit};
|
use crate::{TextRange, TextSize};
|
||||||
|
|
||||||
/// Represents the result of unsuccessful tokenization, parsing
|
/// Represents the result of unsuccessful tokenization, parsing
|
||||||
/// or tree validation.
|
/// or tree validation.
|
||||||
|
@ -23,8 +23,8 @@ impl SyntaxError {
|
||||||
pub fn new(message: impl Into<String>, range: TextRange) -> Self {
|
pub fn new(message: impl Into<String>, range: TextRange) -> Self {
|
||||||
Self(message.into(), range)
|
Self(message.into(), range)
|
||||||
}
|
}
|
||||||
pub fn new_at_offset(message: impl Into<String>, offset: TextUnit) -> Self {
|
pub fn new_at_offset(message: impl Into<String>, offset: TextSize) -> Self {
|
||||||
Self(message.into(), TextRange::offset_len(offset, 0.into()))
|
Self(message.into(), TextRange::empty(offset))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn range(&self) -> TextRange {
|
pub fn range(&self) -> TextRange {
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
use rowan::{GreenNodeBuilder, Language};
|
use rowan::{GreenNodeBuilder, Language};
|
||||||
|
|
||||||
use crate::{Parse, SmolStr, SyntaxError, SyntaxKind, TextUnit};
|
use crate::{Parse, SmolStr, SyntaxError, SyntaxKind, TextSize};
|
||||||
|
|
||||||
pub(crate) use rowan::{GreenNode, GreenToken};
|
pub(crate) use rowan::{GreenNode, GreenToken};
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ impl SyntaxTreeBuilder {
|
||||||
self.inner.finish_node()
|
self.inner.finish_node()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn error(&mut self, error: ra_parser::ParseError, text_pos: TextUnit) {
|
pub fn error(&mut self, error: ra_parser::ParseError, text_pos: TextSize) {
|
||||||
self.errors.push(SyntaxError::new_at_offset(error.0, text_pos))
|
self.errors.push(SyntaxError::new_at_offset(error.0, text_pos))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::{
|
||||||
|
|
||||||
use test_utils::{collect_rust_files, dir_tests, project_dir, read_text};
|
use test_utils::{collect_rust_files, dir_tests, project_dir, read_text};
|
||||||
|
|
||||||
use crate::{fuzz, tokenize, SourceFile, SyntaxError, TextRange, TextUnit, Token};
|
use crate::{fuzz, tokenize, SourceFile, SyntaxError, TextRange, TextSize, Token};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn lexer_tests() {
|
fn lexer_tests() {
|
||||||
|
@ -121,12 +121,12 @@ fn assert_errors_are_absent(errors: &[SyntaxError], path: &Path) {
|
||||||
|
|
||||||
fn dump_tokens_and_errors(tokens: &[Token], errors: &[SyntaxError], text: &str) -> String {
|
fn dump_tokens_and_errors(tokens: &[Token], errors: &[SyntaxError], text: &str) -> String {
|
||||||
let mut acc = String::new();
|
let mut acc = String::new();
|
||||||
let mut offset = TextUnit::from_usize(0);
|
let mut offset = TextSize::from_usize(0);
|
||||||
for token in tokens {
|
for token in tokens {
|
||||||
let token_len = token.len;
|
let token_len = token.len;
|
||||||
let token_text = &text[TextRange::offset_len(offset, token.len)];
|
let token_text = &text[TextRange::at(offset, token.len)];
|
||||||
offset += token.len;
|
offset += token.len;
|
||||||
writeln!(acc, "{:?} {} {:?}", token.kind, token_len, token_text).unwrap();
|
writeln!(acc, "{:?} {:?} {:?}", token.kind, token_len, token_text).unwrap();
|
||||||
}
|
}
|
||||||
for err in errors {
|
for err in errors {
|
||||||
writeln!(acc, "> error{:?} token({:?}) msg({})", err.range(), &text[err.range()], err)
|
writeln!(acc, "> error{:?} token({:?}) msg({})", err.range(), &text[err.range()], err)
|
||||||
|
|
|
@ -7,7 +7,7 @@ use rustc_lexer::unescape;
|
||||||
use crate::{
|
use crate::{
|
||||||
ast, match_ast, AstNode, SyntaxError,
|
ast, match_ast, AstNode, SyntaxError,
|
||||||
SyntaxKind::{BYTE, BYTE_STRING, CHAR, CONST_DEF, FN_DEF, INT_NUMBER, STRING, TYPE_ALIAS_DEF},
|
SyntaxKind::{BYTE, BYTE_STRING, CHAR, CONST_DEF, FN_DEF, INT_NUMBER, STRING, TYPE_ALIAS_DEF},
|
||||||
SyntaxNode, SyntaxToken, TextUnit, T,
|
SyntaxNode, SyntaxToken, TextSize, T,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn rustc_unescape_error_to_string(err: unescape::EscapeError) -> &'static str {
|
fn rustc_unescape_error_to_string(err: unescape::EscapeError) -> &'static str {
|
||||||
|
@ -112,7 +112,7 @@ fn validate_literal(literal: ast::Literal, acc: &mut Vec<SyntaxError>) {
|
||||||
|
|
||||||
// FIXME: lift this lambda refactor to `fn` (https://github.com/rust-analyzer/rust-analyzer/pull/2834#discussion_r366199205)
|
// FIXME: lift this lambda refactor to `fn` (https://github.com/rust-analyzer/rust-analyzer/pull/2834#discussion_r366199205)
|
||||||
let mut push_err = |prefix_len, (off, err): (usize, unescape::EscapeError)| {
|
let mut push_err = |prefix_len, (off, err): (usize, unescape::EscapeError)| {
|
||||||
let off = token.text_range().start() + TextUnit::from_usize(off + prefix_len);
|
let off = token.text_range().start() + TextSize::from_usize(off + prefix_len);
|
||||||
acc.push(SyntaxError::new_at_offset(rustc_unescape_error_to_string(err), off));
|
acc.push(SyntaxError::new_at_offset(rustc_unescape_error_to_string(err), off));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,5 +9,4 @@ publish = false
|
||||||
doctest = false
|
doctest = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
text_unit = "0.1.10"
|
text-size = { path = "../../../text-size" }
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
mod text_edit;
|
mod text_edit;
|
||||||
|
|
||||||
use text_unit::{TextRange, TextUnit};
|
use text_size::{TextRange, TextSize};
|
||||||
|
|
||||||
pub use crate::text_edit::{TextEdit, TextEditBuilder};
|
pub use crate::text_edit::{TextEdit, TextEditBuilder};
|
||||||
|
|
||||||
|
@ -23,13 +23,13 @@ impl AtomTextEdit {
|
||||||
AtomTextEdit::replace(range, String::new())
|
AtomTextEdit::replace(range, String::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert(offset: TextUnit, text: String) -> AtomTextEdit {
|
pub fn insert(offset: TextSize, text: String) -> AtomTextEdit {
|
||||||
AtomTextEdit::replace(TextRange::offset_len(offset, 0.into()), text)
|
AtomTextEdit::replace(TextRange::empty(offset), text)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply(&self, mut text: String) -> String {
|
pub fn apply(&self, mut text: String) -> String {
|
||||||
let start = self.delete.start().to_usize();
|
let start: usize = self.delete.start().into();
|
||||||
let end = self.delete.end().to_usize();
|
let end: usize = self.delete.end().into();
|
||||||
text.replace_range(start..end, &self.insert);
|
text.replace_range(start..end, &self.insert);
|
||||||
text
|
text
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
//! FIXME: write short doc here
|
//! FIXME: write short doc here
|
||||||
|
|
||||||
use crate::AtomTextEdit;
|
use crate::AtomTextEdit;
|
||||||
use text_unit::{TextRange, TextUnit};
|
// TODO: fix Cargo.toml
|
||||||
|
use text_size::{TextRange, TextSize};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TextEdit {
|
pub struct TextEdit {
|
||||||
|
@ -20,19 +21,19 @@ impl TextEditBuilder {
|
||||||
pub fn delete(&mut self, range: TextRange) {
|
pub fn delete(&mut self, range: TextRange) {
|
||||||
self.atoms.push(AtomTextEdit::delete(range))
|
self.atoms.push(AtomTextEdit::delete(range))
|
||||||
}
|
}
|
||||||
pub fn insert(&mut self, offset: TextUnit, text: String) {
|
pub fn insert(&mut self, offset: TextSize, text: String) {
|
||||||
self.atoms.push(AtomTextEdit::insert(offset, text))
|
self.atoms.push(AtomTextEdit::insert(offset, text))
|
||||||
}
|
}
|
||||||
pub fn finish(self) -> TextEdit {
|
pub fn finish(self) -> TextEdit {
|
||||||
TextEdit::from_atoms(self.atoms)
|
TextEdit::from_atoms(self.atoms)
|
||||||
}
|
}
|
||||||
pub fn invalidates_offset(&self, offset: TextUnit) -> bool {
|
pub fn invalidates_offset(&self, offset: TextSize) -> bool {
|
||||||
self.atoms.iter().any(|atom| atom.delete.contains_inclusive(offset))
|
self.atoms.iter().any(|atom| atom.delete.contains_inclusive(offset))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TextEdit {
|
impl TextEdit {
|
||||||
pub fn insert(offset: TextUnit, text: String) -> TextEdit {
|
pub fn insert(offset: TextSize, text: String) -> TextEdit {
|
||||||
let mut builder = TextEditBuilder::default();
|
let mut builder = TextEditBuilder::default();
|
||||||
builder.insert(offset, text);
|
builder.insert(offset, text);
|
||||||
builder.finish()
|
builder.finish()
|
||||||
|
@ -63,16 +64,16 @@ impl TextEdit {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply(&self, text: &str) -> String {
|
pub fn apply(&self, text: &str) -> String {
|
||||||
let mut total_len = TextUnit::of_str(text);
|
let mut total_len = TextSize::of(text);
|
||||||
for atom in self.atoms.iter() {
|
for atom in self.atoms.iter() {
|
||||||
total_len += TextUnit::of_str(&atom.insert);
|
total_len += TextSize::of(&atom.insert);
|
||||||
total_len -= atom.delete.end() - atom.delete.start();
|
total_len -= atom.delete.end() - atom.delete.start();
|
||||||
}
|
}
|
||||||
let mut buf = String::with_capacity(total_len.to_usize());
|
let mut buf = String::with_capacity(total_len.into());
|
||||||
let mut prev = 0;
|
let mut prev = 0;
|
||||||
for atom in self.atoms.iter() {
|
for atom in self.atoms.iter() {
|
||||||
let start = atom.delete.start().to_usize();
|
let start: usize = atom.delete.start().into();
|
||||||
let end = atom.delete.end().to_usize();
|
let end: usize = atom.delete.end().into();
|
||||||
if start > prev {
|
if start > prev {
|
||||||
buf.push_str(&text[prev..start]);
|
buf.push_str(&text[prev..start]);
|
||||||
}
|
}
|
||||||
|
@ -80,11 +81,11 @@ impl TextEdit {
|
||||||
prev = end;
|
prev = end;
|
||||||
}
|
}
|
||||||
buf.push_str(&text[prev..text.len()]);
|
buf.push_str(&text[prev..text.len()]);
|
||||||
assert_eq!(TextUnit::of_str(&buf), total_len);
|
assert_eq!(TextSize::of(&buf), total_len);
|
||||||
buf
|
buf
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_to_offset(&self, offset: TextUnit) -> Option<TextUnit> {
|
pub fn apply_to_offset(&self, offset: TextSize) -> Option<TextSize> {
|
||||||
let mut res = offset;
|
let mut res = offset;
|
||||||
for atom in self.atoms.iter() {
|
for atom in self.atoms.iter() {
|
||||||
if atom.delete.start() >= offset {
|
if atom.delete.start() >= offset {
|
||||||
|
@ -93,7 +94,7 @@ impl TextEdit {
|
||||||
if offset < atom.delete.end() {
|
if offset < atom.delete.end() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
res += TextUnit::of_str(&atom.insert);
|
res += TextSize::of(&atom.insert);
|
||||||
res -= atom.delete.len();
|
res -= atom.delete.len();
|
||||||
}
|
}
|
||||||
Some(res)
|
Some(res)
|
||||||
|
|
|
@ -130,7 +130,7 @@ pub fn analysis_stats(
|
||||||
let original_file = src.file_id.original_file(db);
|
let original_file = src.file_id.original_file(db);
|
||||||
let path = db.file_relative_path(original_file);
|
let path = db.file_relative_path(original_file);
|
||||||
let syntax_range = src.value.syntax().text_range();
|
let syntax_range = src.value.syntax().text_range();
|
||||||
format_to!(msg, " ({:?} {})", path, syntax_range);
|
format_to!(msg, " ({:?} {:?})", path, syntax_range);
|
||||||
}
|
}
|
||||||
if verbosity.is_spammy() {
|
if verbosity.is_spammy() {
|
||||||
bar.println(msg.to_string());
|
bar.println(msg.to_string());
|
||||||
|
|
|
@ -14,7 +14,7 @@ use ra_ide::{
|
||||||
InlayHint, InlayKind, InsertTextFormat, LineCol, LineIndex, NavigationTarget, RangeInfo,
|
InlayHint, InlayKind, InsertTextFormat, LineCol, LineIndex, NavigationTarget, RangeInfo,
|
||||||
ReferenceAccess, Severity, SourceChange, SourceFileEdit,
|
ReferenceAccess, Severity, SourceChange, SourceFileEdit,
|
||||||
};
|
};
|
||||||
use ra_syntax::{SyntaxKind, TextRange, TextUnit};
|
use ra_syntax::{SyntaxKind, TextRange, TextSize};
|
||||||
use ra_text_edit::{AtomTextEdit, TextEdit};
|
use ra_text_edit::{AtomTextEdit, TextEdit};
|
||||||
use ra_vfs::LineEndings;
|
use ra_vfs::LineEndings;
|
||||||
|
|
||||||
|
@ -124,13 +124,13 @@ impl ConvWith<(&LineIndex, LineEndings)> for CompletionItem {
|
||||||
// LSP does not allow arbitrary edits in completion, so we have to do a
|
// LSP does not allow arbitrary edits in completion, so we have to do a
|
||||||
// non-trivial mapping here.
|
// non-trivial mapping here.
|
||||||
for atom_edit in self.text_edit().as_atoms() {
|
for atom_edit in self.text_edit().as_atoms() {
|
||||||
if self.source_range().is_subrange(&atom_edit.delete) {
|
if atom_edit.delete.contains_range(self.source_range()) {
|
||||||
text_edit = Some(if atom_edit.delete == self.source_range() {
|
text_edit = Some(if atom_edit.delete == self.source_range() {
|
||||||
atom_edit.conv_with((ctx.0, ctx.1))
|
atom_edit.conv_with((ctx.0, ctx.1))
|
||||||
} else {
|
} else {
|
||||||
assert!(self.source_range().end() == atom_edit.delete.end());
|
assert!(self.source_range().end() == atom_edit.delete.end());
|
||||||
let range1 =
|
let range1 =
|
||||||
TextRange::from_to(atom_edit.delete.start(), self.source_range().start());
|
TextRange::new(atom_edit.delete.start(), self.source_range().start());
|
||||||
let range2 = self.source_range();
|
let range2 = self.source_range();
|
||||||
let edit1 = AtomTextEdit::replace(range1, String::new());
|
let edit1 = AtomTextEdit::replace(range1, String::new());
|
||||||
let edit2 = AtomTextEdit::replace(range2, atom_edit.insert.clone());
|
let edit2 = AtomTextEdit::replace(range2, atom_edit.insert.clone());
|
||||||
|
@ -138,7 +138,7 @@ impl ConvWith<(&LineIndex, LineEndings)> for CompletionItem {
|
||||||
edit2.conv_with((ctx.0, ctx.1))
|
edit2.conv_with((ctx.0, ctx.1))
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
assert!(self.source_range().intersection(&atom_edit.delete).is_none());
|
assert!(self.source_range().intersect(atom_edit.delete).is_none());
|
||||||
additional_text_edits.push(atom_edit.conv_with((ctx.0, ctx.1)));
|
additional_text_edits.push(atom_edit.conv_with((ctx.0, ctx.1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,15 +184,15 @@ impl ConvWith<(&LineIndex, LineEndings)> for CompletionItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConvWith<&LineIndex> for Position {
|
impl ConvWith<&LineIndex> for Position {
|
||||||
type Output = TextUnit;
|
type Output = TextSize;
|
||||||
|
|
||||||
fn conv_with(self, line_index: &LineIndex) -> TextUnit {
|
fn conv_with(self, line_index: &LineIndex) -> TextSize {
|
||||||
let line_col = LineCol { line: self.line as u32, col_utf16: self.character as u32 };
|
let line_col = LineCol { line: self.line as u32, col_utf16: self.character as u32 };
|
||||||
line_index.offset(line_col)
|
line_index.offset(line_col)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConvWith<&LineIndex> for TextUnit {
|
impl ConvWith<&LineIndex> for TextSize {
|
||||||
type Output = Position;
|
type Output = Position;
|
||||||
|
|
||||||
fn conv_with(self, line_index: &LineIndex) -> Position {
|
fn conv_with(self, line_index: &LineIndex) -> Position {
|
||||||
|
@ -213,7 +213,7 @@ impl ConvWith<&LineIndex> for Range {
|
||||||
type Output = TextRange;
|
type Output = TextRange;
|
||||||
|
|
||||||
fn conv_with(self, line_index: &LineIndex) -> TextRange {
|
fn conv_with(self, line_index: &LineIndex) -> TextRange {
|
||||||
TextRange::from_to(self.start.conv_with(line_index), self.end.conv_with(line_index))
|
TextRange::new(self.start.conv_with(line_index), self.end.conv_with(line_index))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,7 +300,7 @@ impl ConvWith<&FoldConvCtx<'_>> for Fold {
|
||||||
// range.end.line from the folding region if there is more text after range.end
|
// range.end.line from the folding region if there is more text after range.end
|
||||||
// on the same line.
|
// on the same line.
|
||||||
let has_more_text_on_end_line = ctx.text
|
let has_more_text_on_end_line = ctx.text
|
||||||
[TextRange::from_to(self.range.end(), TextUnit::of_str(ctx.text))]
|
[TextRange::new(self.range.end(), TextSize::of(ctx.text))]
|
||||||
.chars()
|
.chars()
|
||||||
.take_while(|it| *it != '\n')
|
.take_while(|it| *it != '\n')
|
||||||
.any(|it| !it.is_whitespace());
|
.any(|it| !it.is_whitespace());
|
||||||
|
|
|
@ -23,7 +23,7 @@ use ra_ide::{
|
||||||
SearchScope,
|
SearchScope,
|
||||||
};
|
};
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
use ra_syntax::{AstNode, SyntaxKind, TextRange, TextUnit};
|
use ra_syntax::{AstNode, SyntaxKind, TextRange, TextSize};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::to_value;
|
use serde_json::to_value;
|
||||||
|
@ -97,7 +97,7 @@ pub fn handle_selection_range(
|
||||||
.map(|position| {
|
.map(|position| {
|
||||||
let mut ranges = Vec::new();
|
let mut ranges = Vec::new();
|
||||||
{
|
{
|
||||||
let mut range = TextRange::from_to(position, position);
|
let mut range = TextRange::new(position, position);
|
||||||
loop {
|
loop {
|
||||||
ranges.push(range);
|
ranges.push(range);
|
||||||
let frange = FileRange { file_id, range };
|
let frange = FileRange { file_id, range };
|
||||||
|
@ -184,11 +184,11 @@ pub fn handle_on_type_formatting(
|
||||||
|
|
||||||
// in `ra_ide`, the `on_type` invariant is that
|
// in `ra_ide`, the `on_type` invariant is that
|
||||||
// `text.char_at(position) == typed_char`.
|
// `text.char_at(position) == typed_char`.
|
||||||
position.offset -= TextUnit::of_char('.');
|
position.offset -= TextSize::of('.');
|
||||||
let char_typed = params.ch.chars().next().unwrap_or('\0');
|
let char_typed = params.ch.chars().next().unwrap_or('\0');
|
||||||
assert!({
|
assert!({
|
||||||
let text = world.analysis().file_text(position.file_id)?;
|
let text = world.analysis().file_text(position.file_id)?;
|
||||||
text[position.offset.to_usize()..].starts_with(char_typed)
|
text[usize::from(position.offset)..].starts_with(char_typed)
|
||||||
});
|
});
|
||||||
|
|
||||||
// We have an assist that inserts ` ` after typing `->` in `fn foo() ->{`,
|
// We have an assist that inserts ` ` after typing `->` in `fn foo() ->{`,
|
||||||
|
@ -403,7 +403,7 @@ pub fn handle_completion(
|
||||||
let syntax = source_file.syntax();
|
let syntax = source_file.syntax();
|
||||||
let text = syntax.text();
|
let text = syntax.text();
|
||||||
if let Some(next_char) = text.char_at(position.offset) {
|
if let Some(next_char) = text.char_at(position.offset) {
|
||||||
let diff = TextUnit::of_char(next_char) + TextUnit::of_char(':');
|
let diff = TextSize::of(next_char) + TextSize::of(':');
|
||||||
let prev_char = position.offset - diff;
|
let prev_char = position.offset - diff;
|
||||||
if text.char_at(prev_char) != Some(':') {
|
if text.char_at(prev_char) != Some(':') {
|
||||||
res = true;
|
res = true;
|
||||||
|
@ -592,7 +592,7 @@ pub fn handle_formatting(
|
||||||
let crate_ids = world.analysis().crate_for(file_id)?;
|
let crate_ids = world.analysis().crate_for(file_id)?;
|
||||||
|
|
||||||
let file_line_index = world.analysis().file_line_index(file_id)?;
|
let file_line_index = world.analysis().file_line_index(file_id)?;
|
||||||
let end_position = TextUnit::of_str(&file).conv_with(&file_line_index);
|
let end_position = TextSize::of(&file).conv_with(&file_line_index);
|
||||||
|
|
||||||
let mut rustfmt = match &world.config.rustfmt {
|
let mut rustfmt = match &world.config.rustfmt {
|
||||||
RustfmtConfig::Rustfmt { extra_args } => {
|
RustfmtConfig::Rustfmt { extra_args } => {
|
||||||
|
@ -698,7 +698,7 @@ pub fn handle_code_action(
|
||||||
let fixes_from_diagnostics = diagnostics
|
let fixes_from_diagnostics = diagnostics
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|d| Some((d.range, d.fix?)))
|
.filter_map(|d| Some((d.range, d.fix?)))
|
||||||
.filter(|(diag_range, _fix)| diag_range.intersection(&range).is_some())
|
.filter(|(diag_range, _fix)| diag_range.intersect(range).is_some())
|
||||||
.map(|(_range, fix)| fix);
|
.map(|(_range, fix)| fix);
|
||||||
|
|
||||||
for source_edit in fixes_from_diagnostics {
|
for source_edit in fixes_from_diagnostics {
|
||||||
|
@ -723,7 +723,7 @@ pub fn handle_code_action(
|
||||||
|
|
||||||
for fix in world.check_fixes.get(&file_id).into_iter().flatten() {
|
for fix in world.check_fixes.get(&file_id).into_iter().flatten() {
|
||||||
let fix_range = fix.range.conv_with(&line_index);
|
let fix_range = fix.range.conv_with(&line_index);
|
||||||
if fix_range.intersection(&range).is_none() {
|
if fix_range.intersect(range).is_none() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
res.push(fix.action.clone());
|
res.push(fix.action.clone());
|
||||||
|
@ -1107,7 +1107,7 @@ pub fn handle_semantic_tokens(
|
||||||
let (token_index, modifier_bitset) = highlight_range.highlight.conv();
|
let (token_index, modifier_bitset) = highlight_range.highlight.conv();
|
||||||
for mut range in line_index.lines(highlight_range.range) {
|
for mut range in line_index.lines(highlight_range.range) {
|
||||||
if text[range].ends_with('\n') {
|
if text[range].ends_with('\n') {
|
||||||
range = TextRange::from_to(range.start(), range.end() - TextUnit::of_char('\n'));
|
range = TextRange::new(range.start(), range.end() - TextSize::of('\n'));
|
||||||
}
|
}
|
||||||
let range = range.conv_with(&line_index);
|
let range = range.conv_with(&line_index);
|
||||||
builder.push(range, token_index, modifier_bitset);
|
builder.push(range, token_index, modifier_bitset);
|
||||||
|
|
|
@ -9,5 +9,5 @@ doctest = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
difference = "2.0.0"
|
difference = "2.0.0"
|
||||||
text_unit = "0.1.10"
|
text-size = { path = "../../../text-size" }
|
||||||
serde_json = "1.0.48"
|
serde_json = "1.0.48"
|
||||||
|
|
|
@ -15,7 +15,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use text_unit::{TextRange, TextUnit};
|
use text_size::{TextRange, TextSize};
|
||||||
|
|
||||||
pub use difference::Changeset as __Changeset;
|
pub use difference::Changeset as __Changeset;
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ macro_rules! assert_eq_text {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Infallible version of `try_extract_offset()`.
|
/// Infallible version of `try_extract_offset()`.
|
||||||
pub fn extract_offset(text: &str) -> (TextUnit, String) {
|
pub fn extract_offset(text: &str) -> (TextSize, String) {
|
||||||
match try_extract_offset(text) {
|
match try_extract_offset(text) {
|
||||||
None => panic!("text should contain cursor marker"),
|
None => panic!("text should contain cursor marker"),
|
||||||
Some(result) => result,
|
Some(result) => result,
|
||||||
|
@ -58,12 +58,12 @@ pub fn extract_offset(text: &str) -> (TextUnit, String) {
|
||||||
|
|
||||||
/// Returns the offset of the first occurence of `<|>` marker and the copy of `text`
|
/// Returns the offset of the first occurence of `<|>` marker and the copy of `text`
|
||||||
/// without the marker.
|
/// without the marker.
|
||||||
fn try_extract_offset(text: &str) -> Option<(TextUnit, String)> {
|
fn try_extract_offset(text: &str) -> Option<(TextSize, String)> {
|
||||||
let cursor_pos = text.find(CURSOR_MARKER)?;
|
let cursor_pos = text.find(CURSOR_MARKER)?;
|
||||||
let mut new_text = String::with_capacity(text.len() - CURSOR_MARKER.len());
|
let mut new_text = String::with_capacity(text.len() - CURSOR_MARKER.len());
|
||||||
new_text.push_str(&text[..cursor_pos]);
|
new_text.push_str(&text[..cursor_pos]);
|
||||||
new_text.push_str(&text[cursor_pos + CURSOR_MARKER.len()..]);
|
new_text.push_str(&text[cursor_pos + CURSOR_MARKER.len()..]);
|
||||||
let cursor_pos = TextUnit::from(cursor_pos as u32);
|
let cursor_pos = TextSize::from(cursor_pos as u32);
|
||||||
Some((cursor_pos, new_text))
|
Some((cursor_pos, new_text))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,25 +80,25 @@ pub fn extract_range(text: &str) -> (TextRange, String) {
|
||||||
fn try_extract_range(text: &str) -> Option<(TextRange, String)> {
|
fn try_extract_range(text: &str) -> Option<(TextRange, String)> {
|
||||||
let (start, text) = try_extract_offset(text)?;
|
let (start, text) = try_extract_offset(text)?;
|
||||||
let (end, text) = try_extract_offset(&text)?;
|
let (end, text) = try_extract_offset(&text)?;
|
||||||
Some((TextRange::from_to(start, end), text))
|
Some((TextRange::new(start, end), text))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum RangeOrOffset {
|
pub enum RangeOrOffset {
|
||||||
Range(TextRange),
|
Range(TextRange),
|
||||||
Offset(TextUnit),
|
Offset(TextSize),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<RangeOrOffset> for TextRange {
|
impl From<RangeOrOffset> for TextRange {
|
||||||
fn from(selection: RangeOrOffset) -> Self {
|
fn from(selection: RangeOrOffset) -> Self {
|
||||||
match selection {
|
match selection {
|
||||||
RangeOrOffset::Range(it) => it,
|
RangeOrOffset::Range(it) => it,
|
||||||
RangeOrOffset::Offset(it) => TextRange::from_to(it, it),
|
RangeOrOffset::Offset(it) => TextRange::new(it, it),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extracts `TextRange` or `TextUnit` depending on the amount of `<|>` markers
|
/// Extracts `TextRange` or `TextSize` depending on the amount of `<|>` markers
|
||||||
/// found in `text`.
|
/// found in `text`.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
|
@ -129,13 +129,13 @@ pub fn extract_ranges(mut text: &str, tag: &str) -> (Vec<TextRange>, String) {
|
||||||
text = &text[i..];
|
text = &text[i..];
|
||||||
if text.starts_with(&open) {
|
if text.starts_with(&open) {
|
||||||
text = &text[open.len()..];
|
text = &text[open.len()..];
|
||||||
let from = TextUnit::of_str(&res);
|
let from = TextSize::of(&res);
|
||||||
stack.push(from);
|
stack.push(from);
|
||||||
} else if text.starts_with(&close) {
|
} else if text.starts_with(&close) {
|
||||||
text = &text[close.len()..];
|
text = &text[close.len()..];
|
||||||
let from = stack.pop().unwrap_or_else(|| panic!("unmatched </{}>", tag));
|
let from = stack.pop().unwrap_or_else(|| panic!("unmatched </{}>", tag));
|
||||||
let to = TextUnit::of_str(&res);
|
let to = TextSize::of(&res);
|
||||||
ranges.push(TextRange::from_to(from, to));
|
ranges.push(TextRange::new(from, to));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -146,8 +146,8 @@ pub fn extract_ranges(mut text: &str, tag: &str) -> (Vec<TextRange>, String) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Inserts `<|>` marker into the `text` at `offset`.
|
/// Inserts `<|>` marker into the `text` at `offset`.
|
||||||
pub fn add_cursor(text: &str, offset: TextUnit) -> String {
|
pub fn add_cursor(text: &str, offset: TextSize) -> String {
|
||||||
let offset: usize = offset.to_usize();
|
let offset: usize = offset.into();
|
||||||
let mut res = String::new();
|
let mut res = String::new();
|
||||||
res.push_str(&text[..offset]);
|
res.push_str(&text[..offset]);
|
||||||
res.push_str("<|>");
|
res.push_str("<|>");
|
||||||
|
|
|
@ -132,7 +132,7 @@ That is, it's not an index into interning table, so you don't have to have the t
|
||||||
Each tree is fully self-contained (although different trees might share parts).
|
Each tree is fully self-contained (although different trees might share parts).
|
||||||
Currently, the interner is created per-file, but it will be easy to use a per-thread or per-some-contex one.
|
Currently, the interner is created per-file, but it will be easy to use a per-thread or per-some-contex one.
|
||||||
|
|
||||||
We use a `TextUnit`, a newtyped `u32`, to store the length of the text.
|
We use a `TextSize`, a newtyped `u32`, to store the length of the text.
|
||||||
|
|
||||||
We currently use `SmolStr`, an small object optimized string to store text.
|
We currently use `SmolStr`, an small object optimized string to store text.
|
||||||
This was mostly relevant *before* we implmented tree interning, to avoid allocating common keywords and identifiers. We should switch to storing text data alongside the interned tokens.
|
This was mostly relevant *before* we implmented tree interning, to avoid allocating common keywords and identifiers. We should switch to storing text data alongside the interned tokens.
|
||||||
|
|
Loading…
Reference in a new issue