Implement other non-db reliant server::Span functions

This commit is contained in:
Lukas Wirth 2023-12-11 13:59:30 +01:00
parent 428a34a9b4
commit f427f56812
3 changed files with 81 additions and 17 deletions

View file

@ -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
} }
} }

View file

@ -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]

View file

@ -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