Index: pkg/analysis_server/test/services/completion/invocation_computer_test.dart |
diff --git a/pkg/analysis_server/test/services/completion/invocation_computer_test.dart b/pkg/analysis_server/test/services/completion/invocation_computer_test.dart |
index 2dd068bfe0582f07ed8b04f5123a59fff56ae637..ddfb327cb259951bbd9b5c5f8198659368cc491c 100644 |
--- a/pkg/analysis_server/test/services/completion/invocation_computer_test.dart |
+++ b/pkg/analysis_server/test/services/completion/invocation_computer_test.dart |
@@ -5,6 +5,8 @@ |
library test.services.completion.invocation; |
+import 'dart:async'; |
+ |
import 'package:analysis_server/src/protocol.dart'; |
import 'package:analysis_server/src/services/completion/dart_completion_manager.dart'; |
import 'package:analysis_server/src/services/completion/invocation_computer.dart'; |
@@ -31,11 +33,105 @@ class InvocationComputerTest extends AbstractSelectorSuggestionTest { |
isDeprecated: isDeprecated); |
} |
+ /** |
+ * Check whether a declaration of the form [shadower] in a derived class |
+ * shadows a declaration of the form [shadowee] in a base class, for the |
+ * purposes of what is shown during completion. [shouldBeShadowed] indicates |
+ * whether shadowing is expected. |
+ */ |
+ Future check_shadowing(String shadower, String shadowee, |
+ bool shouldBeShadowed) { |
+ addTestSource(''' |
+class Base { |
+ $shadowee |
+} |
+class Derived extends Base { |
+ $shadower |
+} |
+void f(Derived d) { |
+ d.^ |
+} |
+'''); |
+ return computeFull((bool result) { |
+ List<CompletionSuggestion> suggestionsForX = request.suggestions.where( |
+ (CompletionSuggestion s) => s.completion == 'x').toList(); |
+ if (shouldBeShadowed) { |
+ expect(suggestionsForX, hasLength(1)); |
+ expect(suggestionsForX[0].declaringType, 'Derived'); |
+ } else { |
+ expect(suggestionsForX, hasLength(2)); |
+ } |
+ }); |
+ } |
+ |
@override |
void setUpComputer() { |
computer = new InvocationComputer(); |
} |
+ test_generic_field() { |
+ addTestSource(''' |
+class C<T> { |
+ T t; |
+} |
+void f(C<int> c) { |
+ c.^ |
+} |
+'''); |
+ return computeFull((bool result) { |
+ assertSuggestField('t', 'int'); |
+ }); |
+ } |
+ |
+ test_generic_getter() { |
+ addTestSource(''' |
+class C<T> { |
+ T get t => null; |
+} |
+void f(C<int> c) { |
+ c.^ |
+} |
+'''); |
+ return computeFull((bool result) { |
+ assertSuggestGetter('t', 'int'); |
+ }); |
+ } |
+ |
+ test_generic_method() { |
+ addTestSource(''' |
+class C<T> { |
+ T m(T t) {} |
+} |
+void f(C<int> c) { |
+ c.^ |
+} |
+'''); |
+ return computeFull((bool result) { |
+ CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'int'); |
+ expect(suggestion.parameterTypes[0], 'int'); |
+ expect(suggestion.element.returnType, 'int'); |
+ expect(suggestion.element.parameters, '(int t)'); |
+ }); |
+ } |
+ |
+ test_generic_setter() { |
+ addTestSource(''' |
+class C<T> { |
+ set t(T value) {} |
+} |
+void f(C<int> c) { |
+ c.^ |
+} |
+'''); |
+ return computeFull((bool result) { |
+ // TODO(paulberry): modify assertSuggestSetter so that we can pass 'int' |
+ // as a parmeter to it, and it will check the appropriate field in |
+ // the suggestion object. |
+ CompletionSuggestion suggestion = assertSuggestSetter('t'); |
+ expect(suggestion.element.parameters, '(int value)'); |
+ }); |
+ } |
+ |
test_method_parameters_mixed_required_and_named() { |
addTestSource(''' |
class C { |
@@ -177,4 +273,116 @@ void main() {int y = new C().^}'''); |
assertHasNoParameterInfo(suggestion); |
}); |
} |
+ |
+ test_shadowing_field_over_field() => |
+ check_shadowing('int x;', 'int x;', true); |
+ |
+ test_shadowing_field_over_getter() => |
+ check_shadowing('int x;', 'int get x => null;', true); |
+ |
+ test_shadowing_field_over_method() => |
+ check_shadowing('int x;', 'void x() {}', true); |
+ |
+ test_shadowing_field_over_setter() => |
+ check_shadowing('int x;', 'set x(int value) {}', true); |
+ |
+ test_shadowing_getter_over_field() => |
+ check_shadowing('int get x => null;', 'int x;', false); |
+ |
+ test_shadowing_getter_over_getter() => |
+ check_shadowing('int get x => null;', 'int get x => null;', true); |
+ |
+ test_shadowing_getter_over_method() => |
+ check_shadowing('int get x => null;', 'void x() {}', true); |
+ |
+ test_shadowing_getter_over_setter() => |
+ check_shadowing('int get x => null;', 'set x(int value) {}', false); |
+ |
+ test_shadowing_method_over_field() => |
+ check_shadowing('void x() {}', 'int x;', true); |
+ |
+ test_shadowing_method_over_getter() => |
+ check_shadowing('void x() {}', 'int get x => null;', true); |
+ |
+ test_shadowing_method_over_method() => |
+ check_shadowing('void x() {}', 'void x() {}', true); |
+ |
+ test_shadowing_method_over_setter() => |
+ check_shadowing('void x() {}', 'set x(int value) {}', true); |
+ |
+ test_shadowing_mixin_order() { |
+ addTestSource(''' |
+class Base { |
+} |
+class Mixin1 { |
+ void f() {} |
+} |
+class Mixin2 { |
+ void f() {} |
+} |
+class Derived extends Base with Mixin1, Mixin2 { |
+} |
+void test(Derived d) { |
+ d.^ |
+} |
+'''); |
+ return computeFull((bool result) { |
+ // Note: due to dartbug.com/22069, analyzer currently analyzes mixins in |
+ // reverse order. The correct order is that Derived inherits from |
+ // "Base with Mixin1, Mixin2", which inherits from "Base with Mixin1", |
+ // which inherits from "Base". So the definition of f in Mixin2 should |
+ // shadow the definition in Mixin1. |
+ assertSuggestMethod('f', 'Mixin2', 'void'); |
+ }); |
+ } |
+ |
+ test_shadowing_mixin_over_superclass() { |
+ addTestSource(''' |
+class Base { |
+ void f() {} |
+} |
+class Mixin { |
+ void f() {} |
+} |
+class Derived extends Base with Mixin { |
+} |
+void test(Derived d) { |
+ d.^ |
+} |
+'''); |
+ return computeFull((bool result) { |
+ assertSuggestMethod('f', 'Mixin', 'void'); |
+ }); |
+ } |
+ |
+ test_shadowing_setter_over_field() => |
+ check_shadowing('set x(int value) {}', 'int x;', false); |
+ |
+ test_shadowing_setter_over_getter() => |
+ check_shadowing('set x(int value) {}', 'int get x => null;', false); |
+ |
+ test_shadowing_setter_over_method() => |
+ check_shadowing('set x(int value) {}', 'void x() {}', true); |
+ |
+ test_shadowing_setter_over_setter() => |
+ check_shadowing('set x(int value) {}', 'set x(int value) {}', true); |
+ |
+ test_shadowing_superclass_over_interface() { |
+ addTestSource(''' |
+class Base { |
+ void f() {} |
+} |
+class Interface { |
+ void f() {} |
+} |
+class Derived extends Base implements Interface { |
+} |
+void test(Derived d) { |
+ d.^ |
+} |
+'''); |
+ return computeFull((bool result) { |
+ assertSuggestMethod('f', 'Base', 'void'); |
+ }); |
+ } |
} |