| // 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.plugin.analysis_contributor; |
| |
| import 'dart:async'; |
| |
| import 'package:analysis_server/plugin/analysis/analysis_domain.dart'; |
| import 'package:analysis_server/plugin/analysis/navigation/navigation.dart'; |
| import 'package:analysis_server/plugin/analysis/navigation/navigation_core.dart'; |
| import 'package:analysis_server/plugin/analysis/occurrences/occurrences.dart'; |
| import 'package:analysis_server/plugin/analysis/occurrences/occurrences_core.dart'; |
| import 'package:analysis_server/plugin/protocol/protocol.dart'; |
| import 'package:analysis_server/src/constants.dart'; |
| import 'package:analyzer/src/generated/engine.dart'; |
| import 'package:analyzer/src/generated/source.dart'; |
| import 'package:analyzer/task/dart.dart'; |
| import 'package:plugin/plugin.dart'; |
| import 'package:test_reflective_loader/test_reflective_loader.dart'; |
| import 'package:unittest/unittest.dart'; |
| |
| import '../analysis_abstract.dart'; |
| import '../utils.dart'; |
| |
| main() { |
| initializeTestEnvironment(); |
| defineReflectiveTests(SetAnalysisDomainTest); |
| } |
| |
| /** |
| * This test uses [SET_ANALYSIS_DOMAIN_EXTENSION_POINT_ID] and |
| * [NAVIGATION_CONTRIBUTOR_EXTENSION_POINT_ID] extension points to validate |
| * that plugins can listen for analysis and force sending navigation |
| * notifications. |
| */ |
| @reflectiveTest |
| class SetAnalysisDomainTest extends AbstractAnalysisTest { |
| final Set<String> parsedUnitFiles = new Set<String>(); |
| |
| AnalysisNavigationParams navigationParams; |
| AnalysisOccurrencesParams occurrencesParams; |
| |
| @override |
| void addServerPlugins(List<Plugin> plugins) { |
| var plugin = new TestSetAnalysisDomainPlugin(this); |
| plugins.add(plugin); |
| } |
| |
| @override |
| void processNotification(Notification notification) { |
| if (notification.event == ANALYSIS_NAVIGATION) { |
| var params = new AnalysisNavigationParams.fromNotification(notification); |
| if (params.file == testFile) { |
| navigationParams = params; |
| } |
| } |
| if (notification.event == ANALYSIS_OCCURRENCES) { |
| var params = new AnalysisOccurrencesParams.fromNotification(notification); |
| if (params.file == testFile) { |
| occurrencesParams = params; |
| } |
| } |
| } |
| |
| Future test_contributorIsInvoked() async { |
| createProject(); |
| addAnalysisSubscription(AnalysisService.NAVIGATION, testFile); |
| addAnalysisSubscription(AnalysisService.OCCURRENCES, testFile); |
| addTestFile('// usually no navigation'); |
| await server.onAnalysisComplete; |
| // we have PARSED_UNIT |
| expect(parsedUnitFiles, contains(testFile)); |
| // we have an additional navigation region/target |
| { |
| expect(navigationParams.regions, hasLength(1)); |
| { |
| NavigationRegion region = navigationParams.regions.single; |
| expect(region.offset, 1); |
| expect(region.length, 5); |
| expect(region.targets.single, 0); |
| } |
| { |
| NavigationTarget target = navigationParams.targets.single; |
| expect(target.fileIndex, 0); |
| expect(target.offset, 1); |
| expect(target.length, 2); |
| expect(target.startLine, 3); |
| expect(target.startColumn, 4); |
| } |
| expect(navigationParams.files.single, '/testLocation.dart'); |
| } |
| // we have additional occurrences |
| { |
| expect(occurrencesParams.occurrences, hasLength(1)); |
| Occurrences occurrences = occurrencesParams.occurrences.single; |
| expect(occurrences.element.name, 'TestElement'); |
| expect(occurrences.length, 5); |
| expect(occurrences.offsets, unorderedEquals([1, 2, 3])); |
| } |
| } |
| } |
| |
| class TestNavigationContributor implements NavigationContributor { |
| final SetAnalysisDomainTest test; |
| |
| TestNavigationContributor(this.test); |
| |
| @override |
| void computeNavigation(NavigationCollector collector, AnalysisContext context, |
| Source source, int offset, int length) { |
| collector.addRegion(1, 5, ElementKind.CLASS, |
| new Location('/testLocation.dart', 1, 2, 3, 4)); |
| } |
| } |
| |
| class TestOccurrencesContributor implements OccurrencesContributor { |
| final SetAnalysisDomainTest test; |
| |
| TestOccurrencesContributor(this.test); |
| |
| @override |
| void computeOccurrences( |
| OccurrencesCollector collector, AnalysisContext context, Source source) { |
| Element element = new Element(ElementKind.UNKNOWN, 'TestElement', 0); |
| collector.addOccurrences(new Occurrences(element, <int>[1, 2], 5)); |
| collector.addOccurrences(new Occurrences(element, <int>[3], 5)); |
| } |
| } |
| |
| class TestSetAnalysisDomainPlugin implements Plugin { |
| final SetAnalysisDomainTest test; |
| |
| TestSetAnalysisDomainPlugin(this.test); |
| |
| @override |
| String get uniqueIdentifier => 'test'; |
| |
| @override |
| void registerExtensionPoints(RegisterExtensionPoint register) {} |
| |
| @override |
| void registerExtensions(RegisterExtension register) { |
| register(SET_ANALYSIS_DOMAIN_EXTENSION_POINT_ID, _setAnalysisDomain); |
| register(NAVIGATION_CONTRIBUTOR_EXTENSION_POINT_ID, |
| new TestNavigationContributor(test)); |
| register(OCCURRENCES_CONTRIBUTOR_EXTENSION_POINT_ID, |
| new TestOccurrencesContributor(test)); |
| } |
| |
| void _setAnalysisDomain(AnalysisDomain domain) { |
| domain.onResultComputed(PARSED_UNIT).listen((result) { |
| expect(result.context, isNotNull); |
| expect(result.target, isNotNull); |
| expect(result.value, isNotNull); |
| Source source = result.target.source; |
| test.parsedUnitFiles.add(source.fullName); |
| domain.scheduleNotification( |
| result.context, source, AnalysisService.NAVIGATION); |
| domain.scheduleNotification( |
| result.context, source, AnalysisService.OCCURRENCES); |
| }); |
| } |
| } |