forked from dart-lang/sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
See dart-lang#27034
- Loading branch information
Showing
5 changed files
with
202 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
99 changes: 99 additions & 0 deletions
99
pkg/analysis_server/lib/src/computer/computer_signature_information.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
// Copyright (c) 2017, 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 | ||
AnalysisGetSignatureInformationResult, | ||
HoverInformation, | ||
ParameterInfo, | ||
ParameterKind; | ||
import 'package:analysis_server/src/computer/computer_hover.dart'; | ||
import 'package:analysis_server/src/computer/computer_overrides.dart'; | ||
import 'package:analysis_server/src/utilities/documentation.dart'; | ||
import 'package:analyzer/dart/ast/ast.dart'; | ||
import 'package:analyzer/dart/element/element.dart'; | ||
import 'package:analyzer/dart/element/type.dart'; | ||
import 'package:analyzer/src/dart/ast/utilities.dart'; | ||
|
||
/** | ||
* A computer for the signature information at the specified offset of a Dart [CompilationUnit]. | ||
*/ | ||
class DartUnitSignatureInformationComputer { | ||
final CompilationUnit _unit; | ||
final int _offset; | ||
|
||
DartUnitSignatureInformationComputer(this._unit, this._offset); | ||
|
||
/** | ||
* Returns the computed signature information, maybe `null`. | ||
*/ | ||
AnalysisGetSignatureInformationResult compute() { | ||
AstNode node = new NodeLocator(_offset).searchWithin(_unit); | ||
if (node == null) { | ||
return null; | ||
} | ||
|
||
// Find the closest argument list. | ||
while (node != null && !(node is ArgumentList)) { | ||
node = node.parent; | ||
} | ||
|
||
if (node == null) { | ||
return null; | ||
} | ||
|
||
final args = node; | ||
// TODO(dantup) Constructor? | ||
final method = args.parent as MethodInvocation; | ||
final methodElement = ElementLocator.locate(method) as FunctionElement; | ||
final parameters = | ||
methodElement.parameters.map((p) => _convertParam(p)).toList(); | ||
|
||
return new AnalysisGetSignatureInformationResult( | ||
method.methodName.name, | ||
DartUnitHoverComputer.computeDocumentation(methodElement), | ||
parameters, | ||
0); | ||
} | ||
|
||
String _computeDocumentation(Element element) { | ||
if (element is FieldFormalParameterElement) { | ||
element = (element as FieldFormalParameterElement).field; | ||
} | ||
if (element is ParameterElement) { | ||
element = element.enclosingElement; | ||
} | ||
if (element == null) { | ||
// This can happen when the code is invalid, such as having a field formal | ||
// parameter for a field that does not exist. | ||
return null; | ||
} | ||
// The documentation of the element itself. | ||
if (element.documentationComment != null) { | ||
return removeDartDocDelimiters(element.documentationComment); | ||
} | ||
// Look for documentation comments of overridden members. | ||
OverriddenElements overridden = findOverriddenElements(element); | ||
for (Element superElement in [] | ||
..addAll(overridden.superElements) | ||
..addAll(overridden.interfaceElements)) { | ||
String rawDoc = superElement.documentationComment; | ||
if (rawDoc != null) { | ||
Element interfaceClass = superElement.enclosingElement; | ||
return removeDartDocDelimiters(rawDoc) + | ||
'\n\nCopied from `${interfaceClass.displayName}`.'; | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
ParameterInfo _convertParam(ParameterElement param) { | ||
// TODO(dantup) Can we reuse the existing ParamterKind rather than making our own? | ||
todo: this cast fails | ||
final kind = param.parameterKind as ParameterKind; | ||
return new ParameterInfo(kind, param.displayName, param.type.displayName); | ||
} | ||
|
||
static _safeToString(obj) => obj?.toString(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
76 changes: 76 additions & 0 deletions
76
pkg/analysis_server/test/analysis/get_signature_information_test.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
// Copyright (c) 2017, 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 'dart:async'; | ||
|
||
import 'package:analysis_server/protocol/protocol.dart'; | ||
import 'package:analysis_server/protocol/protocol_generated.dart'; | ||
import 'package:test/test.dart'; | ||
import 'package:test_reflective_loader/test_reflective_loader.dart'; | ||
|
||
import '../analysis_abstract.dart'; | ||
|
||
main() { | ||
defineReflectiveSuite(() { | ||
defineReflectiveTests(AnalysisSignatureInformationTest); | ||
}); | ||
} | ||
|
||
@reflectiveTest | ||
class AnalysisSignatureInformationTest extends AbstractAnalysisTest { | ||
Future<AnalysisGetSignatureInformationResult> prepareSignatureInformation( | ||
String search) { | ||
int offset = findOffset(search); | ||
return prepareSignatureInformationAt(offset); | ||
} | ||
|
||
Future<AnalysisGetSignatureInformationResult> prepareSignatureInformationAt( | ||
int offset) async { | ||
await waitForTasksFinished(); | ||
Request request = | ||
new AnalysisGetSignatureInformationParams(testFile, offset) | ||
.toRequest('0'); | ||
Response response = await waitResponse(request); | ||
return new AnalysisGetSignatureInformationResult.fromResponse(response); | ||
} | ||
|
||
@override | ||
void setUp() { | ||
super.setUp(); | ||
createProject(); | ||
} | ||
|
||
test_simple() async { | ||
addTestFile(''' | ||
/// one doc | ||
one(String name, int length) {} | ||
main() { | ||
one("Danny", /*^*/); | ||
} | ||
'''); | ||
var result = await prepareSignatureInformation('/*^*/'); | ||
expect(result.name, equals("one")); | ||
expect(result.dartdoc, equals("one doc")); | ||
expect(result.parameters, hasLength(2)); | ||
expect(result.parameters[0], | ||
equals(new ParameterInfo(ParameterKind.NAMED, "name", "String"))); | ||
expect(result.parameters[1], | ||
equals(new ParameterInfo(ParameterKind.NAMED, "length", "int"))); | ||
} | ||
|
||
// TODO: | ||
// No signature info | ||
// named | ||
// optional | ||
// Not yet ready | ||
// Constructor | ||
// Named constructor | ||
// Static method | ||
// Instance method | ||
// Anonymous function | ||
// Content changed during response (CONTENT_MODIFIED) | ||
// invali file (GET_SIGNATURE_INVALID_FILE) | ||
// invalid offset (GET_SIGNATURE_INVALID_OFFSET) | ||
// invalid function (GET_SIGNATURE_UNKNOWN_FUNCTION) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters