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

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

Issue 965753003: fix invocation completion with trailing stmt (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: merge Created 5 years, 9 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
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/services/completion/local_declaration_visitor.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.invocation; 5 library services.completion.computer.dart.invocation;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 8
9 import 'package:analysis_server/src/services/completion/dart_completion_manager. dart'; 9 import 'package:analysis_server/src/services/completion/dart_completion_manager. dart';
10 import 'package:analysis_server/src/services/completion/local_declaration_visito r.dart';
10 import 'package:analysis_server/src/services/completion/optype.dart'; 11 import 'package:analysis_server/src/services/completion/optype.dart';
11 import 'package:analysis_server/src/services/completion/suggestion_builder.dart' ; 12 import 'package:analysis_server/src/services/completion/suggestion_builder.dart' ;
12 import 'package:analyzer/src/generated/ast.dart'; 13 import 'package:analyzer/src/generated/ast.dart';
13 import 'package:analyzer/src/generated/element.dart'; 14 import 'package:analyzer/src/generated/element.dart';
14 15
15 import '../../protocol_server.dart' show CompletionSuggestionKind; 16 import '../../protocol_server.dart' show CompletionSuggestionKind;
16 17
17 /** 18 /**
18 * A computer for calculating invocation / access suggestions 19 * A computer for calculating invocation / access suggestions
19 * `completion.getSuggestions` request results. 20 * `completion.getSuggestions` request results.
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 return new _ExpressionSuggestionBuilder(request); 115 return new _ExpressionSuggestionBuilder(request);
115 } 116 }
116 117
117 @override 118 @override
118 SuggestionBuilder visitSimpleIdentifier(SimpleIdentifier node) { 119 SuggestionBuilder visitSimpleIdentifier(SimpleIdentifier node) {
119 return node.parent.accept(this); 120 return node.parent.accept(this);
120 } 121 }
121 } 122 }
122 123
123 /** 124 /**
125 * An [AstVisitor] which looks for a declaration with the given name
126 * and if found, tries to determine a type for that declaration.
127 */
128 class _LocalBestTypeVisitor extends LocalDeclarationVisitor {
129
130 /**
131 * The name for the declaration to be found.
132 */
133 final String targetName;
134
135 /**
136 * The best type for the found declaration,
137 * or `null` if no declaration found or failed to determine a type.
138 */
139 DartType typeFound;
140
141 /**
142 * Construct a new instance to search for a declaration
143 */
144 _LocalBestTypeVisitor(this.targetName, int offset) : super(offset);
145
146 @override
147 void declaredClass(ClassDeclaration declaration) {
148 if (declaration.name.name == targetName) {
149 finished = true;
150 // no type
151 }
152 }
153
154 @override
155 void declaredClassTypeAlias(ClassTypeAlias declaration) {
156 if (declaration.name.name == targetName) {
157 finished = true;
158 // no type
159 }
160 }
161
162 @override
163 void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
164 if (varDecl.name.name == targetName) {
165 finished = true;
166 // Type provided by the element in computeFull above
167 }
168 }
169
170 @override
171 void declaredFunction(FunctionDeclaration declaration) {
172 if (declaration.name.name == targetName) {
173 finished = true;
174 TypeName typeName = declaration.returnType;
175 if (typeName != null) {
176 typeFound = typeName.type;
177 }
178 }
179 }
180
181 @override
182 void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {
183 if (declaration.name.name == targetName) {
184 finished = true;
185 TypeName typeName = declaration.returnType;
186 if (typeName != null) {
187 typeFound = typeName.type;
188 }
189 }
190 }
191
192 @override
193 void declaredLabel(Label label, bool isCaseLabel) {
194 if (label.label.name == targetName) {
195 finished = true;
196 // no type
197 }
198 }
199
200 @override
201 void declaredLocalVar(SimpleIdentifier name, TypeName type) {
202 if (name.name == targetName) {
203 finished = true;
204 typeFound = name.bestType;
205 }
206 }
207
208 @override
209 void declaredMethod(MethodDeclaration declaration) {
210 if (declaration.name.name == targetName) {
211 finished = true;
212 TypeName typeName = declaration.returnType;
213 if (typeName != null) {
214 typeFound = typeName.type;
215 }
216 }
217 }
218
219 @override
220 void declaredParam(SimpleIdentifier name, TypeName type) {
221 if (name.name == targetName) {
222 finished = true;
223 // Type provided by the element in computeFull above
224 }
225 }
226
227 @override
228 void declaredTopLevelVar(VariableDeclarationList varList,
229 VariableDeclaration varDecl) {
230 if (varDecl.name.name == targetName) {
231 finished = true;
232 // Type provided by the element in computeFull above
233 }
234 }
235 }
236
237 /**
124 * An [Element] visitor for determining the appropriate invocation/access 238 * An [Element] visitor for determining the appropriate invocation/access
125 * suggestions based upon the element for which the completion is requested. 239 * suggestions based upon the element for which the completion is requested.
126 */ 240 */
127 class _PrefixedIdentifierSuggestionBuilder extends 241 class _PrefixedIdentifierSuggestionBuilder extends
128 GeneralizingElementVisitor<Future<bool>> implements SuggestionBuilder { 242 GeneralizingElementVisitor<Future<bool>> implements SuggestionBuilder {
129 243
130 final DartCompletionRequest request; 244 final DartCompletionRequest request;
131 245
132 _PrefixedIdentifierSuggestionBuilder(this.request); 246 _PrefixedIdentifierSuggestionBuilder(this.request);
133 247
(...skipping 10 matching lines...) Expand all
144 if (node is ConstructorName) { 258 if (node is ConstructorName) {
145 // some PrefixedIdentifier nodes are transformed into 259 // some PrefixedIdentifier nodes are transformed into
146 // ConstructorName nodes during the resolution process. 260 // ConstructorName nodes during the resolution process.
147 return new NamedConstructorSuggestionBuilder(request).computeFull(node); 261 return new NamedConstructorSuggestionBuilder(request).computeFull(node);
148 } 262 }
149 if (node is PrefixedIdentifier) { 263 if (node is PrefixedIdentifier) {
150 SimpleIdentifier prefix = node.prefix; 264 SimpleIdentifier prefix = node.prefix;
151 if (prefix != null) { 265 if (prefix != null) {
152 Element element = prefix.bestElement; 266 Element element = prefix.bestElement;
153 DartType type = prefix.bestType; 267 DartType type = prefix.bestType;
154 if (element is! ClassElement && type != null && !type.isDynamic) { 268 if (element is! ClassElement) {
155 InterfaceTypeSuggestionBuilder.suggestionsFor( 269 if (type == null || type.isDynamic) {
156 request, 270 //
157 type); 271 // Given `g. int y = 0;`, the parser interprets `g` as a prefixed
158 return new Future.value(true); 272 // identifier with no type.
159 } else if (element != null) { 273 // If the user is requesting completions for `g`,
274 // then check for a function, getter, or similar with a type.
275 //
276 _LocalBestTypeVisitor visitor =
277 new _LocalBestTypeVisitor(prefix.name, request.offset);
278 prefix.accept(visitor);
279 type = visitor.typeFound;
280 }
281 if (type != null && !type.isDynamic) {
282 InterfaceTypeSuggestionBuilder.suggestionsFor(request, type);
283 return new Future.value(true);
284 }
285 }
286 if (element != null) {
160 return element.accept(this); 287 return element.accept(this);
161 } 288 }
162 } 289 }
163 } 290 }
164 return new Future.value(false); 291 return new Future.value(false);
165 } 292 }
166 293
167 @override 294 @override
168 Future<bool> visitClassElement(ClassElement element) { 295 Future<bool> visitClassElement(ClassElement element) {
169 if (element != null) { 296 if (element != null) {
(...skipping 11 matching lines...) Expand all
181 Future<bool> visitElement(Element element) { 308 Future<bool> visitElement(Element element) {
182 return new Future.value(false); 309 return new Future.value(false);
183 } 310 }
184 311
185 @override 312 @override
186 Future<bool> visitPrefixElement(PrefixElement element) { 313 Future<bool> visitPrefixElement(PrefixElement element) {
187 //TODO (danrubel) reimplement to use prefixElement.importedLibraries 314 //TODO (danrubel) reimplement to use prefixElement.importedLibraries
188 // once that accessor is implemented and available in Dart 315 // once that accessor is implemented and available in Dart
189 bool modified = false; 316 bool modified = false;
190 // Find the import directive with the given prefix 317 // Find the import directive with the given prefix
191 request.unit.directives.forEach((Directive directive) { 318 for (Directive directive in request.unit.directives) {
192 if (directive is ImportDirective) { 319 if (directive is ImportDirective) {
193 if (directive.prefix != null) { 320 if (directive.prefix != null) {
194 if (directive.prefix.name == element.name) { 321 if (directive.prefix.name == element.name) {
195 // Suggest elements from the imported library 322 // Suggest elements from the imported library
196 LibraryElement library = directive.uriElement; 323 LibraryElement library = directive.uriElement;
197 LibraryElementSuggestionBuilder.suggestionsFor( 324 LibraryElementSuggestionBuilder.suggestionsFor(
198 request, 325 request,
199 CompletionSuggestionKind.INVOCATION, 326 CompletionSuggestionKind.INVOCATION,
200 library); 327 library);
201 modified = true; 328 modified = true;
202 } 329 }
203 } 330 }
204 } 331 }
205 }); 332 };
206 return new Future.value(modified); 333 return new Future.value(modified);
207 } 334 }
208 335
209 @override 336 @override
210 Future<bool> visitPropertyAccessorElement(PropertyAccessorElement element) { 337 Future<bool> visitPropertyAccessorElement(PropertyAccessorElement element) {
211 if (element != null) { 338 if (element != null) {
212 PropertyInducingElement elemVar = element.variable; 339 PropertyInducingElement elemVar = element.variable;
213 if (elemVar != null) { 340 if (elemVar != null) {
214 InterfaceTypeSuggestionBuilder.suggestionsFor(request, elemVar.type); 341 InterfaceTypeSuggestionBuilder.suggestionsFor(request, elemVar.type);
215 } 342 }
216 return new Future.value(true); 343 return new Future.value(true);
217 } 344 }
218 return new Future.value(false); 345 return new Future.value(false);
219 } 346 }
220 347
221 @override 348 @override
222 Future<bool> visitVariableElement(VariableElement element) { 349 Future<bool> visitVariableElement(VariableElement element) {
223 InterfaceTypeSuggestionBuilder.suggestionsFor(request, element.type); 350 InterfaceTypeSuggestionBuilder.suggestionsFor(request, element.type);
224 return new Future.value(true); 351 return new Future.value(true);
225 } 352 }
226 } 353 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/services/completion/local_declaration_visitor.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698