| // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| library test.services.completion.toplevel; |
| |
| import 'package:analysis_server/src/analysis_server.dart'; |
| import 'package:analysis_server/src/protocol.dart' as protocol |
| show Element, ElementKind; |
| import 'package:analysis_server/src/protocol.dart' hide Element, ElementKind; |
| import 'package:analysis_server/src/services/completion/dart_completion_cache.dart'; |
| import 'package:analysis_server/src/services/completion/dart_completion_manager.dart'; |
| import 'package:analysis_server/src/services/completion/imported_reference_contributor.dart'; |
| import 'package:analyzer/src/generated/ast.dart'; |
| import 'package:analyzer/src/generated/element.dart'; |
| import 'package:analyzer/src/generated/engine.dart'; |
| import 'package:analyzer/src/generated/source.dart'; |
| import 'package:test_reflective_loader/test_reflective_loader.dart'; |
| import 'package:unittest/unittest.dart'; |
| |
| import '../../abstract_context.dart'; |
| import '../../operation/operation_queue_test.dart'; |
| import '../../utils.dart'; |
| import 'completion_test_util.dart'; |
| |
| main() { |
| initializeTestEnvironment(); |
| defineReflectiveTests(ImportedReferenceContributorTest); |
| } |
| |
| @reflectiveTest |
| class ImportedReferenceContributorTest extends AbstractSelectorSuggestionTest { |
| void assertCached(String completion) { |
| DartCompletionCache cache = request.cache; |
| if (!isCached(cache.importedTypeSuggestions, completion) && |
| !isCached(cache.importedVoidReturnSuggestions, completion) && |
| !isCached(cache.libraryPrefixSuggestions, completion) && |
| !isCached(cache.otherImportedSuggestions, completion)) { |
| fail('expected $completion to be cached'); |
| } |
| } |
| |
| /** |
| * Assert that the ImportedReferenceContributor uses cached results |
| * to produce identical suggestions to the original set of suggestions. |
| */ |
| @override |
| assertCachedCompute(_) { |
| if (!(contributor as ImportedReferenceContributor) |
| .shouldWaitForLowPrioritySuggestions) { |
| return null; |
| } |
| List<CompletionSuggestion> oldSuggestions = request.suggestions; |
| /* |
| * Simulate a source change to flush the cached compilation unit |
| */ |
| ChangeSet changes = new ChangeSet(); |
| changes.addedSource(testSource); |
| context.applyChanges(changes); |
| /* |
| * Calculate a new completion at the same location |
| */ |
| setUpContributor(); |
| int replacementOffset = request.replacementOffset; |
| int replacementLength = request.replacementLength; |
| AnalysisServer server = new AnalysisServerMock(); |
| /* |
| * Pass null for searchEngine to ensure that it is not used |
| * when the cache has been populated. |
| */ |
| request = new DartCompletionRequest( |
| server, context, testSource, completionOffset, cache); |
| request.replacementOffset = replacementOffset; |
| request.replacementLength = replacementLength; |
| |
| void assertResultsFromCache(List<CompletionSuggestion> oldSuggestions) { |
| List<CompletionSuggestion> newSuggestions = request.suggestions; |
| if (newSuggestions.length == oldSuggestions.length) { |
| if (!oldSuggestions |
| .any((CompletionSuggestion s) => !newSuggestions.contains(s))) { |
| return; |
| } |
| } |
| StringBuffer sb = new StringBuffer( |
| 'suggestions based upon cached results do not match expectations'); |
| sb.write('\n Expected:'); |
| oldSuggestions.toList() |
| ..sort(suggestionComparator) |
| ..forEach((CompletionSuggestion suggestion) { |
| sb.write('\n ${suggestion.completion} -> $suggestion'); |
| }); |
| sb.write('\n Actual:'); |
| newSuggestions.toList() |
| ..sort(suggestionComparator) |
| ..forEach((CompletionSuggestion suggestion) { |
| sb.write('\n ${suggestion.completion} -> $suggestion'); |
| }); |
| fail(sb.toString()); |
| } |
| |
| computeFastResult = null; |
| if (computeFast()) { |
| expect(request.unit.element, isNull); |
| assertResultsFromCache(oldSuggestions); |
| } else { |
| // Results from cache might need to be adjusted |
| // if target is a function argument in an argument list |
| resolve(false); |
| return contributor.computeFull(request).then((bool result) { |
| expect(result, isTrue); |
| expect(request.unit.element, isNotNull); |
| assertResultsFromCache(oldSuggestions); |
| }); |
| } |
| } |
| |
| void assertNotCached(String completion) { |
| DartCompletionCache cache = request.cache; |
| if (isCached(cache.importedTypeSuggestions, completion) || |
| isCached(cache.importedVoidReturnSuggestions, completion) || |
| isCached(cache.libraryPrefixSuggestions, completion) || |
| isCached(cache.otherImportedSuggestions, completion)) { |
| fail('expected $completion NOT to be cached'); |
| } |
| } |
| |
| @override |
| CompletionSuggestion assertSuggestImportedClass(String name, |
| {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION, |
| int relevance: DART_RELEVANCE_DEFAULT, |
| String importUri, |
| String elemFile}) { |
| return assertSuggestClass(name, |
| relevance: relevance, |
| kind: kind, |
| importUri: importUri, |
| elemFile: elemFile); |
| } |
| |
| @override |
| CompletionSuggestion assertSuggestImportedConstructor(String name, |
| {int relevance: DART_RELEVANCE_DEFAULT, String importUri}) { |
| return assertSuggestConstructor(name, |
| relevance: relevance, importUri: importUri); |
| } |
| |
| @override |
| CompletionSuggestion assertSuggestImportedField(String name, String type, |
| {int relevance: DART_RELEVANCE_INHERITED_FIELD, String importUri}) { |
| return assertSuggestField(name, type, |
| relevance: relevance, importUri: importUri); |
| } |
| |
| @override |
| CompletionSuggestion assertSuggestImportedFunction( |
| String name, String returnType, |
| {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION, |
| bool deprecated: false, |
| int relevance: DART_RELEVANCE_DEFAULT, |
| String importUri}) { |
| return assertSuggestFunction(name, returnType, |
| kind: kind, |
| deprecated: deprecated, |
| relevance: relevance, |
| importUri: importUri); |
| } |
| |
| @override |
| CompletionSuggestion assertSuggestImportedFunctionTypeAlias( |
| String name, String returnType, |
| [bool isDeprecated = false, |
| int relevance = DART_RELEVANCE_DEFAULT, |
| CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION, |
| String importUri]) { |
| return assertSuggestFunctionTypeAlias( |
| name, returnType, isDeprecated, relevance, kind, importUri); |
| } |
| |
| CompletionSuggestion assertSuggestImportedGetter( |
| String name, String returnType, |
| {int relevance: DART_RELEVANCE_INHERITED_ACCESSOR, String importUri}) { |
| return assertSuggestGetter(name, returnType, |
| relevance: relevance, importUri: importUri); |
| } |
| |
| CompletionSuggestion assertSuggestImportedMethod( |
| String name, String declaringType, String returnType, |
| {int relevance: DART_RELEVANCE_INHERITED_METHOD, String importUri}) { |
| return assertSuggestMethod(name, declaringType, returnType, |
| relevance: relevance, importUri: importUri); |
| } |
| |
| CompletionSuggestion assertSuggestImportedSetter(String name, |
| {int relevance: DART_RELEVANCE_INHERITED_ACCESSOR, String importUri}) { |
| return assertSuggestSetter(name, relevance, importUri); |
| } |
| |
| @override |
| CompletionSuggestion assertSuggestImportedTopLevelVar( |
| String name, String returnType, |
| [int relevance = DART_RELEVANCE_DEFAULT, |
| CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION, |
| String importUri]) { |
| return assertSuggestTopLevelVar( |
| name, returnType, relevance, kind, importUri); |
| } |
| |
| @override |
| CompletionSuggestion assertSuggestLibraryPrefix(String prefix, |
| [int relevance = DART_RELEVANCE_DEFAULT, |
| CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) { |
| CompletionSuggestion cs = |
| assertSuggest(prefix, csKind: kind, relevance: relevance); |
| protocol.Element element = cs.element; |
| expect(element, isNotNull); |
| expect(element.kind, equals(protocol.ElementKind.LIBRARY)); |
| expect(element.parameters, isNull); |
| expect(element.returnType, isNull); |
| assertHasNoParameterInfo(cs); |
| return cs; |
| } |
| |
| fail_enum_deprecated() { |
| addSource('/libA.dart', 'library A; @deprecated enum E { one, two }'); |
| addTestSource('import "/libA.dart"; main() {^}'); |
| return computeFull((bool result) { |
| // TODO(danrube) investigate why suggestion/element is not deprecated |
| // when AST node has correct @deprecated annotation |
| assertSuggestEnum('E', isDeprecated: true); |
| assertNotSuggested('one'); |
| assertNotSuggested('two'); |
| }); |
| } |
| |
| bool isCached(List<CompletionSuggestion> suggestions, String completion) => |
| suggestions.any((CompletionSuggestion s) => s.completion == completion); |
| |
| @override |
| void setUpContributor() { |
| contributor = new ImportedReferenceContributor( |
| shouldWaitForLowPrioritySuggestions: true); |
| } |
| |
| @override |
| test_ArgumentList() { |
| return super.test_ArgumentList().then((_) { |
| expect(request.cache.importKey, "import '/libA.dart';"); |
| ClassElement objClassElem1 = request.cache.importedClassMap['Object']; |
| expect(objClassElem1, isNotNull); |
| ClassElement objClassElem2 = request.cache.objectClassElement; |
| expect(objClassElem1, same(objClassElem2)); |
| }); |
| } |
| |
| @override |
| test_ArgumentList_imported_function() { |
| return super.test_ArgumentList_imported_function().then((_) { |
| expect(request.cache.importKey, "import '/libA.dart';"); |
| }); |
| } |
| |
| @override |
| test_AssignmentExpression_RHS() { |
| return super.test_AssignmentExpression_RHS().then((_) { |
| expect(request.cache.importKey, ''); |
| }); |
| } |
| |
| @override |
| test_Block() { |
| return super.test_Block().then((_) { |
| expect(request.cache.importKey, |
| 'import "/testAB.dart";import "/testCD.dart" hide D;import "/testEEF.dart" show EE;import "/testG.dart" as g;'); |
| assertCached('A'); |
| assertCached('T3'); |
| }); |
| } |
| |
| @override |
| test_Block_inherited_imported() { |
| return super.test_Block_inherited_imported().then((_) { |
| assertCached('E'); |
| assertCached('F'); |
| assertNotCached('e1'); |
| assertNotCached('i2'); |
| assertNotCached('m1'); |
| assertNotCached('_pf'); |
| }); |
| } |
| |
| test_Block_partial_results() { |
| // Block BlockFunctionBody MethodDeclaration |
| addSource( |
| '/testAB.dart', |
| ''' |
| export "dart:math" hide max; |
| class A {int x;} |
| @deprecated D1() {int x;} |
| class _B { }'''); |
| addSource( |
| '/testCD.dart', |
| ''' |
| String T1; |
| var _T2; |
| class C { } |
| class D { }'''); |
| addSource( |
| '/testEEF.dart', |
| ''' |
| class EE { } |
| class F { }'''); |
| addSource('/testG.dart', 'class G { }'); |
| addSource( |
| '/testH.dart', |
| ''' |
| class H { } |
| int T3; |
| var _T4;'''); // not imported |
| addTestSource(''' |
| import "/testAB.dart"; |
| import "/testCD.dart" hide D; |
| import "/testEEF.dart" show EE; |
| import "/testG.dart" as g; |
| int T5; |
| var _T6; |
| Z D2() {int x;} |
| class X {a() {var f; {var x;} ^ var r;} void b() { }} |
| class Z { }'''); |
| ImportedReferenceContributor contributor = this.contributor; |
| contributor.shouldWaitForLowPrioritySuggestions = false; |
| computeFast(); |
| return computeFull((bool result) { |
| assertSuggestImportedClass('C'); |
| // Assert contributor does not wait for or include low priority results |
| // from non-imported libraries unless instructed to do so. |
| assertNotSuggested('H'); |
| }); |
| } |
| |
| test_enum() { |
| addSource('/libA.dart', 'library A; enum E { one, two }'); |
| addTestSource('import "/libA.dart"; main() {^}'); |
| return computeFull((bool result) { |
| assertSuggestEnum('E'); |
| assertNotSuggested('one'); |
| assertNotSuggested('two'); |
| }); |
| } |
| |
| test_function_parameters_mixed_required_and_named() { |
| addSource( |
| '/libA.dart', |
| ''' |
| void m(x, {int y}) {} |
| '''); |
| addTestSource(''' |
| import '/libA.dart'; |
| class B extends A { |
| main() {^} |
| } |
| '''); |
| return computeFull((bool result) { |
| CompletionSuggestion suggestion = assertSuggestFunction('m', 'void'); |
| expect(suggestion.parameterNames, hasLength(2)); |
| expect(suggestion.parameterNames[0], 'x'); |
| expect(suggestion.parameterTypes[0], 'dynamic'); |
| expect(suggestion.parameterNames[1], 'y'); |
| expect(suggestion.parameterTypes[1], 'int'); |
| expect(suggestion.requiredParameterCount, 1); |
| expect(suggestion.hasNamedParameters, true); |
| }); |
| } |
| |
| test_function_parameters_mixed_required_and_positional() { |
| addSource( |
| '/libA.dart', |
| ''' |
| void m(x, [int y]) {} |
| '''); |
| addTestSource(''' |
| import '/libA.dart'; |
| class B extends A { |
| main() {^} |
| } |
| '''); |
| return computeFull((bool result) { |
| CompletionSuggestion suggestion = assertSuggestFunction('m', 'void'); |
| expect(suggestion.parameterNames, hasLength(2)); |
| expect(suggestion.parameterNames[0], 'x'); |
| expect(suggestion.parameterTypes[0], 'dynamic'); |
| expect(suggestion.parameterNames[1], 'y'); |
| expect(suggestion.parameterTypes[1], 'int'); |
| expect(suggestion.requiredParameterCount, 1); |
| expect(suggestion.hasNamedParameters, false); |
| }); |
| } |
| |
| test_function_parameters_named() { |
| addSource( |
| '/libA.dart', |
| ''' |
| void m({x, int y}) {} |
| '''); |
| addTestSource(''' |
| import '/libA.dart'; |
| class B extends A { |
| main() {^} |
| } |
| '''); |
| return computeFull((bool result) { |
| CompletionSuggestion suggestion = assertSuggestFunction('m', 'void'); |
| expect(suggestion.parameterNames, hasLength(2)); |
| expect(suggestion.parameterNames[0], 'x'); |
| expect(suggestion.parameterTypes[0], 'dynamic'); |
| expect(suggestion.parameterNames[1], 'y'); |
| expect(suggestion.parameterTypes[1], 'int'); |
| expect(suggestion.requiredParameterCount, 0); |
| expect(suggestion.hasNamedParameters, true); |
| }); |
| } |
| |
| test_function_parameters_none() { |
| addSource( |
| '/libA.dart', |
| ''' |
| void m() {} |
| '''); |
| addTestSource(''' |
| import '/libA.dart'; |
| class B extends A { |
| main() {^} |
| } |
| '''); |
| computeFast(); |
| return computeFull((bool result) { |
| CompletionSuggestion suggestion = assertSuggestFunction('m', 'void'); |
| expect(suggestion.parameterNames, isEmpty); |
| expect(suggestion.parameterTypes, isEmpty); |
| expect(suggestion.requiredParameterCount, 0); |
| expect(suggestion.hasNamedParameters, false); |
| }); |
| } |
| |
| test_function_parameters_positional() { |
| addSource( |
| '/libA.dart', |
| ''' |
| void m([x, int y]) {} |
| '''); |
| addTestSource(''' |
| import '/libA.dart'; |
| class B extends A { |
| main() {^} |
| } |
| '''); |
| return computeFull((bool result) { |
| CompletionSuggestion suggestion = assertSuggestFunction('m', 'void'); |
| expect(suggestion.parameterNames, hasLength(2)); |
| expect(suggestion.parameterNames[0], 'x'); |
| expect(suggestion.parameterTypes[0], 'dynamic'); |
| expect(suggestion.parameterNames[1], 'y'); |
| expect(suggestion.parameterTypes[1], 'int'); |
| expect(suggestion.requiredParameterCount, 0); |
| expect(suggestion.hasNamedParameters, false); |
| }); |
| } |
| |
| test_function_parameters_required() { |
| addSource( |
| '/libA.dart', |
| ''' |
| void m(x, int y) {} |
| '''); |
| addTestSource(''' |
| import '/libA.dart'; |
| class B extends A { |
| main() {^} |
| } |
| '''); |
| return computeFull((bool result) { |
| CompletionSuggestion suggestion = assertSuggestFunction('m', 'void'); |
| expect(suggestion.parameterNames, hasLength(2)); |
| expect(suggestion.parameterNames[0], 'x'); |
| expect(suggestion.parameterTypes[0], 'dynamic'); |
| expect(suggestion.parameterNames[1], 'y'); |
| expect(suggestion.parameterTypes[1], 'int'); |
| expect(suggestion.requiredParameterCount, 2); |
| expect(suggestion.hasNamedParameters, false); |
| }); |
| } |
| |
| test_InstanceCreationExpression() { |
| addSource( |
| '/testA.dart', |
| ''' |
| class A {foo(){var f; {var x;}}} |
| class B {B(this.x, [String boo]) { } int x;} |
| class C {C.bar({boo: 'hoo', int z: 0}) { } }'''); |
| addTestSource(''' |
| import "/testA.dart"; |
| import "dart:math" as math; |
| main() {new ^ String x = "hello";}'''); |
| computeFast(); |
| return computeFull((bool result) { |
| CompletionSuggestion suggestion; |
| |
| suggestion = assertSuggestImportedConstructor('Object'); |
| expect(suggestion.element.parameters, '()'); |
| expect(suggestion.parameterNames, hasLength(0)); |
| expect(suggestion.requiredParameterCount, 0); |
| expect(suggestion.hasNamedParameters, false); |
| |
| suggestion = assertSuggestImportedConstructor('A'); |
| expect(suggestion.element.parameters, '()'); |
| expect(suggestion.parameterNames, hasLength(0)); |
| expect(suggestion.requiredParameterCount, 0); |
| expect(suggestion.hasNamedParameters, false); |
| |
| suggestion = assertSuggestImportedConstructor('B'); |
| expect(suggestion.element.parameters, '(int x, [String boo])'); |
| expect(suggestion.parameterNames, hasLength(2)); |
| expect(suggestion.parameterNames[0], 'x'); |
| expect(suggestion.parameterTypes[0], 'int'); |
| expect(suggestion.parameterNames[1], 'boo'); |
| expect(suggestion.parameterTypes[1], 'String'); |
| expect(suggestion.requiredParameterCount, 1); |
| expect(suggestion.hasNamedParameters, false); |
| |
| suggestion = assertSuggestImportedConstructor('C.bar'); |
| expect(suggestion.element.parameters, "({dynamic boo: 'hoo', int z: 0})"); |
| expect(suggestion.parameterNames, hasLength(2)); |
| expect(suggestion.parameterNames[0], 'boo'); |
| expect(suggestion.parameterTypes[0], 'dynamic'); |
| expect(suggestion.parameterNames[1], 'z'); |
| expect(suggestion.parameterTypes[1], 'int'); |
| expect(suggestion.requiredParameterCount, 0); |
| expect(suggestion.hasNamedParameters, true); |
| |
| assertSuggestLibraryPrefix('math'); |
| }); |
| } |
| |
| test_internal_sdk_libs() { |
| addTestSource('main() {p^}'); |
| computeFast(); |
| return computeFull((bool result) { |
| assertSuggest('print'); |
| assertSuggest('pow', |
| relevance: DART_RELEVANCE_LOW, importUri: 'dart:math'); |
| // Do not suggest completions from internal SDK library |
| assertNotSuggested('printToConsole'); |
| }); |
| } |
| |
| test_method_parameters_mixed_required_and_named() { |
| addSource( |
| '/libA.dart', |
| ''' |
| class A { |
| void m(x, {int y}) {} |
| } |
| '''); |
| addTestSource(''' |
| import '/libA.dart'; |
| class B extends A { |
| main() {^} |
| } |
| '''); |
| return computeFull((bool result) { |
| CompletionSuggestion suggestion = |
| assertSuggestImportedMethod('m', 'A', 'void'); |
| expect(suggestion.parameterNames, hasLength(2)); |
| expect(suggestion.parameterNames[0], 'x'); |
| expect(suggestion.parameterTypes[0], 'dynamic'); |
| expect(suggestion.parameterNames[1], 'y'); |
| expect(suggestion.parameterTypes[1], 'int'); |
| expect(suggestion.requiredParameterCount, 1); |
| expect(suggestion.hasNamedParameters, true); |
| }); |
| } |
| |
| test_method_parameters_mixed_required_and_positional() { |
| addSource( |
| '/libA.dart', |
| ''' |
| class A { |
| void m(x, [int y]) {} |
| } |
| '''); |
| addTestSource(''' |
| import '/libA.dart'; |
| class B extends A { |
| main() {^} |
| } |
| '''); |
| return computeFull((bool result) { |
| CompletionSuggestion suggestion = |
| assertSuggestImportedMethod('m', 'A', 'void'); |
| expect(suggestion.parameterNames, hasLength(2)); |
| expect(suggestion.parameterNames[0], 'x'); |
| expect(suggestion.parameterTypes[0], 'dynamic'); |
| expect(suggestion.parameterNames[1], 'y'); |
| expect(suggestion.parameterTypes[1], 'int'); |
| expect(suggestion.requiredParameterCount, 1); |
| expect(suggestion.hasNamedParameters, false); |
| }); |
| } |
| |
| test_method_parameters_named() { |
| addSource( |
| '/libA.dart', |
| ''' |
| class A { |
| void m({x, int y}) {} |
| } |
| '''); |
| addTestSource(''' |
| import '/libA.dart'; |
| class B extends A { |
| main() {^} |
| } |
| '''); |
| return computeFull((bool result) { |
| CompletionSuggestion suggestion = |
| assertSuggestImportedMethod('m', 'A', 'void'); |
| expect(suggestion.parameterNames, hasLength(2)); |
| expect(suggestion.parameterNames[0], 'x'); |
| expect(suggestion.parameterTypes[0], 'dynamic'); |
| expect(suggestion.parameterNames[1], 'y'); |
| expect(suggestion.parameterTypes[1], 'int'); |
| expect(suggestion.requiredParameterCount, 0); |
| expect(suggestion.hasNamedParameters, true); |
| }); |
| } |
| |
| test_method_parameters_none() { |
| addSource( |
| '/libA.dart', |
| ''' |
| class A { |
| void m() {} |
| } |
| '''); |
| addTestSource(''' |
| import '/libA.dart'; |
| class B extends A { |
| main() {^} |
| } |
| '''); |
| computeFast(); |
| return computeFull((bool result) { |
| CompletionSuggestion suggestion = |
| assertSuggestImportedMethod('m', 'A', 'void'); |
| expect(suggestion.parameterNames, isEmpty); |
| expect(suggestion.parameterTypes, isEmpty); |
| expect(suggestion.requiredParameterCount, 0); |
| expect(suggestion.hasNamedParameters, false); |
| }); |
| } |
| |
| test_method_parameters_positional() { |
| addSource( |
| '/libA.dart', |
| ''' |
| class A { |
| void m([x, int y]) {} |
| } |
| '''); |
| addTestSource(''' |
| import '/libA.dart'; |
| class B extends A { |
| main() {^} |
| } |
| '''); |
| return computeFull((bool result) { |
| CompletionSuggestion suggestion = |
| assertSuggestImportedMethod('m', 'A', 'void'); |
| expect(suggestion.parameterNames, hasLength(2)); |
| expect(suggestion.parameterNames[0], 'x'); |
| expect(suggestion.parameterTypes[0], 'dynamic'); |
| expect(suggestion.parameterNames[1], 'y'); |
| expect(suggestion.parameterTypes[1], 'int'); |
| expect(suggestion.requiredParameterCount, 0); |
| expect(suggestion.hasNamedParameters, false); |
| }); |
| } |
| |
| test_method_parameters_required() { |
| addSource( |
| '/libA.dart', |
| ''' |
| class A { |
| void m(x, int y) {} |
| } |
| '''); |
| addTestSource(''' |
| import '/libA.dart'; |
| class B extends A { |
| main() {^} |
| } |
| '''); |
| return computeFull((bool result) { |
| CompletionSuggestion suggestion = |
| assertSuggestImportedMethod('m', 'A', 'void'); |
| expect(suggestion.parameterNames, hasLength(2)); |
| expect(suggestion.parameterNames[0], 'x'); |
| expect(suggestion.parameterTypes[0], 'dynamic'); |
| expect(suggestion.parameterNames[1], 'y'); |
| expect(suggestion.parameterTypes[1], 'int'); |
| expect(suggestion.requiredParameterCount, 2); |
| expect(suggestion.hasNamedParameters, false); |
| }); |
| } |
| |
| test_mixin_ordering() { |
| addSource( |
| '/libA.dart', |
| ''' |
| class B {} |
| class M1 { |
| void m() {} |
| } |
| class M2 { |
| void m() {} |
| } |
| '''); |
| addTestSource(''' |
| import '/libA.dart'; |
| class C extends B with M1, M2 { |
| void f() { |
| ^ |
| } |
| } |
| '''); |
| return computeFull((bool result) { |
| assertSuggestImportedMethod('m', 'M2', 'void'); |
| }); |
| } |
| |
| /** |
| * Ensure that completions in one context don't appear in another |
| */ |
| test_multiple_contexts() { |
| // Create a 2nd context with source |
| var context2 = AnalysisEngine.instance.createAnalysisContext(); |
| context2.sourceFactory = |
| new SourceFactory([AbstractContextTest.SDK_RESOLVER, resourceResolver]); |
| String content2 = 'class ClassFromAnotherContext { }'; |
| Source source2 = |
| provider.newFile('/context2/foo.dart', content2).createSource(); |
| ChangeSet changeSet = new ChangeSet(); |
| changeSet.addedSource(source2); |
| context2.applyChanges(changeSet); |
| context2.setContents(source2, content2); |
| |
| // Resolve the source in the 2nd context and update the index |
| var result = context2.performAnalysisTask(); |
| while (result.hasMoreWork) { |
| result.changeNotices.forEach((ChangeNotice notice) { |
| CompilationUnit unit = notice.resolvedDartUnit; |
| if (unit != null) { |
| index.index(context2, unit); |
| } |
| }); |
| result = context2.performAnalysisTask(); |
| } |
| |
| // Check that source in 2nd context does not appear in completion in 1st |
| addSource( |
| '/context1/libA.dart', |
| ''' |
| library libA; |
| class ClassInLocalContext {int x;}'''); |
| testFile = '/context1/completionTest.dart'; |
| addTestSource(''' |
| import "/context1/libA.dart"; |
| import "/foo.dart"; |
| main() {C^} |
| '''); |
| computeFast(); |
| return computeFull((bool result) { |
| assertSuggestImportedClass('ClassInLocalContext'); |
| // Assert contributor does not include results from 2nd context. |
| assertNotSuggested('ClassFromAnotherContext'); |
| }); |
| } |
| |
| test_no_parameters_field() { |
| addSource( |
| '/libA.dart', |
| ''' |
| class A { |
| int x; |
| } |
| '''); |
| addTestSource(''' |
| import '/libA.dart'; |
| class B extends A { |
| main() {^} |
| } |
| '''); |
| return computeFull((bool result) { |
| CompletionSuggestion suggestion = assertSuggestImportedField('x', 'int'); |
| assertHasNoParameterInfo(suggestion); |
| }); |
| } |
| |
| test_no_parameters_getter() { |
| addSource( |
| '/libA.dart', |
| ''' |
| class A { |
| int get x => null; |
| } |
| '''); |
| addTestSource(''' |
| import '/libA.dart'; |
| class B extends A { |
| main() {^} |
| } |
| '''); |
| return computeFull((bool result) { |
| CompletionSuggestion suggestion = assertSuggestImportedGetter('x', 'int'); |
| assertHasNoParameterInfo(suggestion); |
| }); |
| } |
| |
| test_no_parameters_setter() { |
| addSource( |
| '/libA.dart', |
| ''' |
| class A { |
| set x(int value) {}; |
| } |
| '''); |
| addTestSource(''' |
| import '/libA.dart'; |
| class B extends A { |
| main() {^} |
| } |
| '''); |
| return computeFull((bool result) { |
| CompletionSuggestion suggestion = assertSuggestImportedSetter('x'); |
| assertHasNoParameterInfo(suggestion); |
| }); |
| } |
| |
| @override |
| test_partFile_TypeName() { |
| return super.test_partFile_TypeName().then((_) { |
| expect(request.cache.importKey, 'part of libA;'); |
| }); |
| } |
| |
| @override |
| test_partFile_TypeName2() { |
| return super.test_partFile_TypeName2().then((_) { |
| expect(request.cache.importKey, |
| 'library libA;import "/testB.dart";part "/testA.dart";'); |
| }); |
| } |
| } |