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 import 'package:analysis_server/src/collections.dart'; | 5 import 'package:analysis_server/src/collections.dart'; |
6 import 'package:analyzer/dart/ast/ast.dart'; | 6 import 'package:analyzer/dart/ast/ast.dart'; |
7 import 'package:analyzer/dart/ast/visitor.dart'; | 7 import 'package:analyzer/dart/ast/visitor.dart'; |
8 import 'package:analyzer/dart/element/element.dart' as engine; | 8 import 'package:analyzer/dart/element/element.dart' as engine; |
9 import 'package:analyzer/dart/element/type.dart' as engine; | 9 import 'package:analyzer/dart/element/type.dart' as engine; |
10 import 'package:analyzer/src/generated/source.dart'; | 10 import 'package:analyzer/src/generated/source.dart'; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 } | 83 } |
84 if (unitMember is FunctionTypeAlias) { | 84 if (unitMember is FunctionTypeAlias) { |
85 FunctionTypeAlias alias = unitMember; | 85 FunctionTypeAlias alias = unitMember; |
86 unitContents.add(_newFunctionTypeAliasOutline(alias)); | 86 unitContents.add(_newFunctionTypeAliasOutline(alias)); |
87 } | 87 } |
88 } | 88 } |
89 Outline unitOutline = _newUnitOutline(unitContents); | 89 Outline unitOutline = _newUnitOutline(unitContents); |
90 return unitOutline; | 90 return unitOutline; |
91 } | 91 } |
92 | 92 |
93 List<Outline> _addLocalFunctionOutlines(FunctionBody body) { | 93 List<Outline> _addFunctionBodyOutlines(FunctionBody body) { |
94 List<Outline> contents = <Outline>[]; | 94 List<Outline> contents = <Outline>[]; |
95 body.accept(new _LocalFunctionOutlinesVisitor(this, contents)); | 95 body.accept(new _FunctionBodyOutlinesVisitor(this, contents)); |
96 return contents; | 96 return contents; |
97 } | 97 } |
98 | 98 |
99 Location _getLocationNode(AstNode node) { | 99 Location _getLocationNode(AstNode node) { |
100 int offset = node.offset; | 100 int offset = node.offset; |
101 int length = node.length; | 101 int length = node.length; |
102 return _getLocationOffsetLength(offset, length); | 102 return _getLocationOffsetLength(offset, length); |
103 } | 103 } |
104 | 104 |
105 Location _getLocationOffsetLength(int offset, int length) { | 105 Location _getLocationOffsetLength(int offset, int length) { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 SourceRange range = _getSourceRange(constructor); | 205 SourceRange range = _getSourceRange(constructor); |
206 FormalParameterList parameters = constructor.parameters; | 206 FormalParameterList parameters = constructor.parameters; |
207 String parametersStr = _safeToSource(parameters); | 207 String parametersStr = _safeToSource(parameters); |
208 Element element = new Element( | 208 Element element = new Element( |
209 ElementKind.CONSTRUCTOR, | 209 ElementKind.CONSTRUCTOR, |
210 name, | 210 name, |
211 Element.makeFlags( | 211 Element.makeFlags( |
212 isPrivate: isPrivate, isDeprecated: _isDeprecated(constructor)), | 212 isPrivate: isPrivate, isDeprecated: _isDeprecated(constructor)), |
213 location: _getLocationOffsetLength(offset, length), | 213 location: _getLocationOffsetLength(offset, length), |
214 parameters: parametersStr); | 214 parameters: parametersStr); |
215 List<Outline> contents = _addLocalFunctionOutlines(constructor.body); | 215 List<Outline> contents = _addFunctionBodyOutlines(constructor.body); |
216 Outline outline = new Outline(element, range.offset, range.length, | 216 Outline outline = new Outline(element, range.offset, range.length, |
217 children: nullIfEmpty(contents)); | 217 children: nullIfEmpty(contents)); |
218 return outline; | 218 return outline; |
219 } | 219 } |
220 | 220 |
221 Outline _newEnumConstant(EnumConstantDeclaration node) { | 221 Outline _newEnumConstant(EnumConstantDeclaration node) { |
222 SimpleIdentifier nameNode = node.name; | 222 SimpleIdentifier nameNode = node.name; |
223 String name = nameNode.name; | 223 String name = nameNode.name; |
224 SourceRange range = _getSourceRange(node); | 224 SourceRange range = _getSourceRange(node); |
225 Element element = new Element( | 225 Element element = new Element( |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 Element element = new Element( | 267 Element element = new Element( |
268 kind, | 268 kind, |
269 name, | 269 name, |
270 Element.makeFlags( | 270 Element.makeFlags( |
271 isPrivate: Identifier.isPrivateName(name), | 271 isPrivate: Identifier.isPrivateName(name), |
272 isDeprecated: _isDeprecated(function), | 272 isDeprecated: _isDeprecated(function), |
273 isStatic: isStatic), | 273 isStatic: isStatic), |
274 location: _getLocationNode(nameNode), | 274 location: _getLocationNode(nameNode), |
275 parameters: parametersStr, | 275 parameters: parametersStr, |
276 returnType: returnTypeStr); | 276 returnType: returnTypeStr); |
277 List<Outline> contents = _addLocalFunctionOutlines(functionExpression.body); | 277 List<Outline> contents = _addFunctionBodyOutlines(functionExpression.body); |
278 Outline outline = new Outline(element, range.offset, range.length, | 278 Outline outline = new Outline(element, range.offset, range.length, |
279 children: nullIfEmpty(contents)); | 279 children: nullIfEmpty(contents)); |
280 return outline; | 280 return outline; |
281 } | 281 } |
282 | 282 |
283 Outline _newFunctionTypeAliasOutline(FunctionTypeAlias node) { | 283 Outline _newFunctionTypeAliasOutline(FunctionTypeAlias node) { |
284 TypeAnnotation returnType = node.returnType; | 284 TypeAnnotation returnType = node.returnType; |
285 SimpleIdentifier nameNode = node.name; | 285 SimpleIdentifier nameNode = node.name; |
286 String name = nameNode.name; | 286 String name = nameNode.name; |
287 SourceRange range = _getSourceRange(node); | 287 SourceRange range = _getSourceRange(node); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 kind, | 321 kind, |
322 name, | 322 name, |
323 Element.makeFlags( | 323 Element.makeFlags( |
324 isPrivate: Identifier.isPrivateName(name), | 324 isPrivate: Identifier.isPrivateName(name), |
325 isDeprecated: _isDeprecated(method), | 325 isDeprecated: _isDeprecated(method), |
326 isAbstract: method.isAbstract, | 326 isAbstract: method.isAbstract, |
327 isStatic: method.isStatic), | 327 isStatic: method.isStatic), |
328 location: _getLocationNode(nameNode), | 328 location: _getLocationNode(nameNode), |
329 parameters: parametersStr, | 329 parameters: parametersStr, |
330 returnType: returnTypeStr); | 330 returnType: returnTypeStr); |
331 List<Outline> contents = _addLocalFunctionOutlines(method.body); | 331 List<Outline> contents = _addFunctionBodyOutlines(method.body); |
332 Outline outline = new Outline(element, range.offset, range.length, | 332 Outline outline = new Outline(element, range.offset, range.length, |
333 children: nullIfEmpty(contents)); | 333 children: nullIfEmpty(contents)); |
334 return outline; | 334 return outline; |
335 } | 335 } |
336 | 336 |
337 Outline _newUnitOutline(List<Outline> unitContents) { | 337 Outline _newUnitOutline(List<Outline> unitContents) { |
338 Element element = new Element( | 338 Element element = new Element( |
339 ElementKind.COMPILATION_UNIT, '<unit>', Element.makeFlags(), | 339 ElementKind.COMPILATION_UNIT, '<unit>', Element.makeFlags(), |
340 location: _getLocationNode(unit)); | 340 location: _getLocationNode(unit)); |
341 return new Outline(element, unit.offset, unit.length, | 341 return new Outline(element, unit.offset, unit.length, |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 return element != null && element.isDeprecated; | 377 return element != null && element.isDeprecated; |
378 } | 378 } |
379 | 379 |
380 static String _safeToSource(AstNode node) => | 380 static String _safeToSource(AstNode node) => |
381 node == null ? '' : node.toSource(); | 381 node == null ? '' : node.toSource(); |
382 } | 382 } |
383 | 383 |
384 /** | 384 /** |
385 * A visitor for building local function outlines. | 385 * A visitor for building local function outlines. |
386 */ | 386 */ |
387 class _LocalFunctionOutlinesVisitor extends RecursiveAstVisitor { | 387 class _FunctionBodyOutlinesVisitor extends RecursiveAstVisitor { |
388 final DartUnitOutlineComputer outlineComputer; | 388 final DartUnitOutlineComputer outlineComputer; |
389 final List<Outline> contents; | 389 final List<Outline> contents; |
390 | 390 |
391 _LocalFunctionOutlinesVisitor(this.outlineComputer, this.contents); | 391 _FunctionBodyOutlinesVisitor(this.outlineComputer, this.contents); |
| 392 |
| 393 bool isGroup(engine.ExecutableElement element) { |
| 394 if (element is engine.FunctionElement && element.name == 'group') { |
| 395 engine.Element parent = element.enclosingElement; |
| 396 return parent is engine.CompilationUnitElement && |
| 397 parent.source.fullName.endsWith('test.dart'); |
| 398 } |
| 399 return false; |
| 400 } |
| 401 |
| 402 bool isTest(engine.ExecutableElement element) { |
| 403 if (element is engine.FunctionElement && element.name == 'test') { |
| 404 engine.Element parent = element.enclosingElement; |
| 405 return parent is engine.CompilationUnitElement && |
| 406 parent.source.fullName.endsWith('test.dart'); |
| 407 } |
| 408 return false; |
| 409 } |
392 | 410 |
393 @override | 411 @override |
394 visitFunctionDeclaration(FunctionDeclaration node) { | 412 visitFunctionDeclaration(FunctionDeclaration node) { |
395 contents.add(outlineComputer._newFunctionOutline(node, false)); | 413 contents.add(outlineComputer._newFunctionOutline(node, false)); |
396 } | 414 } |
| 415 |
| 416 @override |
| 417 visitMethodInvocation(MethodInvocation node) { |
| 418 SimpleIdentifier nameNode = node.methodName; |
| 419 engine.ExecutableElement executableElement = nameNode.bestElement; |
| 420 |
| 421 String extractString(NodeList<Expression> arguments) { |
| 422 if (arguments != null && arguments.length > 0) { |
| 423 Expression argument = arguments[0]; |
| 424 if (argument is StringLiteral) { |
| 425 String value = argument.stringValue; |
| 426 if (value != null) { |
| 427 return value; |
| 428 } |
| 429 } |
| 430 return argument.toSource(); |
| 431 } |
| 432 return 'unnamed'; |
| 433 } |
| 434 |
| 435 void addOutline(String kind, [List<Outline> children]) { |
| 436 SourceRange range = outlineComputer._getSourceRange(node); |
| 437 String name = kind + ' ' + extractString(node.argumentList?.arguments); |
| 438 Element element = new Element(ElementKind.UNKNOWN, name, 0, |
| 439 location: outlineComputer._getLocationNode(nameNode)); |
| 440 contents.add(new Outline(element, range.offset, range.length, |
| 441 children: nullIfEmpty(children))); |
| 442 } |
| 443 |
| 444 if (isGroup(executableElement)) { |
| 445 List<Outline> groupContents = <Outline>[]; |
| 446 node.argumentList.accept( |
| 447 new _FunctionBodyOutlinesVisitor(outlineComputer, groupContents)); |
| 448 addOutline('group', groupContents); |
| 449 } else if (isTest(executableElement)) { |
| 450 addOutline('test'); |
| 451 } else { |
| 452 super.visitMethodInvocation(node); |
| 453 } |
| 454 } |
397 } | 455 } |
OLD | NEW |