From 98860ab89066c69e9ebefbbe914ca30b6f198d16 Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Wed, 6 Dec 2017 22:48:48 +0900 Subject: [PATCH] Add SnippetProvider --- src/visitor.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/visitor.rs b/src/visitor.rs index 6db1999ee23..510bf6e8f5c 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::rc::Rc; use std::cmp; +use std::mem; use strings::string_buffer::StringBuffer; use syntax::{ast, visit}; @@ -47,6 +49,32 @@ fn is_extern_crate(item: &ast::Item) -> bool { } } +/// Creates a string slice corresponding to the specified span. +pub struct SnippetProvider { + /// A pointer to the content of the file we are formatting. + big_snippet: *const Rc, + /// A position of the start of `big_snippet`, used as an offset. + start_pos: usize, +} + +impl SnippetProvider { + pub fn span_to_snippet(&self, span: Span) -> Option<&str> { + let start_index = span.lo().to_usize().checked_sub(self.start_pos)?; + let end_index = span.hi().to_usize().checked_sub(self.start_pos)?; + unsafe { Some(&(*self.big_snippet)[start_index..end_index]) } + } + + pub fn from_codemap(codemap: &CodeMap, span: Span) -> Self { + let filemap = codemap.lookup_char_pos(span.lo()).file; + let big_snippet = unsafe { mem::transmute(&filemap.src) }; + let start_pos = filemap.start_pos.to_usize(); + SnippetProvider { + big_snippet, + start_pos, + } + } +} + pub struct FmtVisitor<'a> { pub parse_session: &'a ParseSess, pub codemap: &'a CodeMap,