| 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.contributor.dart.local; | 5 library services.completion.contributor.dart.local; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol | 9 import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol |
| 10 show Element, ElementKind; | 10 show Element, ElementKind; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 // Collect suggestions from the specific child [AstNode] that contains | 34 // Collect suggestions from the specific child [AstNode] that contains |
| 35 // the completion offset and all of its parents recursively. | 35 // the completion offset and all of its parents recursively. |
| 36 if (!optype.isPrefixed) { | 36 if (!optype.isPrefixed) { |
| 37 if (optype.includeReturnValueSuggestions || | 37 if (optype.includeReturnValueSuggestions || |
| 38 optype.includeTypeNameSuggestions || | 38 optype.includeTypeNameSuggestions || |
| 39 optype.includeVoidReturnSuggestions) { | 39 optype.includeVoidReturnSuggestions) { |
| 40 _LocalVisitor localVisitor = | 40 _LocalVisitor localVisitor = |
| 41 new _LocalVisitor(request, request.offset, optype); | 41 new _LocalVisitor(request, request.offset, optype); |
| 42 localVisitor.visit(request.target.containingNode); | 42 localVisitor.visit(request.target.containingNode); |
| 43 } | 43 } |
| 44 if (optype.includeConstructorSuggestions) { | |
| 45 new _ConstructorVisitor(request).visit(request.target.containingNode); | |
| 46 } | |
| 47 } | 44 } |
| 48 | 45 |
| 49 // If target is an argument in an argument list | 46 // If target is an argument in an argument list |
| 50 // then suggestions may need to be adjusted | 47 // then suggestions may need to be adjusted |
| 51 return request.target.argIndex == null; | 48 return request.target.argIndex == null; |
| 52 } | 49 } |
| 53 | 50 |
| 54 @override | 51 @override |
| 55 Future<bool> computeFull(DartCompletionRequest request) { | 52 Future<bool> computeFull(DartCompletionRequest request) { |
| 56 _updateSuggestions(request); | 53 _updateSuggestions(request); |
| 57 return new Future.value(false); | 54 return new Future.value(false); |
| 58 } | 55 } |
| 59 | 56 |
| 60 /** | 57 /** |
| 61 * If target is a function argument, suggest identifiers not invocations | 58 * If target is a function argument, suggest identifiers not invocations |
| 62 */ | 59 */ |
| 63 void _updateSuggestions(DartCompletionRequest request) { | 60 void _updateSuggestions(DartCompletionRequest request) { |
| 64 if (request.target.isFunctionalArgument()) { | 61 if (request.target.isFunctionalArgument()) { |
| 65 request.convertInvocationsToIdentifiers(); | 62 request.convertInvocationsToIdentifiers(); |
| 66 } | 63 } |
| 67 } | 64 } |
| 68 } | 65 } |
| 69 | 66 |
| 70 /** | 67 /** |
| 71 * A visitor for collecting constructor suggestions. | |
| 72 */ | |
| 73 class _ConstructorVisitor extends LocalDeclarationVisitor { | |
| 74 final DartCompletionRequest request; | |
| 75 | |
| 76 _ConstructorVisitor(DartCompletionRequest request) | |
| 77 : super(request.offset), | |
| 78 request = request; | |
| 79 | |
| 80 @override | |
| 81 void declaredClass(ClassDeclaration declaration) { | |
| 82 bool found = false; | |
| 83 for (ClassMember member in declaration.members) { | |
| 84 if (member is ConstructorDeclaration) { | |
| 85 found = true; | |
| 86 _addSuggestion(declaration, member); | |
| 87 } | |
| 88 } | |
| 89 if (!found) { | |
| 90 _addSuggestion(declaration, null); | |
| 91 } | |
| 92 } | |
| 93 | |
| 94 @override | |
| 95 void declaredClassTypeAlias(ClassTypeAlias declaration) {} | |
| 96 | |
| 97 @override | |
| 98 void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {} | |
| 99 | |
| 100 @override | |
| 101 void declaredFunction(FunctionDeclaration declaration) {} | |
| 102 | |
| 103 @override | |
| 104 void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {} | |
| 105 | |
| 106 @override | |
| 107 void declaredLabel(Label label, bool isCaseLabel) {} | |
| 108 | |
| 109 @override | |
| 110 void declaredLocalVar(SimpleIdentifier name, TypeName type) {} | |
| 111 | |
| 112 @override | |
| 113 void declaredMethod(MethodDeclaration declaration) {} | |
| 114 | |
| 115 @override | |
| 116 void declaredParam(SimpleIdentifier name, TypeName type) {} | |
| 117 | |
| 118 @override | |
| 119 void declaredTopLevelVar( | |
| 120 VariableDeclarationList varList, VariableDeclaration varDecl) {} | |
| 121 | |
| 122 /** | |
| 123 * For the given class and constructor, | |
| 124 * add a suggestion of the form B(...) or B.name(...). | |
| 125 * If the given constructor is `null` | |
| 126 * then add a default constructor suggestion. | |
| 127 */ | |
| 128 CompletionSuggestion _addSuggestion( | |
| 129 ClassDeclaration classDecl, ConstructorDeclaration constructorDecl) { | |
| 130 SimpleIdentifier elemId; | |
| 131 String completion = classDecl.name.name; | |
| 132 if (constructorDecl != null) { | |
| 133 elemId = constructorDecl.name; | |
| 134 if (elemId != null) { | |
| 135 String name = elemId.name; | |
| 136 if (name != null && name.length > 0) { | |
| 137 completion = '$completion.$name'; | |
| 138 } | |
| 139 } | |
| 140 } | |
| 141 bool deprecated = constructorDecl != null && isDeprecated(constructorDecl); | |
| 142 List<String> parameterNames = new List<String>(); | |
| 143 List<String> parameterTypes = new List<String>(); | |
| 144 int requiredParameterCount = 0; | |
| 145 bool hasNamedParameters = false; | |
| 146 StringBuffer paramBuf = new StringBuffer(); | |
| 147 paramBuf.write('('); | |
| 148 int paramCount = 0; | |
| 149 if (constructorDecl != null) { | |
| 150 for (FormalParameter param in constructorDecl.parameters.parameters) { | |
| 151 if (paramCount > 0) { | |
| 152 paramBuf.write(', '); | |
| 153 } | |
| 154 String paramName; | |
| 155 String typeName; | |
| 156 if (param is NormalFormalParameter) { | |
| 157 paramName = param.identifier.name; | |
| 158 typeName = _nameForParamType(param); | |
| 159 ++requiredParameterCount; | |
| 160 } else if (param is DefaultFormalParameter) { | |
| 161 NormalFormalParameter childParam = param.parameter; | |
| 162 paramName = childParam.identifier.name; | |
| 163 typeName = _nameForParamType(childParam); | |
| 164 if (param.kind == ParameterKind.NAMED) { | |
| 165 hasNamedParameters = true; | |
| 166 } | |
| 167 if (paramCount == requiredParameterCount) { | |
| 168 paramBuf.write(hasNamedParameters ? '{' : '['); | |
| 169 } | |
| 170 } | |
| 171 parameterNames.add(paramName); | |
| 172 parameterTypes.add(typeName); | |
| 173 paramBuf.write(typeName); | |
| 174 paramBuf.write(' '); | |
| 175 paramBuf.write(paramName); | |
| 176 ++paramCount; | |
| 177 } | |
| 178 } | |
| 179 if (paramCount > requiredParameterCount) { | |
| 180 paramBuf.write(hasNamedParameters ? '}' : ']'); | |
| 181 } | |
| 182 paramBuf.write(')'); | |
| 183 protocol.Element element = createElement( | |
| 184 request.source, protocol.ElementKind.CONSTRUCTOR, elemId, | |
| 185 parameters: paramBuf.toString()); | |
| 186 element.returnType = classDecl.name.name; | |
| 187 CompletionSuggestion suggestion = new CompletionSuggestion( | |
| 188 CompletionSuggestionKind.INVOCATION, | |
| 189 deprecated ? DART_RELEVANCE_LOW : DART_RELEVANCE_DEFAULT, | |
| 190 completion, | |
| 191 completion.length, | |
| 192 0, | |
| 193 deprecated, | |
| 194 false, | |
| 195 declaringType: classDecl.name.name, | |
| 196 element: element, | |
| 197 parameterNames: parameterNames, | |
| 198 parameterTypes: parameterTypes, | |
| 199 requiredParameterCount: requiredParameterCount, | |
| 200 hasNamedParameters: hasNamedParameters); | |
| 201 request.addSuggestion(suggestion); | |
| 202 return suggestion; | |
| 203 } | |
| 204 | |
| 205 /** | |
| 206 * Determine the name of the type for the given constructor parameter. | |
| 207 */ | |
| 208 String _nameForParamType(NormalFormalParameter param) { | |
| 209 if (param is SimpleFormalParameter) { | |
| 210 return nameForType(param.type); | |
| 211 } | |
| 212 SimpleIdentifier id = param.identifier; | |
| 213 if (param is FieldFormalParameter && id != null) { | |
| 214 String fieldName = id.name; | |
| 215 AstNode classDecl = param.getAncestor((p) => p is ClassDeclaration); | |
| 216 if (classDecl is ClassDeclaration) { | |
| 217 for (ClassMember member in classDecl.members) { | |
| 218 if (member is FieldDeclaration) { | |
| 219 for (VariableDeclaration field in member.fields.variables) { | |
| 220 if (field.name.name == fieldName) { | |
| 221 return nameForType(member.fields.type); | |
| 222 } | |
| 223 } | |
| 224 } | |
| 225 } | |
| 226 } | |
| 227 } | |
| 228 return DYNAMIC; | |
| 229 } | |
| 230 } | |
| 231 | |
| 232 /** | |
| 233 * A visitor for collecting suggestions from the most specific child [AstNode] | 68 * A visitor for collecting suggestions from the most specific child [AstNode] |
| 234 * that contains the completion offset to the [CompilationUnit]. | 69 * that contains the completion offset to the [CompilationUnit]. |
| 235 */ | 70 */ |
| 236 class _LocalVisitor extends LocalDeclarationVisitor { | 71 class _LocalVisitor extends LocalDeclarationVisitor { |
| 237 final DartCompletionRequest request; | 72 final DartCompletionRequest request; |
| 238 final OpType optype; | 73 final OpType optype; |
| 239 int privateMemberRelevance = DART_RELEVANCE_DEFAULT; | 74 int privateMemberRelevance = DART_RELEVANCE_DEFAULT; |
| 240 | 75 |
| 241 _LocalVisitor(this.request, int offset, this.optype) : super(offset) { | 76 _LocalVisitor(this.request, int offset, this.optype) : super(offset) { |
| 242 includeLocalInheritedTypes = !optype.inStaticMethodBody; | 77 includeLocalInheritedTypes = !optype.inStaticMethodBody; |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 471 bool _isVoid(TypeName returnType) { | 306 bool _isVoid(TypeName returnType) { |
| 472 if (returnType != null) { | 307 if (returnType != null) { |
| 473 Identifier id = returnType.name; | 308 Identifier id = returnType.name; |
| 474 if (id != null && id.name == 'void') { | 309 if (id != null && id.name == 'void') { |
| 475 return true; | 310 return true; |
| 476 } | 311 } |
| 477 } | 312 } |
| 478 return false; | 313 return false; |
| 479 } | 314 } |
| 480 } | 315 } |
| OLD | NEW |