Skip to content

Commit

Permalink
Skip whitespace prefix when creating the span (#1761)
Browse files Browse the repository at this point in the history
commit-id:f0ce5a05

---

**Stack**:
- #1749
- #1748
- #1745
- #1761⚠️ *Part of a stack created by [spr](https://github.com/ejoffe/spr). Do
not merge manually using the UI - doing so may have unexpected results.*
  • Loading branch information
maciektr committed Nov 25, 2024
1 parent ad94f7e commit f5576c3
Showing 1 changed file with 48 additions and 2 deletions.
50 changes: 48 additions & 2 deletions scarb/src/compiler/plugin/proc_macro/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use cairo_lang_macro::{
AllocationContext, TextSpan, Token, TokenStream, TokenStreamMetadata, TokenTree,
};
use cairo_lang_syntax::node::{db::SyntaxGroup, SyntaxNode};
use std::ops::Add;

/// Helps creating TokenStream based on multiple SyntaxNodes,
/// which aren't descendants or ascendants of each other inside the SyntaxTree.
Expand Down Expand Up @@ -46,10 +47,55 @@ impl<'a> TokenStreamBuilder<'a> {

pub fn token_from_syntax_node(&self, node: SyntaxNode, ctx: &AllocationContext) -> Token {
let span = node.span(self.db).to_str_range();
let text = node.get_text(self.db);
let span = TextSpan {
start: span.start,
// We skip the whitespace prefix, so that diagnostics start where the actual token contents is.
start: span.start.add(whitespace_prefix_len(&text)),
end: span.end,
};
Token::new_in(node.get_text(self.db), span, ctx)
Token::new_in(text, span, ctx)
}
}

fn whitespace_prefix_len(s: &str) -> usize {
s.chars().take_while(|c| c.is_whitespace()).count()
}

#[cfg(test)]
mod tests {
use crate::compiler::plugin::proc_macro::TokenStreamBuilder;
use cairo_lang_macro::{AllocationContext, TextSpan, TokenStream, TokenTree};
use cairo_lang_parser::utils::SimpleParserDatabase;
use indoc::indoc;

#[test]
fn whitespace_skipped() {
let db = SimpleParserDatabase::default();
let mut builder = TokenStreamBuilder::new(&db);
let content = indoc! {r#"
fn main() {
let x = 42;
}
"#};
let parsed = db.parse_virtual(content).unwrap();
builder.add_node(parsed);
let ctx = AllocationContext::default();
let token_stream = builder.build(&ctx);
let token_at = |token_stream: &TokenStream, idx: usize| {
let token: TokenTree = token_stream.tokens[idx].clone();
match token {
TokenTree::Ident(token) => token,
}
};
let token = token_at(&token_stream, 4);
assert_eq!(token.content.as_ref(), "{\n");
assert_eq!(token.span, TextSpan { start: 10, end: 12 });
let token = token_at(&token_stream, 5);
assert_eq!(token.content.as_ref(), " let ");
// Note we skip 4 whitespaces characters in the span.
assert_eq!(token.span, TextSpan { start: 16, end: 20 });
let token = token_at(&token_stream, 6);
assert_eq!(token.content.as_ref(), "x ");
assert_eq!(token.span, TextSpan { start: 20, end: 22 });
}
}

0 comments on commit f5576c3

Please sign in to comment.