| 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.suggestion.builder; | 5 library services.completion.suggestion.builder; |
| 6 | 6 |
| 7 import 'package:analysis_server/src/protocol_server.dart' as protocol; | 7 import 'package:analysis_server/src/protocol_server.dart' as protocol; |
| 8 import 'package:analysis_server/src/protocol_server.dart' hide Element, ElementK
ind; | 8 import 'package:analysis_server/src/protocol_server.dart' hide Element, |
| 9 ElementKind; |
| 9 import 'package:analysis_server/src/services/completion/dart_completion_manager.
dart'; | 10 import 'package:analysis_server/src/services/completion/dart_completion_manager.
dart'; |
| 10 import 'package:analyzer/src/generated/element.dart'; | 11 import 'package:analyzer/src/generated/element.dart'; |
| 11 | 12 |
| 12 /** | 13 /** |
| 13 * This class visits elements in a class and provides suggestions based upon | 14 * This class visits elements in a class and provides suggestions based upon |
| 14 * the visible members in that class. Clients should call | 15 * the visible members in that class. Clients should call |
| 15 * [ClassElementSuggestionBuilder.suggestionsFor]. | 16 * [ClassElementSuggestionBuilder.suggestionsFor]. |
| 16 */ | 17 */ |
| 17 class ClassElementSuggestionBuilder extends GeneralizingElementVisitor { | 18 class ClassElementSuggestionBuilder extends _AbstractSuggestionBuilder { |
| 18 final DartCompletionRequest request; | |
| 19 final Set<String> _completions = new Set<String>(); | |
| 20 | 19 |
| 21 ClassElementSuggestionBuilder(this.request); | 20 ClassElementSuggestionBuilder(DartCompletionRequest request) : super(request); |
| 22 | 21 |
| 23 @override | 22 @override |
| 24 visitClassElement(ClassElement element) { | 23 visitClassElement(ClassElement element) { |
| 25 element.visitChildren(this); | 24 element.visitChildren(this); |
| 26 element.allSupertypes.forEach((InterfaceType type) { | 25 element.allSupertypes.forEach((InterfaceType type) { |
| 27 type.element.visitChildren(this); | 26 type.element.visitChildren(this); |
| 28 }); | 27 }); |
| 29 } | 28 } |
| 30 | 29 |
| 31 @override | 30 @override |
| 32 visitElement(Element element) { | 31 visitElement(Element element) { |
| 33 // ignored | 32 // ignored |
| 34 } | 33 } |
| 35 | 34 |
| 36 @override | 35 @override |
| 37 visitFieldElement(FieldElement element) { | 36 visitFieldElement(FieldElement element) { |
| 38 _addSuggestion( | 37 _addElementSuggestion( |
| 39 element, | 38 element, |
| 40 CompletionSuggestionKind.GETTER, | 39 CompletionSuggestionKind.GETTER, |
| 41 element.type, | 40 element.type, |
| 42 element.enclosingElement); | 41 element.enclosingElement); |
| 43 } | 42 } |
| 44 | 43 |
| 45 @override | 44 @override |
| 46 visitMethodElement(MethodElement element) { | 45 visitMethodElement(MethodElement element) { |
| 47 _addSuggestion( | 46 _addElementSuggestion( |
| 48 element, | 47 element, |
| 49 CompletionSuggestionKind.METHOD, | 48 CompletionSuggestionKind.METHOD, |
| 50 element.returnType, | 49 element.returnType, |
| 51 element.enclosingElement); | 50 element.enclosingElement); |
| 52 } | 51 } |
| 53 | 52 |
| 54 @override | 53 @override |
| 55 visitPropertyAccessorElement(PropertyAccessorElement element) { | 54 visitPropertyAccessorElement(PropertyAccessorElement element) { |
| 56 if (element.isGetter) { | 55 if (element.isGetter) { |
| 57 _addSuggestion( | 56 _addElementSuggestion( |
| 58 element, | 57 element, |
| 59 CompletionSuggestionKind.GETTER, | 58 CompletionSuggestionKind.GETTER, |
| 60 element.returnType, | 59 element.returnType, |
| 61 element.enclosingElement); | 60 element.enclosingElement); |
| 62 } else if (element.isSetter) { | 61 } else if (element.isSetter) { |
| 63 _addSuggestion( | 62 _addElementSuggestion( |
| 64 element, | 63 element, |
| 65 CompletionSuggestionKind.SETTER, | 64 CompletionSuggestionKind.SETTER, |
| 66 element.returnType, | 65 element.returnType, |
| 67 element.enclosingElement); | 66 element.enclosingElement); |
| 68 } | 67 } |
| 69 } | 68 } |
| 70 | 69 |
| 71 void _addSuggestion(Element element, CompletionSuggestionKind kind, | |
| 72 DartType type, ClassElement enclosingElement) { | |
| 73 if (element.isSynthetic) { | |
| 74 return; | |
| 75 } | |
| 76 if (element.isPrivate) { | |
| 77 LibraryElement elementLibrary = | |
| 78 element.getAncestor((parent) => parent is LibraryElement); | |
| 79 LibraryElement unitLibrary = | |
| 80 request.unit.element.getAncestor((parent) => parent is LibraryElement)
; | |
| 81 if (elementLibrary != unitLibrary) { | |
| 82 return; | |
| 83 } | |
| 84 } | |
| 85 String completion = element.displayName; | |
| 86 if (completion == null || | |
| 87 completion.length <= 0 || | |
| 88 !_completions.add(completion)) { | |
| 89 return; | |
| 90 } | |
| 91 CompletionSuggestion suggestion = new CompletionSuggestion( | |
| 92 kind, | |
| 93 CompletionRelevance.DEFAULT, | |
| 94 completion, | |
| 95 completion.length, | |
| 96 0, | |
| 97 element.isDeprecated, | |
| 98 false); | |
| 99 suggestion.element = newElement_fromEngine(element); | |
| 100 if (suggestion.element != null) { | |
| 101 if (element is FieldElement) { | |
| 102 suggestion.element.kind = protocol.ElementKind.GETTER; | |
| 103 suggestion.element.returnType = | |
| 104 element.type != null ? element.type.displayName : 'dynamic'; | |
| 105 } | |
| 106 } | |
| 107 if (enclosingElement != null) { | |
| 108 suggestion.declaringType = enclosingElement.displayName; | |
| 109 } | |
| 110 if (type != null) { | |
| 111 String typeName = type.displayName; | |
| 112 if (typeName != null && typeName.length > 0 && typeName != 'dynamic') { | |
| 113 suggestion.returnType = typeName; | |
| 114 } | |
| 115 } | |
| 116 request.suggestions.add(suggestion); | |
| 117 } | |
| 118 | |
| 119 /** | 70 /** |
| 120 * Add suggestions for the visible members in the given class | 71 * Add suggestions for the visible members in the given class |
| 121 */ | 72 */ |
| 122 static void suggestionsFor(DartCompletionRequest request, Element element) { | 73 static void suggestionsFor(DartCompletionRequest request, Element element) { |
| 123 if (element is ClassElement) { | 74 if (element is ClassElement) { |
| 124 element.accept(new ClassElementSuggestionBuilder(request)); | 75 return element.accept(new ClassElementSuggestionBuilder(request)); |
| 125 } | 76 } |
| 126 } | 77 } |
| 127 } | 78 } |
| 128 | 79 |
| 129 /** | 80 /** |
| 130 * This class visits elements in a library and provides suggestions based upon | 81 * This class visits elements in a library and provides suggestions based upon |
| 131 * the visible members in that library. Clients should call | 82 * the visible members in that library. Clients should call |
| 132 * [LibraryElementSuggestionBuilder.suggestionsFor]. | 83 * [LibraryElementSuggestionBuilder.suggestionsFor]. |
| 133 */ | 84 */ |
| 134 class LibraryElementSuggestionBuilder extends GeneralizingElementVisitor { | 85 class LibraryElementSuggestionBuilder extends GeneralizingElementVisitor { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 /** | 136 /** |
| 186 * Add suggestions for the visible members in the given library | 137 * Add suggestions for the visible members in the given library |
| 187 */ | 138 */ |
| 188 static void suggestionsFor(DartCompletionRequest request, | 139 static void suggestionsFor(DartCompletionRequest request, |
| 189 LibraryElement library) { | 140 LibraryElement library) { |
| 190 if (library != null) { | 141 if (library != null) { |
| 191 library.visitChildren(new LibraryElementSuggestionBuilder(request)); | 142 library.visitChildren(new LibraryElementSuggestionBuilder(request)); |
| 192 } | 143 } |
| 193 } | 144 } |
| 194 } | 145 } |
| 146 |
| 147 /** |
| 148 * This class visits elements in a class and provides suggestions based upon |
| 149 * the visible named constructors in that class. Clients should call |
| 150 * [NamedConstructorSuggestionBuilder.suggestionsFor]. |
| 151 */ |
| 152 class NamedConstructorSuggestionBuilder extends _AbstractSuggestionBuilder { |
| 153 |
| 154 NamedConstructorSuggestionBuilder(DartCompletionRequest request) |
| 155 : super(request); |
| 156 |
| 157 @override |
| 158 visitClassElement(ClassElement element) { |
| 159 element.visitChildren(this); |
| 160 } |
| 161 |
| 162 @override |
| 163 visitConstructorElement(ConstructorElement element) { |
| 164 _addElementSuggestion( |
| 165 element, |
| 166 CompletionSuggestionKind.CONSTRUCTOR, |
| 167 element.returnType, |
| 168 element.enclosingElement); |
| 169 } |
| 170 |
| 171 @override |
| 172 visitElement(Element element) { |
| 173 // ignored |
| 174 } |
| 175 |
| 176 /** |
| 177 * Add suggestions for the visible members in the given class |
| 178 */ |
| 179 static void suggestionsFor(DartCompletionRequest request, Element element) { |
| 180 if (element is ClassElement) { |
| 181 element.accept(new NamedConstructorSuggestionBuilder(request)); |
| 182 } |
| 183 } |
| 184 } |
| 185 |
| 186 /** |
| 187 * Common superclass for sharing behavior |
| 188 */ |
| 189 class _AbstractSuggestionBuilder extends GeneralizingElementVisitor { |
| 190 final DartCompletionRequest request; |
| 191 final Set<String> _completions = new Set<String>(); |
| 192 |
| 193 _AbstractSuggestionBuilder(this.request); |
| 194 |
| 195 void _addElementSuggestion(Element element, CompletionSuggestionKind kind, |
| 196 DartType type, ClassElement enclosingElement) { |
| 197 if (element.isSynthetic) { |
| 198 return; |
| 199 } |
| 200 if (element.isPrivate) { |
| 201 LibraryElement elementLibrary = element.library; |
| 202 LibraryElement unitLibrary = request.unit.element.library; |
| 203 if (elementLibrary != unitLibrary) { |
| 204 return; |
| 205 } |
| 206 } |
| 207 String completion = element.displayName; |
| 208 if (completion == null || |
| 209 completion.length <= 0 || |
| 210 !_completions.add(completion)) { |
| 211 return; |
| 212 } |
| 213 CompletionSuggestion suggestion = new CompletionSuggestion( |
| 214 kind, |
| 215 CompletionRelevance.DEFAULT, |
| 216 completion, |
| 217 completion.length, |
| 218 0, |
| 219 element.isDeprecated, |
| 220 false); |
| 221 suggestion.element = protocol.newElement_fromEngine(element); |
| 222 if (suggestion.element != null) { |
| 223 if (element is FieldElement) { |
| 224 suggestion.element.kind = protocol.ElementKind.GETTER; |
| 225 suggestion.element.returnType = |
| 226 element.type != null ? element.type.displayName : 'dynamic'; |
| 227 } |
| 228 } |
| 229 if (enclosingElement != null) { |
| 230 suggestion.declaringType = enclosingElement.displayName; |
| 231 } |
| 232 if (type != null) { |
| 233 String typeName = type.displayName; |
| 234 if (typeName != null && typeName.length > 0 && typeName != 'dynamic') { |
| 235 suggestion.returnType = typeName; |
| 236 } |
| 237 } |
| 238 request.suggestions.add(suggestion); |
| 239 } |
| 240 } |
| OLD | NEW |