mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 15:01:51 +00:00
fix stray curly
This commit is contained in:
parent
a48964c64d
commit
a450142aca
@ -32,7 +32,7 @@ use libsyntax2::{
|
||||
ast::{self, AstNode, NameOwner},
|
||||
SyntaxKind::*,
|
||||
};
|
||||
use libeditor::{LineIndex, FileSymbol, find_node};
|
||||
use libeditor::{LineIndex, FileSymbol, find_node_at_offset};
|
||||
|
||||
use self::{
|
||||
symbol_index::FileSymbols,
|
||||
@ -183,10 +183,10 @@ impl World {
|
||||
) -> Result<Vec<(FileId, FileSymbol)>> {
|
||||
let file = self.file_syntax(id)?;
|
||||
let syntax = file.syntax();
|
||||
if let Some(name_ref) = find_node::<ast::NameRef>(syntax, offset) {
|
||||
if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) {
|
||||
return Ok(self.index_resolve(name_ref));
|
||||
}
|
||||
if let Some(name) = find_node::<ast::Name>(syntax, offset) {
|
||||
if let Some(name) = find_node_at_offset::<ast::Name>(syntax, offset) {
|
||||
if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) {
|
||||
if module.has_semi() {
|
||||
let file_ids = self.resolve_module(id, module);
|
||||
|
@ -3,7 +3,7 @@ use std::{
|
||||
};
|
||||
|
||||
use libsyntax2::{
|
||||
File,
|
||||
File, TextUnit,
|
||||
ast::{self, AstNode, AttrsOwner, TypeParamsOwner, NameOwner},
|
||||
SyntaxKind::COMMA,
|
||||
SyntaxNodeRef,
|
||||
@ -13,7 +13,7 @@ use libsyntax2::{
|
||||
},
|
||||
};
|
||||
|
||||
use {TextUnit, EditBuilder, Edit};
|
||||
use {EditBuilder, Edit, find_node_at_offset};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ActionResult {
|
||||
@ -39,7 +39,7 @@ pub fn flip_comma<'a>(file: &'a File, offset: TextUnit) -> Option<impl FnOnce()
|
||||
}
|
||||
|
||||
pub fn add_derive<'a>(file: &'a File, offset: TextUnit) -> Option<impl FnOnce() -> ActionResult + 'a> {
|
||||
let nominal = find_node::<ast::NominalDef>(file.syntax(), offset)?;
|
||||
let nominal = find_node_at_offset::<ast::NominalDef>(file.syntax(), offset)?;
|
||||
Some(move || {
|
||||
let derive_attr = nominal
|
||||
.attrs()
|
||||
@ -66,7 +66,7 @@ pub fn add_derive<'a>(file: &'a File, offset: TextUnit) -> Option<impl FnOnce()
|
||||
}
|
||||
|
||||
pub fn add_impl<'a>(file: &'a File, offset: TextUnit) -> Option<impl FnOnce() -> ActionResult + 'a> {
|
||||
let nominal = find_node::<ast::NominalDef>(file.syntax(), offset)?;
|
||||
let nominal = find_node_at_offset::<ast::NominalDef>(file.syntax(), offset)?;
|
||||
let name = nominal.name()?;
|
||||
|
||||
Some(move || {
|
||||
@ -105,16 +105,6 @@ fn non_trivia_sibling(node: SyntaxNodeRef, direction: Direction) -> Option<Synta
|
||||
.find(|node| !node.kind().is_trivia())
|
||||
}
|
||||
|
||||
pub fn find_node<'a, N: AstNode<'a>>(syntax: SyntaxNodeRef<'a>, offset: TextUnit) -> Option<N> {
|
||||
let leaves = find_leaf_at_offset(syntax, offset);
|
||||
let leaf = leaves.clone()
|
||||
.find(|leaf| !leaf.kind().is_trivia())
|
||||
.or_else(|| leaves.right_biased())?;
|
||||
ancestors(leaf)
|
||||
.filter_map(N::cast)
|
||||
.next()
|
||||
}
|
||||
|
||||
fn comma_list(buf: &mut String, bra: &str, ket: &str, items: impl Iterator<Item=impl fmt::Display>) {
|
||||
buf.push_str(bra);
|
||||
let mut first = true;
|
||||
|
31
crates/libeditor/src/completion.rs
Normal file
31
crates/libeditor/src/completion.rs
Normal file
@ -0,0 +1,31 @@
|
||||
use libsyntax2::{
|
||||
File, TextUnit,
|
||||
ast,
|
||||
algo::find_leaf_at_offset,
|
||||
};
|
||||
|
||||
use {
|
||||
AtomEdit, find_node_at_offset,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CompletionItem {
|
||||
name: String,
|
||||
}
|
||||
|
||||
pub fn scope_completion(file: &File, offset: TextUnit) -> Option<Vec<CompletionItem>> {
|
||||
// Insert a fake ident to get a valid parse tree
|
||||
let file = {
|
||||
let edit = AtomEdit::insert(offset, "intellijRulezz".to_string());
|
||||
// Don't bother with completion if incremental reparse fails
|
||||
file.incremental_reparse(&edit)?
|
||||
};
|
||||
let name_ref = find_node_at_offset::<ast::NameRef>(file.syntax(), offset)?;
|
||||
Some(complete(name_ref))
|
||||
}
|
||||
|
||||
fn complete(name_ref: ast::NameRef) -> Vec<CompletionItem> {
|
||||
vec![CompletionItem {
|
||||
name: "foo".to_string()
|
||||
}]
|
||||
}
|
@ -8,11 +8,12 @@ mod line_index;
|
||||
mod edit;
|
||||
mod code_actions;
|
||||
mod typing;
|
||||
mod completion;
|
||||
|
||||
use libsyntax2::{
|
||||
File, TextUnit, TextRange,
|
||||
File, TextUnit, TextRange, SyntaxNodeRef,
|
||||
ast::{AstNode, NameOwner},
|
||||
algo::{walk, find_leaf_at_offset},
|
||||
algo::{walk, find_leaf_at_offset, ancestors},
|
||||
SyntaxKind::{self, *},
|
||||
};
|
||||
pub use libsyntax2::AtomEdit;
|
||||
@ -22,10 +23,11 @@ pub use self::{
|
||||
symbols::{StructureNode, file_structure, FileSymbol, file_symbols},
|
||||
edit::{EditBuilder, Edit},
|
||||
code_actions::{
|
||||
ActionResult, find_node,
|
||||
ActionResult,
|
||||
flip_comma, add_derive, add_impl,
|
||||
},
|
||||
typing::join_lines,
|
||||
completion::scope_completion,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -138,3 +140,16 @@ pub fn runnables(file: &File) -> Vec<Runnable> {
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn find_node_at_offset<'a, N: AstNode<'a>>(
|
||||
syntax: SyntaxNodeRef<'a>,
|
||||
offset: TextUnit,
|
||||
) -> Option<N> {
|
||||
let leaves = find_leaf_at_offset(syntax, offset);
|
||||
let leaf = leaves.clone()
|
||||
.find(|leaf| !leaf.kind().is_trivia())
|
||||
.or_else(|| leaves.right_biased())?;
|
||||
ancestors(leaf)
|
||||
.filter_map(N::cast)
|
||||
.next()
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ use libeditor::{
|
||||
ActionResult,
|
||||
highlight, runnables, extend_selection, file_structure,
|
||||
flip_comma, add_derive, add_impl, matching_brace,
|
||||
join_lines,
|
||||
join_lines, scope_completion,
|
||||
};
|
||||
|
||||
#[test]
|
||||
@ -244,6 +244,26 @@ struct Foo { f: u32 }
|
||||
");
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn test_completion() {
|
||||
// fn do_check(code: &str, expected_completions: &str) {
|
||||
// let (off, code) = extract_offset(&code);
|
||||
// let file = file(&code);
|
||||
// let completions = scope_completion(&file, off).unwrap();
|
||||
// assert_eq_dbg(expected_completions, &completions);
|
||||
// }
|
||||
|
||||
// do_check(r"
|
||||
// fn foo(foo: i32) {
|
||||
// let bar = 92;
|
||||
// 1 + <|>
|
||||
// }
|
||||
// ", r#"
|
||||
// CompletionItem { name: "bar" },
|
||||
// CompletionItem { name: "foo" },
|
||||
// "#);
|
||||
// }
|
||||
|
||||
fn file(text: &str) -> File {
|
||||
File::parse(text)
|
||||
}
|
||||
|
@ -43,7 +43,12 @@ pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool, flavor: ItemF
|
||||
m.abandon(p);
|
||||
if p.at(L_CURLY) {
|
||||
error_block(p, "expected an item");
|
||||
} else if !p.at(EOF) && !(stop_on_r_curly && p.at(R_CURLY)) {
|
||||
} else if p.at(R_CURLY) && !stop_on_r_curly {
|
||||
let e = p.start();
|
||||
p.error("unmatched `}`");
|
||||
p.bump();
|
||||
e.complete(p, ERROR);
|
||||
} else if !p.at(EOF) && !p.at(R_CURLY) {
|
||||
p.err_and_bump("expected an item");
|
||||
} else {
|
||||
p.error("expected an item");
|
||||
|
@ -127,12 +127,12 @@ fn validate_block_structure(root: SyntaxNodeRef) {
|
||||
assert_eq!(
|
||||
node.parent(),
|
||||
pair.parent(),
|
||||
"unpaired curleys:\n{}",
|
||||
"\nunpaired curleys:\n{}",
|
||||
utils::dump_tree(root),
|
||||
);
|
||||
assert!(
|
||||
node.next_sibling().is_none() && pair.prev_sibling().is_none(),
|
||||
"floating curlys at {:?}\nfile:\n{}\nerror:\n{}\n",
|
||||
"\nfloating curlys at {:?}\nfile:\n{}\nerror:\n{}\n",
|
||||
node,
|
||||
root.text(),
|
||||
node.text(),
|
||||
|
@ -141,7 +141,9 @@ impl<'t> Parser<'t> {
|
||||
pub(crate) fn err_and_bump(&mut self, message: &str) {
|
||||
let m = self.start();
|
||||
self.error(message);
|
||||
self.bump();
|
||||
if !self.at(SyntaxKind::L_CURLY) && !self.at(SyntaxKind::R_CURLY) {
|
||||
self.bump();
|
||||
}
|
||||
m.complete(self, ERROR);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
ROOT@[0; 31)
|
||||
ERROR@[0; 1)
|
||||
R_CURLY@[0; 1)
|
||||
err: `expected an item`
|
||||
err: `unmatched `}``
|
||||
WHITESPACE@[1; 3)
|
||||
STRUCT_DEF@[3; 12)
|
||||
STRUCT_KW@[3; 9)
|
||||
@ -10,7 +10,7 @@ ROOT@[0; 31)
|
||||
IDENT@[10; 11) "S"
|
||||
SEMI@[11; 12)
|
||||
WHITESPACE@[12; 14)
|
||||
err: `expected an item`
|
||||
err: `unmatched `}``
|
||||
ERROR@[14; 15)
|
||||
R_CURLY@[14; 15)
|
||||
WHITESPACE@[15; 17)
|
||||
@ -26,7 +26,7 @@ ROOT@[0; 31)
|
||||
L_CURLY@[25; 26)
|
||||
R_CURLY@[26; 27)
|
||||
WHITESPACE@[27; 29)
|
||||
err: `expected an item`
|
||||
err: `unmatched `}``
|
||||
ERROR@[29; 30)
|
||||
R_CURLY@[29; 30)
|
||||
WHITESPACE@[30; 31)
|
||||
|
@ -9,7 +9,7 @@ ROOT@[0; 14)
|
||||
err: `expected value parameter`
|
||||
err: `expected R_PAREN`
|
||||
err: `expected a block`
|
||||
err: `expected an item`
|
||||
err: `unmatched `}``
|
||||
ERROR@[7; 8)
|
||||
R_CURLY@[7; 8)
|
||||
err: `expected an item`
|
||||
|
@ -0,0 +1,4 @@
|
||||
fn foo(foo: i32) {
|
||||
let bar = 92;
|
||||
1 +
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
ROOT@[0; 47)
|
||||
FN_DEF@[0; 46)
|
||||
FN_KW@[0; 2)
|
||||
WHITESPACE@[2; 3)
|
||||
NAME@[3; 6)
|
||||
IDENT@[3; 6) "foo"
|
||||
PARAM_LIST@[6; 16)
|
||||
L_PAREN@[6; 7)
|
||||
PARAM@[7; 15)
|
||||
BIND_PAT@[7; 10)
|
||||
NAME@[7; 10)
|
||||
IDENT@[7; 10) "foo"
|
||||
COLON@[10; 11)
|
||||
WHITESPACE@[11; 12)
|
||||
PATH_TYPE@[12; 15)
|
||||
PATH@[12; 15)
|
||||
PATH_SEGMENT@[12; 15)
|
||||
NAME_REF@[12; 15)
|
||||
IDENT@[12; 15) "i32"
|
||||
R_PAREN@[15; 16)
|
||||
WHITESPACE@[16; 17)
|
||||
BLOCK@[17; 46)
|
||||
L_CURLY@[17; 18)
|
||||
WHITESPACE@[18; 23)
|
||||
LET_STMT@[23; 36)
|
||||
LET_KW@[23; 26)
|
||||
WHITESPACE@[26; 27)
|
||||
BIND_PAT@[27; 30)
|
||||
NAME@[27; 30)
|
||||
IDENT@[27; 30) "bar"
|
||||
WHITESPACE@[30; 31)
|
||||
EQ@[31; 32)
|
||||
WHITESPACE@[32; 33)
|
||||
LITERAL@[33; 35)
|
||||
INT_NUMBER@[33; 35) "92"
|
||||
SEMI@[35; 36)
|
||||
WHITESPACE@[36; 41)
|
||||
BIN_EXPR@[41; 45)
|
||||
LITERAL@[41; 42)
|
||||
INT_NUMBER@[41; 42) "1"
|
||||
WHITESPACE@[42; 43)
|
||||
PLUS@[43; 44)
|
||||
WHITESPACE@[44; 45)
|
||||
err: `expected expression`
|
||||
ERROR@[45; 45)
|
||||
R_CURLY@[45; 46)
|
||||
WHITESPACE@[46; 47)
|
@ -26,6 +26,7 @@ fn lexer_tests() {
|
||||
#[test]
|
||||
fn parser_tests() {
|
||||
dir_tests(&["parser/inline", "parser/ok", "parser/err"], |text| {
|
||||
eprintln!("\n{}\n", text);
|
||||
let file = File::parse(text);
|
||||
dump_tree(file.syntax())
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user