Skip to content

Commit f427f56

Browse files
committed
Implement other non-db reliant server::Span functions
1 parent 428a34a commit f427f56

File tree

3 files changed

+80
-16
lines changed

3 files changed

+80
-16
lines changed

crates/proc-macro-srv/src/server/rust_analyzer_span.rs

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::{
44
ops::{Bound, Range},
55
};
66

7+
use ::tt::{TextRange, TextSize};
78
use proc_macro::bridge::{self, server};
89
use span::Span;
910

@@ -241,11 +242,11 @@ impl server::Span for RaSpanServer {
241242
SourceFile {}
242243
}
243244
fn save_span(&mut self, _span: Self::Span) -> usize {
244-
// FIXME stub
245+
// FIXME stub, requires builtin quote! implementation
245246
0
246247
}
247248
fn recover_proc_macro_span(&mut self, _id: usize) -> Self::Span {
248-
// FIXME stub
249+
// FIXME stub, requires builtin quote! implementation
249250
self.call_site
250251
}
251252
/// Recent feature, not yet in the proc_macro
@@ -289,32 +290,64 @@ impl server::Span for RaSpanServer {
289290
fn subspan(
290291
&mut self,
291292
span: Self::Span,
292-
_start: Bound<usize>,
293-
_end: Bound<usize>,
293+
start: Bound<usize>,
294+
end: Bound<usize>,
294295
) -> Option<Self::Span> {
295-
// Just return the span again, because some macros will unwrap the result.
296-
Some(span)
296+
// FIXME requires db to resolve the ast id, THIS IS NOT INCREMENTAL as it works on absolute
297+
// ranges
298+
let length = span.range.len().into();
299+
300+
let start: u32 = match start {
301+
Bound::Included(lo) => lo,
302+
Bound::Excluded(lo) => lo.checked_add(1)?,
303+
Bound::Unbounded => 0,
304+
}
305+
.try_into()
306+
.ok()?;
307+
308+
let end: u32 = match end {
309+
Bound::Included(hi) => hi.checked_add(1)?,
310+
Bound::Excluded(hi) => hi,
311+
Bound::Unbounded => span.range.len().into(),
312+
}
313+
.try_into()
314+
.ok()?;
315+
316+
// Bounds check the values, preventing addition overflow and OOB spans.
317+
let span_start = span.range.start().into();
318+
if (u32::MAX - start) < span_start
319+
|| (u32::MAX - end) < span_start
320+
|| start >= end
321+
|| end > length
322+
{
323+
return None;
324+
}
325+
326+
Some(Span {
327+
range: TextRange::new(TextSize::from(start), TextSize::from(end)) + span.range.start(),
328+
..span
329+
})
297330
}
298-
fn resolved_at(&mut self, _span: Self::Span, _at: Self::Span) -> Self::Span {
299-
// FIXME handle span
300-
self.call_site
331+
332+
fn resolved_at(&mut self, span: Self::Span, at: Self::Span) -> Self::Span {
333+
Span { ctx: at.ctx, ..span }
301334
}
302335

303-
fn end(&mut self, _self_: Self::Span) -> Self::Span {
304-
self.call_site
336+
fn end(&mut self, span: Self::Span) -> Self::Span {
337+
Span { range: TextRange::empty(span.range.end()), ..span }
305338
}
306339

307-
fn start(&mut self, _self_: Self::Span) -> Self::Span {
308-
self.call_site
340+
fn start(&mut self, span: Self::Span) -> Self::Span {
341+
Span { range: TextRange::empty(span.range.start()), ..span }
309342
}
310343

311344
fn line(&mut self, _span: Self::Span) -> usize {
312-
// FIXME handle line
345+
// FIXME requires db to resolve line index, THIS IS NOT INCREMENTAL
313346
0
314347
}
315348

316349
fn column(&mut self, _span: Self::Span) -> usize {
317-
// FIXME handle column
350+
// FIXME requires db to resolve line index, THIS IS NOT INCREMENTAL
318351
0
319352
}
320353
}

crates/proc-macro-srv/src/tests/mod.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,24 @@ fn test_fn_like_fn_like_span_join() {
105105
);
106106
}
107107

108+
#[test]
109+
fn test_fn_like_fn_like_span_ops() {
110+
assert_expand(
111+
"fn_like_span_ops",
112+
"set_def_site resolved_at_def_site start_span",
113+
expect![[r#"
114+
SUBTREE $$ 1 1
115+
IDENT set_def_site 0
116+
IDENT resolved_at_def_site 1
117+
IDENT start_span 1"#]],
118+
expect![[r#"
119+
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) }
120+
IDENT set_def_site SpanData { range: 0..150, anchor: SpanAnchor(FileId(41), 1), ctx: SyntaxContextId(0) }
121+
IDENT resolved_at_def_site SpanData { range: 13..33, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) }
122+
IDENT start_span SpanData { range: 34..34, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) }"#]],
123+
);
124+
}
125+
108126
#[test]
109127
fn test_fn_like_mk_literals() {
110128
assert_expand(
@@ -218,6 +236,7 @@ fn list_test_macros() {
218236
fn_like_mk_literals [FuncLike]
219237
fn_like_mk_idents [FuncLike]
220238
fn_like_span_join [FuncLike]
239+
fn_like_span_ops [FuncLike]
221240
attr_noop [Attr]
222241
attr_panic [Attr]
223242
attr_error [Attr]

crates/proc-macro-test/imp/src/lib.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Exports a few trivial procedural macros for testing.
22
33
#![warn(rust_2018_idioms, unused_lifetimes)]
4-
#![feature(proc_macro_span)]
4+
#![feature(proc_macro_span, proc_macro_def_site)]
55

66
use proc_macro::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree};
77

@@ -61,6 +61,18 @@ pub fn fn_like_span_join(args: TokenStream) -> TokenStream {
6161
)))
6262
}
6363

64+
#[proc_macro]
65+
pub fn fn_like_span_ops(args: TokenStream) -> TokenStream {
66+
let args = &mut args.into_iter();
67+
let mut first = args.next().unwrap();
68+
first.set_span(Span::def_site());
69+
let mut second = args.next().unwrap();
70+
second.set_span(second.span().resolved_at(Span::def_site()));
71+
let mut third = args.next().unwrap();
72+
third.set_span(third.span().start());
73+
TokenStream::from_iter(vec![first, second, third])
74+
}
75+
6476
#[proc_macro_attribute]
6577
pub fn attr_noop(_args: TokenStream, item: TokenStream) -> TokenStream {
6678
item

0 commit comments

Comments
 (0)