| // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import 'dart:async'; |
| |
| import 'package:analysis_server/src/protocol_server.dart' |
| show CompletionSuggestion, CompletionSuggestionKind; |
| import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; |
| import 'package:analysis_server/src/services/completion/dart/completion_manager.dart' |
| show DartCompletionRequestImpl; |
| import 'package:analysis_server/src/services/correction/name_suggestion.dart'; |
| import 'package:analyzer/dart/ast/ast.dart'; |
| import 'package:analyzer_plugin/src/utilities/completion/optype.dart'; |
| |
| /** |
| * Given some [String] name "foo", return a [CompletionSuggestion] with the |
| * [String]. |
| * |
| * If the passed [String] is null or empty, null is returned. |
| */ |
| CompletionSuggestion _createNameSuggestion(String name) { |
| if (name == null || name.isEmpty) { |
| return null; |
| } |
| return new CompletionSuggestion(CompletionSuggestionKind.IDENTIFIER, |
| DART_RELEVANCE_DEFAULT, name, name.length, 0, false, false); |
| } |
| |
| /** |
| * Convert some [Identifier] to its [String] name. |
| */ |
| String _getStringName(Identifier id) { |
| if (id == null) { |
| return null; |
| } |
| if (id is SimpleIdentifier) { |
| return id.name; |
| } else if (id is PrefixedIdentifier) { |
| return id.identifier.name; |
| } |
| return id.name; |
| } |
| |
| /** |
| * A contributor for calculating suggestions for variable names. |
| */ |
| class VariableNameContributor extends DartCompletionContributor { |
| @override |
| Future<List<CompletionSuggestion>> computeSuggestions( |
| DartCompletionRequest request) async { |
| // TODO(brianwilkerson) Determine whether this await is necessary. |
| await null; |
| OpType optype = (request as DartCompletionRequestImpl).opType; |
| |
| // Collect suggestions from the specific child [AstNode] that contains |
| // the completion offset and all of its parents recursively. |
| if (optype.includeVarNameSuggestions) { |
| // Resolution not needed for this completion |
| |
| AstNode node = request.target.containingNode; |
| |
| String strName = null; |
| if (node is ExpressionStatement) { |
| if (node.expression is Identifier) { |
| strName = _getStringName(node.expression as Identifier); |
| } |
| } else if (node is VariableDeclarationList) { |
| TypeAnnotation typeAnnotation = node.type; |
| if (typeAnnotation is TypeName) { |
| strName = _getStringName(typeAnnotation.name); |
| } |
| } else if (node is TopLevelVariableDeclaration) { |
| // The parser parses 'Foo ' and 'Foo ;' differently, resulting in the |
| // following. |
| // 'Foo ': handled above |
| // 'Foo ;': TopLevelVariableDeclaration with type null, and a first |
| // variable of 'Foo' |
| VariableDeclarationList varDeclarationList = node.variables; |
| TypeAnnotation typeAnnotation = varDeclarationList.type; |
| if (typeAnnotation != null) { |
| if (typeAnnotation is TypeName) { |
| strName = _getStringName(typeAnnotation.name); |
| } |
| } else { |
| NodeList<VariableDeclaration> varDeclarations = |
| varDeclarationList.variables; |
| if (varDeclarations.length == 1) { |
| VariableDeclaration varDeclaration = varDeclarations.first; |
| strName = _getStringName(varDeclaration.name); |
| } |
| } |
| } |
| if (strName == null) { |
| return const <CompletionSuggestion>[]; |
| } |
| |
| var doIncludePrivateVersion = !optype.inMethodBody && |
| !optype.inFunctionBody && |
| !optype.inConstructorBody; |
| |
| List<String> variableNameSuggestions = getCamelWordCombinations(strName); |
| variableNameSuggestions.remove(strName); |
| List<CompletionSuggestion> suggestions = <CompletionSuggestion>[]; |
| for (String varName in variableNameSuggestions) { |
| CompletionSuggestion suggestion = _createNameSuggestion(varName); |
| if (suggestion != null) { |
| suggestions.add(suggestion); |
| } |
| if (doIncludePrivateVersion) { |
| CompletionSuggestion privateSuggestion = |
| _createNameSuggestion('_' + varName); |
| if (privateSuggestion != null) { |
| suggestions.add(privateSuggestion); |
| } |
| } |
| } |
| return suggestions; |
| } |
| return const <CompletionSuggestion>[]; |
| } |
| } |