| // Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| import 'package:analysis_server/protocol/protocol_generated.dart' | |
| show AnalysisGetSignatureResult; | |
| import 'package:analysis_server/src/computer/computer_hover.dart'; | |
| import 'package:analysis_server/src/protocol_server.dart'; | |
| import 'package:analyzer/dart/ast/ast.dart'; | |
| import 'package:analyzer/dart/element/element.dart'; | |
| import 'package:analyzer/src/dart/ast/element_locator.dart'; | |
| import 'package:analyzer/src/dart/ast/utilities.dart'; | |
| import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart'; | |
| /** | |
| * A computer for the signature at the specified offset of a Dart [CompilationUnit]. | |
| */ | |
| class DartUnitSignatureComputer { | |
| final DartdocDirectiveInfo _dartdocInfo; | |
| final AstNode _node; | |
| DartUnitSignatureComputer( | |
| this._dartdocInfo, CompilationUnit _unit, int _offset) | |
| : _node = new NodeLocator(_offset).searchWithin(_unit); | |
| bool get offsetIsValid => _node != null; | |
| /** | |
| * Returns the computed signature information, maybe `null`. | |
| */ | |
| AnalysisGetSignatureResult compute() { | |
| if (_node == null) { | |
| return null; | |
| } | |
| // Find the closest argument list. | |
| var argsNode = _node; | |
| while (argsNode != null && !(argsNode is ArgumentList)) { | |
| // Certain nodes don't make sense to search above for an argument list | |
| // (for example when inside a function epxression). | |
| if (argsNode is FunctionExpression) { | |
| return null; | |
| } | |
| argsNode = argsNode.parent; | |
| } | |
| if (argsNode == null) { | |
| return null; | |
| } | |
| final args = argsNode; | |
| String name; | |
| ExecutableElement execElement; | |
| if (args.parent is MethodInvocation) { | |
| MethodInvocation method = args.parent; | |
| name = method.methodName.name; | |
| execElement = ElementLocator.locate(method) as ExecutableElement; | |
| } else if (args.parent is InstanceCreationExpression) { | |
| InstanceCreationExpression constructor = args.parent; | |
| name = constructor.constructorName.type.name.name; | |
| if (constructor.constructorName.name != null) { | |
| name += ".${constructor.constructorName.name.name}"; | |
| } | |
| execElement = ElementLocator.locate(constructor) as ExecutableElement; | |
| } | |
| if (execElement == null) { | |
| return null; | |
| } | |
| final parameters = | |
| execElement.parameters.map((p) => _convertParam(p)).toList(); | |
| return new AnalysisGetSignatureResult(name, parameters, | |
| dartdoc: DartUnitHoverComputer.computeDocumentation( | |
| _dartdocInfo, execElement)); | |
| } | |
| ParameterInfo _convertParam(ParameterElement param) { | |
| return new ParameterInfo( | |
| param.isOptionalPositional | |
| ? ParameterKind.OPTIONAL | |
| : param.isPositional ? ParameterKind.REQUIRED : ParameterKind.NAMED, | |
| param.displayName, | |
| param.type.displayName, | |
| defaultValue: param.defaultValueCode); | |
| } | |
| } |