Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(267)

Side by Side Diff: pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart

Issue 1503463002: move combinator contributor to new task model (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: remove old code Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
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.
4
5 library services.completion.dart.suggestion.builder;
6
7 import 'package:analysis_server/src/protocol_server.dart' as protocol;
8 import 'package:analysis_server/src/protocol_server.dart'
9 hide Element, ElementKind;
10 import 'package:analyzer/src/generated/element.dart';
11 import 'package:analyzer/src/generated/source.dart';
12 import 'package:analyzer/src/generated/utilities_dart.dart';
13 import 'package:path/path.dart' as path;
14 import 'package:analysis_server/src/provisional/completion/dart/completion_dart. dart';
15
16 const String DYNAMIC = 'dynamic';
17
18 /**
19 * Return a suggestion based upon the given element
20 * or `null` if a suggestion is not appropriate for the given element.
21 * If the suggestion is not currently in scope, then specify
22 * importForSource as the source to which an import should be added.
23 */
24 CompletionSuggestion createSuggestion(Element element,
25 {String completion,
26 CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
27 int relevance: DART_RELEVANCE_DEFAULT,
28 Source importForSource}) {
29 if (element is ExecutableElement && element.isOperator) {
30 // Do not include operators in suggestions
31 return null;
32 }
33 if (completion == null) {
34 completion = element.displayName;
35 }
36 bool isDeprecated = element.isDeprecated;
37 CompletionSuggestion suggestion = new CompletionSuggestion(
38 kind,
39 isDeprecated ? DART_RELEVANCE_LOW : relevance,
40 completion,
41 completion.length,
42 0,
43 isDeprecated,
44 false);
45 suggestion.element = protocol.convertElement(element);
46 Element enclosingElement = element.enclosingElement;
47 if (enclosingElement is ClassElement) {
48 suggestion.declaringType = enclosingElement.displayName;
49 }
50 suggestion.returnType = getReturnTypeString(element);
51 if (element is ExecutableElement && element is! PropertyAccessorElement) {
52 suggestion.parameterNames = element.parameters
53 .map((ParameterElement parameter) => parameter.name)
54 .toList();
55 suggestion.parameterTypes = element.parameters
56 .map((ParameterElement parameter) => parameter.type.displayName)
57 .toList();
58 suggestion.requiredParameterCount = element.parameters
59 .where((ParameterElement parameter) =>
60 parameter.parameterKind == ParameterKind.REQUIRED)
61 .length;
62 suggestion.hasNamedParameters = element.parameters.any(
63 (ParameterElement parameter) =>
64 parameter.parameterKind == ParameterKind.NAMED);
65 }
66 if (importForSource != null) {
67 String srcPath = path.dirname(importForSource.fullName);
68 LibraryElement libElem = element.library;
69 if (libElem != null) {
70 Source libSource = libElem.source;
71 if (libSource != null) {
72 UriKind uriKind = libSource.uriKind;
73 if (uriKind == UriKind.DART_URI) {
74 suggestion.importUri = libSource.uri.toString();
75 } else if (uriKind == UriKind.PACKAGE_URI) {
76 suggestion.importUri = libSource.uri.toString();
77 } else if (uriKind == UriKind.FILE_URI &&
78 element.source.uriKind == UriKind.FILE_URI) {
79 try {
80 suggestion.importUri =
81 path.relative(libSource.fullName, from: srcPath);
82 } catch (_) {
83 // ignored
84 }
85 }
86 }
87 }
88 if (suggestion.importUri == null) {
89 // Do not include out of scope suggestions
90 // for which we cannot determine an import
91 return null;
92 }
93 }
94 return suggestion;
95 }
96
97 /**
98 * Common mixin for sharing behavior
99 */
100 abstract class ElementSuggestionBuilder {
101 /**
102 * A collection of completion suggestions.
103 */
104 final List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
105
106 /**
107 * Return the kind of suggestions that should be built.
108 */
109 CompletionSuggestionKind get kind;
110
111 /**
112 * Return the request on which the builder is operating.
113 */
114 DartCompletionRequest get request;
115
116 /**
117 * Add a suggestion based upon the given element.
118 */
119 void addSuggestion(Element element,
120 {String prefix, int relevance: DART_RELEVANCE_DEFAULT}) {
121 if (element.isPrivate) {
122 LibraryElement elementLibrary = element.library;
123 CompilationUnitElement unitElem = request.target.unit.element;
124 if (unitElem == null) {
125 return;
126 }
127 LibraryElement unitLibrary = unitElem.library;
128 if (elementLibrary != unitLibrary) {
129 return;
130 }
131 }
132 if (prefix == null && element.isSynthetic) {
133 if ((element is PropertyAccessorElement) ||
134 element is FieldElement && !_isSpecialEnumField(element)) {
135 return;
136 }
137 }
138 String completion = element.displayName;
139 if (prefix != null && prefix.length > 0) {
140 if (completion == null || completion.length <= 0) {
141 completion = prefix;
142 } else {
143 completion = '$prefix.$completion';
144 }
145 }
146 if (completion == null || completion.length <= 0) {
147 return;
148 }
149 CompletionSuggestion suggestion = createSuggestion(element,
150 completion: completion, kind: kind, relevance: relevance);
151 if (suggestion != null) {
152 suggestions.add(suggestion);
153 }
154 }
155
156 /**
157 * Determine if the given element is one of the synthetic enum accessors
158 * for which we should generate a suggestion.
159 */
160 bool _isSpecialEnumField(FieldElement element) {
161 Element parent = element.enclosingElement;
162 if (parent is ClassElement && parent.isEnum) {
163 if (element.name == 'values') {
164 return true;
165 }
166 }
167 return false;
168 }
169 }
170
171 /**
172 * This class visits elements in a library and provides suggestions based upon
173 * the visible members in that library. Clients should call
174 * [LibraryElementSuggestionBuilder.suggestionsFor].
175 */
176 class LibraryElementSuggestionBuilder extends GeneralizingElementVisitor
177 with ElementSuggestionBuilder {
178 final DartCompletionRequest request;
179 final CompletionSuggestionKind kind;
180 final bool typesOnly;
181 final bool instCreation;
182
183 LibraryElementSuggestionBuilder(
184 this.request, this.kind, this.typesOnly, this.instCreation);
185
186 @override
187 visitClassElement(ClassElement element) {
188 if (instCreation) {
189 element.visitChildren(this);
190 } else {
191 addSuggestion(element);
192 }
193 }
194
195 @override
196 visitCompilationUnitElement(CompilationUnitElement element) {
197 element.visitChildren(this);
198 LibraryElement containingLibrary = element.library;
199 if (containingLibrary != null) {
200 for (var lib in containingLibrary.exportedLibraries) {
201 lib.visitChildren(this);
202 }
203 }
204 }
205
206 @override
207 visitConstructorElement(ConstructorElement element) {
208 if (instCreation) {
209 ClassElement classElem = element.enclosingElement;
210 if (classElem != null) {
211 String prefix = classElem.name;
212 if (prefix != null && prefix.length > 0) {
213 addSuggestion(element, prefix: prefix);
214 }
215 }
216 }
217 }
218
219 @override
220 visitElement(Element element) {
221 // ignored
222 }
223
224 @override
225 visitFunctionElement(FunctionElement element) {
226 if (!typesOnly) {
227 addSuggestion(element);
228 }
229 }
230
231 @override
232 visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
233 if (!instCreation) {
234 addSuggestion(element);
235 }
236 }
237
238 @override
239 visitTopLevelVariableElement(TopLevelVariableElement element) {
240 if (!typesOnly) {
241 addSuggestion(element);
242 }
243 }
244
245 /**
246 * Add suggestions for the visible members in the given library
247 */
248 static void suggestionsFor(
249 DartCompletionRequest request,
250 CompletionSuggestionKind kind,
251 LibraryElement library,
252 bool typesOnly,
253 bool instCreation) {
254 if (library != null) {
255 library.visitChildren(new LibraryElementSuggestionBuilder(
256 request, kind, typesOnly, instCreation));
257 }
258 }
259 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698