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

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

Issue 580623002: add element to completion suggestions (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: merge Created 6 years, 3 months 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'; 9 import 'package:analysis_server/src/protocol.dart' as protocol show Element, Ele mentKind;
10 import 'package:analysis_server/src/protocol.dart' hide Element, ElementKind;
10 import 'package:analysis_server/src/services/completion/dart_completion_manager. dart'; 11 import 'package:analysis_server/src/services/completion/dart_completion_manager. dart';
11 import 'package:analyzer/src/generated/ast.dart'; 12 import 'package:analyzer/src/generated/ast.dart';
13 import 'package:analyzer/src/generated/scanner.dart';
12 14
13 /** 15 /**
14 * A computer for calculating `completion.getSuggestions` request results 16 * A computer for calculating `completion.getSuggestions` request results
15 * for the local library in which the completion is requested. 17 * for the local library in which the completion is requested.
16 */ 18 */
17 class LocalComputer extends DartCompletionComputer { 19 class LocalComputer extends DartCompletionComputer {
18 20
19 @override 21 @override
20 bool computeFast(DartCompletionRequest request) { 22 bool computeFast(DartCompletionRequest request) {
21 23
(...skipping 14 matching lines...) Expand all
36 // include results from part files that are included in the library 38 // include results from part files that are included in the library
37 return new Future.value(false); 39 return new Future.value(false);
38 } 40 }
39 } 41 }
40 42
41 /** 43 /**
42 * A visitor for collecting suggestions from the most specific child [AstNode] 44 * A visitor for collecting suggestions from the most specific child [AstNode]
43 * that contains the completion offset to the [CompilationUnit]. 45 * that contains the completion offset to the [CompilationUnit].
44 */ 46 */
45 class _LocalVisitor extends GeneralizingAstVisitor<dynamic> { 47 class _LocalVisitor extends GeneralizingAstVisitor<dynamic> {
48 static const DYNAMIC = 'dynamic';
49
50 static final TypeName NO_RETURN_TYPE = new TypeName(
51 new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, '', 0)),
52 null);
53
54 static final TypeName STACKTRACE_TYPE = new TypeName(
55 new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, 'StackTrace', 0 )),
56 null);
57
46 final DartCompletionRequest request; 58 final DartCompletionRequest request;
47 59
48 _LocalVisitor(this.request); 60 _LocalVisitor(this.request);
49 61
50 @override 62 @override
51 visitBlock(Block node) { 63 visitBlock(Block node) {
52 node.statements.forEach((Statement stmt) { 64 node.statements.forEach((Statement stmt) {
53 if (stmt.offset < request.offset) { 65 if (stmt.offset < request.offset) {
54 if (stmt is LabeledStatement) { 66 if (stmt is LabeledStatement) {
55 stmt.labels.forEach((Label label) { 67 stmt.labels.forEach((Label label) {
56 // _addSuggestion(label.label, CompletionSuggestionKind.LABEL); 68 // _addSuggestion(label.label, CompletionSuggestionKind.LABEL);
57 }); 69 });
58 } else if (stmt is VariableDeclarationStatement) { 70 } else if (stmt is VariableDeclarationStatement) {
59 VariableDeclarationList varList = stmt.variables; 71 var varList = stmt.variables;
60 if (varList != null) { 72 if (varList != null) {
61 varList.variables.forEach((VariableDeclaration varDecl) { 73 varList.variables.forEach((VariableDeclaration varDecl) {
62 if (varDecl.end < request.offset) { 74 if (varDecl.end < request.offset) {
63 _addSuggestion( 75 _addLocalVarSuggestion(varDecl.name, varList.type);
64 varDecl.name,
65 CompletionSuggestionKind.LOCAL_VARIABLE,
66 varList.type,
67 null);
68 } 76 }
69 }); 77 });
70 } 78 }
71 } 79 }
72 } 80 }
73 }); 81 });
74 visitNode(node); 82 visitNode(node);
75 } 83 }
76 84
77 @override 85 @override
78 visitCatchClause(CatchClause node) { 86 visitCatchClause(CatchClause node) {
79 _addSuggestion( 87 _addParamSuggestion(node.exceptionParameter, node.exceptionType);
80 node.exceptionParameter, 88 CompletionSuggestion suggestion =
81 CompletionSuggestionKind.PARAMETER, 89 _addParamSuggestion(node.stackTraceParameter, STACKTRACE_TYPE);
82 node.exceptionType,
83 null);
84 // TODO (danrubel) add stack trace types
85 _addSuggestion(
86 node.stackTraceParameter,
87 CompletionSuggestionKind.PARAMETER,
88 null,
89 null);
90 visitNode(node); 90 visitNode(node);
91 } 91 }
92 92
93 @override 93 @override
94 visitClassDeclaration(ClassDeclaration node) { 94 visitClassDeclaration(ClassDeclaration node) {
95 node.members.forEach((ClassMember classMbr) { 95 node.members.forEach((ClassMember classMbr) {
96 if (classMbr is FieldDeclaration) { 96 if (classMbr is FieldDeclaration) {
97 _addVarListSuggestions( 97 _addFieldSuggestions(node, classMbr);
98 classMbr.fields,
99 CompletionSuggestionKind.FIELD,
100 node);
101 } else if (classMbr is MethodDeclaration) { 98 } else if (classMbr is MethodDeclaration) {
102 _addSuggestion( 99 _addMethodSuggestion(node, classMbr);
103 classMbr.name,
104 CompletionSuggestionKind.METHOD_NAME,
105 classMbr.returnType,
106 node);
107 } 100 }
108 }); 101 });
109 visitNode(node); 102 visitNode(node);
110 } 103 }
111 104
112 @override 105 @override
113 visitCompilationUnit(CompilationUnit node) { 106 visitCompilationUnit(CompilationUnit node) {
114 node.directives.forEach((Directive directive) { 107 node.directives.forEach((Directive directive) {
115 if (directive is ImportDirective) { 108 if (directive is ImportDirective) {
116 _addSuggestion( 109 _addLibraryPrefixSuggestion(directive);
117 directive.prefix,
118 CompletionSuggestionKind.LIBRARY_PREFIX,
119 null,
120 null);
121 } 110 }
122 }); 111 });
123 node.declarations.forEach((Declaration declaration) { 112 node.declarations.forEach((Declaration declaration) {
124 if (declaration is ClassDeclaration) { 113 if (declaration is ClassDeclaration) {
125 _addSuggestion( 114 _addClassSuggestion(declaration);
126 declaration.name,
127 CompletionSuggestionKind.CLASS,
128 null,
129 null);
130 } else if (declaration is EnumDeclaration) { 115 } else if (declaration is EnumDeclaration) {
131 // _addSuggestion(d.name, CompletionSuggestionKind.ENUM); 116 // _addSuggestion(d.name, CompletionSuggestionKind.ENUM);
132 } else if (declaration is FunctionDeclaration) { 117 } else if (declaration is FunctionDeclaration) {
133 _addSuggestion( 118 _addFunctionSuggestion(declaration);
134 declaration.name,
135 CompletionSuggestionKind.FUNCTION,
136 declaration.returnType,
137 null);
138 } else if (declaration is TopLevelVariableDeclaration) { 119 } else if (declaration is TopLevelVariableDeclaration) {
139 _addVarListSuggestions( 120 _addTopLevelVarSuggestions(declaration.variables);
140 declaration.variables,
141 CompletionSuggestionKind.TOP_LEVEL_VARIABLE,
142 null);
143 } else if (declaration is ClassTypeAlias) { 121 } else if (declaration is ClassTypeAlias) {
144 _addSuggestion( 122 _addSuggestion(
145 declaration.name, 123 declaration.name,
146 CompletionSuggestionKind.CLASS_ALIAS, 124 CompletionSuggestionKind.CLASS_ALIAS,
147 null, 125 null,
148 null); 126 null);
149 } else if (declaration is FunctionTypeAlias) { 127 } else if (declaration is FunctionTypeAlias) {
150 _addSuggestion( 128 _addSuggestion(
151 declaration.name, 129 declaration.name,
152 CompletionSuggestionKind.FUNCTION_TYPE_ALIAS, 130 CompletionSuggestionKind.FUNCTION_TYPE_ALIAS,
(...skipping 11 matching lines...) Expand all
164 // TODO (danrubel) suggest possible names for variable declaration 142 // TODO (danrubel) suggest possible names for variable declaration
165 // based upon variable type 143 // based upon variable type
166 return; 144 return;
167 } 145 }
168 } 146 }
169 visitNode(node); 147 visitNode(node);
170 } 148 }
171 149
172 @override 150 @override
173 visitForEachStatement(ForEachStatement node) { 151 visitForEachStatement(ForEachStatement node) {
174 // TODO (danrubel) supply type of local variable 152 SimpleIdentifier id;
175 _addSuggestion( 153 TypeName type;
176 node.identifier, 154 DeclaredIdentifier loopVar = node.loopVariable;
177 CompletionSuggestionKind.LOCAL_VARIABLE, 155 if (loopVar != null) {
178 null, 156 id = loopVar.identifier;
179 null); 157 type = loopVar.type;
158 } else {
159 id = node.identifier;
160 type = null;
161 }
162 _addLocalVarSuggestion(id, type);
180 visitNode(node); 163 visitNode(node);
181 } 164 }
182 165
183 @override 166 @override
184 visitForStatement(ForStatement node) { 167 visitForStatement(ForStatement node) {
185 _addVarListSuggestions( 168 var varList = node.variables;
186 node.variables, 169 if (varList != null) {
187 CompletionSuggestionKind.LOCAL_VARIABLE, 170 varList.variables.forEach((VariableDeclaration varDecl) {
188 null); 171 _addLocalVarSuggestion(varDecl.name, varList.type);
172 });
173 }
189 visitNode(node); 174 visitNode(node);
190 } 175 }
191 176
192 @override 177 @override
193 visitFunctionDeclaration(FunctionDeclaration node) { 178 visitFunctionDeclaration(FunctionDeclaration node) {
194 // This is added by the compilation unit containing it 179 // This is added by the compilation unit containing it
195 //_addSuggestion(node.name, CompletionSuggestionKind.FUNCTION); 180 //_addSuggestion(node.name, CompletionSuggestionKind.FUNCTION);
196 visitNode(node); 181 visitNode(node);
197 } 182 }
198 183
(...skipping 18 matching lines...) Expand all
217 visitVariableDeclaration(VariableDeclaration node) { 202 visitVariableDeclaration(VariableDeclaration node) {
218 // Do not add suggestions if editing the name in a var declaration 203 // Do not add suggestions if editing the name in a var declaration
219 SimpleIdentifier name = node.name; 204 SimpleIdentifier name = node.name;
220 if (name == null || 205 if (name == null ||
221 name.offset < request.offset || 206 name.offset < request.offset ||
222 request.offset > name.end) { 207 request.offset > name.end) {
223 visitNode(node); 208 visitNode(node);
224 } 209 }
225 } 210 }
226 211
212 void _addClassSuggestion(ClassDeclaration declaration) {
213 CompletionSuggestion suggestion =
214 _addSuggestion(declaration.name, CompletionSuggestionKind.CLASS, null, n ull);
215 if (suggestion != null) {
216 suggestion.element = _createElement(
217 protocol.ElementKind.CLASS,
218 declaration.name,
219 NO_RETURN_TYPE,
220 declaration.isAbstract,
221 _isDeprecated(declaration.metadata));
222 }
223 }
224
225 void _addFieldSuggestions(ClassDeclaration node, FieldDeclaration fieldDecl) {
226 bool isDeprecated = _isDeprecated(fieldDecl.metadata);
227 fieldDecl.fields.variables.forEach((VariableDeclaration varDecl) {
228 CompletionSuggestion suggestion = _addSuggestion(
229 varDecl.name,
230 CompletionSuggestionKind.GETTER,
231 fieldDecl.fields.type,
232 node);
233 if (suggestion != null) {
234 suggestion.element = _createElement(
235 protocol.ElementKind.GETTER,
236 varDecl.name,
237 fieldDecl.fields.type,
238 false,
239 isDeprecated || _isDeprecated(varDecl.metadata));
240 }
241 });
242 }
243
244 void _addFunctionSuggestion(FunctionDeclaration declaration) {
245 CompletionSuggestion suggestion = _addSuggestion(
246 declaration.name,
247 CompletionSuggestionKind.FUNCTION,
248 declaration.returnType,
249 null);
250 if (suggestion != null) {
251 suggestion.element = _createElement(
252 protocol.ElementKind.FUNCTION,
253 declaration.name,
254 declaration.returnType,
255 false,
256 _isDeprecated(declaration.metadata));
257 }
258 }
259
260 void _addLibraryPrefixSuggestion(ImportDirective directive) {
261 CompletionSuggestion suggestion = _addSuggestion(
262 directive.prefix,
263 CompletionSuggestionKind.LIBRARY_PREFIX,
264 null,
265 null);
266 if (suggestion != null) {
267 suggestion.element = _createElement(
268 protocol.ElementKind.LIBRARY,
269 directive.prefix,
270 NO_RETURN_TYPE,
271 false,
272 false);
273 }
274 }
275
276 void _addLocalVarSuggestion(SimpleIdentifier id, TypeName returnType) {
277 CompletionSuggestion suggestion =
278 _addSuggestion(id, CompletionSuggestionKind.LOCAL_VARIABLE, returnType, null);
279 if (suggestion != null) {
280 suggestion.element = _createElement(
281 protocol.ElementKind.LOCAL_VARIABLE,
282 id,
283 returnType,
284 false,
285 false);
286 }
287 }
288
289 void _addMethodSuggestion(ClassDeclaration node, MethodDeclaration classMbr) {
290 protocol.ElementKind kind;
291 CompletionSuggestionKind csKind;
292 if (classMbr.isGetter) {
293 kind = protocol.ElementKind.GETTER;
294 csKind = CompletionSuggestionKind.GETTER;
295 } else if (classMbr.isSetter) {
296 kind = protocol.ElementKind.SETTER;
297 csKind = CompletionSuggestionKind.SETTER;
298 } else {
299 kind = protocol.ElementKind.METHOD;
300 csKind = CompletionSuggestionKind.METHOD;
301 }
302 CompletionSuggestion suggestion =
303 _addSuggestion(classMbr.name, csKind, classMbr.returnType, node);
304 suggestion.element = _createElement(
305 kind,
306 classMbr.name,
307 classMbr.returnType,
308 classMbr.isAbstract,
309 _isDeprecated(classMbr.metadata));
310 }
311
227 void _addParamListSuggestions(FormalParameterList paramList) { 312 void _addParamListSuggestions(FormalParameterList paramList) {
228 if (paramList != null) { 313 if (paramList != null) {
229 paramList.parameters.forEach((FormalParameter param) { 314 paramList.parameters.forEach((FormalParameter param) {
230 NormalFormalParameter normalParam; 315 NormalFormalParameter normalParam;
231 if (param is DefaultFormalParameter) { 316 if (param is DefaultFormalParameter) {
232 normalParam = param.parameter; 317 normalParam = param.parameter;
233 } else if (param is NormalFormalParameter) { 318 } else if (param is NormalFormalParameter) {
234 normalParam = param; 319 normalParam = param;
235 } 320 }
236 TypeName type = null; 321 TypeName type = null;
237 if (normalParam is FieldFormalParameter) { 322 if (normalParam is FieldFormalParameter) {
238 type = normalParam.type; 323 type = normalParam.type;
239 } else if (normalParam is FunctionTypedFormalParameter) { 324 } else if (normalParam is FunctionTypedFormalParameter) {
240 type = normalParam.returnType; 325 type = normalParam.returnType;
241 } else if (normalParam is SimpleFormalParameter) { 326 } else if (normalParam is SimpleFormalParameter) {
242 type = normalParam.type; 327 type = normalParam.type;
243 } 328 }
244 _addSuggestion( 329 _addParamSuggestion(param.identifier, type);
245 param.identifier,
246 CompletionSuggestionKind.PARAMETER,
247 type,
248 null);
249 }); 330 });
250 } 331 }
251 } 332 }
252 333
253 void _addSuggestion(SimpleIdentifier id, CompletionSuggestionKind kind, 334 CompletionSuggestion _addParamSuggestion(SimpleIdentifier identifier,
254 TypeName typeName, ClassDeclaration classDecl) { 335 TypeName type) {
336 CompletionSuggestion suggestion =
337 _addSuggestion(identifier, CompletionSuggestionKind.PARAMETER, type, nul l);
338 if (suggestion != null) {
339 suggestion.element =
340 _createElement(protocol.ElementKind.PARAMETER, identifier, type, false , false);
341 }
342 return suggestion;
343 }
344
345 CompletionSuggestion _addSuggestion(SimpleIdentifier id,
346 CompletionSuggestionKind kind, TypeName typeName, ClassDeclaration classDe cl) {
255 if (id != null) { 347 if (id != null) {
256 String completion = id.name; 348 String completion = id.name;
257 if (completion != null && completion.length > 0) { 349 if (completion != null && completion.length > 0) {
258 CompletionSuggestion suggestion = new CompletionSuggestion( 350 CompletionSuggestion suggestion = new CompletionSuggestion(
259 kind, 351 kind,
260 CompletionRelevance.DEFAULT, 352 CompletionRelevance.DEFAULT,
261 completion, 353 completion,
262 completion.length, 354 completion.length,
263 0, 355 0,
264 false, 356 false,
(...skipping 10 matching lines...) Expand all
275 if (typeName != null) { 367 if (typeName != null) {
276 Identifier identifier = typeName.name; 368 Identifier identifier = typeName.name;
277 if (identifier != null) { 369 if (identifier != null) {
278 String name = identifier.name; 370 String name = identifier.name;
279 if (name != null && name.length > 0) { 371 if (name != null && name.length > 0) {
280 suggestion.returnType = name; 372 suggestion.returnType = name;
281 } 373 }
282 } 374 }
283 } 375 }
284 request.suggestions.add(suggestion); 376 request.suggestions.add(suggestion);
377 return suggestion;
285 } 378 }
286 } 379 }
380 return null;
381 }
382
383 void _addTopLevelVarSuggestions(VariableDeclarationList varList) {
384 if (varList != null) {
385 bool isDeprecated = _isDeprecated(varList.metadata);
386 varList.variables.forEach((VariableDeclaration varDecl) {
387 CompletionSuggestion suggestion = _addSuggestion(
388 varDecl.name,
389 CompletionSuggestionKind.TOP_LEVEL_VARIABLE,
390 varList.type,
391 null);
392 if (suggestion != null) {
393 suggestion.element = _createElement(
394 protocol.ElementKind.TOP_LEVEL_VARIABLE,
395 varDecl.name,
396 varList.type,
397 false,
398 isDeprecated || _isDeprecated(varDecl.metadata));
399 }
400 });
401 }
287 } 402 }
288 403
289 void _addVarListSuggestions(VariableDeclarationList variables, 404 /**
290 CompletionSuggestionKind kind, ClassDeclaration classDecl) { 405 * Create a new protocol Element for inclusion in a completion suggestion.
291 variables.variables.forEach((VariableDeclaration varDecl) { 406 */
292 _addSuggestion(varDecl.name, kind, variables.type, classDecl); 407 protocol.Element _createElement(protocol.ElementKind kind,
293 }); 408 SimpleIdentifier id, TypeName returnType, bool isAbstract, bool isDeprecat ed) {
409 String name = id.name;
410 int flags = protocol.Element.makeFlags(
411 isAbstract: isAbstract,
412 isDeprecated: isDeprecated,
413 isPrivate: Identifier.isPrivateName(name));
414 return new protocol.Element(
415 kind,
416 name,
417 flags,
418 returnType: _nameForType(returnType));
419 }
420
421 /**
422 * Return `true` if the @deprecated annotation is present
423 */
424 bool _isDeprecated(NodeList<Annotation> metadata) =>
425 metadata != null &&
426 metadata.any(
427 (Annotation a) => a.name is SimpleIdentifier && a.name.name == 'de precated');
428
429 /**
430 * Return the name for the given type.
431 */
432 String _nameForType(TypeName type) {
433 if (type == NO_RETURN_TYPE) {
434 return null;
435 }
436 if (type == null) {
437 return DYNAMIC;
438 }
439 Identifier id = type.name;
440 if (id == null) {
441 return DYNAMIC;
442 }
443 String name = id.name;
444 if (name == null || name.length <= 0) {
445 return DYNAMIC;
446 }
447 TypeArgumentList typeArgs = type.typeArguments;
448 if (typeArgs != null) {
449 //TODO (danrubel) include type arguments
450 }
451 return name;
294 } 452 }
295 } 453 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698