mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-11-14 01:41:26 +00:00
Workaround missing none group support in builtin macros
This commit is contained in:
parent
5b852da4c3
commit
54c87d8753
4 changed files with 22 additions and 40 deletions
|
|
@ -7,6 +7,7 @@ use intern::{
|
||||||
Symbol,
|
Symbol,
|
||||||
sym::{self},
|
sym::{self},
|
||||||
};
|
};
|
||||||
|
use itertools::Itertools;
|
||||||
use mbe::{DelimiterKind, expect_fragment};
|
use mbe::{DelimiterKind, expect_fragment};
|
||||||
use span::{Edition, FileId, Span};
|
use span::{Edition, FileId, Span};
|
||||||
use stdx::format_to;
|
use stdx::format_to;
|
||||||
|
|
@ -681,11 +682,19 @@ fn relative_file(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_string(tt: &tt::TopSubtree) -> Result<(Symbol, Span), ExpandError> {
|
fn parse_string(tt: &tt::TopSubtree) -> Result<(Symbol, Span), ExpandError> {
|
||||||
let delimiter = tt.top_subtree().delimiter;
|
let mut tt = TtElement::Subtree(tt.top_subtree(), tt.iter());
|
||||||
tt.iter()
|
(|| {
|
||||||
.next()
|
// FIXME: We wrap expression fragments in parentheses which can break this expectation
|
||||||
.ok_or(delimiter.open.cover(delimiter.close))
|
// here
|
||||||
.and_then(|tt| match tt {
|
// Remove this once we handle none delims correctly
|
||||||
|
while let TtElement::Subtree(sub, tt_iter) = &mut tt
|
||||||
|
&& let DelimiterKind::Parenthesis | DelimiterKind::Invisible = sub.delimiter.kind
|
||||||
|
{
|
||||||
|
tt =
|
||||||
|
tt_iter.exactly_one().map_err(|_| sub.delimiter.open.cover(sub.delimiter.close))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
match tt {
|
||||||
TtElement::Leaf(tt::Leaf::Literal(tt::Literal {
|
TtElement::Leaf(tt::Leaf::Literal(tt::Literal {
|
||||||
symbol: text,
|
symbol: text,
|
||||||
span,
|
span,
|
||||||
|
|
@ -698,35 +707,11 @@ fn parse_string(tt: &tt::TopSubtree) -> Result<(Symbol, Span), ExpandError> {
|
||||||
kind: tt::LitKind::StrRaw(_),
|
kind: tt::LitKind::StrRaw(_),
|
||||||
suffix: _,
|
suffix: _,
|
||||||
})) => Ok((text.clone(), *span)),
|
})) => Ok((text.clone(), *span)),
|
||||||
// FIXME: We wrap expression fragments in parentheses which can break this expectation
|
|
||||||
// here
|
|
||||||
// Remove this once we handle none delims correctly
|
|
||||||
TtElement::Subtree(tt, mut tt_iter)
|
|
||||||
if tt.delimiter.kind == DelimiterKind::Parenthesis =>
|
|
||||||
{
|
|
||||||
tt_iter
|
|
||||||
.next()
|
|
||||||
.and_then(|tt| match tt {
|
|
||||||
TtElement::Leaf(tt::Leaf::Literal(tt::Literal {
|
|
||||||
symbol: text,
|
|
||||||
span,
|
|
||||||
kind: tt::LitKind::Str,
|
|
||||||
suffix: _,
|
|
||||||
})) => Some((unescape_symbol(text), *span)),
|
|
||||||
TtElement::Leaf(tt::Leaf::Literal(tt::Literal {
|
|
||||||
symbol: text,
|
|
||||||
span,
|
|
||||||
kind: tt::LitKind::StrRaw(_),
|
|
||||||
suffix: _,
|
|
||||||
})) => Some((text.clone(), *span)),
|
|
||||||
_ => None,
|
|
||||||
})
|
|
||||||
.ok_or(delimiter.open.cover(delimiter.close))
|
|
||||||
}
|
|
||||||
TtElement::Leaf(l) => Err(*l.span()),
|
TtElement::Leaf(l) => Err(*l.span()),
|
||||||
TtElement::Subtree(tt, _) => Err(tt.delimiter.open.cover(tt.delimiter.close)),
|
TtElement::Subtree(tt, _) => Err(tt.delimiter.open.cover(tt.delimiter.close)),
|
||||||
})
|
}
|
||||||
.map_err(|span| ExpandError::other(span, "expected string literal"))
|
})()
|
||||||
|
.map_err(|span| ExpandError::other(span, "expected string literal"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn include_expand(
|
fn include_expand(
|
||||||
|
|
|
||||||
|
|
@ -1526,7 +1526,7 @@ impl Config {
|
||||||
CompletionConfig {
|
CompletionConfig {
|
||||||
enable_postfix_completions: self.completion_postfix_enable(source_root).to_owned(),
|
enable_postfix_completions: self.completion_postfix_enable(source_root).to_owned(),
|
||||||
enable_imports_on_the_fly: self.completion_autoimport_enable(source_root).to_owned()
|
enable_imports_on_the_fly: self.completion_autoimport_enable(source_root).to_owned()
|
||||||
&& self.caps.completion_item_edit_resolve(),
|
&& self.caps.has_completion_item_resolve_additionalTextEdits(),
|
||||||
enable_self_on_the_fly: self.completion_autoself_enable(source_root).to_owned(),
|
enable_self_on_the_fly: self.completion_autoself_enable(source_root).to_owned(),
|
||||||
enable_auto_iter: *self.completion_autoIter_enable(source_root),
|
enable_auto_iter: *self.completion_autoIter_enable(source_root),
|
||||||
enable_auto_await: *self.completion_autoAwait_enable(source_root),
|
enable_auto_await: *self.completion_autoAwait_enable(source_root),
|
||||||
|
|
@ -2355,10 +2355,6 @@ impl Config {
|
||||||
.and_then(|it| it.version.as_ref())
|
.and_then(|it| it.version.as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn client_is_helix(&self) -> bool {
|
|
||||||
self.client_info.as_ref().map(|it| it.name == "helix").unwrap_or_default()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn client_is_neovim(&self) -> bool {
|
pub fn client_is_neovim(&self) -> bool {
|
||||||
self.client_info.as_ref().map(|it| it.name == "Neovim").unwrap_or_default()
|
self.client_info.as_ref().map(|it| it.name == "Neovim").unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ pub fn server_capabilities(config: &Config) -> ServerCapabilities {
|
||||||
hover_provider: Some(HoverProviderCapability::Simple(true)),
|
hover_provider: Some(HoverProviderCapability::Simple(true)),
|
||||||
completion_provider: Some(CompletionOptions {
|
completion_provider: Some(CompletionOptions {
|
||||||
resolve_provider: if config.client_is_neovim() {
|
resolve_provider: if config.client_is_neovim() {
|
||||||
config.completion_item_edit_resolve().then_some(true)
|
config.has_completion_item_resolve_additionalTextEdits().then_some(true)
|
||||||
} else {
|
} else {
|
||||||
Some(config.caps().completions_resolve_provider())
|
Some(config.caps().completions_resolve_provider())
|
||||||
},
|
},
|
||||||
|
|
@ -207,8 +207,8 @@ impl ClientCapabilities {
|
||||||
serde_json::from_value(self.0.experimental.as_ref()?.get(index)?.clone()).ok()
|
serde_json::from_value(self.0.experimental.as_ref()?.get(index)?.clone()).ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses client capabilities and returns all completion resolve capabilities rust-analyzer supports.
|
#[allow(non_snake_case)]
|
||||||
pub fn completion_item_edit_resolve(&self) -> bool {
|
pub fn has_completion_item_resolve_additionalTextEdits(&self) -> bool {
|
||||||
(|| {
|
(|| {
|
||||||
Some(
|
Some(
|
||||||
self.0
|
self.0
|
||||||
|
|
|
||||||
|
|
@ -211,6 +211,7 @@ impl<'a, S: Copy> TtIter<'a, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub enum TtElement<'a, S> {
|
pub enum TtElement<'a, S> {
|
||||||
Leaf(&'a Leaf<S>),
|
Leaf(&'a Leaf<S>),
|
||||||
Subtree(&'a Subtree<S>, TtIter<'a, S>),
|
Subtree(&'a Subtree<S>, TtIter<'a, S>),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue