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

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

Issue 711533003: first cut argument list completion suggestions (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month 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 | Annotate | Revision Log
OLDNEW
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.computer.dart.local; 5 library services.completion.computer.dart.local;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 8
9 import 'package:analysis_server/src/protocol.dart' as protocol show Element, 9 import 'package:analysis_server/src/protocol.dart' as protocol show Element,
10 ElementKind; 10 ElementKind;
11 import 'package:analysis_server/src/protocol.dart' hide Element, ElementKind; 11 import 'package:analysis_server/src/protocol.dart' hide Element, ElementKind;
12 import 'package:analysis_server/src/services/completion/dart_completion_manager. dart'; 12 import 'package:analysis_server/src/services/completion/dart_completion_manager. dart';
13 import 'package:analysis_server/src/services/completion/suggestion_builder.dart' ; 13 import 'package:analysis_server/src/services/completion/local_declaration_visito r.dart';
14 import 'package:analyzer/src/generated/ast.dart'; 14 import 'package:analyzer/src/generated/ast.dart';
15 import 'package:analyzer/src/generated/scanner.dart'; 15 import 'package:analyzer/src/generated/scanner.dart';
16 16
17 /** 17 /**
18 * A computer for calculating `completion.getSuggestions` request results 18 * A computer for calculating `completion.getSuggestions` request results
19 * for the local library in which the completion is requested. 19 * for the local library in which the completion is requested.
20 */ 20 */
21 class LocalComputer extends DartCompletionComputer { 21 class LocalComputer extends DartCompletionComputer {
22 22
23 @override 23 @override
24 bool computeFast(DartCompletionRequest request) { 24 bool computeFast(DartCompletionRequest request) {
25 25
26 // Find the specific child [AstNode] that contains the completion offset 26 // Collect suggestions from the specific child [AstNode] that contains
27 // and collect suggestions starting with that node 27 // the completion offset and all of its parents recursively.
28 request.node.accept(new _LocalVisitor(request)); 28 request.node.accept(new _LocalVisitor(request, request.offset));
29 29
30 // If the unit is not a part and does not reference any parts 30 // If the unit is not a part and does not reference any parts
31 // then work is complete 31 // then work is complete
32 return !request.unit.directives.any( 32 return !request.unit.directives.any(
33 (Directive directive) => 33 (Directive directive) =>
34 directive is PartOfDirective || directive is PartDirective); 34 directive is PartOfDirective || directive is PartDirective);
35 } 35 }
36 36
37 @override 37 @override
38 Future<bool> computeFull(DartCompletionRequest request) { 38 Future<bool> computeFull(DartCompletionRequest request) {
39 // TODO: implement computeFull 39 // TODO: implement computeFull
40 // include results from part files that are included in the library 40 // include results from part files that are included in the library
41 return new Future.value(false); 41 return new Future.value(false);
42 } 42 }
43 } 43 }
44 44
45 /** 45 /**
46 * A visitor for collecting suggestions from the most specific child [AstNode] 46 * A visitor for collecting suggestions from the most specific child [AstNode]
47 * that contains the completion offset to the [CompilationUnit]. 47 * that contains the completion offset to the [CompilationUnit].
48 */ 48 */
49 class _LocalVisitor extends GeneralizingAstVisitor<dynamic> { 49 class _LocalVisitor extends LocalDeclarationVisitor {
50 static const DYNAMIC = 'dynamic'; 50 static const DYNAMIC = 'dynamic';
51 51
52 static final TypeName NO_RETURN_TYPE = new TypeName( 52 static final TypeName NO_RETURN_TYPE = new TypeName(
53 new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, '', 0)), 53 new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, '', 0)),
54 null); 54 null);
55 55
56 static final TypeName STACKTRACE_TYPE = new TypeName(
57 new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, 'StackTrace', 0 )),
58 null);
59
60 final DartCompletionRequest request; 56 final DartCompletionRequest request;
61 bool typesOnly = false; 57 bool typesOnly = false;
62 bool excludeVoidReturn; 58 bool excludeVoidReturn;
63 59
64 _LocalVisitor(this.request) { 60 _LocalVisitor(this.request, int offset) : super(offset) {
65 excludeVoidReturn = _computeExcludeVoidReturn(request.node); 61 excludeVoidReturn = _computeExcludeVoidReturn(request.node);
66 } 62 }
67 63
68 @override 64 @override
69 visitBlock(Block node) { 65 void declaredClass(ClassDeclaration declaration) {
70 node.statements.forEach((Statement stmt) {
71 if (stmt.offset < request.offset) {
72 if (stmt is LabeledStatement) {
73 stmt.labels.forEach((Label label) {
74 // _addSuggestion(label.label, CompletionSuggestionKind.LABEL);
75 });
76 } else if (stmt is VariableDeclarationStatement) {
77 var varList = stmt.variables;
78 if (varList != null) {
79 varList.variables.forEach((VariableDeclaration varDecl) {
80 if (varDecl.end < request.offset) {
81 _addLocalVarSuggestion(varDecl.name, varList.type);
82 }
83 });
84 }
85 }
86 }
87 });
88 visitNode(node);
89 }
90
91 @override
92 visitCascadeExpression(CascadeExpression node) {
93 Expression target = node.target;
94 // This computer handles the expression
95 // while InvocationComputer handles the cascade selector
96 if (target != null && request.offset <= target.end) {
97 visitNode(node);
98 }
99 }
100
101 @override
102 visitCatchClause(CatchClause node) {
103 _addParamSuggestion(node.exceptionParameter, node.exceptionType);
104 _addParamSuggestion(node.stackTraceParameter, STACKTRACE_TYPE);
105 visitNode(node);
106 }
107
108 @override
109 visitClassDeclaration(ClassDeclaration node) {
110 _addClassDeclarationMembers(node);
111 visitInheritedTypes(node, (ClassDeclaration classNode) {
112 _addClassDeclarationMembers(classNode);
113 }, (String typeName) {
114 // ignored
115 });
116 visitNode(node);
117 }
118
119 @override
120 visitCombinator(Combinator node) {
121 // Handled by ImportedComputer
122 }
123
124 @override
125 visitCompilationUnit(CompilationUnit node) {
126 node.declarations.forEach((Declaration declaration) {
127 if (declaration is ClassDeclaration) {
128 _addClassSuggestion(declaration);
129 } else if (declaration is EnumDeclaration) {
130 // _addSuggestion(d.name, CompletionSuggestionKind.ENUM);
131 } else if (declaration is FunctionDeclaration) {
132 _addFunctionSuggestion(declaration);
133 } else if (declaration is TopLevelVariableDeclaration) {
134 _addTopLevelVarSuggestions(declaration.variables);
135 } else if (declaration is ClassTypeAlias) {
136 bool isDeprecated = _isDeprecated(declaration);
137 CompletionSuggestion suggestion =
138 _addSuggestion(declaration.name, null, null, isDeprecated);
139 if (suggestion != null) {
140 suggestion.element = _createElement(
141 protocol.ElementKind.CLASS_TYPE_ALIAS,
142 declaration.name,
143 null,
144 NO_RETURN_TYPE,
145 true,
146 isDeprecated);
147 }
148 } else if (declaration is FunctionTypeAlias) {
149 bool isDeprecated = _isDeprecated(declaration);
150 CompletionSuggestion suggestion =
151 _addSuggestion(declaration.name, declaration.returnType, null, isDep recated);
152 if (suggestion != null) {
153 // TODO (danrubel) determine parameters and return type
154 suggestion.element = _createElement(
155 protocol.ElementKind.FUNCTION_TYPE_ALIAS,
156 declaration.name,
157 null,
158 NO_RETURN_TYPE,
159 true,
160 isDeprecated);
161 }
162 }
163 });
164 }
165
166 @override
167 visitExpressionStatement(ExpressionStatement node) {
168 Expression expression = node.expression;
169 if (expression is SimpleIdentifier) {
170 if (expression.end < request.offset) {
171 // TODO (danrubel) suggest possible names for variable declaration
172 // based upon variable type
173 return;
174 }
175 }
176 visitNode(node);
177 }
178
179 @override
180 visitForEachStatement(ForEachStatement node) {
181 SimpleIdentifier id;
182 TypeName type;
183 DeclaredIdentifier loopVar = node.loopVariable;
184 if (loopVar != null) {
185 id = loopVar.identifier;
186 type = loopVar.type;
187 } else {
188 id = node.identifier;
189 type = null;
190 }
191 _addLocalVarSuggestion(id, type);
192 visitNode(node);
193 }
194
195 @override
196 visitForStatement(ForStatement node) {
197 var varList = node.variables;
198 if (varList != null) {
199 varList.variables.forEach((VariableDeclaration varDecl) {
200 _addLocalVarSuggestion(varDecl.name, varList.type);
201 });
202 }
203 visitNode(node);
204 }
205
206 @override
207 visitFunctionDeclaration(FunctionDeclaration node) {
208 // This is added by the compilation unit containing it
209 //_addSuggestion(node.name, CompletionSuggestionKind.FUNCTION);
210 visitNode(node);
211 }
212
213 @override
214 visitFunctionExpression(FunctionExpression node) {
215 _addParamListSuggestions(node.parameters);
216 visitNode(node);
217 }
218
219 @override
220 visitInterpolationExpression(InterpolationExpression node) {
221 visitNode(node);
222 }
223
224 @override
225 visitMethodDeclaration(MethodDeclaration node) {
226 _addParamListSuggestions(node.parameters);
227 visitNode(node);
228 }
229
230 @override
231 visitMethodInvocation(MethodInvocation node) {
232 // InvocationComputer adds suggestions for method selector
233 Token period = node.period;
234 if (period != null && period.offset < request.offset) {
235 ArgumentList argumentList = node.argumentList;
236 if (argumentList == null || request.offset <= argumentList.offset) {
237 return;
238 }
239 }
240 visitNode(node);
241 }
242
243 @override
244 visitNamespaceDirective(NamespaceDirective node) {
245 // No suggestions
246 }
247
248 @override
249 visitNode(AstNode node) {
250 node.parent.accept(this);
251 }
252
253 @override
254 visitPrefixedIdentifier(PrefixedIdentifier node) {
255 // InvocationComputer adds suggestions for prefixed elements
256 // but this computer adds suggestions for the prefix itself
257 SimpleIdentifier prefix = node.prefix;
258 if (prefix == null || request.offset <= prefix.end) {
259 visitNode(node);
260 }
261 }
262
263 @override
264 visitPropertyAccess(PropertyAccess node) {
265 // InvocationComputer adds suggestions for property access selector
266 }
267
268 @override
269 visitStringInterpolation(StringInterpolation node) {
270 visitNode(node);
271 }
272
273 @override
274 visitStringLiteral(StringLiteral node) {
275 // ignore
276 }
277
278 @override
279 visitTypeName(TypeName node) {
280 // If suggesting completions within a TypeName node
281 // then limit suggestions to only types
282 typesOnly = true;
283 return visitNode(node);
284 }
285
286 @override
287 visitVariableDeclaration(VariableDeclaration node) {
288 // Do not add suggestions if editing the name in a var declaration
289 SimpleIdentifier name = node.name;
290 if (name == null ||
291 name.offset < request.offset ||
292 request.offset > name.end) {
293 visitNode(node);
294 }
295 }
296
297 void _addClassDeclarationMembers(ClassDeclaration node) {
298 node.members.forEach((ClassMember classMbr) {
299 if (classMbr is FieldDeclaration) {
300 _addFieldSuggestions(node, classMbr);
301 } else if (classMbr is MethodDeclaration) {
302 _addMethodSuggestion(node, classMbr);
303 }
304 });
305 }
306
307 void _addClassSuggestion(ClassDeclaration declaration) {
308 bool isDeprecated = _isDeprecated(declaration); 66 bool isDeprecated = _isDeprecated(declaration);
309 CompletionSuggestion suggestion = 67 CompletionSuggestion suggestion =
310 _addSuggestion(declaration.name, null, null, isDeprecated); 68 _addSuggestion(declaration.name, null, null, isDeprecated);
311 if (suggestion != null) { 69 if (suggestion != null) {
312 suggestion.element = _createElement( 70 suggestion.element = _createElement(
313 protocol.ElementKind.CLASS, 71 protocol.ElementKind.CLASS,
314 declaration.name, 72 declaration.name,
315 null, 73 null,
316 NO_RETURN_TYPE, 74 _LocalVisitor.NO_RETURN_TYPE,
317 declaration.isAbstract, 75 declaration.isAbstract,
318 isDeprecated); 76 isDeprecated);
319 } 77 }
320 } 78 }
321 79
322 void _addFieldSuggestions(ClassDeclaration node, FieldDeclaration fieldDecl) { 80 @override
81 void declaredClassTypeAlias(ClassTypeAlias declaration) {
82 bool isDeprecated = _isDeprecated(declaration);
83 CompletionSuggestion suggestion =
84 _addSuggestion(declaration.name, null, null, isDeprecated);
85 if (suggestion != null) {
86 suggestion.element = _createElement(
87 protocol.ElementKind.CLASS_TYPE_ALIAS,
88 declaration.name,
89 null,
90 NO_RETURN_TYPE,
91 true,
92 isDeprecated);
93 }
94 }
95
96 @override
97 void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
323 if (typesOnly) { 98 if (typesOnly) {
324 return; 99 return;
325 } 100 }
326 bool isDeprecated = _isDeprecated(fieldDecl); 101 bool isDeprecated = _isDeprecated(fieldDecl) || _isDeprecated(varDecl);
327 fieldDecl.fields.variables.forEach((VariableDeclaration varDecl) { 102 CompletionSuggestion suggestion = _addSuggestion(
328 bool isSingleFieldDeprecated = isDeprecated || _isDeprecated(varDecl); 103 varDecl.name,
329 CompletionSuggestion suggestion = _addSuggestion( 104 fieldDecl.fields.type,
105 fieldDecl.parent,
106 isDeprecated);
107 if (suggestion != null) {
108 suggestion.element = _createElement(
109 protocol.ElementKind.GETTER,
330 varDecl.name, 110 varDecl.name,
111 '()',
331 fieldDecl.fields.type, 112 fieldDecl.fields.type,
332 node, 113 false,
333 isSingleFieldDeprecated); 114 isDeprecated);
334 if (suggestion != null) { 115 }
335 suggestion.element = _createElement(
336 protocol.ElementKind.GETTER,
337 varDecl.name,
338 '()',
339 fieldDecl.fields.type,
340 false,
341 isSingleFieldDeprecated);
342 }
343 });
344 } 116 }
345 117
346 void _addFunctionSuggestion(FunctionDeclaration declaration) { 118 @override
119 bool visitCascadeExpression(CascadeExpression node) {
120 Expression target = node.target;
121 // This computer handles the expression
122 // while InvocationComputer handles the cascade selector
123 if (target != null && offset <= target.end) {
124 return visitNode(node);
125 } else {
126 return finished;
127 }
128 }
129
130 @override
131 bool visitNamespaceDirective(NamespaceDirective node) {
132 // No suggestions
133 return finished;
134 }
135
136 @override
137 bool visitStringLiteral(StringLiteral node) {
138 // ignore
139 return finished;
140 }
141
142 @override
143 bool visitVariableDeclaration(VariableDeclaration node) {
144 // Do not add suggestions if editing the name in a var declaration
145 SimpleIdentifier name = node.name;
146 if (name == null || name.offset < offset || offset > name.end) {
147 return visitNode(node);
148 } else {
149 return finished;
150 }
151 }
152
153 @override
154 void declaredFunction(FunctionDeclaration declaration) {
347 if (typesOnly) { 155 if (typesOnly) {
348 return; 156 return;
349 } 157 }
350 if (excludeVoidReturn && _isVoid(declaration.returnType)) { 158 if (excludeVoidReturn && _isVoid(declaration.returnType)) {
351 return; 159 return;
352 } 160 }
353 bool isDeprecated = _isDeprecated(declaration); 161 bool isDeprecated = _isDeprecated(declaration);
354 CompletionSuggestion suggestion = 162 CompletionSuggestion suggestion =
355 _addSuggestion(declaration.name, declaration.returnType, null, isDepreca ted); 163 _addSuggestion(declaration.name, declaration.returnType, null, isDepreca ted);
356 if (suggestion != null) { 164 if (suggestion != null) {
357 suggestion.element = _createElement( 165 suggestion.element = _createElement(
358 protocol.ElementKind.FUNCTION, 166 protocol.ElementKind.FUNCTION,
359 declaration.name, 167 declaration.name,
360 declaration.functionExpression.parameters.toSource(), 168 declaration.functionExpression.parameters.toSource(),
361 declaration.returnType, 169 declaration.returnType,
362 false, 170 false,
363 isDeprecated); 171 isDeprecated);
364 } 172 }
365 } 173 }
366 174
367 void _addLocalVarSuggestion(SimpleIdentifier id, TypeName returnType) { 175 @override
368 if (typesOnly) { 176 void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {
369 return; 177 bool isDeprecated = _isDeprecated(declaration);
370 }
371 CompletionSuggestion suggestion = 178 CompletionSuggestion suggestion =
372 _addSuggestion(id, returnType, null, false); 179 _addSuggestion(declaration.name, declaration.returnType, null, isDepreca ted);
373 if (suggestion != null) { 180 if (suggestion != null) {
181 // TODO (danrubel) determine parameters and return type
374 suggestion.element = _createElement( 182 suggestion.element = _createElement(
375 protocol.ElementKind.LOCAL_VARIABLE, 183 protocol.ElementKind.FUNCTION_TYPE_ALIAS,
376 id, 184 declaration.name,
377 null, 185 null,
378 returnType, 186 NO_RETURN_TYPE,
379 false, 187 true,
380 false);
381 }
382 }
383
384 void _addMethodSuggestion(ClassDeclaration node, MethodDeclaration classMbr) {
385 if (typesOnly) {
386 return;
387 }
388 protocol.ElementKind kind;
389 String parameters;
390 if (classMbr.isGetter) {
391 kind = protocol.ElementKind.GETTER;
392 parameters = '()';
393 } else if (classMbr.isSetter) {
394 if (excludeVoidReturn) {
395 return;
396 }
397 kind = protocol.ElementKind.SETTER;
398 parameters = '(${classMbr.returnType.toSource()} value)';
399 } else {
400 if (excludeVoidReturn && _isVoid(classMbr.returnType)) {
401 return;
402 }
403 kind = protocol.ElementKind.METHOD;
404 parameters = classMbr.parameters.toSource();
405 }
406 bool isDeprecated = _isDeprecated(classMbr);
407 CompletionSuggestion suggestion =
408 _addSuggestion(classMbr.name, classMbr.returnType, node, isDeprecated);
409 if (suggestion != null) {
410 suggestion.element = _createElement(
411 kind,
412 classMbr.name,
413 parameters,
414 classMbr.returnType,
415 classMbr.isAbstract,
416 isDeprecated); 188 isDeprecated);
417 } 189 }
418 } 190 }
419 191
420 void _addParamListSuggestions(FormalParameterList paramList) { 192 @override
193 void declaredLabel(Label label) {
194 // ignored
195 }
196
197 @override
198 void declaredLocalVar(SimpleIdentifier name, TypeName type) {
421 if (typesOnly) { 199 if (typesOnly) {
422 return; 200 return;
423 } 201 }
424 if (paramList != null) { 202 CompletionSuggestion suggestion = _addSuggestion(name, type, null, false);
425 paramList.parameters.forEach((FormalParameter param) {
426 NormalFormalParameter normalParam;
427 if (param is DefaultFormalParameter) {
428 normalParam = param.parameter;
429 } else if (param is NormalFormalParameter) {
430 normalParam = param;
431 }
432 TypeName type = null;
433 if (normalParam is FieldFormalParameter) {
434 type = normalParam.type;
435 } else if (normalParam is FunctionTypedFormalParameter) {
436 type = normalParam.returnType;
437 } else if (normalParam is SimpleFormalParameter) {
438 type = normalParam.type;
439 }
440 _addParamSuggestion(param.identifier, type);
441 });
442 }
443 }
444
445 void _addParamSuggestion(SimpleIdentifier identifier, TypeName type) {
446 if (typesOnly) {
447 return;
448 }
449 CompletionSuggestion suggestion =
450 _addSuggestion(identifier, type, null, false);
451 if (suggestion != null) { 203 if (suggestion != null) {
452 suggestion.element = _createElement( 204 suggestion.element = _createElement(
453 protocol.ElementKind.PARAMETER, 205 protocol.ElementKind.LOCAL_VARIABLE,
454 identifier, 206 name,
455 null, 207 null,
456 type, 208 type,
457 false, 209 false,
458 false); 210 false);
459 } 211 }
460 } 212 }
461 213
214 @override
215 void declaredMethod(MethodDeclaration declaration) {
216 if (typesOnly) {
217 return;
218 }
219 protocol.ElementKind kind;
220 String parameters;
221 if (declaration.isGetter) {
222 kind = protocol.ElementKind.GETTER;
223 parameters = '()';
224 } else if (declaration.isSetter) {
225 if (excludeVoidReturn) {
226 return;
227 }
228 kind = protocol.ElementKind.SETTER;
229 parameters = '(${declaration.returnType.toSource()} value)';
230 } else {
231 if (excludeVoidReturn && _isVoid(declaration.returnType)) {
232 return;
233 }
234 kind = protocol.ElementKind.METHOD;
235 parameters = declaration.parameters.toSource();
236 }
237 bool isDeprecated = _isDeprecated(declaration);
238 CompletionSuggestion suggestion = _addSuggestion(
239 declaration.name,
240 declaration.returnType,
241 declaration.parent,
242 isDeprecated);
243 if (suggestion != null) {
244 suggestion.element = _createElement(
245 kind,
246 declaration.name,
247 parameters,
248 declaration.returnType,
249 declaration.isAbstract,
250 isDeprecated);
251 }
252 }
253
254 @override
255 void declaredParam(SimpleIdentifier name, TypeName type) {
256 if (typesOnly) {
257 return;
258 }
259 CompletionSuggestion suggestion = _addSuggestion(name, type, null, false);
260 if (suggestion != null) {
261 suggestion.element =
262 _createElement(protocol.ElementKind.PARAMETER, name, null, type, false , false);
263 }
264 }
265
266 @override
267 void declaredTopLevelVar(VariableDeclarationList varList,
268 VariableDeclaration varDecl) {
269 if (typesOnly) {
270 return;
271 }
272 bool isDeprecated = _isDeprecated(varList) || _isDeprecated(varDecl);
273 CompletionSuggestion suggestion =
274 _addSuggestion(varDecl.name, varList.type, null, isDeprecated);
275 if (suggestion != null) {
276 suggestion.element = _createElement(
277 protocol.ElementKind.TOP_LEVEL_VARIABLE,
278 varDecl.name,
279 null,
280 varList.type,
281 false,
282 isDeprecated);
283 }
284 }
285
286 @override
287 visitCombinator(Combinator node) {
288 // Handled by CombinatorComputer
289 }
290
291 @override
292 visitMethodInvocation(MethodInvocation node) {
293 // InvocationComputer adds suggestions for method selector
294 Token period = node.period;
295 if (period != null && period.offset < request.offset) {
296 ArgumentList argumentList = node.argumentList;
297 if (argumentList == null || request.offset <= argumentList.offset) {
298 return;
299 }
300 }
301 visitNode(node);
302 }
303
304 @override
305 visitPrefixedIdentifier(PrefixedIdentifier node) {
306 // InvocationComputer adds suggestions for prefixed elements
307 // but this computer adds suggestions for the prefix itself
308 SimpleIdentifier prefix = node.prefix;
309 if (prefix == null || request.offset <= prefix.end) {
310 visitNode(node);
311 }
312 }
313
314 @override
315 visitPropertyAccess(PropertyAccess node) {
316 // InvocationComputer adds suggestions for property access selector
317 }
318
319 @override
320 visitTypeName(TypeName node) {
321 // If suggesting completions within a TypeName node
322 // then limit suggestions to only types
323 typesOnly = true;
324 return visitNode(node);
325 }
326
462 CompletionSuggestion _addSuggestion(SimpleIdentifier id, TypeName typeName, 327 CompletionSuggestion _addSuggestion(SimpleIdentifier id, TypeName typeName,
463 ClassDeclaration classDecl, bool isDeprecated) { 328 ClassDeclaration classDecl, bool isDeprecated) {
464 if (id != null) { 329 if (id != null) {
465 String completion = id.name; 330 String completion = id.name;
466 if (completion != null && completion.length > 0 && completion != '_') { 331 if (completion != null && completion.length > 0 && completion != '_') {
467 CompletionSuggestion suggestion = new CompletionSuggestion( 332 CompletionSuggestion suggestion = new CompletionSuggestion(
468 CompletionSuggestionKind.INVOCATION, 333 CompletionSuggestionKind.INVOCATION,
469 isDeprecated ? CompletionRelevance.LOW : CompletionRelevance.DEFAULT , 334 isDeprecated ? CompletionRelevance.LOW : CompletionRelevance.DEFAULT ,
470 completion, 335 completion,
471 completion.length, 336 completion.length,
(...skipping 18 matching lines...) Expand all
490 } 355 }
491 } 356 }
492 } 357 }
493 request.suggestions.add(suggestion); 358 request.suggestions.add(suggestion);
494 return suggestion; 359 return suggestion;
495 } 360 }
496 } 361 }
497 return null; 362 return null;
498 } 363 }
499 364
500 void _addTopLevelVarSuggestions(VariableDeclarationList varList) {
501 if (typesOnly) {
502 return;
503 }
504 if (varList != null) {
505 bool isDeprecated = _isDeprecated(varList);
506 varList.variables.forEach((VariableDeclaration varDecl) {
507 bool isSingleVarDeprecated = isDeprecated || _isDeprecated(varDecl);
508 CompletionSuggestion suggestion =
509 _addSuggestion(varDecl.name, varList.type, null, isSingleVarDeprecat ed);
510 if (suggestion != null) {
511 suggestion.element = _createElement(
512 protocol.ElementKind.TOP_LEVEL_VARIABLE,
513 varDecl.name,
514 null,
515 varList.type,
516 false,
517 isSingleVarDeprecated);
518 }
519 });
520 }
521 }
522
523 bool _computeExcludeVoidReturn(AstNode node) { 365 bool _computeExcludeVoidReturn(AstNode node) {
524 if (node is Block) { 366 if (node is Block) {
525 return false; 367 return false;
526 } else if (node is SimpleIdentifier) { 368 } else if (node is SimpleIdentifier) {
527 return node.parent is ExpressionStatement ? false : true; 369 return node.parent is ExpressionStatement ? false : true;
528 } else { 370 } else {
529 return true; 371 return true;
530 } 372 }
531 } 373 }
532 374
375
533 /** 376 /**
534 * Create a new protocol Element for inclusion in a completion suggestion. 377 * Create a new protocol Element for inclusion in a completion suggestion.
535 */ 378 */
536 protocol.Element _createElement(protocol.ElementKind kind, 379 protocol.Element _createElement(protocol.ElementKind kind,
537 SimpleIdentifier id, String parameters, TypeName returnType, bool isAbstra ct, 380 SimpleIdentifier id, String parameters, TypeName returnType, bool isAbstra ct,
538 bool isDeprecated) { 381 bool isDeprecated) {
539 String name = id.name; 382 String name = id.name;
540 int flags = protocol.Element.makeFlags( 383 int flags = protocol.Element.makeFlags(
541 isAbstract: isAbstract, 384 isAbstract: isAbstract,
542 isDeprecated: isDeprecated, 385 isDeprecated: isDeprecated,
543 isPrivate: Identifier.isPrivateName(name)); 386 isPrivate: Identifier.isPrivateName(name));
544 return new protocol.Element( 387 return new protocol.Element(
545 kind, 388 kind,
546 name, 389 name,
547 flags, 390 flags,
548 parameters: parameters, 391 parameters: parameters,
549 returnType: _nameForType(returnType)); 392 returnType: _nameForType(returnType));
550 } 393 }
551 394
552
553 /** 395 /**
554 * Return `true` if the @deprecated annotation is present 396 * Return `true` if the @deprecated annotation is present
555 */ 397 */
556 bool _isDeprecated(AnnotatedNode node) { 398 bool _isDeprecated(AnnotatedNode node) {
557 if (node != null) { 399 if (node != null) {
558 NodeList<Annotation> metadata = node.metadata; 400 NodeList<Annotation> metadata = node.metadata;
559 if (metadata != null) { 401 if (metadata != null) {
560 return metadata.any((Annotation a) { 402 return metadata.any((Annotation a) {
561 return a.name is SimpleIdentifier && a.name.name == 'deprecated'; 403 return a.name is SimpleIdentifier && a.name.name == 'deprecated';
562 }); 404 });
(...skipping 30 matching lines...) Expand all
593 if (name == null || name.length <= 0) { 435 if (name == null || name.length <= 0) {
594 return DYNAMIC; 436 return DYNAMIC;
595 } 437 }
596 TypeArgumentList typeArgs = type.typeArguments; 438 TypeArgumentList typeArgs = type.typeArguments;
597 if (typeArgs != null) { 439 if (typeArgs != null) {
598 //TODO (danrubel) include type arguments 440 //TODO (danrubel) include type arguments
599 } 441 }
600 return name; 442 return name;
601 } 443 }
602 } 444 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698