47e988b781
Change-Id: Iee3110f92ab0f24312ddd1eff407d2229f895321 Reviewed-on: https://dart-review.googlesource.com/c/89101 Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
136 lines
4.6 KiB
Dart
136 lines
4.6 KiB
Dart
// 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.
|
|
|
|
import 'package:analysis_server/protocol/protocol_generated.dart';
|
|
import 'package:analyzer_plugin/protocol/protocol_common.dart';
|
|
import 'package:test/test.dart';
|
|
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
|
|
|
import '../support/integration_tests.dart';
|
|
|
|
main() {
|
|
defineReflectiveSuite(() {
|
|
defineReflectiveTests(AnalysisNavigationTest);
|
|
});
|
|
}
|
|
|
|
@reflectiveTest
|
|
class AnalysisNavigationTest extends AbstractAnalysisServerIntegrationTest {
|
|
test_navigation() async {
|
|
String pathname1 = sourcePath('test1.dart');
|
|
String text1 = r'''
|
|
library foo;
|
|
|
|
import 'dart:async';
|
|
part 'test2.dart';
|
|
|
|
class Class<TypeParameter> {
|
|
Class.constructor(); /* constructor declaration */
|
|
|
|
TypeParameter field;
|
|
|
|
method() {}
|
|
}
|
|
|
|
typedef FunctionTypeAlias();
|
|
|
|
function(FunctionTypeAlias parameter) {
|
|
print(parameter());
|
|
}
|
|
|
|
int topLevelVariable;
|
|
|
|
main() {
|
|
Class<int> localVariable = new Class<int>.constructor(); // usage
|
|
function(() => localVariable.field);
|
|
localVariable.method();
|
|
localVariable.field = 1;
|
|
}
|
|
''';
|
|
writeFile(pathname1, text1);
|
|
String pathname2 = sourcePath('test2.dart');
|
|
String text2 = r'''
|
|
part of foo;
|
|
''';
|
|
writeFile(pathname2, text2);
|
|
standardAnalysisSetup();
|
|
sendAnalysisSetSubscriptions({
|
|
AnalysisService.NAVIGATION: [pathname1]
|
|
});
|
|
List<NavigationRegion> regions;
|
|
List<NavigationTarget> targets;
|
|
List<String> targetFiles;
|
|
onAnalysisNavigation.listen((AnalysisNavigationParams params) {
|
|
expect(params.file, equals(pathname1));
|
|
regions = params.regions;
|
|
targets = params.targets;
|
|
targetFiles = params.files;
|
|
});
|
|
|
|
await analysisFinished;
|
|
|
|
// There should be a single error, due to the fact that 'dart:async' is not
|
|
// used.
|
|
expect(currentAnalysisErrors[pathname1], hasLength(1));
|
|
expect(currentAnalysisErrors[pathname2], isEmpty);
|
|
NavigationTarget findTargetElement(int index) {
|
|
for (NavigationRegion region in regions) {
|
|
if (region.offset <= index && index < region.offset + region.length) {
|
|
expect(region.targets, hasLength(1));
|
|
int targetIndex = region.targets[0];
|
|
return targets[targetIndex];
|
|
}
|
|
}
|
|
fail('No element found for index $index');
|
|
}
|
|
|
|
void checkLocal(
|
|
String source, String expectedTarget, ElementKind expectedKind) {
|
|
int sourceIndex = text1.indexOf(source);
|
|
int targetIndex = text1.indexOf(expectedTarget);
|
|
NavigationTarget element = findTargetElement(sourceIndex);
|
|
expect(targetFiles[element.fileIndex], equals(pathname1));
|
|
expect(element.offset, equals(targetIndex));
|
|
expect(element.kind, equals(expectedKind));
|
|
}
|
|
|
|
void checkRemote(
|
|
String source, String expectedTargetRegexp, ElementKind expectedKind) {
|
|
int sourceIndex = text1.indexOf(source);
|
|
NavigationTarget element = findTargetElement(sourceIndex);
|
|
expect(targetFiles[element.fileIndex], matches(expectedTargetRegexp));
|
|
expect(element.kind, equals(expectedKind));
|
|
}
|
|
|
|
// TODO(paulberry): will the element type 'CLASS_TYPE_ALIAS' ever appear as
|
|
// a navigation target?
|
|
checkLocal('Class<int>', 'Class<TypeParameter>', ElementKind.CLASS);
|
|
checkRemote("'test2.dart';", r'test2.dart$', ElementKind.COMPILATION_UNIT);
|
|
checkLocal(
|
|
'Class<int>.constructor',
|
|
'constructor(); /* constructor declaration */',
|
|
ElementKind.CONSTRUCTOR);
|
|
checkLocal(
|
|
'constructor(); // usage',
|
|
'constructor(); /* constructor declaration */',
|
|
ElementKind.CONSTRUCTOR);
|
|
checkLocal('field;', 'field;', ElementKind.FIELD);
|
|
checkLocal('function(() => localVariable.field)',
|
|
'function(FunctionTypeAlias parameter)', ElementKind.FUNCTION);
|
|
checkLocal('FunctionTypeAlias parameter', 'FunctionTypeAlias();',
|
|
ElementKind.FUNCTION_TYPE_ALIAS);
|
|
checkLocal('field)', 'field;', ElementKind.GETTER);
|
|
checkRemote("'dart:async'", r'async\.dart$', ElementKind.LIBRARY);
|
|
checkLocal(
|
|
'localVariable.field', 'localVariable =', ElementKind.LOCAL_VARIABLE);
|
|
checkLocal('method();', 'method() {', ElementKind.METHOD);
|
|
checkLocal('parameter());', 'parameter) {', ElementKind.PARAMETER);
|
|
checkLocal('field = 1', 'field;', ElementKind.SETTER);
|
|
checkLocal('topLevelVariable;', 'topLevelVariable;',
|
|
ElementKind.TOP_LEVEL_VARIABLE);
|
|
checkLocal(
|
|
'TypeParameter field;', 'TypeParameter>', ElementKind.TYPE_PARAMETER);
|
|
}
|
|
}
|