Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(298)

Side by Side Diff: utils/dartdoc/classify.dart

Issue 9555013: Get dartdoc in the SDK and working correctly. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Update copyright date. Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 #library('classify');
6
7 #import('../../frog/lang.dart');
8 #import('markdown.dart', prefix: 'md');
9
10 /**
11 * Kinds of tokens that we care to highlight differently. The values of the
12 * fields here will be used as CSS class names for the generated spans.
13 */
14 class Classification {
15 static final NONE = null;
16 static final ERROR = "e";
17 static final COMMENT = "c";
18 static final IDENTIFIER = "i";
19 static final KEYWORD = "k";
20 static final OPERATOR = "o";
21 static final STRING = "s";
22 static final NUMBER = "n";
23 static final PUNCTUATION = "p";
24
25 // A few things that are nice to make different:
26 static final TYPE_IDENTIFIER = "t";
27
28 // Between a keyword and an identifier
29 static final SPECIAL_IDENTIFIER = "r";
30
31 static final ARROW_OPERATOR = "a";
32
33 static final STRING_INTERPOLATION = 'si';
34 }
35
36 String classifySource(SourceFile src) {
37 var html = new StringBuffer();
38 var tokenizer = new Tokenizer(src, /*skipWhitespace:*/false);
39
40 var token;
41 var inString = false;
42 while ((token = tokenizer.next()).kind != TokenKind.END_OF_FILE) {
43
44 // Track whether or not we're in a string.
45 switch (token.kind) {
46 case TokenKind.STRING:
47 case TokenKind.STRING_PART:
48 case TokenKind.INCOMPLETE_STRING:
49 case TokenKind.INCOMPLETE_MULTILINE_STRING_DQ:
50 case TokenKind.INCOMPLETE_MULTILINE_STRING_SQ:
51 inString = true;
52 break;
53 }
54
55 final kind = classify(token);
56 final text = md.escapeHtml(token.text);
57 if (kind != null) {
58 // Add a secondary class to tokens appearing within a string so that
59 // we can highlight tokens in an interpolation specially.
60 var stringClass = inString ? Classification.STRING_INTERPOLATION : '';
61 html.add('<span class="$kind $stringClass">$text</span>');
62 } else {
63 html.add('<span>$text</span>');
64 }
65
66 // Track whether or not we're in a string.
67 if (token.kind == TokenKind.STRING) {
68 inString = false;
69 }
70 }
71 return html.toString();
72 }
73
74 bool _looksLikeType(String name) {
75 // If the name looks like an UppercaseName, assume it's a type.
76 return _looksLikePublicType(name) || _looksLikePrivateType(name);
77 }
78
79 bool _looksLikePublicType(String name) {
80 // If the name looks like an UppercaseName, assume it's a type.
81 return name.length >= 2 && isUpper(name[0]) && isLower(name[1]);
82 }
83
84 bool _looksLikePrivateType(String name) {
85 // If the name looks like an _UppercaseName, assume it's a type.
86 return (name.length >= 3 && name[0] == '_' && isUpper(name[1])
87 && isLower(name[2]));
88 }
89
90 // These ensure that they don't return "true" if the string only has symbols.
91 bool isUpper(String s) => s.toLowerCase() != s;
92 bool isLower(String s) => s.toUpperCase() != s;
93
94 String classify(Token token) {
95 switch (token.kind) {
96 case TokenKind.ERROR:
97 return Classification.ERROR;
98
99 case TokenKind.IDENTIFIER:
100 // Special case for names that look like types.
101 if (_looksLikeType(token.text)
102 || token.text == 'num'
103 || token.text == 'bool'
104 || token.text == 'int'
105 || token.text == 'double') {
106 return Classification.TYPE_IDENTIFIER;
107 }
108 return Classification.IDENTIFIER;
109
110 // Even though it's a reserved word, let's try coloring it like a type.
111 case TokenKind.VOID:
112 return Classification.TYPE_IDENTIFIER;
113
114 case TokenKind.THIS:
115 case TokenKind.SUPER:
116 return Classification.SPECIAL_IDENTIFIER;
117
118 case TokenKind.STRING:
119 case TokenKind.STRING_PART:
120 case TokenKind.INCOMPLETE_STRING:
121 case TokenKind.INCOMPLETE_MULTILINE_STRING_DQ:
122 case TokenKind.INCOMPLETE_MULTILINE_STRING_SQ:
123 return Classification.STRING;
124
125 case TokenKind.INTEGER:
126 case TokenKind.HEX_INTEGER:
127 case TokenKind.DOUBLE:
128 return Classification.NUMBER;
129
130 case TokenKind.COMMENT:
131 case TokenKind.INCOMPLETE_COMMENT:
132 return Classification.COMMENT;
133
134 // => is so awesome it is in a class of its own.
135 case TokenKind.ARROW:
136 return Classification.ARROW_OPERATOR;
137
138 case TokenKind.HASHBANG:
139 case TokenKind.LPAREN:
140 case TokenKind.RPAREN:
141 case TokenKind.LBRACK:
142 case TokenKind.RBRACK:
143 case TokenKind.LBRACE:
144 case TokenKind.RBRACE:
145 case TokenKind.COLON:
146 case TokenKind.SEMICOLON:
147 case TokenKind.COMMA:
148 case TokenKind.DOT:
149 case TokenKind.ELLIPSIS:
150 return Classification.PUNCTUATION;
151
152 case TokenKind.INCR:
153 case TokenKind.DECR:
154 case TokenKind.BIT_NOT:
155 case TokenKind.NOT:
156 case TokenKind.ASSIGN:
157 case TokenKind.ASSIGN_OR:
158 case TokenKind.ASSIGN_XOR:
159 case TokenKind.ASSIGN_AND:
160 case TokenKind.ASSIGN_SHL:
161 case TokenKind.ASSIGN_SAR:
162 case TokenKind.ASSIGN_SHR:
163 case TokenKind.ASSIGN_ADD:
164 case TokenKind.ASSIGN_SUB:
165 case TokenKind.ASSIGN_MUL:
166 case TokenKind.ASSIGN_DIV:
167 case TokenKind.ASSIGN_TRUNCDIV:
168 case TokenKind.ASSIGN_MOD:
169 case TokenKind.CONDITIONAL:
170 case TokenKind.OR:
171 case TokenKind.AND:
172 case TokenKind.BIT_OR:
173 case TokenKind.BIT_XOR:
174 case TokenKind.BIT_AND:
175 case TokenKind.SHL:
176 case TokenKind.SAR:
177 case TokenKind.SHR:
178 case TokenKind.ADD:
179 case TokenKind.SUB:
180 case TokenKind.MUL:
181 case TokenKind.DIV:
182 case TokenKind.TRUNCDIV:
183 case TokenKind.MOD:
184 case TokenKind.EQ:
185 case TokenKind.NE:
186 case TokenKind.EQ_STRICT:
187 case TokenKind.NE_STRICT:
188 case TokenKind.LT:
189 case TokenKind.GT:
190 case TokenKind.LTE:
191 case TokenKind.GTE:
192 case TokenKind.INDEX:
193 case TokenKind.SETINDEX:
194 return Classification.OPERATOR;
195
196 // Color this like a keyword
197 case TokenKind.HASH:
198
199 case TokenKind.ABSTRACT:
200 case TokenKind.ASSERT:
201 case TokenKind.CLASS:
202 case TokenKind.EXTENDS:
203 case TokenKind.FACTORY:
204 case TokenKind.GET:
205 case TokenKind.IMPLEMENTS:
206 case TokenKind.IMPORT:
207 case TokenKind.INTERFACE:
208 case TokenKind.LIBRARY:
209 case TokenKind.NATIVE:
210 case TokenKind.NEGATE:
211 case TokenKind.OPERATOR:
212 case TokenKind.SET:
213 case TokenKind.SOURCE:
214 case TokenKind.STATIC:
215 case TokenKind.TYPEDEF:
216 case TokenKind.BREAK:
217 case TokenKind.CASE:
218 case TokenKind.CATCH:
219 case TokenKind.CONST:
220 case TokenKind.CONTINUE:
221 case TokenKind.DEFAULT:
222 case TokenKind.DO:
223 case TokenKind.ELSE:
224 case TokenKind.FALSE:
225 case TokenKind.FINALLY:
226 case TokenKind.FOR:
227 case TokenKind.IF:
228 case TokenKind.IN:
229 case TokenKind.IS:
230 case TokenKind.NEW:
231 case TokenKind.NULL:
232 case TokenKind.RETURN:
233 case TokenKind.SWITCH:
234 case TokenKind.THROW:
235 case TokenKind.TRUE:
236 case TokenKind.TRY:
237 case TokenKind.WHILE:
238 case TokenKind.VAR:
239 case TokenKind.FINAL:
240 return Classification.KEYWORD;
241
242 case TokenKind.WHITESPACE:
243 case TokenKind.END_OF_FILE:
244 return Classification.NONE;
245
246 default:
247 return Classification.NONE;
248 }
249 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698