| OLD | NEW |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 import 'dart:async'; | 5 import 'dart:async'; |
| 6 import 'dart:collection'; | 6 import 'dart:collection'; |
| 7 | 7 |
| 8 import 'package:analyzer/dart/ast/ast.dart'; | 8 import 'package:analyzer/dart/ast/ast.dart'; |
| 9 import 'package:analyzer/dart/element/element.dart'; | 9 import 'package:analyzer/dart/element/element.dart'; |
| 10 import 'package:analyzer/dart/element/type.dart'; | 10 import 'package:analyzer/dart/element/type.dart'; |
| 11 import 'package:analyzer/file_system/file_system.dart'; | 11 import 'package:analyzer/file_system/file_system.dart'; |
| 12 import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element; | 12 import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element; |
| 13 import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart'
; | 13 import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart'
; |
| 14 import 'package:analyzer_plugin/src/utilities/completion/suggestion_builder.dart
'; | 14 import 'package:analyzer_plugin/src/utilities/completion/suggestion_builder.dart
'; |
| 15 import 'package:analyzer_plugin/src/utilities/visitors/local_declaration_visitor
.dart'; | 15 import 'package:analyzer_plugin/src/utilities/visitors/local_declaration_visitor
.dart'; |
| 16 import 'package:analyzer_plugin/utilities/completion/completion_core.dart'; | 16 import 'package:analyzer_plugin/utilities/completion/completion_core.dart'; |
| 17 import 'package:analyzer_plugin/utilities/completion/relevance.dart'; | 17 import 'package:analyzer_plugin/utilities/completion/relevance.dart'; |
| 18 import 'package:analyzer_plugin/utilities/completion/suggestion_builder.dart'; | 18 import 'package:analyzer_plugin/utilities/completion/suggestion_builder.dart'; |
| 19 | 19 |
| 20 /** | 20 /** |
| 21 * A completion contributor that will generate suggestions for instance | 21 * A completion contributor that will generate suggestions for instance |
| 22 * invocations and accesses. | 22 * invocations and accesses. |
| 23 */ | 23 */ |
| 24 class TypeMemberContributor implements CompletionContributor { | 24 class TypeMemberContributor implements CompletionContributor { |
| 25 /** |
| 26 * Clients should not overload this function. |
| 27 */ |
| 28 Future<Null> computeSuggestionsWithEntryPoint(CompletionRequest request, |
| 29 CompletionCollector collector, AstNode entryPoint) async { |
| 30 LibraryElement containingLibrary = request.result.libraryElement; |
| 31 // Gracefully degrade if the library element is not resolved |
| 32 // e.g. detached part file or source change |
| 33 if (containingLibrary == null) { |
| 34 return; |
| 35 } |
| 36 |
| 37 // Recompute the target since resolution may have changed it |
| 38 Expression expression = _computeDotTarget(request, entryPoint); |
| 39 if (expression == null || expression.isSynthetic) { |
| 40 return; |
| 41 } |
| 42 _computeSuggestions(request, collector, containingLibrary, expression); |
| 43 } |
| 44 |
| 45 /** |
| 46 * Plugin contributors should primarily overload this function. |
| 47 * Should more parameters be needed for autocompletion needs, the |
| 48 * overloaded function should define those parameters and |
| 49 * call on `computeSuggestionsWithEntryPoint`. |
| 50 */ |
| 25 @override | 51 @override |
| 26 Future<Null> computeSuggestions( | 52 Future<Null> computeSuggestions( |
| 27 CompletionRequest request, CompletionCollector collector) async { | 53 CompletionRequest request, CompletionCollector collector) async { |
| 28 LibraryElement containingLibrary = request.result.libraryElement; | 54 LibraryElement containingLibrary = request.result.libraryElement; |
| 29 // Gracefully degrade if the library element is not resolved | 55 // Gracefully degrade if the library element is not resolved |
| 30 // e.g. detached part file or source change | 56 // e.g. detached part file or source change |
| 31 if (containingLibrary == null) { | 57 if (containingLibrary == null) { |
| 32 return; | 58 return; |
| 33 } | 59 } |
| 34 | 60 |
| 35 // Recompute the target since resolution may have changed it | 61 // Recompute the target since resolution may have changed it |
| 36 Expression expression = _computeDotTarget(request); | 62 Expression expression = _computeDotTarget(request, null); |
| 37 if (expression == null || expression.isSynthetic) { | 63 if (expression == null || expression.isSynthetic) { |
| 38 return; | 64 return; |
| 39 } | 65 } |
| 66 _computeSuggestions(request, collector, containingLibrary, expression); |
| 67 } |
| 68 |
| 69 void _computeSuggestions( |
| 70 CompletionRequest request, |
| 71 CompletionCollector collector, |
| 72 LibraryElement containingLibrary, |
| 73 Expression expression) { |
| 40 if (expression is Identifier) { | 74 if (expression is Identifier) { |
| 41 Element element = expression.bestElement; | 75 Element element = expression.bestElement; |
| 42 if (element is ClassElement) { | 76 if (element is ClassElement) { |
| 43 // Suggestions provided by StaticMemberContributor | 77 // Suggestions provided by StaticMemberContributor |
| 44 return; | 78 return; |
| 45 } | 79 } |
| 46 if (element is PrefixElement) { | 80 if (element is PrefixElement) { |
| 47 // Suggestions provided by LibraryMemberContributor | 81 // Suggestions provided by LibraryMemberContributor |
| 48 return; | 82 return; |
| 49 } | 83 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 if (type is InterfaceType) { | 133 if (type is InterfaceType) { |
| 100 _SuggestionBuilder builder = new _SuggestionBuilder( | 134 _SuggestionBuilder builder = new _SuggestionBuilder( |
| 101 request.resourceProvider, collector, containingLibrary); | 135 request.resourceProvider, collector, containingLibrary); |
| 102 builder.buildSuggestions(type, containingMethodName); | 136 builder.buildSuggestions(type, containingMethodName); |
| 103 } | 137 } |
| 104 } | 138 } |
| 105 | 139 |
| 106 /** | 140 /** |
| 107 * Update the completion [target] and [dotTarget] based on the given [unit]. | 141 * Update the completion [target] and [dotTarget] based on the given [unit]. |
| 108 */ | 142 */ |
| 109 Expression _computeDotTarget(CompletionRequest request) { | 143 Expression _computeDotTarget(CompletionRequest request, AstNode entryPoint) { |
| 110 CompletionTarget target = | 144 CompletionTarget target = new CompletionTarget.forOffset( |
| 111 new CompletionTarget.forOffset(request.result.unit, request.offset); | 145 request.result.unit, request.offset, |
| 146 entryPoint: entryPoint); |
| 112 AstNode node = target.containingNode; | 147 AstNode node = target.containingNode; |
| 113 if (node is MethodInvocation) { | 148 if (node is MethodInvocation) { |
| 114 if (identical(node.methodName, target.entity)) { | 149 if (identical(node.methodName, target.entity)) { |
| 115 return node.realTarget; | 150 return node.realTarget; |
| 116 } else if (node.isCascaded && node.operator.offset + 1 == target.offset) { | 151 } else if (node.isCascaded && node.operator.offset + 1 == target.offset) { |
| 117 return node.realTarget; | 152 return node.realTarget; |
| 118 } | 153 } |
| 119 } | 154 } |
| 120 if (node is PropertyAccess) { | 155 if (node is PropertyAccess) { |
| 121 if (identical(node.propertyName, target.entity)) { | 156 if (identical(node.propertyName, target.entity)) { |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 // in the reverse order. | 489 // in the reverse order. |
| 455 typesToVisit.addAll(nextType.interfaces); | 490 typesToVisit.addAll(nextType.interfaces); |
| 456 if (nextType.superclass != null) { | 491 if (nextType.superclass != null) { |
| 457 typesToVisit.add(nextType.superclass); | 492 typesToVisit.add(nextType.superclass); |
| 458 } | 493 } |
| 459 typesToVisit.addAll(nextType.mixins); | 494 typesToVisit.addAll(nextType.mixins); |
| 460 } | 495 } |
| 461 return result; | 496 return result; |
| 462 } | 497 } |
| 463 } | 498 } |
| OLD | NEW |