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

Side by Side Diff: frog/samples/classify.dart

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

Powered by Google App Engine
This is Rietveld 408576698