mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-29 06:23:25 +00:00
Implement other non-db reliant server::Span functions
This commit is contained in:
parent
428a34a9b4
commit
f427f56812
3 changed files with 81 additions and 17 deletions
|
@ -4,6 +4,7 @@ use std::{
|
||||||
ops::{Bound, Range},
|
ops::{Bound, Range},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use ::tt::{TextRange, TextSize};
|
||||||
use proc_macro::bridge::{self, server};
|
use proc_macro::bridge::{self, server};
|
||||||
use span::Span;
|
use span::Span;
|
||||||
|
|
||||||
|
@ -241,11 +242,11 @@ impl server::Span for RaSpanServer {
|
||||||
SourceFile {}
|
SourceFile {}
|
||||||
}
|
}
|
||||||
fn save_span(&mut self, _span: Self::Span) -> usize {
|
fn save_span(&mut self, _span: Self::Span) -> usize {
|
||||||
// FIXME stub
|
// FIXME stub, requires builtin quote! implementation
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
fn recover_proc_macro_span(&mut self, _id: usize) -> Self::Span {
|
fn recover_proc_macro_span(&mut self, _id: usize) -> Self::Span {
|
||||||
// FIXME stub
|
// FIXME stub, requires builtin quote! implementation
|
||||||
self.call_site
|
self.call_site
|
||||||
}
|
}
|
||||||
/// Recent feature, not yet in the proc_macro
|
/// Recent feature, not yet in the proc_macro
|
||||||
|
@ -289,32 +290,64 @@ impl server::Span for RaSpanServer {
|
||||||
fn subspan(
|
fn subspan(
|
||||||
&mut self,
|
&mut self,
|
||||||
span: Self::Span,
|
span: Self::Span,
|
||||||
_start: Bound<usize>,
|
start: Bound<usize>,
|
||||||
_end: Bound<usize>,
|
end: Bound<usize>,
|
||||||
) -> Option<Self::Span> {
|
) -> Option<Self::Span> {
|
||||||
// Just return the span again, because some macros will unwrap the result.
|
// FIXME requires db to resolve the ast id, THIS IS NOT INCREMENTAL as it works on absolute
|
||||||
Some(span)
|
// ranges
|
||||||
}
|
let length = span.range.len().into();
|
||||||
fn resolved_at(&mut self, _span: Self::Span, _at: Self::Span) -> Self::Span {
|
|
||||||
// FIXME handle span
|
let start: u32 = match start {
|
||||||
self.call_site
|
Bound::Included(lo) => lo,
|
||||||
|
Bound::Excluded(lo) => lo.checked_add(1)?,
|
||||||
|
Bound::Unbounded => 0,
|
||||||
|
}
|
||||||
|
.try_into()
|
||||||
|
.ok()?;
|
||||||
|
|
||||||
|
let end: u32 = match end {
|
||||||
|
Bound::Included(hi) => hi.checked_add(1)?,
|
||||||
|
Bound::Excluded(hi) => hi,
|
||||||
|
Bound::Unbounded => span.range.len().into(),
|
||||||
|
}
|
||||||
|
.try_into()
|
||||||
|
.ok()?;
|
||||||
|
|
||||||
|
// Bounds check the values, preventing addition overflow and OOB spans.
|
||||||
|
let span_start = span.range.start().into();
|
||||||
|
if (u32::MAX - start) < span_start
|
||||||
|
|| (u32::MAX - end) < span_start
|
||||||
|
|| start >= end
|
||||||
|
|| end > length
|
||||||
|
{
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(Span {
|
||||||
|
range: TextRange::new(TextSize::from(start), TextSize::from(end)) + span.range.start(),
|
||||||
|
..span
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end(&mut self, _self_: Self::Span) -> Self::Span {
|
fn resolved_at(&mut self, span: Self::Span, at: Self::Span) -> Self::Span {
|
||||||
self.call_site
|
Span { ctx: at.ctx, ..span }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start(&mut self, _self_: Self::Span) -> Self::Span {
|
fn end(&mut self, span: Self::Span) -> Self::Span {
|
||||||
self.call_site
|
Span { range: TextRange::empty(span.range.end()), ..span }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start(&mut self, span: Self::Span) -> Self::Span {
|
||||||
|
Span { range: TextRange::empty(span.range.start()), ..span }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn line(&mut self, _span: Self::Span) -> usize {
|
fn line(&mut self, _span: Self::Span) -> usize {
|
||||||
// FIXME handle line
|
// FIXME requires db to resolve line index, THIS IS NOT INCREMENTAL
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn column(&mut self, _span: Self::Span) -> usize {
|
fn column(&mut self, _span: Self::Span) -> usize {
|
||||||
// FIXME handle column
|
// FIXME requires db to resolve line index, THIS IS NOT INCREMENTAL
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,6 +105,24 @@ fn test_fn_like_fn_like_span_join() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fn_like_fn_like_span_ops() {
|
||||||
|
assert_expand(
|
||||||
|
"fn_like_span_ops",
|
||||||
|
"set_def_site resolved_at_def_site start_span",
|
||||||
|
expect![[r#"
|
||||||
|
SUBTREE $$ 1 1
|
||||||
|
IDENT set_def_site 0
|
||||||
|
IDENT resolved_at_def_site 1
|
||||||
|
IDENT start_span 1"#]],
|
||||||
|
expect![[r#"
|
||||||
|
SUBTREE $$ SpanData { range: 0..100, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) } SpanData { range: 0..100, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) }
|
||||||
|
IDENT set_def_site SpanData { range: 0..150, anchor: SpanAnchor(FileId(41), 1), ctx: SyntaxContextId(0) }
|
||||||
|
IDENT resolved_at_def_site SpanData { range: 13..33, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) }
|
||||||
|
IDENT start_span SpanData { range: 34..34, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) }"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fn_like_mk_literals() {
|
fn test_fn_like_mk_literals() {
|
||||||
assert_expand(
|
assert_expand(
|
||||||
|
@ -218,6 +236,7 @@ fn list_test_macros() {
|
||||||
fn_like_mk_literals [FuncLike]
|
fn_like_mk_literals [FuncLike]
|
||||||
fn_like_mk_idents [FuncLike]
|
fn_like_mk_idents [FuncLike]
|
||||||
fn_like_span_join [FuncLike]
|
fn_like_span_join [FuncLike]
|
||||||
|
fn_like_span_ops [FuncLike]
|
||||||
attr_noop [Attr]
|
attr_noop [Attr]
|
||||||
attr_panic [Attr]
|
attr_panic [Attr]
|
||||||
attr_error [Attr]
|
attr_error [Attr]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! Exports a few trivial procedural macros for testing.
|
//! Exports a few trivial procedural macros for testing.
|
||||||
|
|
||||||
#![warn(rust_2018_idioms, unused_lifetimes)]
|
#![warn(rust_2018_idioms, unused_lifetimes)]
|
||||||
#![feature(proc_macro_span)]
|
#![feature(proc_macro_span, proc_macro_def_site)]
|
||||||
|
|
||||||
use proc_macro::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree};
|
use proc_macro::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree};
|
||||||
|
|
||||||
|
@ -61,6 +61,18 @@ pub fn fn_like_span_join(args: TokenStream) -> TokenStream {
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn fn_like_span_ops(args: TokenStream) -> TokenStream {
|
||||||
|
let args = &mut args.into_iter();
|
||||||
|
let mut first = args.next().unwrap();
|
||||||
|
first.set_span(Span::def_site());
|
||||||
|
let mut second = args.next().unwrap();
|
||||||
|
second.set_span(second.span().resolved_at(Span::def_site()));
|
||||||
|
let mut third = args.next().unwrap();
|
||||||
|
third.set_span(third.span().start());
|
||||||
|
TokenStream::from_iter(vec![first, second, third])
|
||||||
|
}
|
||||||
|
|
||||||
#[proc_macro_attribute]
|
#[proc_macro_attribute]
|
||||||
pub fn attr_noop(_args: TokenStream, item: TokenStream) -> TokenStream {
|
pub fn attr_noop(_args: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
item
|
item
|
||||||
|
|
Loading…
Reference in a new issue