Chromium Code Reviews| 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.dart' as protocol show Element, Ele mentKind; | 7 import 'package:analysis_server/src/protocol.dart' as protocol show Element, |
| 8 ElementKind; | |
| 8 import 'package:analysis_server/src/protocol.dart' hide Element, ElementKind; | 9 import 'package:analysis_server/src/protocol.dart' hide Element, 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 = new protocol.Element.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 = | |
| 202 element.getAncestor((parent) => parent is LibraryElement); | |
|
scheglov
2014/10/06 21:36:14
element.library
danrubel
2014/10/07 12:42:01
Good suggestion. Done.
| |
| 203 LibraryElement unitLibrary = | |
| 204 request.unit.element.getAncestor((parent) => parent is LibraryElement) ; | |
| 205 if (elementLibrary != unitLibrary) { | |
| 206 return; | |
| 207 } | |
| 208 } | |
| 209 String completion = element.displayName; | |
| 210 if (completion == null || | |
| 211 completion.length <= 0 || | |
| 212 !_completions.add(completion)) { | |
| 213 return; | |
| 214 } | |
| 215 CompletionSuggestion suggestion = new CompletionSuggestion( | |
| 216 kind, | |
| 217 CompletionRelevance.DEFAULT, | |
| 218 completion, | |
| 219 completion.length, | |
| 220 0, | |
| 221 element.isDeprecated, | |
| 222 false); | |
| 223 suggestion.element = new protocol.Element.fromEngine(element); | |
| 224 if (suggestion.element != null) { | |
| 225 if (element is FieldElement) { | |
| 226 suggestion.element.kind = protocol.ElementKind.GETTER; | |
| 227 suggestion.element.returnType = | |
| 228 element.type != null ? element.type.displayName : 'dynamic'; | |
| 229 } | |
| 230 } | |
| 231 if (enclosingElement != null) { | |
| 232 suggestion.declaringType = enclosingElement.displayName; | |
| 233 } | |
| 234 if (type != null) { | |
| 235 String typeName = type.displayName; | |
| 236 if (typeName != null && typeName.length > 0 && typeName != 'dynamic') { | |
| 237 suggestion.returnType = typeName; | |
| 238 } | |
| 239 } | |
| 240 request.suggestions.add(suggestion); | |
| 241 } | |
| 242 } | |
| OLD | NEW |