OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library computer.highlights; | 5 library computer.highlights2; |
6 | 6 |
7 import 'package:analysis_server/src/protocol.dart' hide Element; | 7 import 'package:analysis_server/src/protocol.dart' hide Element; |
8 import 'package:analyzer/src/generated/ast.dart'; | 8 import 'package:analyzer/src/generated/ast.dart'; |
9 import 'package:analyzer/src/generated/element.dart'; | 9 import 'package:analyzer/src/generated/element.dart'; |
10 import 'package:analyzer/src/generated/scanner.dart'; | 10 import 'package:analyzer/src/generated/scanner.dart'; |
11 | 11 |
12 /** | 12 /** |
13 * A computer for [HighlightRegion]s in a Dart [CompilationUnit]. | 13 * A computer for [HighlightRegion]s in a Dart [CompilationUnit]. |
14 */ | 14 */ |
15 class DartUnitHighlightsComputer { | 15 class DartUnitHighlightsComputer2 { |
16 final CompilationUnit _unit; | 16 final CompilationUnit _unit; |
17 | 17 |
18 final List<HighlightRegion> _regions = <HighlightRegion>[]; | 18 final List<HighlightRegion> _regions = <HighlightRegion>[]; |
19 | 19 |
20 DartUnitHighlightsComputer(this._unit); | 20 DartUnitHighlightsComputer2(this._unit); |
21 | 21 |
22 /** | 22 /** |
23 * Returns the computed highlight regions, not `null`. | 23 * Returns the computed highlight regions, not `null`. |
24 */ | 24 */ |
25 List<HighlightRegion> compute() { | 25 List<HighlightRegion> compute() { |
26 _unit.accept(new _DartUnitHighlightsComputerVisitor(this)); | 26 _unit.accept(new _DartUnitHighlightsComputerVisitor2(this)); |
27 _addCommentRanges(); | 27 _addCommentRanges(); |
28 return _regions; | 28 return _regions; |
29 } | 29 } |
30 | 30 |
31 void _addCommentRanges() { | 31 void _addCommentRanges() { |
32 Token token = _unit.beginToken; | 32 Token token = _unit.beginToken; |
33 while (token != null && token.type != TokenType.EOF) { | 33 while (token != null && token.type != TokenType.EOF) { |
34 Token commentToken = token.precedingComments; | 34 Token commentToken = token.precedingComments; |
35 while (commentToken != null) { | 35 while (commentToken != null) { |
36 HighlightRegionType highlightType = null; | 36 HighlightRegionType highlightType = null; |
(...skipping 19 matching lines...) Expand all Loading... |
56 void _addIdentifierRegion(SimpleIdentifier node) { | 56 void _addIdentifierRegion(SimpleIdentifier node) { |
57 if (_addIdentifierRegion_keyword(node)) { | 57 if (_addIdentifierRegion_keyword(node)) { |
58 return; | 58 return; |
59 } | 59 } |
60 if (_addIdentifierRegion_class(node)) { | 60 if (_addIdentifierRegion_class(node)) { |
61 return; | 61 return; |
62 } | 62 } |
63 if (_addIdentifierRegion_constructor(node)) { | 63 if (_addIdentifierRegion_constructor(node)) { |
64 return; | 64 return; |
65 } | 65 } |
66 if (_addIdentifierRegion_dynamicType(node)) { | 66 if (_addIdentifierRegion_dynamicLocal(node)) { |
67 return; | 67 return; |
68 } | 68 } |
69 if (_addIdentifierRegion_getterSetterDeclaration(node)) { | 69 if (_addIdentifierRegion_getterSetterDeclaration(node)) { |
70 return; | 70 return; |
71 } | 71 } |
72 if (_addIdentifierRegion_field(node)) { | 72 if (_addIdentifierRegion_field(node)) { |
73 return; | 73 return; |
74 } | 74 } |
75 if (_addIdentifierRegion_function(node)) { | 75 if (_addIdentifierRegion_function(node)) { |
76 return; | 76 return; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 } | 128 } |
129 | 129 |
130 bool _addIdentifierRegion_constructor(SimpleIdentifier node) { | 130 bool _addIdentifierRegion_constructor(SimpleIdentifier node) { |
131 Element element = node.staticElement; | 131 Element element = node.staticElement; |
132 if (element is! ConstructorElement) { | 132 if (element is! ConstructorElement) { |
133 return false; | 133 return false; |
134 } | 134 } |
135 return _addRegion_node(node, HighlightRegionType.CONSTRUCTOR); | 135 return _addRegion_node(node, HighlightRegionType.CONSTRUCTOR); |
136 } | 136 } |
137 | 137 |
138 bool _addIdentifierRegion_dynamicType(SimpleIdentifier node) { | 138 bool _addIdentifierRegion_dynamicLocal(SimpleIdentifier node) { |
139 // should be variable | 139 // no propagated type |
140 Element element = node.staticElement; | |
141 if (element is! VariableElement) { | |
142 return false; | |
143 } | |
144 // has propagated type | |
145 if (node.propagatedType != null) { | 140 if (node.propagatedType != null) { |
146 return false; | 141 return false; |
147 } | 142 } |
148 // has dynamic static type | 143 // has dynamic static type |
149 DartType staticType = node.staticType; | 144 DartType staticType = node.staticType; |
150 if (staticType == null || !staticType.isDynamic) { | 145 if (staticType == null || !staticType.isDynamic) { |
151 return false; | 146 return false; |
152 } | 147 } |
153 // OK | 148 // OK |
154 return _addRegion_node(node, HighlightRegionType.DYNAMIC_TYPE); | 149 Element element = node.staticElement; |
| 150 if (element is LocalVariableElement) { |
| 151 HighlightRegionType type = node.inDeclarationContext() |
| 152 ? HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_DECLARATION |
| 153 : HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_REFERENCE; |
| 154 return _addRegion_node(node, type); |
| 155 } |
| 156 if (element is ParameterElement) { |
| 157 HighlightRegionType type = node.inDeclarationContext() |
| 158 ? HighlightRegionType.DYNAMIC_PARAMETER_DECLARATION |
| 159 : HighlightRegionType.DYNAMIC_PARAMETER_REFERENCE; |
| 160 return _addRegion_node(node, type); |
| 161 } |
| 162 return false; |
155 } | 163 } |
156 | 164 |
157 bool _addIdentifierRegion_field(SimpleIdentifier node) { | 165 bool _addIdentifierRegion_field(SimpleIdentifier node) { |
158 Element element = node.bestElement; | 166 Element element = node.bestElement; |
159 if (element is FieldFormalParameterElement) { | 167 if (element is FieldFormalParameterElement) { |
160 element = (element as FieldFormalParameterElement).field; | 168 element = (element as FieldFormalParameterElement).field; |
161 } | 169 } |
162 if (element is PropertyAccessorElement) { | |
163 element = (element as PropertyAccessorElement).variable; | |
164 } | |
165 // prepare type | 170 // prepare type |
166 HighlightRegionType type; | 171 HighlightRegionType type; |
167 if (element is FieldElement) { | 172 if (element is FieldElement) { |
168 Element enclosingElement = element.enclosingElement; | 173 Element enclosingElement = element.enclosingElement; |
169 if (enclosingElement is ClassElement && enclosingElement.isEnum) { | 174 if (enclosingElement is ClassElement && enclosingElement.isEnum) { |
170 type = HighlightRegionType.ENUM_CONSTANT; | 175 type = HighlightRegionType.ENUM_CONSTANT; |
171 } else if (element.isStatic) { | 176 } else if (element.isStatic) { |
172 type = HighlightRegionType.FIELD_STATIC; | 177 type = HighlightRegionType.STATIC_FIELD_DECLARATION; |
173 } else { | 178 } else { |
174 type = HighlightRegionType.FIELD; | 179 type = node.inDeclarationContext() |
| 180 ? HighlightRegionType.INSTANCE_FIELD_DECLARATION |
| 181 : HighlightRegionType.INSTANCE_FIELD_REFERENCE; |
175 } | 182 } |
176 } else if (element is TopLevelVariableElement) { | 183 } else if (element is TopLevelVariableElement) { |
177 type = HighlightRegionType.TOP_LEVEL_VARIABLE; | 184 type = HighlightRegionType.TOP_LEVEL_VARIABLE_DECLARATION; |
| 185 } |
| 186 if (element is PropertyAccessorElement) { |
| 187 PropertyAccessorElement accessor = element; |
| 188 Element enclosingElement = element.enclosingElement; |
| 189 if (accessor.variable is TopLevelVariableElement) { |
| 190 type = accessor.isGetter |
| 191 ? HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE |
| 192 : HighlightRegionType.TOP_LEVEL_SETTER_REFERENCE; |
| 193 } else if (enclosingElement is ClassElement && enclosingElement.isEnum) { |
| 194 type = HighlightRegionType.ENUM_CONSTANT; |
| 195 } else if (accessor.isStatic) { |
| 196 type = accessor.isGetter |
| 197 ? HighlightRegionType.STATIC_GETTER_REFERENCE |
| 198 : HighlightRegionType.STATIC_SETTER_REFERENCE; |
| 199 } else { |
| 200 type = accessor.isGetter |
| 201 ? HighlightRegionType.INSTANCE_GETTER_REFERENCE |
| 202 : HighlightRegionType.INSTANCE_SETTER_REFERENCE; |
| 203 } |
178 } | 204 } |
179 // add region | 205 // add region |
180 if (type != null) { | 206 if (type != null) { |
181 return _addRegion_node(node, type); | 207 return _addRegion_node(node, type); |
182 } | 208 } |
183 return false; | 209 return false; |
184 } | 210 } |
185 | 211 |
186 bool _addIdentifierRegion_function(SimpleIdentifier node) { | 212 bool _addIdentifierRegion_function(SimpleIdentifier node) { |
187 Element element = node.staticElement; | 213 Element element = node.staticElement; |
188 if (element is! FunctionElement) { | 214 if (element is! FunctionElement) { |
189 return false; | 215 return false; |
190 } | 216 } |
191 HighlightRegionType type; | 217 HighlightRegionType type; |
| 218 bool isTopLevel = element.enclosingElement is CompilationUnitElement; |
192 if (node.inDeclarationContext()) { | 219 if (node.inDeclarationContext()) { |
193 type = HighlightRegionType.FUNCTION_DECLARATION; | 220 type = isTopLevel |
| 221 ? HighlightRegionType.TOP_LEVEL_FUNCTION_DECLARATION |
| 222 : HighlightRegionType.LOCAL_FUNCTION_DECLARATION; |
194 } else { | 223 } else { |
195 type = HighlightRegionType.FUNCTION; | 224 type = isTopLevel |
| 225 ? HighlightRegionType.TOP_LEVEL_FUNCTION_REFERENCE |
| 226 : HighlightRegionType.LOCAL_FUNCTION_REFERENCE; |
196 } | 227 } |
197 return _addRegion_node(node, type); | 228 return _addRegion_node(node, type); |
198 } | 229 } |
199 | 230 |
200 bool _addIdentifierRegion_functionTypeAlias(SimpleIdentifier node) { | 231 bool _addIdentifierRegion_functionTypeAlias(SimpleIdentifier node) { |
201 Element element = node.staticElement; | 232 Element element = node.staticElement; |
202 if (element is! FunctionTypeAliasElement) { | 233 if (element is! FunctionTypeAliasElement) { |
203 return false; | 234 return false; |
204 } | 235 } |
205 return _addRegion_node(node, HighlightRegionType.FUNCTION_TYPE_ALIAS); | 236 return _addRegion_node(node, HighlightRegionType.FUNCTION_TYPE_ALIAS); |
206 } | 237 } |
207 | 238 |
208 bool _addIdentifierRegion_getterSetterDeclaration(SimpleIdentifier node) { | 239 bool _addIdentifierRegion_getterSetterDeclaration(SimpleIdentifier node) { |
209 // should be declaration | 240 // should be declaration |
210 AstNode parent = node.parent; | 241 AstNode parent = node.parent; |
211 if (!(parent is MethodDeclaration || parent is FunctionDeclaration)) { | 242 if (!(parent is MethodDeclaration || parent is FunctionDeclaration)) { |
212 return false; | 243 return false; |
213 } | 244 } |
214 // should be property accessor | 245 // should be property accessor |
215 Element element = node.staticElement; | 246 Element element = node.staticElement; |
216 if (element is! PropertyAccessorElement) { | 247 if (element is! PropertyAccessorElement) { |
217 return false; | 248 return false; |
218 } | 249 } |
219 // getter or setter | 250 // getter or setter |
220 PropertyAccessorElement propertyAccessorElement = | 251 PropertyAccessorElement propertyAccessorElement = |
221 element as PropertyAccessorElement; | 252 element as PropertyAccessorElement; |
| 253 bool isTopLevel = element.enclosingElement is CompilationUnitElement; |
| 254 HighlightRegionType type; |
222 if (propertyAccessorElement.isGetter) { | 255 if (propertyAccessorElement.isGetter) { |
223 return _addRegion_node(node, HighlightRegionType.GETTER_DECLARATION); | 256 if (isTopLevel) { |
| 257 type = HighlightRegionType.TOP_LEVEL_GETTER_DECLARATION; |
| 258 } else if (propertyAccessorElement.isStatic) { |
| 259 type = HighlightRegionType.STATIC_GETTER_DECLARATION; |
| 260 } else { |
| 261 type = HighlightRegionType.INSTANCE_GETTER_DECLARATION; |
| 262 } |
224 } else { | 263 } else { |
225 return _addRegion_node(node, HighlightRegionType.SETTER_DECLARATION); | 264 if (isTopLevel) { |
| 265 type = HighlightRegionType.TOP_LEVEL_SETTER_DECLARATION; |
| 266 } else if (propertyAccessorElement.isStatic) { |
| 267 type = HighlightRegionType.STATIC_SETTER_DECLARATION; |
| 268 } else { |
| 269 type = HighlightRegionType.INSTANCE_SETTER_DECLARATION; |
| 270 } |
226 } | 271 } |
| 272 return _addRegion_node(node, type); |
227 } | 273 } |
228 | 274 |
229 bool _addIdentifierRegion_importPrefix(SimpleIdentifier node) { | 275 bool _addIdentifierRegion_importPrefix(SimpleIdentifier node) { |
230 Element element = node.staticElement; | 276 Element element = node.staticElement; |
231 if (element is! PrefixElement) { | 277 if (element is! PrefixElement) { |
232 return false; | 278 return false; |
233 } | 279 } |
234 return _addRegion_node(node, HighlightRegionType.IMPORT_PREFIX); | 280 return _addRegion_node(node, HighlightRegionType.IMPORT_PREFIX); |
235 } | 281 } |
236 | 282 |
(...skipping 12 matching lines...) Expand all Loading... |
249 } | 295 } |
250 return _addRegion_node(node, HighlightRegionType.LABEL); | 296 return _addRegion_node(node, HighlightRegionType.LABEL); |
251 } | 297 } |
252 | 298 |
253 bool _addIdentifierRegion_localVariable(SimpleIdentifier node) { | 299 bool _addIdentifierRegion_localVariable(SimpleIdentifier node) { |
254 Element element = node.staticElement; | 300 Element element = node.staticElement; |
255 if (element is! LocalVariableElement) { | 301 if (element is! LocalVariableElement) { |
256 return false; | 302 return false; |
257 } | 303 } |
258 // OK | 304 // OK |
259 HighlightRegionType type; | 305 HighlightRegionType type = node.inDeclarationContext() |
260 if (node.inDeclarationContext()) { | 306 ? HighlightRegionType.LOCAL_VARIABLE_DECLARATION |
261 type = HighlightRegionType.LOCAL_VARIABLE_DECLARATION; | 307 : HighlightRegionType.LOCAL_VARIABLE_REFERENCE; |
262 } else { | |
263 type = HighlightRegionType.LOCAL_VARIABLE; | |
264 } | |
265 return _addRegion_node(node, type); | 308 return _addRegion_node(node, type); |
266 } | 309 } |
267 | 310 |
268 bool _addIdentifierRegion_method(SimpleIdentifier node) { | 311 bool _addIdentifierRegion_method(SimpleIdentifier node) { |
269 Element element = node.bestElement; | 312 Element element = node.bestElement; |
270 if (element is! MethodElement) { | 313 if (element is! MethodElement) { |
271 return false; | 314 return false; |
272 } | 315 } |
273 MethodElement methodElement = element as MethodElement; | 316 MethodElement methodElement = element as MethodElement; |
274 bool isStatic = methodElement.isStatic; | 317 bool isStatic = methodElement.isStatic; |
275 // OK | 318 // OK |
276 HighlightRegionType type; | 319 HighlightRegionType type; |
277 if (node.inDeclarationContext()) { | 320 if (node.inDeclarationContext()) { |
278 if (isStatic) { | 321 if (isStatic) { |
279 type = HighlightRegionType.METHOD_DECLARATION_STATIC; | 322 type = HighlightRegionType.STATIC_METHOD_DECLARATION; |
280 } else { | 323 } else { |
281 type = HighlightRegionType.METHOD_DECLARATION; | 324 type = HighlightRegionType.INSTANCE_METHOD_DECLARATION; |
282 } | 325 } |
283 } else { | 326 } else { |
284 if (isStatic) { | 327 if (isStatic) { |
285 type = HighlightRegionType.METHOD_STATIC; | 328 type = HighlightRegionType.STATIC_METHOD_REFERENCE; |
286 } else { | 329 } else { |
287 type = HighlightRegionType.METHOD; | 330 type = HighlightRegionType.INSTANCE_METHOD_REFERENCE; |
288 } | 331 } |
289 } | 332 } |
290 return _addRegion_node(node, type); | 333 return _addRegion_node(node, type); |
291 } | 334 } |
292 | 335 |
293 bool _addIdentifierRegion_parameter(SimpleIdentifier node) { | 336 bool _addIdentifierRegion_parameter(SimpleIdentifier node) { |
294 Element element = node.staticElement; | 337 Element element = node.staticElement; |
295 if (element is! ParameterElement) { | 338 if (element is! ParameterElement) { |
296 return false; | 339 return false; |
297 } | 340 } |
298 return _addRegion_node(node, HighlightRegionType.PARAMETER); | 341 HighlightRegionType type = node.inDeclarationContext() |
| 342 ? HighlightRegionType.PARAMETER_DECLARATION |
| 343 : HighlightRegionType.PARAMETER_REFERENCE; |
| 344 return _addRegion_node(node, type); |
299 } | 345 } |
300 | 346 |
301 bool _addIdentifierRegion_typeParameter(SimpleIdentifier node) { | 347 bool _addIdentifierRegion_typeParameter(SimpleIdentifier node) { |
302 Element element = node.staticElement; | 348 Element element = node.staticElement; |
303 if (element is! TypeParameterElement) { | 349 if (element is! TypeParameterElement) { |
304 return false; | 350 return false; |
305 } | 351 } |
306 return _addRegion_node(node, HighlightRegionType.TYPE_PARAMETER); | 352 return _addRegion_node(node, HighlightRegionType.TYPE_PARAMETER); |
307 } | 353 } |
308 | 354 |
(...skipping 25 matching lines...) Expand all Loading... |
334 | 380 |
335 void _addRegion_tokenStart_tokenEnd( | 381 void _addRegion_tokenStart_tokenEnd( |
336 Token a, Token b, HighlightRegionType type) { | 382 Token a, Token b, HighlightRegionType type) { |
337 int offset = a.offset; | 383 int offset = a.offset; |
338 int end = b.end; | 384 int end = b.end; |
339 _addRegion(offset, end - offset, type); | 385 _addRegion(offset, end - offset, type); |
340 } | 386 } |
341 } | 387 } |
342 | 388 |
343 /** | 389 /** |
344 * An AST visitor for [DartUnitHighlightsComputer]. | 390 * An AST visitor for [DartUnitHighlightsComputer2]. |
345 */ | 391 */ |
346 class _DartUnitHighlightsComputerVisitor extends RecursiveAstVisitor<Object> { | 392 class _DartUnitHighlightsComputerVisitor2 extends RecursiveAstVisitor<Object> { |
347 final DartUnitHighlightsComputer computer; | 393 final DartUnitHighlightsComputer2 computer; |
348 | 394 |
349 _DartUnitHighlightsComputerVisitor(this.computer); | 395 _DartUnitHighlightsComputerVisitor2(this.computer); |
350 | 396 |
351 @override | 397 @override |
352 Object visitAnnotation(Annotation node) { | 398 Object visitAnnotation(Annotation node) { |
353 computer._addIdentifierRegion_annotation(node); | 399 computer._addIdentifierRegion_annotation(node); |
354 return super.visitAnnotation(node); | 400 return super.visitAnnotation(node); |
355 } | 401 } |
356 | 402 |
357 @override | 403 @override |
358 Object visitAsExpression(AsExpression node) { | 404 Object visitAsExpression(AsExpression node) { |
359 computer._addRegion_token(node.asOperator, HighlightRegionType.BUILT_IN); | 405 computer._addRegion_token(node.asOperator, HighlightRegionType.BUILT_IN); |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
715 void _addRegions_functionBody(FunctionBody node) { | 761 void _addRegions_functionBody(FunctionBody node) { |
716 Token keyword = node.keyword; | 762 Token keyword = node.keyword; |
717 if (keyword != null) { | 763 if (keyword != null) { |
718 Token star = node.star; | 764 Token star = node.star; |
719 int offset = keyword.offset; | 765 int offset = keyword.offset; |
720 int end = star != null ? star.end : keyword.end; | 766 int end = star != null ? star.end : keyword.end; |
721 computer._addRegion(offset, end - offset, HighlightRegionType.BUILT_IN); | 767 computer._addRegion(offset, end - offset, HighlightRegionType.BUILT_IN); |
722 } | 768 } |
723 } | 769 } |
724 } | 770 } |
OLD | NEW |