| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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.dart.suggestion.builder; | 5 library services.completion.dart.suggestion.builder; |
| 6 | 6 |
| 7 import 'package:analysis_server/src/ide_options.dart'; |
| 7 import 'package:analysis_server/src/protocol_server.dart' as protocol; | 8 import 'package:analysis_server/src/protocol_server.dart' as protocol; |
| 8 import 'package:analysis_server/src/protocol_server.dart' | 9 import 'package:analysis_server/src/protocol_server.dart' |
| 9 hide Element, ElementKind; | 10 hide Element, ElementKind; |
| 10 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.
dart'; | 11 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.
dart'; |
| 11 import 'package:analysis_server/src/services/completion/dart/utilities.dart'; | 12 import 'package:analysis_server/src/services/completion/dart/utilities.dart'; |
| 12 import 'package:analysis_server/src/utilities/documentation.dart'; | 13 import 'package:analysis_server/src/utilities/documentation.dart'; |
| 13 import 'package:analyzer/dart/element/element.dart'; | 14 import 'package:analyzer/dart/element/element.dart'; |
| 14 import 'package:analyzer/dart/element/type.dart'; | 15 import 'package:analyzer/dart/element/type.dart'; |
| 15 import 'package:analyzer/dart/element/visitor.dart'; | 16 import 'package:analyzer/dart/element/visitor.dart'; |
| 16 import 'package:analyzer/src/generated/source.dart'; | 17 import 'package:analyzer/src/generated/source.dart'; |
| 17 import 'package:analyzer/src/generated/utilities_dart.dart'; | 18 import 'package:analyzer/src/generated/utilities_dart.dart'; |
| 18 import 'package:path/path.dart' as path; | 19 import 'package:path/path.dart' as path; |
| 19 | 20 |
| 20 const String DYNAMIC = 'dynamic'; | 21 const String DYNAMIC = 'dynamic'; |
| 21 | 22 |
| 22 /** | 23 /** |
| 23 * Return a suggestion based upon the given element | 24 * Return a suggestion based upon the given element |
| 24 * or `null` if a suggestion is not appropriate for the given element. | 25 * or `null` if a suggestion is not appropriate for the given element. |
| 25 * If the suggestion is not currently in scope, then specify | 26 * If the suggestion is not currently in scope, then specify |
| 26 * importForSource as the source to which an import should be added. | 27 * importForSource as the source to which an import should be added. |
| 27 */ | 28 */ |
| 28 CompletionSuggestion createSuggestion(Element element, | 29 CompletionSuggestion createSuggestion(Element element, IdeOptions options, |
| 29 {String completion, | 30 {String completion, |
| 30 CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION, | 31 CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION, |
| 31 int relevance: DART_RELEVANCE_DEFAULT, | 32 int relevance: DART_RELEVANCE_DEFAULT, |
| 32 Source importForSource}) { | 33 Source importForSource}) { |
| 33 if (element == null) { | 34 if (element == null) { |
| 34 return null; | 35 return null; |
| 35 } | 36 } |
| 36 if (element is ExecutableElement && element.isOperator) { | 37 if (element is ExecutableElement && element.isOperator) { |
| 37 // Do not include operators in suggestions | 38 // Do not include operators in suggestions |
| 38 return null; | 39 return null; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 | 75 |
| 75 Iterable<ParameterElement> requiredParameters = element.parameters.where( | 76 Iterable<ParameterElement> requiredParameters = element.parameters.where( |
| 76 (ParameterElement param) => | 77 (ParameterElement param) => |
| 77 param.parameterKind == ParameterKind.REQUIRED); | 78 param.parameterKind == ParameterKind.REQUIRED); |
| 78 suggestion.requiredParameterCount = requiredParameters.length; | 79 suggestion.requiredParameterCount = requiredParameters.length; |
| 79 | 80 |
| 80 Iterable<ParameterElement> namedParameters = element.parameters.where( | 81 Iterable<ParameterElement> namedParameters = element.parameters.where( |
| 81 (ParameterElement param) => param.parameterKind == ParameterKind.NAMED); | 82 (ParameterElement param) => param.parameterKind == ParameterKind.NAMED); |
| 82 suggestion.hasNamedParameters = namedParameters.isNotEmpty; | 83 suggestion.hasNamedParameters = namedParameters.isNotEmpty; |
| 83 | 84 |
| 84 addDefaultArgDetails(suggestion, requiredParameters, namedParameters); | 85 addDefaultArgDetails( |
| 86 suggestion, element, requiredParameters, namedParameters, options); |
| 85 } | 87 } |
| 86 if (importForSource != null) { | 88 if (importForSource != null) { |
| 87 String srcPath = path.dirname(importForSource.fullName); | 89 String srcPath = path.dirname(importForSource.fullName); |
| 88 LibraryElement libElem = element.library; | 90 LibraryElement libElem = element.library; |
| 89 if (libElem != null) { | 91 if (libElem != null) { |
| 90 Source libSource = libElem.source; | 92 Source libSource = libElem.source; |
| 91 if (libSource != null) { | 93 if (libSource != null) { |
| 92 UriKind uriKind = libSource.uriKind; | 94 UriKind uriKind = libSource.uriKind; |
| 93 if (uriKind == UriKind.DART_URI) { | 95 if (uriKind == UriKind.DART_URI) { |
| 94 suggestion.importUri = libSource.uri.toString(); | 96 suggestion.importUri = libSource.uri.toString(); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 LibraryElement get containingLibrary; | 142 LibraryElement get containingLibrary; |
| 141 | 143 |
| 142 /** | 144 /** |
| 143 * Return the kind of suggestions that should be built. | 145 * Return the kind of suggestions that should be built. |
| 144 */ | 146 */ |
| 145 CompletionSuggestionKind get kind; | 147 CompletionSuggestionKind get kind; |
| 146 | 148 |
| 147 /** | 149 /** |
| 148 * Add a suggestion based upon the given element. | 150 * Add a suggestion based upon the given element. |
| 149 */ | 151 */ |
| 150 void addSuggestion(Element element, | 152 void addSuggestion(Element element, IdeOptions ideOptions, |
| 151 {String prefix, int relevance: DART_RELEVANCE_DEFAULT}) { | 153 {String prefix, int relevance: DART_RELEVANCE_DEFAULT}) { |
| 152 if (element.isPrivate) { | 154 if (element.isPrivate) { |
| 153 if (element.library != containingLibrary) { | 155 if (element.library != containingLibrary) { |
| 154 return; | 156 return; |
| 155 } | 157 } |
| 156 } | 158 } |
| 157 String completion = element.displayName; | 159 String completion = element.displayName; |
| 158 if (prefix != null && prefix.length > 0) { | 160 if (prefix != null && prefix.length > 0) { |
| 159 if (completion == null || completion.length <= 0) { | 161 if (completion == null || completion.length <= 0) { |
| 160 completion = prefix; | 162 completion = prefix; |
| 161 } else { | 163 } else { |
| 162 completion = '$prefix.$completion'; | 164 completion = '$prefix.$completion'; |
| 163 } | 165 } |
| 164 } | 166 } |
| 165 if (completion == null || completion.length <= 0) { | 167 if (completion == null || completion.length <= 0) { |
| 166 return; | 168 return; |
| 167 } | 169 } |
| 168 CompletionSuggestion suggestion = createSuggestion(element, | 170 CompletionSuggestion suggestion = createSuggestion(element, ideOptions, |
| 169 completion: completion, kind: kind, relevance: relevance); | 171 completion: completion, kind: kind, relevance: relevance); |
| 170 if (suggestion != null) { | 172 if (suggestion != null) { |
| 171 if (element.isSynthetic && element is PropertyAccessorElement) { | 173 if (element.isSynthetic && element is PropertyAccessorElement) { |
| 172 String cacheKey; | 174 String cacheKey; |
| 173 if (element.isGetter) { | 175 if (element.isGetter) { |
| 174 cacheKey = element.name; | 176 cacheKey = element.name; |
| 175 } | 177 } |
| 176 if (element.isSetter) { | 178 if (element.isSetter) { |
| 177 cacheKey = element.name; | 179 cacheKey = element.name; |
| 178 cacheKey = cacheKey.substring(0, cacheKey.length - 1); | 180 cacheKey = cacheKey.substring(0, cacheKey.length - 1); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 /** | 215 /** |
| 214 * This class visits elements in a library and provides suggestions based upon | 216 * This class visits elements in a library and provides suggestions based upon |
| 215 * the visible members in that library. | 217 * the visible members in that library. |
| 216 */ | 218 */ |
| 217 class LibraryElementSuggestionBuilder extends GeneralizingElementVisitor | 219 class LibraryElementSuggestionBuilder extends GeneralizingElementVisitor |
| 218 with ElementSuggestionBuilder { | 220 with ElementSuggestionBuilder { |
| 219 final LibraryElement containingLibrary; | 221 final LibraryElement containingLibrary; |
| 220 final CompletionSuggestionKind kind; | 222 final CompletionSuggestionKind kind; |
| 221 final bool typesOnly; | 223 final bool typesOnly; |
| 222 final bool instCreation; | 224 final bool instCreation; |
| 225 final IdeOptions options; |
| 223 | 226 |
| 224 LibraryElementSuggestionBuilder( | 227 LibraryElementSuggestionBuilder(this.containingLibrary, this.kind, |
| 225 this.containingLibrary, this.kind, this.typesOnly, this.instCreation); | 228 this.typesOnly, this.instCreation, this.options); |
| 226 | 229 |
| 227 @override | 230 @override |
| 228 visitClassElement(ClassElement element) { | 231 visitClassElement(ClassElement element) { |
| 229 if (instCreation) { | 232 if (instCreation) { |
| 230 element.visitChildren(this); | 233 element.visitChildren(this); |
| 231 } else { | 234 } else { |
| 232 addSuggestion(element); | 235 addSuggestion(element, options); |
| 233 } | 236 } |
| 234 } | 237 } |
| 235 | 238 |
| 236 @override | 239 @override |
| 237 visitCompilationUnitElement(CompilationUnitElement element) { | 240 visitCompilationUnitElement(CompilationUnitElement element) { |
| 238 element.visitChildren(this); | 241 element.visitChildren(this); |
| 239 LibraryElement containingLibrary = element.library; | 242 LibraryElement containingLibrary = element.library; |
| 240 if (containingLibrary != null) { | 243 if (containingLibrary != null) { |
| 241 for (var lib in containingLibrary.exportedLibraries) { | 244 for (var lib in containingLibrary.exportedLibraries) { |
| 242 lib.visitChildren(this); | 245 lib.visitChildren(this); |
| 243 } | 246 } |
| 244 } | 247 } |
| 245 } | 248 } |
| 246 | 249 |
| 247 @override | 250 @override |
| 248 visitConstructorElement(ConstructorElement element) { | 251 visitConstructorElement(ConstructorElement element) { |
| 249 if (instCreation) { | 252 if (instCreation) { |
| 250 ClassElement classElem = element.enclosingElement; | 253 ClassElement classElem = element.enclosingElement; |
| 251 if (classElem != null) { | 254 if (classElem != null) { |
| 252 String prefix = classElem.name; | 255 String prefix = classElem.name; |
| 253 if (prefix != null && prefix.length > 0) { | 256 if (prefix != null && prefix.length > 0) { |
| 254 addSuggestion(element, prefix: prefix); | 257 addSuggestion(element, options, prefix: prefix); |
| 255 } | 258 } |
| 256 } | 259 } |
| 257 } | 260 } |
| 258 } | 261 } |
| 259 | 262 |
| 260 @override | 263 @override |
| 261 visitElement(Element element) { | 264 visitElement(Element element) { |
| 262 // ignored | 265 // ignored |
| 263 } | 266 } |
| 264 | 267 |
| 265 @override | 268 @override |
| 266 visitFunctionElement(FunctionElement element) { | 269 visitFunctionElement(FunctionElement element) { |
| 267 if (!typesOnly) { | 270 if (!typesOnly) { |
| 268 int relevance = element.library == containingLibrary | 271 int relevance = element.library == containingLibrary |
| 269 ? DART_RELEVANCE_LOCAL_FUNCTION | 272 ? DART_RELEVANCE_LOCAL_FUNCTION |
| 270 : DART_RELEVANCE_DEFAULT; | 273 : DART_RELEVANCE_DEFAULT; |
| 271 addSuggestion(element, relevance: relevance); | 274 addSuggestion(element, options, relevance: relevance); |
| 272 } | 275 } |
| 273 } | 276 } |
| 274 | 277 |
| 275 @override | 278 @override |
| 276 visitFunctionTypeAliasElement(FunctionTypeAliasElement element) { | 279 visitFunctionTypeAliasElement(FunctionTypeAliasElement element) { |
| 277 if (!instCreation) { | 280 if (!instCreation) { |
| 278 addSuggestion(element); | 281 addSuggestion(element, options); |
| 279 } | 282 } |
| 280 } | 283 } |
| 281 | 284 |
| 282 @override | 285 @override |
| 283 visitTopLevelVariableElement(TopLevelVariableElement element) { | 286 visitTopLevelVariableElement(TopLevelVariableElement element) { |
| 284 if (!typesOnly) { | 287 if (!typesOnly) { |
| 285 int relevance = element.library == containingLibrary | 288 int relevance = element.library == containingLibrary |
| 286 ? DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE | 289 ? DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE |
| 287 : DART_RELEVANCE_DEFAULT; | 290 : DART_RELEVANCE_DEFAULT; |
| 288 addSuggestion(element, relevance: relevance); | 291 addSuggestion(element, options, relevance: relevance); |
| 289 } | 292 } |
| 290 } | 293 } |
| 291 } | 294 } |
| OLD | NEW |