Merge: doc: fixed some typos and other misc. corrections
[nit.git] / src / highlight.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Highlighting of Nit AST
16 module highlight
17
18 import frontend
19 import astutil
20 import console
21
22 # Visitor used to produce a HTML tree based on a AST on a `Source`
23 class AbstractHighlightVisitor
24 # The first line to generate, null if start at the first line
25 var first_line: nullable Int = null is writable
26
27 # The last line to generate, null if finish at the last line
28 var last_line: nullable Int = null is writable
29
30 # When highlighting a node, show its messages (errors, warnings), if any.
31 #
32 # default: true
33 var show_messages = true is writable
34
35 # When highlighting a node, also consider the loose tokens around it.
36 #
37 # Loose tokens are tokens discarded from the AST but attached before
38 # or after some non-loose tokens. See `Token::is_loose`.
39 #
40 # When this flag is set to `true`, the loose tokens that are before the
41 # first token and after the last token are also highlighted.
42 #
43 # Default: false.
44 var include_loose_tokens = false is writable
45
46 # When highlighting a node, the first and the last lines are fully included.
47 #
48 # If the highlighted node starts (or ends) in the middle of a line,
49 # this flags forces the whole line to be highlighted.
50 #
51 # Default: false
52 var include_whole_lines = false is writable
53
54 # Highlight a AST element.
55 fun highlight_node(n: ANode)
56 do
57 n.parentize_tokens
58
59 var f
60 var l
61
62 if n isa Token then
63 f = n
64 l = n
65 else
66 assert n isa Prod
67 f = n.first_token
68 if f == null then return
69 l = n.last_token
70 if l == null then return
71 end
72
73 if include_loose_tokens then
74 if f.prev_looses.not_empty then f = f.prev_looses.first
75 if l.next_looses.not_empty then l = l.next_looses.last
76 end
77
78 var line = first_line
79 if line != null then
80 while f.location.line_start < line do
81 f = f.next_token
82 if f == null then return
83 end
84 end
85
86 line = last_line
87 if line != null then
88 while l.location.line_end > line do
89 l = l.prev_token
90 if l == null then return
91 end
92 end
93
94 if include_whole_lines then
95 f = f.first_real_token_in_line
96 l = l.last_real_token_in_line
97 end
98
99 do_highlight(f, l)
100 end
101
102 # Highlight a full lexed source file.
103 #
104 # REQUIRE `source.first_token != null`
105 fun highlight_source(source: SourceFile)
106 do
107 do_highlight(source.first_token.as(not null), null)
108 end
109
110 # Low-level highlighting between 2 tokens
111 protected fun do_highlight(first_token: Token, last_token: nullable Token) is abstract
112 end
113
114 # Text-based highlighter that use ANSI escape sequence for colors
115 class AnsiHighlightVisitor
116 super AbstractHighlightVisitor
117
118 # The produced highlighting
119 var result = new Template
120
121 redef fun do_highlight(f, l)
122 do
123 var c
124 c = f
125 while c != null do
126 if c != f then result.add(c.blank_before)
127 result.add c.ansi_colored
128
129 if c == l then
130 c = null
131 else
132 c = c.next_token
133 end
134 end
135 end
136 end
137
138 redef class Token
139 # Return the ANSI colored text
140 fun ansi_colored: String do return text
141 end
142
143 redef class TComment
144 redef fun ansi_colored do return super.blue
145 end
146
147 redef class TokenKeyword
148 redef fun ansi_colored do return super.yellow
149 end
150
151 redef class TClassid
152 redef fun ansi_colored do return super.green
153 end
154
155 redef class TokenLiteral
156 redef fun ansi_colored do return super.red
157 end