]> git.lizzy.rs Git - rust.git/blob - src/librustc_errors/snippet.rs
Rollup merge of #39166 - glandium:master, r=brson
[rust.git] / src / librustc_errors / snippet.rs
1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 // Code for annotating snippets.
12
13 use syntax_pos::{Span, FileMap};
14 use CodeMapper;
15 use std::rc::Rc;
16 use Level;
17
18 #[derive(Clone)]
19 pub struct SnippetData {
20     codemap: Rc<CodeMapper>,
21     files: Vec<FileInfo>,
22 }
23
24 #[derive(Clone)]
25 pub struct FileInfo {
26     file: Rc<FileMap>,
27
28     /// The "primary file", if any, gets a `-->` marker instead of
29     /// `>>>`, and has a line-number/column printed and not just a
30     /// filename.  It appears first in the listing. It is known to
31     /// contain at least one primary span, though primary spans (which
32     /// are designated with `^^^`) may also occur in other files.
33     primary_span: Option<Span>,
34
35     lines: Vec<Line>,
36 }
37
38 #[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
39 pub struct Line {
40     pub line_index: usize,
41     pub annotations: Vec<Annotation>,
42 }
43
44
45 #[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
46 pub struct MultilineAnnotation {
47     pub depth: usize,
48     pub line_start: usize,
49     pub line_end: usize,
50     pub start_col: usize,
51     pub end_col: usize,
52     pub is_primary: bool,
53     pub label: Option<String>,
54 }
55
56 impl MultilineAnnotation {
57     pub fn increase_depth(&mut self) {
58         self.depth += 1;
59     }
60
61     pub fn as_start(&self) -> Annotation {
62         Annotation {
63             start_col: self.start_col,
64             end_col: self.start_col + 1,
65             is_primary: self.is_primary,
66             label: Some("starting here...".to_owned()),
67             annotation_type: AnnotationType::MultilineStart(self.depth)
68         }
69     }
70
71     pub fn as_end(&self) -> Annotation {
72         Annotation {
73             start_col: self.end_col - 1,
74             end_col: self.end_col,
75             is_primary: self.is_primary,
76             label: match self.label {
77                 Some(ref label) => Some(format!("...ending here: {}", label)),
78                 None => Some("...ending here".to_owned()),
79             },
80             annotation_type: AnnotationType::MultilineEnd(self.depth)
81         }
82     }
83
84     pub fn as_line(&self) -> Annotation {
85         Annotation {
86             start_col: 0,
87             end_col: 0,
88             is_primary: self.is_primary,
89             label: None,
90             annotation_type: AnnotationType::MultilineLine(self.depth)
91         }
92     }
93 }
94
95 #[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
96 pub enum AnnotationType {
97     /// Annotation under a single line of code
98     Singleline,
99
100     /// Annotation under the first character of a multiline span
101     Minimized,
102
103     /// Annotation enclosing the first and last character of a multiline span
104     Multiline(MultilineAnnotation),
105
106     // The Multiline type above is replaced with the following three in order
107     // to reuse the current label drawing code.
108     //
109     // Each of these corresponds to one part of the following diagram:
110     //
111     //     x |   foo(1 + bar(x,
112     //       |  _________^ starting here...           < MultilineStart
113     //     x | |             y),                      < MultilineLine
114     //       | |______________^ ...ending here: label < MultilineEnd
115     //     x |       z);
116     /// Annotation marking the first character of a fully shown multiline span
117     MultilineStart(usize),
118     /// Annotation marking the last character of a fully shown multiline span
119     MultilineEnd(usize),
120     /// Line at the left enclosing the lines of a fully shown multiline span
121     MultilineLine(usize),
122 }
123
124 #[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
125 pub struct Annotation {
126     /// Start column, 0-based indexing -- counting *characters*, not
127     /// utf-8 bytes. Note that it is important that this field goes
128     /// first, so that when we sort, we sort orderings by start
129     /// column.
130     pub start_col: usize,
131
132     /// End column within the line (exclusive)
133     pub end_col: usize,
134
135     /// Is this annotation derived from primary span
136     pub is_primary: bool,
137
138     /// Optional label to display adjacent to the annotation.
139     pub label: Option<String>,
140
141     /// Is this a single line, multiline or multiline span minimized down to a
142     /// smaller span.
143     pub annotation_type: AnnotationType,
144 }
145
146 impl Annotation {
147     pub fn is_minimized(&self) -> bool {
148         match self.annotation_type {
149             AnnotationType::Minimized => true,
150             _ => false,
151         }
152     }
153
154     pub fn is_multiline(&self) -> bool {
155         match self.annotation_type {
156             AnnotationType::Multiline(_) |
157             AnnotationType::MultilineStart(_) |
158             AnnotationType::MultilineLine(_) |
159             AnnotationType::MultilineEnd(_) => true,
160             _ => false,
161         }
162     }
163
164 }
165
166 #[derive(Debug)]
167 pub struct StyledString {
168     pub text: String,
169     pub style: Style,
170 }
171
172 #[derive(Copy, Clone, Debug, PartialEq)]
173 pub enum Style {
174     HeaderMsg,
175     FileNameStyle,
176     LineAndColumn,
177     LineNumber,
178     Quotation,
179     UnderlinePrimary,
180     UnderlineSecondary,
181     LabelPrimary,
182     LabelSecondary,
183     OldSchoolNoteText,
184     OldSchoolNote,
185     NoStyle,
186     ErrorCode,
187     Level(Level),
188     Highlight,
189 }