| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 library services.completion.computer.dart.invocation; | |
| 6 | |
| 7 import 'dart:async'; | |
| 8 | |
| 9 import 'package:analysis_services/completion/completion_suggestion.dart'; | |
| 10 import 'package:analysis_services/src/completion/dart_completion_manager.dart'; | |
| 11 import 'package:analyzer/src/generated/ast.dart'; | |
| 12 import 'package:analyzer/src/generated/element.dart'; | |
| 13 | |
| 14 /** | |
| 15 * A computer for calculating invocation / access suggestions | |
| 16 * `completion.getSuggestions` request results. | |
| 17 */ | |
| 18 class InvocationComputer extends DartCompletionComputer { | |
| 19 | |
| 20 @override | |
| 21 bool computeFast(DartCompletionRequest request) { | |
| 22 // TODO: implement computeFast | |
| 23 return false; | |
| 24 } | |
| 25 | |
| 26 @override | |
| 27 Future<bool> computeFull(DartCompletionRequest request) { | |
| 28 return request.node.accept(new _InvocationAstVisitor(request)); | |
| 29 } | |
| 30 } | |
| 31 | |
| 32 /** | |
| 33 * An [AstNode] vistor for determining the appropriate invocation/access | |
| 34 * suggestions based upon the node in which the completion is requested. | |
| 35 */ | |
| 36 class _InvocationAstVisitor extends GeneralizingAstVisitor<Future<bool>> { | |
| 37 final DartCompletionRequest request; | |
| 38 AstNode completionNode; | |
| 39 | |
| 40 _InvocationAstVisitor(this.request); | |
| 41 | |
| 42 @override | |
| 43 Future<bool> visitNode(AstNode node) { | |
| 44 return new Future.value(false); | |
| 45 } | |
| 46 | |
| 47 @override | |
| 48 Future<bool> visitPrefixedIdentifier(PrefixedIdentifier node) { | |
| 49 if (node.identifier == completionNode) { | |
| 50 return _addSuggestions(node.prefix.bestElement); | |
| 51 } | |
| 52 return super.visitPrefixedIdentifier(node); | |
| 53 } | |
| 54 | |
| 55 @override | |
| 56 Future<bool> visitSimpleIdentifier(SimpleIdentifier node) { | |
| 57 completionNode = node; | |
| 58 return node.parent.accept(this); | |
| 59 } | |
| 60 | |
| 61 /** | |
| 62 * Add invocation / access suggestions for the given element. | |
| 63 */ | |
| 64 Future<bool> _addSuggestions(Element element) { | |
| 65 if (element != null) { | |
| 66 return element.accept(new _InvocationElementVisitor(request)); | |
| 67 } | |
| 68 return new Future.value(false); | |
| 69 } | |
| 70 } | |
| 71 | |
| 72 /** | |
| 73 * An [Element] visitor for determining the appropriate invocation/access | |
| 74 * suggestions based upon the element for which the completion is requested. | |
| 75 */ | |
| 76 class _InvocationElementVisitor extends GeneralizingElementVisitor<Future<bool>> | |
| 77 { | |
| 78 final DartCompletionRequest request; | |
| 79 | |
| 80 _InvocationElementVisitor(this.request); | |
| 81 | |
| 82 @override | |
| 83 Future<bool> visitElement(Element element) { | |
| 84 return new Future.value(false); | |
| 85 } | |
| 86 | |
| 87 @override | |
| 88 Future<bool> visitVariableElement(VariableElement element) { | |
| 89 return _addSuggestions(element.type); | |
| 90 } | |
| 91 | |
| 92 Future<bool> _addSuggestions(DartType type) { | |
| 93 if (type != null && type.element != null) { | |
| 94 type.element.accept(new _SuggestionBuilderVisitor(request)); | |
| 95 return new Future.value(true); | |
| 96 } | |
| 97 return new Future.value(false); | |
| 98 } | |
| 99 } | |
| 100 | |
| 101 /** | |
| 102 * An [Element] visitor that builds suggestions by recursively visiting | |
| 103 * elements in a type hierarchy. | |
| 104 */ | |
| 105 class _SuggestionBuilderVisitor extends GeneralizingElementVisitor { | |
| 106 final DartCompletionRequest request; | |
| 107 | |
| 108 _SuggestionBuilderVisitor(this.request); | |
| 109 | |
| 110 @override | |
| 111 visitClassElement(ClassElement element) { | |
| 112 //TODO (danrubel): filter private members if not in the same library | |
| 113 element.visitChildren(this); | |
| 114 } | |
| 115 | |
| 116 @override | |
| 117 visitElement(Element element) { | |
| 118 // ignored | |
| 119 } | |
| 120 | |
| 121 @override | |
| 122 visitFieldElement(FieldElement element) { | |
| 123 if (!element.isSynthetic) { | |
| 124 _addSuggestion(element, CompletionSuggestionKind.FIELD); | |
| 125 } | |
| 126 } | |
| 127 | |
| 128 @override | |
| 129 visitMethodElement(MethodElement element) { | |
| 130 if (!element.isSynthetic) { | |
| 131 _addSuggestion(element, CompletionSuggestionKind.METHOD); | |
| 132 } | |
| 133 } | |
| 134 | |
| 135 @override | |
| 136 visitPropertyAccessorElement(PropertyAccessorElement element) { | |
| 137 if (!element.isSynthetic) { | |
| 138 if (element.isGetter) { | |
| 139 _addSuggestion(element, CompletionSuggestionKind.GETTER); | |
| 140 } else if (element.isSetter) { | |
| 141 _addSuggestion( | |
| 142 element, | |
| 143 CompletionSuggestionKind.SETTER, | |
| 144 element.displayName); | |
| 145 } | |
| 146 } | |
| 147 } | |
| 148 | |
| 149 void _addSuggestion(Element element, CompletionSuggestionKind kind, | |
| 150 [String completion = null]) { | |
| 151 if (completion == null) { | |
| 152 completion = element.name; | |
| 153 } | |
| 154 if (completion != null && completion.length > 0) { | |
| 155 request.suggestions.add( | |
| 156 new CompletionSuggestion( | |
| 157 kind, | |
| 158 CompletionRelevance.DEFAULT, | |
| 159 completion, | |
| 160 completion.length, | |
| 161 0, | |
| 162 element.isDeprecated, | |
| 163 false)); | |
| 164 } | |
| 165 } | |
| 166 } | |
| OLD | NEW |