| 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.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/local_declaration_visito
r.dart'; | 13 import 'package:analysis_server/src/services/completion/local_declaration_visito
r.dart'; |
| 14 import 'package:analysis_server/src/services/completion/optype.dart'; | 14 import 'package:analysis_server/src/services/completion/optype.dart'; |
| 15 import 'package:analyzer/src/generated/ast.dart'; | 15 import 'package:analyzer/src/generated/ast.dart'; |
| 16 import 'package:analyzer/src/generated/scanner.dart'; | 16 import 'package:analyzer/src/generated/scanner.dart'; |
| 17 import 'package:analyzer/src/generated/utilities_dart.dart'; |
| 17 | 18 |
| 18 /** | 19 /** |
| 19 * A computer for calculating `completion.getSuggestions` request results | 20 * A computer for calculating `completion.getSuggestions` request results |
| 20 * for the local library in which the completion is requested. | 21 * for the local library in which the completion is requested. |
| 21 */ | 22 */ |
| 22 class LocalComputer extends DartCompletionComputer { | 23 class LocalComputer extends DartCompletionComputer { |
| 23 | 24 |
| 24 @override | 25 @override |
| 25 bool computeFast(DartCompletionRequest request) { | 26 bool computeFast(DartCompletionRequest request) { |
| 26 OpType optype = request.optype; | 27 OpType optype = request.optype; |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 final bool excludeVoidReturn; | 201 final bool excludeVoidReturn; |
| 201 | 202 |
| 202 _LocalVisitor(this.request, int offset, this.typesOnly, | 203 _LocalVisitor(this.request, int offset, this.typesOnly, |
| 203 this.excludeVoidReturn) | 204 this.excludeVoidReturn) |
| 204 : super(offset); | 205 : super(offset); |
| 205 | 206 |
| 206 @override | 207 @override |
| 207 void declaredClass(ClassDeclaration declaration) { | 208 void declaredClass(ClassDeclaration declaration) { |
| 208 bool isDeprecated = _isDeprecated(declaration); | 209 bool isDeprecated = _isDeprecated(declaration); |
| 209 CompletionSuggestion suggestion = | 210 CompletionSuggestion suggestion = |
| 210 _addSuggestion(declaration.name, NO_RETURN_TYPE, null, isDeprecated); | 211 _addSuggestion(declaration.name, NO_RETURN_TYPE, isDeprecated); |
| 211 if (suggestion != null) { | 212 if (suggestion != null) { |
| 212 suggestion.element = _createElement( | 213 suggestion.element = _createElement( |
| 213 protocol.ElementKind.CLASS, | 214 protocol.ElementKind.CLASS, |
| 214 declaration.name, | 215 declaration.name, |
| 215 null, | 216 returnType: NO_RETURN_TYPE, |
| 216 NO_RETURN_TYPE, | 217 isAbstract: declaration.isAbstract, |
| 217 declaration.isAbstract, | 218 isDeprecated: isDeprecated); |
| 218 isDeprecated); | |
| 219 } | 219 } |
| 220 } | 220 } |
| 221 | 221 |
| 222 @override | 222 @override |
| 223 void declaredClassTypeAlias(ClassTypeAlias declaration) { | 223 void declaredClassTypeAlias(ClassTypeAlias declaration) { |
| 224 bool isDeprecated = _isDeprecated(declaration); | 224 bool isDeprecated = _isDeprecated(declaration); |
| 225 CompletionSuggestion suggestion = | 225 CompletionSuggestion suggestion = |
| 226 _addSuggestion(declaration.name, NO_RETURN_TYPE, null, isDeprecated); | 226 _addSuggestion(declaration.name, NO_RETURN_TYPE, isDeprecated); |
| 227 if (suggestion != null) { | 227 if (suggestion != null) { |
| 228 suggestion.element = _createElement( | 228 suggestion.element = _createElement( |
| 229 protocol.ElementKind.CLASS_TYPE_ALIAS, | 229 protocol.ElementKind.CLASS_TYPE_ALIAS, |
| 230 declaration.name, | 230 declaration.name, |
| 231 null, | 231 returnType: NO_RETURN_TYPE, |
| 232 NO_RETURN_TYPE, | 232 isAbstract: true, |
| 233 true, | 233 isDeprecated: isDeprecated); |
| 234 isDeprecated); | |
| 235 } | 234 } |
| 236 } | 235 } |
| 237 | 236 |
| 238 @override | 237 @override |
| 239 void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) { | 238 void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) { |
| 240 if (typesOnly) { | 239 if (typesOnly) { |
| 241 return; | 240 return; |
| 242 } | 241 } |
| 243 bool isDeprecated = _isDeprecated(fieldDecl) || _isDeprecated(varDecl); | 242 bool isDeprecated = _isDeprecated(fieldDecl) || _isDeprecated(varDecl); |
| 244 TypeName type = fieldDecl.fields.type; | 243 TypeName type = fieldDecl.fields.type; |
| 245 CompletionSuggestion suggestion = | 244 CompletionSuggestion suggestion = |
| 246 _addSuggestion(varDecl.name, type, fieldDecl.parent, isDeprecated); | 245 _addSuggestion(varDecl.name, type, isDeprecated, classDecl: fieldDecl.pa
rent); |
| 247 if (suggestion != null) { | 246 if (suggestion != null) { |
| 248 suggestion.element = _createElement( | 247 suggestion.element = _createElement( |
| 249 protocol.ElementKind.FIELD, | 248 protocol.ElementKind.FIELD, |
| 250 varDecl.name, | 249 varDecl.name, |
| 251 null, | 250 returnType: type, |
| 252 type, | 251 isDeprecated: isDeprecated); |
| 253 false, | |
| 254 isDeprecated); | |
| 255 } | 252 } |
| 256 } | 253 } |
| 257 | 254 |
| 258 @override | 255 @override |
| 259 void declaredFunction(FunctionDeclaration declaration) { | 256 void declaredFunction(FunctionDeclaration declaration) { |
| 260 if (typesOnly) { | 257 if (typesOnly) { |
| 261 return; | 258 return; |
| 262 } | 259 } |
| 263 TypeName returnType = declaration.returnType; | 260 TypeName returnType = declaration.returnType; |
| 264 bool isDeprecated = _isDeprecated(declaration); | 261 bool isDeprecated = _isDeprecated(declaration); |
| 265 protocol.ElementKind kind; | 262 protocol.ElementKind kind; |
| 266 if (declaration.isGetter) { | 263 if (declaration.isGetter) { |
| 267 kind = protocol.ElementKind.GETTER; | 264 kind = protocol.ElementKind.GETTER; |
| 268 } else if (declaration.isSetter) { | 265 } else if (declaration.isSetter) { |
| 269 if (excludeVoidReturn) { | 266 if (excludeVoidReturn) { |
| 270 return; | 267 return; |
| 271 } | 268 } |
| 272 kind = protocol.ElementKind.SETTER; | 269 kind = protocol.ElementKind.SETTER; |
| 273 returnType = NO_RETURN_TYPE; | 270 returnType = NO_RETURN_TYPE; |
| 274 } else { | 271 } else { |
| 275 if (excludeVoidReturn && _isVoid(returnType)) { | 272 if (excludeVoidReturn && _isVoid(returnType)) { |
| 276 return; | 273 return; |
| 277 } | 274 } |
| 278 kind = protocol.ElementKind.FUNCTION; | 275 kind = protocol.ElementKind.FUNCTION; |
| 279 } | 276 } |
| 280 CompletionSuggestion suggestion = | 277 CompletionSuggestion suggestion = |
| 281 _addSuggestion(declaration.name, returnType, null, isDeprecated); | 278 _addSuggestion(declaration.name, returnType, isDeprecated); |
| 282 if (suggestion != null) { | 279 if (suggestion != null) { |
| 283 FormalParameterList param = declaration.functionExpression.parameters; | 280 FormalParameterList param = declaration.functionExpression.parameters; |
| 284 suggestion.element = _createElement( | 281 suggestion.element = _createElement( |
| 285 kind, | 282 kind, |
| 286 declaration.name, | 283 declaration.name, |
| 287 param != null ? param.toSource() : null, | 284 parameters: param != null ? param.toSource() : null, |
| 288 returnType, | 285 returnType: returnType, |
| 289 false, | 286 isDeprecated: isDeprecated); |
| 290 isDeprecated); | 287 if (kind == protocol.ElementKind.FUNCTION) { |
| 288 _addParameterInfo( |
| 289 suggestion, |
| 290 declaration.functionExpression.parameters); |
| 291 } |
| 291 } | 292 } |
| 292 } | 293 } |
| 293 | 294 |
| 294 @override | 295 @override |
| 295 void declaredFunctionTypeAlias(FunctionTypeAlias declaration) { | 296 void declaredFunctionTypeAlias(FunctionTypeAlias declaration) { |
| 296 bool isDeprecated = _isDeprecated(declaration); | 297 bool isDeprecated = _isDeprecated(declaration); |
| 297 TypeName returnType = declaration.returnType; | 298 TypeName returnType = declaration.returnType; |
| 298 CompletionSuggestion suggestion = | 299 CompletionSuggestion suggestion = |
| 299 _addSuggestion(declaration.name, returnType, null, isDeprecated); | 300 _addSuggestion(declaration.name, returnType, isDeprecated); |
| 300 if (suggestion != null) { | 301 if (suggestion != null) { |
| 301 // TODO (danrubel) determine parameters and return type | 302 // TODO (danrubel) determine parameters and return type |
| 302 suggestion.element = _createElement( | 303 suggestion.element = _createElement( |
| 303 protocol.ElementKind.FUNCTION_TYPE_ALIAS, | 304 protocol.ElementKind.FUNCTION_TYPE_ALIAS, |
| 304 declaration.name, | 305 declaration.name, |
| 305 null, | 306 returnType: returnType, |
| 306 returnType, | 307 isAbstract: true, |
| 307 true, | 308 isDeprecated: isDeprecated); |
| 308 isDeprecated); | |
| 309 } | 309 } |
| 310 } | 310 } |
| 311 | 311 |
| 312 @override | 312 @override |
| 313 void declaredLabel(Label label, bool isCaseLabel) { | 313 void declaredLabel(Label label, bool isCaseLabel) { |
| 314 // ignored | 314 // ignored |
| 315 } | 315 } |
| 316 | 316 |
| 317 @override | 317 @override |
| 318 void declaredLocalVar(SimpleIdentifier name, TypeName type) { | 318 void declaredLocalVar(SimpleIdentifier name, TypeName type) { |
| 319 if (typesOnly) { | 319 if (typesOnly) { |
| 320 return; | 320 return; |
| 321 } | 321 } |
| 322 CompletionSuggestion suggestion = _addSuggestion(name, type, null, false); | 322 CompletionSuggestion suggestion = _addSuggestion(name, type, false); |
| 323 if (suggestion != null) { | 323 if (suggestion != null) { |
| 324 suggestion.element = _createElement( | 324 suggestion.element = |
| 325 protocol.ElementKind.LOCAL_VARIABLE, | 325 _createElement(protocol.ElementKind.LOCAL_VARIABLE, name, returnType:
type); |
| 326 name, | |
| 327 null, | |
| 328 type, | |
| 329 false, | |
| 330 false); | |
| 331 } | 326 } |
| 332 } | 327 } |
| 333 | 328 |
| 334 @override | 329 @override |
| 335 void declaredMethod(MethodDeclaration declaration) { | 330 void declaredMethod(MethodDeclaration declaration) { |
| 336 if (typesOnly) { | 331 if (typesOnly) { |
| 337 return; | 332 return; |
| 338 } | 333 } |
| 339 protocol.ElementKind kind; | 334 protocol.ElementKind kind; |
| 340 String parameters; | 335 String parameters; |
| 341 TypeName returnType = declaration.returnType; | 336 TypeName returnType = declaration.returnType; |
| 342 if (declaration.isGetter) { | 337 if (declaration.isGetter) { |
| 343 kind = protocol.ElementKind.GETTER; | 338 kind = protocol.ElementKind.GETTER; |
| 344 parameters = null; | 339 parameters = null; |
| 345 } else if (declaration.isSetter) { | 340 } else if (declaration.isSetter) { |
| 346 if (excludeVoidReturn) { | 341 if (excludeVoidReturn) { |
| 347 return; | 342 return; |
| 348 } | 343 } |
| 349 kind = protocol.ElementKind.SETTER; | 344 kind = protocol.ElementKind.SETTER; |
| 350 returnType = NO_RETURN_TYPE; | 345 returnType = NO_RETURN_TYPE; |
| 351 } else { | 346 } else { |
| 352 if (excludeVoidReturn && _isVoid(returnType)) { | 347 if (excludeVoidReturn && _isVoid(returnType)) { |
| 353 return; | 348 return; |
| 354 } | 349 } |
| 355 kind = protocol.ElementKind.METHOD; | 350 kind = protocol.ElementKind.METHOD; |
| 356 parameters = declaration.parameters.toSource(); | 351 parameters = declaration.parameters.toSource(); |
| 357 } | 352 } |
| 358 bool isDeprecated = _isDeprecated(declaration); | 353 bool isDeprecated = _isDeprecated(declaration); |
| 359 CompletionSuggestion suggestion = | 354 CompletionSuggestion suggestion = _addSuggestion( |
| 360 _addSuggestion(declaration.name, returnType, declaration.parent, isDepre
cated); | 355 declaration.name, |
| 356 returnType, |
| 357 isDeprecated, |
| 358 classDecl: declaration.parent); |
| 361 if (suggestion != null) { | 359 if (suggestion != null) { |
| 362 suggestion.element = _createElement( | 360 suggestion.element = _createElement( |
| 363 kind, | 361 kind, |
| 364 declaration.name, | 362 declaration.name, |
| 365 parameters, | 363 parameters: parameters, |
| 366 returnType, | 364 returnType: returnType, |
| 367 declaration.isAbstract, | 365 isAbstract: declaration.isAbstract, |
| 368 isDeprecated); | 366 isDeprecated: isDeprecated); |
| 367 if (kind == protocol.ElementKind.METHOD) { |
| 368 _addParameterInfo(suggestion, declaration.parameters); |
| 369 } |
| 369 } | 370 } |
| 370 } | 371 } |
| 371 | 372 |
| 372 @override | 373 @override |
| 373 void declaredParam(SimpleIdentifier name, TypeName type) { | 374 void declaredParam(SimpleIdentifier name, TypeName type) { |
| 374 if (typesOnly) { | 375 if (typesOnly) { |
| 375 return; | 376 return; |
| 376 } | 377 } |
| 377 CompletionSuggestion suggestion = _addSuggestion(name, type, null, false); | 378 CompletionSuggestion suggestion = _addSuggestion(name, type, false); |
| 378 if (suggestion != null) { | 379 if (suggestion != null) { |
| 379 suggestion.element = | 380 suggestion.element = |
| 380 _createElement(protocol.ElementKind.PARAMETER, name, null, type, false
, false); | 381 _createElement(protocol.ElementKind.PARAMETER, name, returnType: type)
; |
| 381 } | 382 } |
| 382 } | 383 } |
| 383 | 384 |
| 384 @override | 385 @override |
| 385 void declaredTopLevelVar(VariableDeclarationList varList, | 386 void declaredTopLevelVar(VariableDeclarationList varList, |
| 386 VariableDeclaration varDecl) { | 387 VariableDeclaration varDecl) { |
| 387 if (typesOnly) { | 388 if (typesOnly) { |
| 388 return; | 389 return; |
| 389 } | 390 } |
| 390 bool isDeprecated = _isDeprecated(varList) || _isDeprecated(varDecl); | 391 bool isDeprecated = _isDeprecated(varList) || _isDeprecated(varDecl); |
| 391 CompletionSuggestion suggestion = | 392 CompletionSuggestion suggestion = |
| 392 _addSuggestion(varDecl.name, varList.type, null, isDeprecated); | 393 _addSuggestion(varDecl.name, varList.type, isDeprecated); |
| 393 if (suggestion != null) { | 394 if (suggestion != null) { |
| 394 suggestion.element = _createElement( | 395 suggestion.element = _createElement( |
| 395 protocol.ElementKind.TOP_LEVEL_VARIABLE, | 396 protocol.ElementKind.TOP_LEVEL_VARIABLE, |
| 396 varDecl.name, | 397 varDecl.name, |
| 397 null, | 398 returnType: varList.type, |
| 398 varList.type, | 399 isDeprecated: isDeprecated); |
| 399 false, | |
| 400 isDeprecated); | |
| 401 } | 400 } |
| 402 } | 401 } |
| 403 | 402 |
| 403 void _addParameterInfo(CompletionSuggestion suggestion, |
| 404 FormalParameterList parameters) { |
| 405 var paramList = parameters.parameters; |
| 406 suggestion.parameterNames = |
| 407 paramList.map((FormalParameter param) => param.identifier.name).toList()
; |
| 408 suggestion.parameterTypes = paramList.map((FormalParameter param) { |
| 409 TypeName type = null; |
| 410 if (param is DefaultFormalParameter) { |
| 411 NormalFormalParameter child = param.parameter; |
| 412 if (child is SimpleFormalParameter) { |
| 413 type = child.type; |
| 414 } else if (child is FieldFormalParameter) { |
| 415 type = child.type; |
| 416 } |
| 417 } |
| 418 if (param is SimpleFormalParameter) { |
| 419 type = param.type; |
| 420 } else if (param is FieldFormalParameter) { |
| 421 type = param.type; |
| 422 } |
| 423 if (type == null) { |
| 424 return 'dynamic'; |
| 425 } |
| 426 Identifier typeId = type.name; |
| 427 if (typeId == null) { |
| 428 return 'dynamic'; |
| 429 } |
| 430 return typeId.name; |
| 431 }).toList(); |
| 432 suggestion.requiredParameterCount = paramList.where( |
| 433 (FormalParameter param) => param is! DefaultFormalParameter).length; |
| 434 suggestion.hasNamedParameters = |
| 435 paramList.any((FormalParameter param) => param.kind == ParameterKind.NAM
ED); |
| 436 } |
| 437 |
| 404 CompletionSuggestion _addSuggestion(SimpleIdentifier id, TypeName returnType, | 438 CompletionSuggestion _addSuggestion(SimpleIdentifier id, TypeName returnType, |
| 405 ClassDeclaration classDecl, bool isDeprecated) { | 439 bool isDeprecated, {ClassDeclaration classDecl}) { |
| 406 if (id != null) { | 440 if (id != null) { |
| 407 String completion = id.name; | 441 String completion = id.name; |
| 408 if (completion != null && completion.length > 0 && completion != '_') { | 442 if (completion != null && completion.length > 0 && completion != '_') { |
| 409 CompletionSuggestion suggestion = new CompletionSuggestion( | 443 CompletionSuggestion suggestion = new CompletionSuggestion( |
| 410 CompletionSuggestionKind.INVOCATION, | 444 CompletionSuggestionKind.INVOCATION, |
| 411 isDeprecated ? COMPLETION_RELEVANCE_LOW : COMPLETION_RELEVANCE_DEFAU
LT, | 445 isDeprecated ? COMPLETION_RELEVANCE_LOW : COMPLETION_RELEVANCE_DEFAU
LT, |
| 412 completion, | 446 completion, |
| 413 completion.length, | 447 completion.length, |
| 414 0, | 448 0, |
| 415 false, | 449 isDeprecated, |
| 416 false, | 450 false, |
| 417 returnType: _nameForType(returnType)); | 451 returnType: _nameForType(returnType)); |
| 418 if (classDecl != null) { | 452 if (classDecl != null) { |
| 419 SimpleIdentifier identifier = classDecl.name; | 453 SimpleIdentifier identifier = classDecl.name; |
| 420 if (identifier != null) { | 454 if (identifier != null) { |
| 421 String name = identifier.name; | 455 String name = identifier.name; |
| 422 if (name != null && name.length > 0) { | 456 if (name != null && name.length > 0) { |
| 423 suggestion.declaringType = name; | 457 suggestion.declaringType = name; |
| 424 } | 458 } |
| 425 } | 459 } |
| 426 } | 460 } |
| 427 request.suggestions.add(suggestion); | 461 request.suggestions.add(suggestion); |
| 428 return suggestion; | 462 return suggestion; |
| 429 } | 463 } |
| 430 } | 464 } |
| 431 return null; | 465 return null; |
| 432 } | 466 } |
| 433 | 467 |
| 434 | 468 |
| 435 /** | 469 /** |
| 436 * Create a new protocol Element for inclusion in a completion suggestion. | 470 * Create a new protocol Element for inclusion in a completion suggestion. |
| 437 */ | 471 */ |
| 438 protocol.Element _createElement(protocol.ElementKind kind, | 472 protocol.Element _createElement(protocol.ElementKind kind, |
| 439 SimpleIdentifier id, String parameters, TypeName returnType, bool isAbstra
ct, | 473 SimpleIdentifier id, {String parameters, TypeName returnType, bool isAbstr
act: |
| 440 bool isDeprecated) { | 474 false, bool isDeprecated: false}) { |
| 441 String name = id.name; | 475 String name = id.name; |
| 442 int flags = protocol.Element.makeFlags( | 476 int flags = protocol.Element.makeFlags( |
| 443 isAbstract: isAbstract, | 477 isAbstract: isAbstract, |
| 444 isDeprecated: isDeprecated, | 478 isDeprecated: isDeprecated, |
| 445 isPrivate: Identifier.isPrivateName(name)); | 479 isPrivate: Identifier.isPrivateName(name)); |
| 446 return new protocol.Element( | 480 return new protocol.Element( |
| 447 kind, | 481 kind, |
| 448 name, | 482 name, |
| 449 flags, | 483 flags, |
| 450 parameters: parameters, | 484 parameters: parameters, |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 if (name == null || name.length <= 0) { | 528 if (name == null || name.length <= 0) { |
| 495 return DYNAMIC; | 529 return DYNAMIC; |
| 496 } | 530 } |
| 497 TypeArgumentList typeArgs = type.typeArguments; | 531 TypeArgumentList typeArgs = type.typeArguments; |
| 498 if (typeArgs != null) { | 532 if (typeArgs != null) { |
| 499 //TODO (danrubel) include type arguments | 533 //TODO (danrubel) include type arguments |
| 500 } | 534 } |
| 501 return name; | 535 return name; |
| 502 } | 536 } |
| 503 } | 537 } |
| OLD | NEW |