| 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.invocation; | 5 library services.completion.dart.invocation; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:analysis_server/src/protocol_server.dart' | 9 import 'package:analysis_server/src/protocol_server.dart' |
| 10 show CompletionSuggestion, CompletionSuggestionKind, SourceChange; | 10 show CompletionSuggestion, CompletionSuggestionKind, SourceChange; |
| 11 import 'package:analysis_server/src/protocol_server.dart' as protocol | 11 import 'package:analysis_server/src/protocol_server.dart' as protocol |
| 12 hide CompletionSuggestion, CompletionSuggestionKind; | 12 hide CompletionSuggestion, CompletionSuggestionKind; |
| 13 import 'package:analysis_server/src/provisional/completion/completion_core.dart'
; | 13 import 'package:analysis_server/src/provisional/completion/completion_core.dart'
; |
| 14 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.
dart'; | 14 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.
dart'; |
| 15 import 'package:analysis_server/src/provisional/completion/dart/completion_targe
t.dart'; | 15 import 'package:analysis_server/src/provisional/completion/dart/completion_targe
t.dart'; |
| 16 import 'package:analyzer/src/generated/ast.dart'; | 16 import 'package:analyzer/src/generated/ast.dart'; |
| 17 import 'package:analyzer/src/generated/element.dart'; | 17 import 'package:analyzer/src/generated/element.dart'; |
| 18 import 'package:analyzer/src/generated/resolver.dart'; | 18 import 'package:analyzer/src/generated/resolver.dart'; |
| 19 import 'package:analyzer/src/generated/source.dart'; | 19 import 'package:analyzer/src/generated/source.dart'; |
| 20 | 20 |
| 21 /** | 21 /** |
| 22 * A completion contributor used to suggest replacing partial identifiers inside | 22 * A completion contributor used to suggest replacing partial identifiers inside |
| 23 * a class declaration with templates for inherited members. | 23 * a class declaration with templates for inherited members. |
| 24 */ | 24 */ |
| 25 class InheritedContributor implements DartCompletionContributor { | 25 class InheritedContributor implements DartCompletionContributor { |
| 26 @override | 26 @override |
| 27 Future<List<CompletionSuggestion>> computeSuggestions( | 27 Future<List<CompletionSuggestion>> computeSuggestions( |
| 28 DartCompletionRequest request) async { | 28 DartCompletionRequest request) async { |
| 29 // Determine if the target looks like a partial identifier | |
| 30 // inside a class declaration | |
| 31 SimpleIdentifier targetId = _getTargetId(request.target); | 29 SimpleIdentifier targetId = _getTargetId(request.target); |
| 32 if (targetId == null) { | 30 if (targetId == null) { |
| 33 return EMPTY_LIST; | 31 return EMPTY_LIST; |
| 34 } | 32 } |
| 35 | |
| 36 // Partially resolve the compilation unit | |
| 37 CompilationUnit unit = await request.resolveDeclarationsInScope(); | |
| 38 // Gracefully degrade if the compilation unit could not be resolved | |
| 39 // e.g. detached part file or source change | |
| 40 if (unit == null) { | |
| 41 return EMPTY_LIST; | |
| 42 } | |
| 43 | |
| 44 // Recompute the target since resolution may have changed it | |
| 45 targetId = _getTargetId(request.target); | |
| 46 if (targetId == null) { | |
| 47 return EMPTY_LIST; | |
| 48 } | |
| 49 ClassDeclaration classDecl = | 33 ClassDeclaration classDecl = |
| 50 targetId.getAncestor((p) => p is ClassDeclaration); | 34 targetId.getAncestor((p) => p is ClassDeclaration); |
| 51 if (classDecl == null) { | 35 if (classDecl == null) { |
| 52 return EMPTY_LIST; | 36 return EMPTY_LIST; |
| 53 } | 37 } |
| 54 | 38 |
| 55 // Generate a collection of inherited members | 39 // Generate a collection of inherited members |
| 56 ClassElement classElem = classDecl.element; | 40 ClassElement classElem = classDecl.element; |
| 57 InheritanceManager manager = new InheritanceManager(classElem.library); | 41 InheritanceManager manager = new InheritanceManager(classElem.library); |
| 58 MemberMap map = manager.getMapOfMembersInheritedFromInterfaces(classElem); | 42 MemberMap map = manager.getMapOfMembersInheritedFromInterfaces(classElem); |
| 59 List<String> memberNames = _computeMemberNames(map, classElem); | 43 List<String> memberNames = _computeMemberNames(map, classElem); |
| 60 | 44 |
| 61 // Build suggestions | 45 // Build suggestions |
| 62 List<CompletionSuggestion> suggestions = <CompletionSuggestion>[]; | 46 List<CompletionSuggestion> suggestions = <CompletionSuggestion>[]; |
| 63 for (String memberName in memberNames) { | 47 for (String memberName in memberNames) { |
| 64 ExecutableElement element = map.get(memberName); | 48 ExecutableElement element = map.get(memberName); |
| 65 // Gracefully degrade if the overridden element has not been resolved. | 49 // Gracefully degrade if the overridden element has not been resolved. |
| 66 if (element.returnType != null) { | 50 if (element.returnType != null) { |
| 67 CompletionSuggestion suggestion = | 51 CompletionSuggestion suggestion = |
| 68 _buildSuggestion(request, targetId, unit, element); | 52 _buildSuggestion(request, targetId, element); |
| 69 if (suggestion != null) { | 53 if (suggestion != null) { |
| 70 suggestions.add(suggestion); | 54 suggestions.add(suggestion); |
| 71 } | 55 } |
| 72 } | 56 } |
| 73 } | 57 } |
| 74 return suggestions; | 58 return suggestions; |
| 75 } | 59 } |
| 76 | 60 |
| 77 /** | 61 /** |
| 78 * If the target looks like a partial identifier inside a class declaration | 62 * If the target looks like a partial identifier inside a class declaration |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 // }); | 96 // }); |
| 113 // }); | 97 // }); |
| 114 // return builder.sourceChange.edits[0].edits[0].replacement.trim(); | 98 // return builder.sourceChange.edits[0].edits[0].replacement.trim(); |
| 115 return ''; | 99 return ''; |
| 116 } | 100 } |
| 117 | 101 |
| 118 /** | 102 /** |
| 119 * Build a suggestion to replace [targetId] in the given [unit] | 103 * Build a suggestion to replace [targetId] in the given [unit] |
| 120 * with an override of the given [element]. | 104 * with an override of the given [element]. |
| 121 */ | 105 */ |
| 122 CompletionSuggestion _buildSuggestion( | 106 CompletionSuggestion _buildSuggestion(DartCompletionRequest request, |
| 123 DartCompletionRequest request, | 107 SimpleIdentifier targetId, ExecutableElement element) { |
| 124 SimpleIdentifier targetId, | 108 String completion = _buildRepacementText( |
| 125 CompilationUnit unit, | 109 request.source, targetId, request.target.unit, element); |
| 126 ExecutableElement element) { | |
| 127 String completion = | |
| 128 _buildRepacementText(request.source, targetId, unit, element); | |
| 129 if (completion == null || completion.length == 0) { | 110 if (completion == null || completion.length == 0) { |
| 130 return null; | 111 return null; |
| 131 } | 112 } |
| 132 CompletionSuggestion suggestion = new CompletionSuggestion( | 113 CompletionSuggestion suggestion = new CompletionSuggestion( |
| 133 CompletionSuggestionKind.IDENTIFIER, | 114 CompletionSuggestionKind.IDENTIFIER, |
| 134 DART_RELEVANCE_HIGH, | 115 DART_RELEVANCE_HIGH, |
| 135 completion, | 116 completion, |
| 136 targetId.offset, | 117 targetId.offset, |
| 137 0, | 118 0, |
| 138 element.isDeprecated, | 119 element.isDeprecated, |
| (...skipping 23 matching lines...) Expand all Loading... |
| 162 * Return `true` if the given [classElement] directly declares a member with | 143 * Return `true` if the given [classElement] directly declares a member with |
| 163 * the given [memberName]. | 144 * the given [memberName]. |
| 164 */ | 145 */ |
| 165 bool _hasMember(ClassElement classElement, String memberName) { | 146 bool _hasMember(ClassElement classElement, String memberName) { |
| 166 return classElement.getField(memberName) != null || | 147 return classElement.getField(memberName) != null || |
| 167 classElement.getGetter(memberName) != null || | 148 classElement.getGetter(memberName) != null || |
| 168 classElement.getMethod(memberName) != null || | 149 classElement.getMethod(memberName) != null || |
| 169 classElement.getSetter(memberName) != null; | 150 classElement.getSetter(memberName) != null; |
| 170 } | 151 } |
| 171 } | 152 } |
| OLD | NEW |