mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Merge pull request #19928 from Veykril/push-kznpuqllrvvq
Deduplicate code in proc-macro-srv
This commit is contained in:
commit
634596e2d7
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
use intern::Symbol;
|
||||||
use proc_macro::bridge;
|
use proc_macro::bridge;
|
||||||
|
|
||||||
mod token_stream;
|
mod token_stream;
|
||||||
@ -112,3 +113,135 @@ fn literal_kind_to_internal(kind: bridge::LitKind) -> tt::LitKind {
|
|||||||
bridge::LitKind::ErrWithGuar => tt::LitKind::Err(()),
|
bridge::LitKind::ErrWithGuar => tt::LitKind::Err(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn literal_from_str<Span: Copy>(
|
||||||
|
s: &str,
|
||||||
|
span: Span,
|
||||||
|
) -> Result<bridge::Literal<Span, Symbol>, ()> {
|
||||||
|
use proc_macro::bridge::LitKind;
|
||||||
|
use rustc_lexer::{LiteralKind, Token, TokenKind};
|
||||||
|
|
||||||
|
let mut tokens = rustc_lexer::tokenize(s);
|
||||||
|
let minus_or_lit = tokens.next().unwrap_or(Token { kind: TokenKind::Eof, len: 0 });
|
||||||
|
|
||||||
|
let lit = if minus_or_lit.kind == TokenKind::Minus {
|
||||||
|
let lit = tokens.next().ok_or(())?;
|
||||||
|
if !matches!(
|
||||||
|
lit.kind,
|
||||||
|
TokenKind::Literal { kind: LiteralKind::Int { .. } | LiteralKind::Float { .. }, .. }
|
||||||
|
) {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
lit
|
||||||
|
} else {
|
||||||
|
minus_or_lit
|
||||||
|
};
|
||||||
|
|
||||||
|
if tokens.next().is_some() {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let TokenKind::Literal { kind, suffix_start } = lit.kind else { return Err(()) };
|
||||||
|
let (kind, start_offset, end_offset) = match kind {
|
||||||
|
LiteralKind::Int { .. } => (LitKind::Integer, 0, 0),
|
||||||
|
LiteralKind::Float { .. } => (LitKind::Float, 0, 0),
|
||||||
|
LiteralKind::Char { terminated } => (LitKind::Char, 1, terminated as usize),
|
||||||
|
LiteralKind::Byte { terminated } => (LitKind::Byte, 2, terminated as usize),
|
||||||
|
LiteralKind::Str { terminated } => (LitKind::Str, 1, terminated as usize),
|
||||||
|
LiteralKind::ByteStr { terminated } => (LitKind::ByteStr, 2, terminated as usize),
|
||||||
|
LiteralKind::CStr { terminated } => (LitKind::CStr, 2, terminated as usize),
|
||||||
|
LiteralKind::RawStr { n_hashes } => (
|
||||||
|
LitKind::StrRaw(n_hashes.unwrap_or_default()),
|
||||||
|
2 + n_hashes.unwrap_or_default() as usize,
|
||||||
|
1 + n_hashes.unwrap_or_default() as usize,
|
||||||
|
),
|
||||||
|
LiteralKind::RawByteStr { n_hashes } => (
|
||||||
|
LitKind::ByteStrRaw(n_hashes.unwrap_or_default()),
|
||||||
|
3 + n_hashes.unwrap_or_default() as usize,
|
||||||
|
1 + n_hashes.unwrap_or_default() as usize,
|
||||||
|
),
|
||||||
|
LiteralKind::RawCStr { n_hashes } => (
|
||||||
|
LitKind::CStrRaw(n_hashes.unwrap_or_default()),
|
||||||
|
3 + n_hashes.unwrap_or_default() as usize,
|
||||||
|
1 + n_hashes.unwrap_or_default() as usize,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
let (lit, suffix) = s.split_at(suffix_start as usize);
|
||||||
|
let lit = &lit[start_offset..lit.len() - end_offset];
|
||||||
|
let suffix = match suffix {
|
||||||
|
"" | "_" => None,
|
||||||
|
suffix => Some(Symbol::intern(suffix)),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(bridge::Literal { kind, symbol: Symbol::intern(lit), suffix, span })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn from_token_tree<Span: Copy>(
|
||||||
|
tree: bridge::TokenTree<TokenStream<Span>, Span, Symbol>,
|
||||||
|
) -> TokenStream<Span> {
|
||||||
|
match tree {
|
||||||
|
bridge::TokenTree::Group(group) => {
|
||||||
|
let group = TopSubtree::from_bridge(group);
|
||||||
|
TokenStream { token_trees: group.0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
bridge::TokenTree::Ident(ident) => {
|
||||||
|
let text = ident.sym;
|
||||||
|
let ident: tt::Ident<Span> = tt::Ident {
|
||||||
|
sym: text,
|
||||||
|
span: ident.span,
|
||||||
|
is_raw: if ident.is_raw { tt::IdentIsRaw::Yes } else { tt::IdentIsRaw::No },
|
||||||
|
};
|
||||||
|
let leaf = tt::Leaf::from(ident);
|
||||||
|
let tree = tt::TokenTree::from(leaf);
|
||||||
|
TokenStream { token_trees: vec![tree] }
|
||||||
|
}
|
||||||
|
|
||||||
|
bridge::TokenTree::Literal(literal) => {
|
||||||
|
let token_trees =
|
||||||
|
if let Some((_minus, symbol)) = literal.symbol.as_str().split_once('-') {
|
||||||
|
let punct = tt::Punct {
|
||||||
|
spacing: tt::Spacing::Alone,
|
||||||
|
span: literal.span,
|
||||||
|
char: '-' as char,
|
||||||
|
};
|
||||||
|
let leaf: tt::Leaf<Span> = tt::Leaf::from(punct);
|
||||||
|
let minus_tree = tt::TokenTree::from(leaf);
|
||||||
|
|
||||||
|
let literal = tt::Literal {
|
||||||
|
symbol: Symbol::intern(symbol),
|
||||||
|
suffix: literal.suffix,
|
||||||
|
span: literal.span,
|
||||||
|
kind: literal_kind_to_internal(literal.kind),
|
||||||
|
};
|
||||||
|
let leaf: tt::Leaf<Span> = tt::Leaf::from(literal);
|
||||||
|
let tree = tt::TokenTree::from(leaf);
|
||||||
|
vec![minus_tree, tree]
|
||||||
|
} else {
|
||||||
|
let literal = tt::Literal {
|
||||||
|
symbol: literal.symbol,
|
||||||
|
suffix: literal.suffix,
|
||||||
|
span: literal.span,
|
||||||
|
kind: literal_kind_to_internal(literal.kind),
|
||||||
|
};
|
||||||
|
|
||||||
|
let leaf: tt::Leaf<Span> = tt::Leaf::from(literal);
|
||||||
|
let tree = tt::TokenTree::from(leaf);
|
||||||
|
vec![tree]
|
||||||
|
};
|
||||||
|
TokenStream { token_trees }
|
||||||
|
}
|
||||||
|
|
||||||
|
bridge::TokenTree::Punct(p) => {
|
||||||
|
let punct = tt::Punct {
|
||||||
|
char: p.ch as char,
|
||||||
|
spacing: if p.joint { tt::Spacing::Joint } else { tt::Spacing::Alone },
|
||||||
|
span: p.span,
|
||||||
|
};
|
||||||
|
let leaf = tt::Leaf::from(punct);
|
||||||
|
let tree = tt::TokenTree::from(leaf);
|
||||||
|
TokenStream { token_trees: vec![tree] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -14,16 +14,7 @@ use proc_macro::bridge::{self, server};
|
|||||||
use span::{FIXUP_ERASED_FILE_AST_ID_MARKER, Span};
|
use span::{FIXUP_ERASED_FILE_AST_ID_MARKER, Span};
|
||||||
use tt::{TextRange, TextSize};
|
use tt::{TextRange, TextSize};
|
||||||
|
|
||||||
use crate::server_impl::{TopSubtree, literal_kind_to_internal, token_stream::TokenStreamBuilder};
|
use crate::server_impl::{from_token_tree, literal_from_str, token_stream::TokenStreamBuilder};
|
||||||
mod tt {
|
|
||||||
pub use tt::*;
|
|
||||||
|
|
||||||
pub type TokenTree = ::tt::TokenTree<super::Span>;
|
|
||||||
pub type Leaf = ::tt::Leaf<super::Span>;
|
|
||||||
pub type Literal = ::tt::Literal<super::Span>;
|
|
||||||
pub type Punct = ::tt::Punct<super::Span>;
|
|
||||||
pub type Ident = ::tt::Ident<super::Span>;
|
|
||||||
}
|
|
||||||
|
|
||||||
type TokenStream = crate::server_impl::TokenStream<Span>;
|
type TokenStream = crate::server_impl::TokenStream<Span>;
|
||||||
|
|
||||||
@ -62,66 +53,7 @@ impl server::FreeFunctions for RaSpanServer {
|
|||||||
&mut self,
|
&mut self,
|
||||||
s: &str,
|
s: &str,
|
||||||
) -> Result<bridge::Literal<Self::Span, Self::Symbol>, ()> {
|
) -> Result<bridge::Literal<Self::Span, Self::Symbol>, ()> {
|
||||||
use proc_macro::bridge::LitKind;
|
literal_from_str(s, self.call_site)
|
||||||
use rustc_lexer::{LiteralKind, Token, TokenKind};
|
|
||||||
|
|
||||||
let mut tokens = rustc_lexer::tokenize(s);
|
|
||||||
let minus_or_lit = tokens.next().unwrap_or(Token { kind: TokenKind::Eof, len: 0 });
|
|
||||||
|
|
||||||
let lit = if minus_or_lit.kind == TokenKind::Minus {
|
|
||||||
let lit = tokens.next().ok_or(())?;
|
|
||||||
if !matches!(
|
|
||||||
lit.kind,
|
|
||||||
TokenKind::Literal {
|
|
||||||
kind: LiteralKind::Int { .. } | LiteralKind::Float { .. },
|
|
||||||
..
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
return Err(());
|
|
||||||
}
|
|
||||||
lit
|
|
||||||
} else {
|
|
||||||
minus_or_lit
|
|
||||||
};
|
|
||||||
|
|
||||||
if tokens.next().is_some() {
|
|
||||||
return Err(());
|
|
||||||
}
|
|
||||||
|
|
||||||
let TokenKind::Literal { kind, suffix_start } = lit.kind else { return Err(()) };
|
|
||||||
let (kind, start_offset, end_offset) = match kind {
|
|
||||||
LiteralKind::Int { .. } => (LitKind::Integer, 0, 0),
|
|
||||||
LiteralKind::Float { .. } => (LitKind::Float, 0, 0),
|
|
||||||
LiteralKind::Char { terminated } => (LitKind::Char, 1, terminated as usize),
|
|
||||||
LiteralKind::Byte { terminated } => (LitKind::Byte, 2, terminated as usize),
|
|
||||||
LiteralKind::Str { terminated } => (LitKind::Str, 1, terminated as usize),
|
|
||||||
LiteralKind::ByteStr { terminated } => (LitKind::ByteStr, 2, terminated as usize),
|
|
||||||
LiteralKind::CStr { terminated } => (LitKind::CStr, 2, terminated as usize),
|
|
||||||
LiteralKind::RawStr { n_hashes } => (
|
|
||||||
LitKind::StrRaw(n_hashes.unwrap_or_default()),
|
|
||||||
2 + n_hashes.unwrap_or_default() as usize,
|
|
||||||
1 + n_hashes.unwrap_or_default() as usize,
|
|
||||||
),
|
|
||||||
LiteralKind::RawByteStr { n_hashes } => (
|
|
||||||
LitKind::ByteStrRaw(n_hashes.unwrap_or_default()),
|
|
||||||
3 + n_hashes.unwrap_or_default() as usize,
|
|
||||||
1 + n_hashes.unwrap_or_default() as usize,
|
|
||||||
),
|
|
||||||
LiteralKind::RawCStr { n_hashes } => (
|
|
||||||
LitKind::CStrRaw(n_hashes.unwrap_or_default()),
|
|
||||||
3 + n_hashes.unwrap_or_default() as usize,
|
|
||||||
1 + n_hashes.unwrap_or_default() as usize,
|
|
||||||
),
|
|
||||||
};
|
|
||||||
|
|
||||||
let (lit, suffix) = s.split_at(suffix_start as usize);
|
|
||||||
let lit = &lit[start_offset..lit.len() - end_offset];
|
|
||||||
let suffix = match suffix {
|
|
||||||
"" | "_" => None,
|
|
||||||
suffix => Some(Symbol::intern(suffix)),
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(bridge::Literal { kind, symbol: Symbol::intern(lit), suffix, span: self.call_site })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_diagnostic(&mut self, _: bridge::Diagnostic<Self::Span>) {
|
fn emit_diagnostic(&mut self, _: bridge::Diagnostic<Self::Span>) {
|
||||||
@ -149,70 +81,7 @@ impl server::TokenStream for RaSpanServer {
|
|||||||
&mut self,
|
&mut self,
|
||||||
tree: bridge::TokenTree<Self::TokenStream, Self::Span, Self::Symbol>,
|
tree: bridge::TokenTree<Self::TokenStream, Self::Span, Self::Symbol>,
|
||||||
) -> Self::TokenStream {
|
) -> Self::TokenStream {
|
||||||
match tree {
|
from_token_tree(tree)
|
||||||
bridge::TokenTree::Group(group) => {
|
|
||||||
let group = TopSubtree::from_bridge(group);
|
|
||||||
TokenStream { token_trees: group.0 }
|
|
||||||
}
|
|
||||||
|
|
||||||
bridge::TokenTree::Ident(ident) => {
|
|
||||||
let text = ident.sym;
|
|
||||||
let ident: tt::Ident = tt::Ident {
|
|
||||||
sym: text,
|
|
||||||
span: ident.span,
|
|
||||||
is_raw: if ident.is_raw { tt::IdentIsRaw::Yes } else { tt::IdentIsRaw::No },
|
|
||||||
};
|
|
||||||
let leaf = tt::Leaf::from(ident);
|
|
||||||
let tree = tt::TokenTree::from(leaf);
|
|
||||||
TokenStream { token_trees: vec![tree] }
|
|
||||||
}
|
|
||||||
|
|
||||||
bridge::TokenTree::Literal(literal) => {
|
|
||||||
let token_trees =
|
|
||||||
if let Some((_minus, symbol)) = literal.symbol.as_str().split_once('-') {
|
|
||||||
let punct = tt::Punct {
|
|
||||||
spacing: tt::Spacing::Alone,
|
|
||||||
span: literal.span,
|
|
||||||
char: '-' as char,
|
|
||||||
};
|
|
||||||
let leaf: tt::Leaf = tt::Leaf::from(punct);
|
|
||||||
let minus_tree = tt::TokenTree::from(leaf);
|
|
||||||
|
|
||||||
let literal = tt::Literal {
|
|
||||||
symbol: Symbol::intern(symbol),
|
|
||||||
suffix: literal.suffix,
|
|
||||||
span: literal.span,
|
|
||||||
kind: literal_kind_to_internal(literal.kind),
|
|
||||||
};
|
|
||||||
let leaf: tt::Leaf = tt::Leaf::from(literal);
|
|
||||||
let tree = tt::TokenTree::from(leaf);
|
|
||||||
vec![minus_tree, tree]
|
|
||||||
} else {
|
|
||||||
let literal = tt::Literal {
|
|
||||||
symbol: literal.symbol,
|
|
||||||
suffix: literal.suffix,
|
|
||||||
span: literal.span,
|
|
||||||
kind: literal_kind_to_internal(literal.kind),
|
|
||||||
};
|
|
||||||
|
|
||||||
let leaf: tt::Leaf = tt::Leaf::from(literal);
|
|
||||||
let tree = tt::TokenTree::from(leaf);
|
|
||||||
vec![tree]
|
|
||||||
};
|
|
||||||
TokenStream { token_trees }
|
|
||||||
}
|
|
||||||
|
|
||||||
bridge::TokenTree::Punct(p) => {
|
|
||||||
let punct = tt::Punct {
|
|
||||||
char: p.ch as char,
|
|
||||||
spacing: if p.joint { tt::Spacing::Joint } else { tt::Spacing::Alone },
|
|
||||||
span: p.span,
|
|
||||||
};
|
|
||||||
let leaf = tt::Leaf::from(punct);
|
|
||||||
let tree = tt::TokenTree::from(leaf);
|
|
||||||
TokenStream { token_trees: vec![tree] }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expand_expr(&mut self, self_: &Self::TokenStream) -> Result<Self::TokenStream, ()> {
|
fn expand_expr(&mut self, self_: &Self::TokenStream) -> Result<Self::TokenStream, ()> {
|
||||||
|
@ -5,23 +5,9 @@ use std::ops::{Bound, Range};
|
|||||||
use intern::Symbol;
|
use intern::Symbol;
|
||||||
use proc_macro::bridge::{self, server};
|
use proc_macro::bridge::{self, server};
|
||||||
|
|
||||||
use crate::server_impl::{TopSubtree, literal_kind_to_internal, token_stream::TokenStreamBuilder};
|
use crate::server_impl::{from_token_tree, literal_from_str, token_stream::TokenStreamBuilder};
|
||||||
mod tt {
|
|
||||||
pub use span::TokenId;
|
|
||||||
|
|
||||||
pub use tt::*;
|
type Span = span::TokenId;
|
||||||
|
|
||||||
pub type TokenTree = ::tt::TokenTree<TokenId>;
|
|
||||||
pub type Leaf = ::tt::Leaf<TokenId>;
|
|
||||||
pub type Literal = ::tt::Literal<TokenId>;
|
|
||||||
pub type Punct = ::tt::Punct<TokenId>;
|
|
||||||
pub type Ident = ::tt::Ident<TokenId>;
|
|
||||||
}
|
|
||||||
type TokenTree = tt::TokenTree;
|
|
||||||
type Punct = tt::Punct;
|
|
||||||
type Spacing = tt::Spacing;
|
|
||||||
type Literal = tt::Literal;
|
|
||||||
type Span = tt::TokenId;
|
|
||||||
type TokenStream = crate::server_impl::TokenStream<Span>;
|
type TokenStream = crate::server_impl::TokenStream<Span>;
|
||||||
|
|
||||||
pub struct FreeFunctions;
|
pub struct FreeFunctions;
|
||||||
@ -49,67 +35,7 @@ impl server::FreeFunctions for TokenIdServer {
|
|||||||
&mut self,
|
&mut self,
|
||||||
s: &str,
|
s: &str,
|
||||||
) -> Result<bridge::Literal<Self::Span, Self::Symbol>, ()> {
|
) -> Result<bridge::Literal<Self::Span, Self::Symbol>, ()> {
|
||||||
use proc_macro::bridge::LitKind;
|
literal_from_str(s, self.call_site)
|
||||||
use rustc_lexer::{LiteralKind, Token, TokenKind};
|
|
||||||
|
|
||||||
let mut tokens = rustc_lexer::tokenize(s);
|
|
||||||
let minus_or_lit = tokens.next().unwrap_or(Token { kind: TokenKind::Eof, len: 0 });
|
|
||||||
|
|
||||||
let lit = if minus_or_lit.kind == TokenKind::Minus {
|
|
||||||
let lit = tokens.next().ok_or(())?;
|
|
||||||
if !matches!(
|
|
||||||
lit.kind,
|
|
||||||
TokenKind::Literal {
|
|
||||||
kind: LiteralKind::Int { .. } | LiteralKind::Float { .. },
|
|
||||||
..
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
return Err(());
|
|
||||||
}
|
|
||||||
lit
|
|
||||||
} else {
|
|
||||||
minus_or_lit
|
|
||||||
};
|
|
||||||
|
|
||||||
if tokens.next().is_some() {
|
|
||||||
return Err(());
|
|
||||||
}
|
|
||||||
|
|
||||||
let TokenKind::Literal { kind, suffix_start } = lit.kind else { return Err(()) };
|
|
||||||
|
|
||||||
let (kind, start_offset, end_offset) = match kind {
|
|
||||||
LiteralKind::Int { .. } => (LitKind::Integer, 0, 0),
|
|
||||||
LiteralKind::Float { .. } => (LitKind::Float, 0, 0),
|
|
||||||
LiteralKind::Char { terminated } => (LitKind::Char, 1, terminated as usize),
|
|
||||||
LiteralKind::Byte { terminated } => (LitKind::Byte, 2, terminated as usize),
|
|
||||||
LiteralKind::Str { terminated } => (LitKind::Str, 1, terminated as usize),
|
|
||||||
LiteralKind::ByteStr { terminated } => (LitKind::ByteStr, 2, terminated as usize),
|
|
||||||
LiteralKind::CStr { terminated } => (LitKind::CStr, 2, terminated as usize),
|
|
||||||
LiteralKind::RawStr { n_hashes } => (
|
|
||||||
LitKind::StrRaw(n_hashes.unwrap_or_default()),
|
|
||||||
2 + n_hashes.unwrap_or_default() as usize,
|
|
||||||
1 + n_hashes.unwrap_or_default() as usize,
|
|
||||||
),
|
|
||||||
LiteralKind::RawByteStr { n_hashes } => (
|
|
||||||
LitKind::ByteStrRaw(n_hashes.unwrap_or_default()),
|
|
||||||
3 + n_hashes.unwrap_or_default() as usize,
|
|
||||||
1 + n_hashes.unwrap_or_default() as usize,
|
|
||||||
),
|
|
||||||
LiteralKind::RawCStr { n_hashes } => (
|
|
||||||
LitKind::CStrRaw(n_hashes.unwrap_or_default()),
|
|
||||||
3 + n_hashes.unwrap_or_default() as usize,
|
|
||||||
1 + n_hashes.unwrap_or_default() as usize,
|
|
||||||
),
|
|
||||||
};
|
|
||||||
|
|
||||||
let (lit, suffix) = s.split_at(suffix_start as usize);
|
|
||||||
let lit = &lit[start_offset..lit.len() - end_offset];
|
|
||||||
let suffix = match suffix {
|
|
||||||
"" | "_" => None,
|
|
||||||
suffix => Some(Symbol::intern(suffix)),
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(bridge::Literal { kind, symbol: Symbol::intern(lit), suffix, span: self.call_site })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_diagnostic(&mut self, _: bridge::Diagnostic<Self::Span>) {}
|
fn emit_diagnostic(&mut self, _: bridge::Diagnostic<Self::Span>) {}
|
||||||
@ -135,69 +61,7 @@ impl server::TokenStream for TokenIdServer {
|
|||||||
&mut self,
|
&mut self,
|
||||||
tree: bridge::TokenTree<Self::TokenStream, Self::Span, Self::Symbol>,
|
tree: bridge::TokenTree<Self::TokenStream, Self::Span, Self::Symbol>,
|
||||||
) -> Self::TokenStream {
|
) -> Self::TokenStream {
|
||||||
match tree {
|
from_token_tree(tree)
|
||||||
bridge::TokenTree::Group(group) => {
|
|
||||||
let group = TopSubtree::from_bridge(group);
|
|
||||||
TokenStream { token_trees: group.0 }
|
|
||||||
}
|
|
||||||
|
|
||||||
bridge::TokenTree::Ident(ident) => {
|
|
||||||
let ident: tt::Ident = tt::Ident {
|
|
||||||
sym: ident.sym,
|
|
||||||
span: ident.span,
|
|
||||||
is_raw: if ident.is_raw { tt::IdentIsRaw::Yes } else { tt::IdentIsRaw::No },
|
|
||||||
};
|
|
||||||
let leaf = tt::Leaf::from(ident);
|
|
||||||
let tree = TokenTree::from(leaf);
|
|
||||||
TokenStream { token_trees: vec![tree] }
|
|
||||||
}
|
|
||||||
|
|
||||||
bridge::TokenTree::Literal(literal) => {
|
|
||||||
let token_trees =
|
|
||||||
if let Some((_minus, symbol)) = literal.symbol.as_str().split_once('-') {
|
|
||||||
let punct = tt::Punct {
|
|
||||||
spacing: tt::Spacing::Alone,
|
|
||||||
span: literal.span,
|
|
||||||
char: '-' as char,
|
|
||||||
};
|
|
||||||
let leaf: tt::Leaf = tt::Leaf::from(punct);
|
|
||||||
let minus_tree = tt::TokenTree::from(leaf);
|
|
||||||
|
|
||||||
let literal = Literal {
|
|
||||||
symbol: Symbol::intern(symbol),
|
|
||||||
suffix: literal.suffix,
|
|
||||||
span: literal.span,
|
|
||||||
kind: literal_kind_to_internal(literal.kind),
|
|
||||||
};
|
|
||||||
let leaf: tt::Leaf = tt::Leaf::from(literal);
|
|
||||||
let tree = tt::TokenTree::from(leaf);
|
|
||||||
vec![minus_tree, tree]
|
|
||||||
} else {
|
|
||||||
let literal = Literal {
|
|
||||||
symbol: literal.symbol,
|
|
||||||
suffix: literal.suffix,
|
|
||||||
span: literal.span,
|
|
||||||
kind: literal_kind_to_internal(literal.kind),
|
|
||||||
};
|
|
||||||
|
|
||||||
let leaf: tt::Leaf = tt::Leaf::from(literal);
|
|
||||||
let tree = tt::TokenTree::from(leaf);
|
|
||||||
vec![tree]
|
|
||||||
};
|
|
||||||
TokenStream { token_trees }
|
|
||||||
}
|
|
||||||
|
|
||||||
bridge::TokenTree::Punct(p) => {
|
|
||||||
let punct = Punct {
|
|
||||||
char: p.ch as char,
|
|
||||||
spacing: if p.joint { Spacing::Joint } else { Spacing::Alone },
|
|
||||||
span: p.span,
|
|
||||||
};
|
|
||||||
let leaf = tt::Leaf::from(punct);
|
|
||||||
let tree = TokenTree::from(leaf);
|
|
||||||
TokenStream { token_trees: vec![tree] }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expand_expr(&mut self, self_: &Self::TokenStream) -> Result<Self::TokenStream, ()> {
|
fn expand_expr(&mut self, self_: &Self::TokenStream) -> Result<Self::TokenStream, ()> {
|
||||||
@ -337,6 +201,8 @@ impl server::Server for TokenIdServer {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use span::TokenId;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -345,18 +211,18 @@ mod tests {
|
|||||||
token_trees: vec![
|
token_trees: vec![
|
||||||
tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
|
tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
|
||||||
sym: Symbol::intern("struct"),
|
sym: Symbol::intern("struct"),
|
||||||
span: tt::TokenId(0),
|
span: TokenId(0),
|
||||||
is_raw: tt::IdentIsRaw::No,
|
is_raw: tt::IdentIsRaw::No,
|
||||||
})),
|
})),
|
||||||
tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
|
tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
|
||||||
sym: Symbol::intern("T"),
|
sym: Symbol::intern("T"),
|
||||||
span: tt::TokenId(0),
|
span: TokenId(0),
|
||||||
is_raw: tt::IdentIsRaw::No,
|
is_raw: tt::IdentIsRaw::No,
|
||||||
})),
|
})),
|
||||||
tt::TokenTree::Subtree(tt::Subtree {
|
tt::TokenTree::Subtree(tt::Subtree {
|
||||||
delimiter: tt::Delimiter {
|
delimiter: tt::Delimiter {
|
||||||
open: tt::TokenId(0),
|
open: TokenId(0),
|
||||||
close: tt::TokenId(0),
|
close: TokenId(0),
|
||||||
kind: tt::DelimiterKind::Brace,
|
kind: tt::DelimiterKind::Brace,
|
||||||
},
|
},
|
||||||
len: 0,
|
len: 0,
|
||||||
@ -372,8 +238,8 @@ mod tests {
|
|||||||
let subtree_paren_a = vec![
|
let subtree_paren_a = vec![
|
||||||
tt::TokenTree::Subtree(tt::Subtree {
|
tt::TokenTree::Subtree(tt::Subtree {
|
||||||
delimiter: tt::Delimiter {
|
delimiter: tt::Delimiter {
|
||||||
open: tt::TokenId(0),
|
open: TokenId(0),
|
||||||
close: tt::TokenId(0),
|
close: TokenId(0),
|
||||||
kind: tt::DelimiterKind::Parenthesis,
|
kind: tt::DelimiterKind::Parenthesis,
|
||||||
},
|
},
|
||||||
len: 1,
|
len: 1,
|
||||||
@ -381,24 +247,24 @@ mod tests {
|
|||||||
tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
|
tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
|
||||||
is_raw: tt::IdentIsRaw::No,
|
is_raw: tt::IdentIsRaw::No,
|
||||||
sym: Symbol::intern("a"),
|
sym: Symbol::intern("a"),
|
||||||
span: tt::TokenId(0),
|
span: TokenId(0),
|
||||||
})),
|
})),
|
||||||
];
|
];
|
||||||
|
|
||||||
let t1 = TokenStream::from_str("(a)", tt::TokenId(0)).unwrap();
|
let t1 = TokenStream::from_str("(a)", TokenId(0)).unwrap();
|
||||||
assert_eq!(t1.token_trees.len(), 2);
|
assert_eq!(t1.token_trees.len(), 2);
|
||||||
assert!(t1.token_trees[0..2] == subtree_paren_a);
|
assert!(t1.token_trees[0..2] == subtree_paren_a);
|
||||||
|
|
||||||
let t2 = TokenStream::from_str("(a);", tt::TokenId(0)).unwrap();
|
let t2 = TokenStream::from_str("(a);", TokenId(0)).unwrap();
|
||||||
assert_eq!(t2.token_trees.len(), 3);
|
assert_eq!(t2.token_trees.len(), 3);
|
||||||
assert!(t2.token_trees[0..2] == subtree_paren_a);
|
assert!(t2.token_trees[0..2] == subtree_paren_a);
|
||||||
|
|
||||||
let underscore = TokenStream::from_str("_", tt::TokenId(0)).unwrap();
|
let underscore = TokenStream::from_str("_", TokenId(0)).unwrap();
|
||||||
assert!(
|
assert!(
|
||||||
underscore.token_trees[0]
|
underscore.token_trees[0]
|
||||||
== tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
|
== tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
|
||||||
sym: Symbol::intern("_"),
|
sym: Symbol::intern("_"),
|
||||||
span: tt::TokenId(0),
|
span: TokenId(0),
|
||||||
is_raw: tt::IdentIsRaw::No,
|
is_raw: tt::IdentIsRaw::No,
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
@ -431,12 +431,6 @@ impl CargoWorkspace {
|
|||||||
.ok_or(cargo_metadata::Error::NoJson)?;
|
.ok_or(cargo_metadata::Error::NoJson)?;
|
||||||
Ok((cargo_metadata::MetadataCommand::parse(stdout)?, None))
|
Ok((cargo_metadata::MetadataCommand::parse(stdout)?, None))
|
||||||
})()
|
})()
|
||||||
.map(|(metadata, error)| {
|
|
||||||
(
|
|
||||||
metadata,
|
|
||||||
error.map(|e| e.context(format!("Failed to run `{:?}`", meta.cargo_command()))),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.with_context(|| format!("Failed to run `{:?}`", meta.cargo_command()))
|
.with_context(|| format!("Failed to run `{:?}`", meta.cargo_command()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,8 +108,7 @@ impl GlobalState {
|
|||||||
/// edge users from being upset!
|
/// edge users from being upset!
|
||||||
pub(crate) fn poke_rust_analyzer_developer(&mut self, message: String) {
|
pub(crate) fn poke_rust_analyzer_developer(&mut self, message: String) {
|
||||||
let from_source_build = option_env!("POKE_RA_DEVS").is_some();
|
let from_source_build = option_env!("POKE_RA_DEVS").is_some();
|
||||||
let profiling_enabled = std::env::var("RA_PROFILE").is_ok();
|
if from_source_build {
|
||||||
if from_source_build || profiling_enabled {
|
|
||||||
self.show_and_log_error(message, None);
|
self.show_and_log_error(message, None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -975,10 +975,6 @@ version = \"0.0.0\"
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn out_dirs_check_impl(root_contains_symlink: bool) {
|
fn out_dirs_check_impl(root_contains_symlink: bool) {
|
||||||
if skip_slow_tests() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut server = Project::with_fixture(
|
let mut server = Project::with_fixture(
|
||||||
r###"
|
r###"
|
||||||
//- /Cargo.toml
|
//- /Cargo.toml
|
||||||
@ -1130,12 +1126,18 @@ fn main() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn out_dirs_check() {
|
fn out_dirs_check() {
|
||||||
|
if skip_slow_tests() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
out_dirs_check_impl(false);
|
out_dirs_check_impl(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(windows))] // windows requires elevated permissions to create symlinks
|
#[cfg(not(windows))] // windows requires elevated permissions to create symlinks
|
||||||
fn root_contains_symlink_out_dirs_check() {
|
fn root_contains_symlink_out_dirs_check() {
|
||||||
|
if skip_slow_tests() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
out_dirs_check_impl(true);
|
out_dirs_check_impl(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user