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 services.completion.suggestion.builder; | 5 library services.completion.suggestion.builder; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:collection'; | 8 import 'dart:collection'; |
9 | 9 |
10 import 'package:analysis_server/src/protocol_server.dart' as protocol; | |
11 import 'package:analysis_server/src/protocol_server.dart' | 10 import 'package:analysis_server/src/protocol_server.dart' |
12 hide Element, ElementKind; | 11 hide Element, ElementKind; |
| 12 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.
dart' |
| 13 show createSuggestion; |
13 import 'package:analysis_server/src/services/completion/dart_completion_manager.
dart'; | 14 import 'package:analysis_server/src/services/completion/dart_completion_manager.
dart'; |
14 import 'package:analyzer/src/generated/ast.dart'; | 15 import 'package:analyzer/src/generated/ast.dart'; |
15 import 'package:analyzer/src/generated/element.dart'; | 16 import 'package:analyzer/src/generated/element.dart'; |
16 import 'package:analyzer/src/generated/engine.dart' as engine; | 17 import 'package:analyzer/src/generated/engine.dart' as engine; |
17 import 'package:analyzer/src/generated/source.dart'; | 18 |
18 import 'package:analyzer/src/generated/utilities_dart.dart'; | 19 export 'package:analysis_server/src/services/completion/dart/suggestion_builder.
dart' |
19 import 'package:path/path.dart' as path; | 20 show createSuggestion; |
20 | 21 |
21 const String DYNAMIC = 'dynamic'; | 22 const String DYNAMIC = 'dynamic'; |
22 | 23 |
23 /** | 24 /** |
24 * Return a suggestion based upon the given element | |
25 * or `null` if a suggestion is not appropriate for the given element. | |
26 * If the suggestion is not currently in scope, then specify | |
27 * importForSource as the source to which an import should be added. | |
28 */ | |
29 CompletionSuggestion createSuggestion(Element element, | |
30 {String completion, | |
31 CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION, | |
32 int relevance: DART_RELEVANCE_DEFAULT, | |
33 Source importForSource}) { | |
34 if (element is ExecutableElement && element.isOperator) { | |
35 // Do not include operators in suggestions | |
36 return null; | |
37 } | |
38 if (completion == null) { | |
39 completion = element.displayName; | |
40 } | |
41 bool isDeprecated = element.isDeprecated; | |
42 CompletionSuggestion suggestion = new CompletionSuggestion( | |
43 kind, | |
44 isDeprecated ? DART_RELEVANCE_LOW : relevance, | |
45 completion, | |
46 completion.length, | |
47 0, | |
48 isDeprecated, | |
49 false); | |
50 suggestion.element = protocol.convertElement(element); | |
51 Element enclosingElement = element.enclosingElement; | |
52 if (enclosingElement is ClassElement) { | |
53 suggestion.declaringType = enclosingElement.displayName; | |
54 } | |
55 suggestion.returnType = getReturnTypeString(element); | |
56 if (element is ExecutableElement && element is! PropertyAccessorElement) { | |
57 suggestion.parameterNames = element.parameters | |
58 .map((ParameterElement parameter) => parameter.name) | |
59 .toList(); | |
60 suggestion.parameterTypes = element.parameters | |
61 .map((ParameterElement parameter) => parameter.type.displayName) | |
62 .toList(); | |
63 suggestion.requiredParameterCount = element.parameters | |
64 .where((ParameterElement parameter) => | |
65 parameter.parameterKind == ParameterKind.REQUIRED) | |
66 .length; | |
67 suggestion.hasNamedParameters = element.parameters.any( | |
68 (ParameterElement parameter) => | |
69 parameter.parameterKind == ParameterKind.NAMED); | |
70 } | |
71 if (importForSource != null) { | |
72 String srcPath = path.dirname(importForSource.fullName); | |
73 LibraryElement libElem = element.library; | |
74 if (libElem != null) { | |
75 Source libSource = libElem.source; | |
76 if (libSource != null) { | |
77 UriKind uriKind = libSource.uriKind; | |
78 if (uriKind == UriKind.DART_URI) { | |
79 suggestion.importUri = libSource.uri.toString(); | |
80 } else if (uriKind == UriKind.PACKAGE_URI) { | |
81 suggestion.importUri = libSource.uri.toString(); | |
82 } else if (uriKind == UriKind.FILE_URI && | |
83 element.source.uriKind == UriKind.FILE_URI) { | |
84 try { | |
85 suggestion.importUri = | |
86 path.relative(libSource.fullName, from: srcPath); | |
87 } catch (_) { | |
88 // ignored | |
89 } | |
90 } | |
91 } | |
92 } | |
93 if (suggestion.importUri == null) { | |
94 // Do not include out of scope suggestions | |
95 // for which we cannot determine an import | |
96 return null; | |
97 } | |
98 } | |
99 return suggestion; | |
100 } | |
101 | |
102 /** | |
103 * Call the given function with each non-null non-empty inherited type name | 25 * Call the given function with each non-null non-empty inherited type name |
104 * that is defined in the given class. | 26 * that is defined in the given class. |
105 */ | 27 */ |
106 visitInheritedTypeNames(ClassDeclaration node, void inherited(String name)) { | 28 visitInheritedTypeNames(ClassDeclaration node, void inherited(String name)) { |
107 void visit(TypeName type) { | 29 void visit(TypeName type) { |
108 if (type != null) { | 30 if (type != null) { |
109 Identifier id = type.name; | 31 Identifier id = type.name; |
110 if (id != null) { | 32 if (id != null) { |
111 String name = id.name; | 33 String name = id.name; |
112 if (name != null && name.length > 0) { | 34 if (name != null && name.length > 0) { |
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
675 * or `false` if [computeFull] should be called. | 597 * or `false` if [computeFull] should be called. |
676 */ | 598 */ |
677 bool computeFast(AstNode node); | 599 bool computeFast(AstNode node); |
678 | 600 |
679 /** | 601 /** |
680 * Return a future that computes the suggestions given a fully resolved AST. | 602 * Return a future that computes the suggestions given a fully resolved AST. |
681 * The future returns `true` if suggestions were added, else `false`. | 603 * The future returns `true` if suggestions were added, else `false`. |
682 */ | 604 */ |
683 Future<bool> computeFull(AstNode node); | 605 Future<bool> computeFull(AstNode node); |
684 } | 606 } |
OLD | NEW |