CQ. Remove assertErrorsInFile2(), use resolveFilesWithDiagnostics().

Add helpers that resolve non-test files using the same inline diagnostic
expectation format as resolveTestCodeWithDiagnostics.
resolveFileWithDiagnostics handles a single file, while
resolveFilesWithDiagnostics writes all related files before resolving
any of them.

Add multi-file diagnostic expectation generation so context messages in
one file can be referenced from diagnostics reported in another. Teach
expectation updating how to target values in a files-to-code map using
per-entry intra-invocation ids.

Remove assertErrorsInFile2 and migrate diagnostics tests from
hand-written ExpectedError offsets to inline markers. This keeps the
diagnostic range, code, message, and cross-file context next to the code
under test, and makes expectation updates reusable for library and part
tests.

Initialize strong-mode type assertions from resolveFile so callers that
resolve files other than testFile get the same setup.

Change-Id: Ie492155b046c28a535faf21fa9a2e47797caffb0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/506180
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Konstantin Shcheglov
2026-05-27 14:05:36 -07:00
committed by dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent 2cd3ec552c
commit 5252e5e3d3
34 changed files with 1353 additions and 1309 deletions
@@ -6,6 +6,9 @@ import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/type_provider.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/results.dart';
import 'package:analyzer/src/dart/ast/extensions.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag;
@@ -68,37 +71,9 @@ class StrongModeLocalInferenceTest extends PubPackageResolutionTest {
late final AsserterBuilder<Element, DartType> _hasElement;
@override
Future<TestResolvedUnitResult> resolveTestFile() async {
var result = await super.resolveTestFile();
var assertions = _assertions;
if (assertions == null) {
var typeProvider = result.typeProvider;
assertions = _assertions = TypeAssertions(typeProvider);
_isType = assertions.isType;
_hasElement = assertions.hasElement;
_isInstantiationOf = assertions.isInstantiationOf;
_isInt = assertions.isInt;
_isNever = assertions.isNever;
_isNull = assertions.isNull;
_isNum = assertions.isNum;
_isObject = assertions.isObject;
_isString = assertions.isString;
_isDynamic = assertions.isDynamic;
_isInvalidType = assertions.isInvalidType;
_isListOf = assertions.isListOf;
_isMapOf = assertions.isMapOf;
_isFunction2Of = assertions.isFunction2Of;
_isFutureOf = _isInstantiationOf(_hasElement(typeProvider.futureElement));
_isFutureOrOf = _isInstantiationOf(
_hasElement(typeProvider.futureOrElement),
);
_isFutureOfDynamic = _isFutureOf([_isDynamic]);
_isFutureOfInt = _isFutureOf([_isInt]);
_isFutureOfNull = _isFutureOf([_isNull]);
_isFutureOrOfInt = _isFutureOrOf([_isInt]);
}
Future<ResolvedUnitResultImpl> resolveFile(File file) async {
var result = await super.resolveFile(file);
_initAssertions(result.typeProvider);
return result;
}
@@ -3597,6 +3572,35 @@ class B<T2, U2> {
);
}
void _initAssertions(TypeProvider typeProvider) {
var assertions = _assertions;
if (assertions == null) {
assertions = _assertions = TypeAssertions(typeProvider);
_isType = assertions.isType;
_hasElement = assertions.hasElement;
_isInstantiationOf = assertions.isInstantiationOf;
_isInt = assertions.isInt;
_isNever = assertions.isNever;
_isNull = assertions.isNull;
_isNum = assertions.isNum;
_isObject = assertions.isObject;
_isString = assertions.isString;
_isDynamic = assertions.isDynamic;
_isInvalidType = assertions.isInvalidType;
_isListOf = assertions.isListOf;
_isMapOf = assertions.isMapOf;
_isFunction2Of = assertions.isFunction2Of;
_isFutureOf = _isInstantiationOf(_hasElement(typeProvider.futureElement));
_isFutureOrOf = _isInstantiationOf(
_hasElement(typeProvider.futureOrElement),
);
_isFutureOfDynamic = _isFutureOf([_isDynamic]);
_isFutureOfInt = _isFutureOf([_isInt]);
_isFutureOfNull = _isFutureOf([_isNull]);
_isFutureOrOfInt = _isFutureOrOf([_isInt]);
}
}
/// Helper method for testing `FutureOr<T>`.
///
/// Validates that [code] produces [expectedDiagnostics]. It should define a
@@ -881,15 +881,13 @@ analyzer:
implicit-casts: true
''');
var aPath = convertPath('/workspace/third_party/dart/aaa/lib/a.dart');
await assertErrorsInFile(
aPath,
r'''
var a = getFile('/workspace/third_party/dart/aaa/lib/a.dart');
await resolveFileWithDiagnostics(a, r'''
num a = 0;
int b = a;
''',
[error(diag.invalidAssignment, 19, 1)],
);
// ^
// [diag.invalidAssignment] A value of type 'num' can't be assigned to a variable of type 'int'.
''');
}
test_analysisOptions_file_inThirdPartyDartLang() async {
@@ -905,15 +903,13 @@ analyzer:
implicit-casts: true
''');
var aPath = convertPath('/workspace/third_party/dart_lang/aaa/lib/a.dart');
await assertErrorsInFile(
aPath,
r'''
var a = getFile('/workspace/third_party/dart_lang/aaa/lib/a.dart');
await resolveFileWithDiagnostics(a, r'''
num a = 0;
int b = a;
''',
[error(diag.invalidAssignment, 19, 1)],
);
// ^
// [diag.invalidAssignment] A value of type 'num' can't be assigned to a variable of type 'int'.
''');
}
test_analysisOptions_lints() async {
@@ -2512,11 +2508,11 @@ void func() {
newFile('/workspace/dart/aaa/BUILD', '');
newFile('/workspace/dart/bbb/BUILD', '');
var aPath = '/workspace/dart/aaa/lib/a.dart';
var aResult = await assertErrorsInFile(aPath, '', []);
var a = getFile('/workspace/dart/aaa/lib/a.dart');
var aResult = await resolveFileWithDiagnostics(a, '');
var bPath = '/workspace/dart/bbb/lib/a.dart';
var bResult = await assertErrorsInFile(bPath, '', []);
var b = getFile('/workspace/dart/bbb/lib/a.dart');
var bResult = await resolveFileWithDiagnostics(b, '');
// Both files use the same (default) analysis options.
// So, when we resolve 'bbb', we can reuse the context after 'aaa'.
@@ -191,6 +191,16 @@ class NodeTextExpectationsCollector {
methodName: 'assertResolvedNodeText',
argument: _ArgumentIndex(1),
),
_AssertMethod(
className: 'ResolutionTest',
methodName: 'resolveFileWithDiagnostics',
argument: _ArgumentIndex(1),
),
_AssertMethod(
className: 'ResolutionTest',
methodName: 'resolveFilesWithDiagnostics',
argument: _ArgumentMapEntryValue(mapArgument: _ArgumentIndex(0)),
),
_AssertMethod(
className: 'ResolutionTest',
methodName: 'resolveTestCodeWithDiagnostics',
@@ -239,18 +249,20 @@ class NodeTextExpectationsCollector {
static final Map<String, _File> _files = {};
static void add(String actual) {
static void add(String actual, {String? intraInvocationId}) {
if (!updatingIsEnabled) {
return;
}
// TODO(scheglov): Use a single mechanism for intra-invocation ids.
intraInvocationId ??= NodeTextExpectationsCollector.intraInvocationId;
var traceLines = '${StackTrace.current}'.split('\n');
for (var assertMethod in assertMethods) {
// Disambiguate multi-expectation arguments.
if (assertMethod.argument case _ArgumentNamed namedArgument) {
if (namedArgument.shouldCheckIntraInvocationId) {
var id = NodeTextExpectationsCollector.intraInvocationId;
if (namedArgument.name != id) {
if (namedArgument.name != intraInvocationId) {
continue;
}
}
@@ -294,7 +306,10 @@ class NodeTextExpectationsCollector {
}
var argumentList = invocation.argumentList;
var argument = assertMethod.argument.get(argumentList);
var argument = assertMethod.argument.get(
argumentList,
intraInvocationId: intraInvocationId,
);
if (argument is! SimpleStringLiteral) {
fail('Not a literal: ${argument.runtimeType}');
}
@@ -329,7 +344,7 @@ class UpdateNodeTextExpectations {
}
sealed class _Argument {
Expression get(ArgumentList argumentList);
Expression get(ArgumentList argumentList, {String? intraInvocationId});
}
final class _ArgumentIndex extends _Argument {
@@ -338,7 +353,7 @@ final class _ArgumentIndex extends _Argument {
_ArgumentIndex(this.index);
@override
Expression get(ArgumentList argumentList) {
Expression get(ArgumentList argumentList, {String? intraInvocationId}) {
return argumentList.arguments
.whereNotType<NamedArgument>()
.elementAt(index)
@@ -346,6 +361,40 @@ final class _ArgumentIndex extends _Argument {
}
}
final class _ArgumentMapEntryValue extends _Argument {
final _Argument mapArgument;
_ArgumentMapEntryValue({required this.mapArgument});
@override
Expression get(ArgumentList argumentList, {String? intraInvocationId}) {
if (intraInvocationId == null) {
fail('Expected an intra-invocation id for a map entry value.');
}
var index = int.tryParse(intraInvocationId);
if (index == null) {
fail('Expected a map entry index, got: $intraInvocationId');
}
var mapExpression = mapArgument.get(argumentList);
if (mapExpression is! SetOrMapLiteral) {
fail('Not a map literal: ${mapExpression.runtimeType}');
}
var elements = mapExpression.elements;
if (elements.any((element) => element is! MapLiteralEntry)) {
fail('Only plain map literal entries are supported.');
}
if (index < 0 || index >= elements.length) {
fail('Map entry index $index is out of range: ${elements.length}');
}
return (elements[index] as MapLiteralEntry).value;
}
}
final class _ArgumentNamed extends _Argument {
final String name;
final bool shouldCheckIntraInvocationId;
@@ -353,7 +402,7 @@ final class _ArgumentNamed extends _Argument {
_ArgumentNamed(this.name, {this.shouldCheckIntraInvocationId = false});
@override
Expression get(ArgumentList argumentList) {
Expression get(ArgumentList argumentList, {String? intraInvocationId}) {
return argumentList.arguments
.whereType<NamedArgument>()
.where((argument) => argument.name.lexeme == name)
@@ -130,26 +130,6 @@ mixin ResolutionTest implements ResourceProviderMixin {
return result;
}
Future<ResolvedUnitResult> assertErrorsInFile(
String path,
String content,
List<ExpectedDiagnostic> expectedDiagnostics,
) async {
var file = newFile(path, content);
var result = await resolveFile(file);
assertErrorsInResolvedUnit(result, expectedDiagnostics);
return result;
}
Future<void> assertErrorsInFile2(
File file,
List<ExpectedDiagnostic> expectedDiagnostics,
) async {
var result = await resolveFile(file);
assertErrorsInResolvedUnit(result, expectedDiagnostics);
}
void assertErrorsInList(
List<Diagnostic> diagnostics,
List<ExpectedDiagnostic> expectedDiagnostics,
@@ -414,6 +394,65 @@ mixin ResolutionTest implements ResourceProviderMixin {
return resolveFile2(file);
}
/// Writes all [filesToCode], resolves each file, and checks that each file's
/// inline diagnostic markers match its diagnostics.
///
/// All files are written before any file is resolved. This supports tests
/// where resolving one file cleanly requires related files to already exist,
/// such as a library with its parts.
Future<Map<File, TestResolvedUnitResult>> resolveFilesWithDiagnostics(
Map<File, String> filesToCode,
) async {
var files = <({File file, String code, String cleanCode})>[];
for (var entry in filesToCode.entries) {
var cleanCode = removeDiagnosticExpectations(entry.value);
modifyFile2(entry.key, cleanCode);
files.add((file: entry.key, code: entry.value, cleanCode: cleanCode));
}
var results = <File, TestResolvedUnitResult>{};
var diagnosticsByFile = <File, List<Diagnostic>>{};
for (var file in files) {
var result = await resolveFile2(file.file);
results[file.file] = result;
diagnosticsByFile[file.file] = result.diagnostics;
}
var actualCodeByFile = updateExpectedDiagnosticsForFiles(
contentByFile: {for (var file in files) file.file: file.cleanCode},
actualDiagnosticsByFile: diagnosticsByFile,
);
var hasMismatch = false;
for (var index = 0; index < files.length; index++) {
var file = files[index];
var actual = actualCodeByFile[file.file]!;
if (actual != file.code) {
NodeTextExpectationsCollector.add(actual, intraInvocationId: '$index');
print('-------- ${file.file.path} --------');
printPrettyDiff(file.code, actual);
hasMismatch = true;
}
}
if (hasMismatch) {
fail('See the difference above.');
}
return results;
}
/// Writes [code] to [file], resolves it, and checks that its inline
/// diagnostic markers match its diagnostics.
Future<TestResolvedUnitResult> resolveFileWithDiagnostics(
File file,
String code,
) async {
return await _resolveFileWithDiagnostics(file, code);
}
/// Put the [code] into the test file, and resolve it.
Future<TestResolvedUnitResult> resolveTestCode(String code) {
addTestFile(code);
@@ -425,21 +464,7 @@ mixin ResolutionTest implements ResourceProviderMixin {
Future<TestResolvedUnitResult> resolveTestCodeWithDiagnostics(
String code,
) async {
var cleanCode = removeDiagnosticExpectations(code);
addTestFile(cleanCode);
var result = await resolveTestFile();
var actual = updateExpectedDiagnostics(
content: cleanCode,
actualDiagnostics: result.diagnostics,
);
if (actual != code) {
NodeTextExpectationsCollector.add(actual);
printPrettyDiff(code, actual);
fail('See the difference above.');
}
return result;
return await _resolveFileWithDiagnostics(testFile, code);
}
Future<TestResolvedUnitResult> resolveTestFile() {
@@ -480,6 +505,27 @@ mixin ResolutionTest implements ResourceProviderMixin {
return buffer.toString();
}
Future<TestResolvedUnitResult> _resolveFileWithDiagnostics(
File file,
String code,
) async {
var cleanCode = removeDiagnosticExpectations(code);
modifyFile2(file, cleanCode);
var result = await resolveFile2(file);
var actual = updateExpectedDiagnostics(
content: cleanCode,
actualDiagnostics: result.diagnostics,
);
if (actual != code) {
NodeTextExpectationsCollector.add(actual);
printPrettyDiff(code, actual);
fail('See the difference above.');
}
return result;
}
}
/// A test-facing view of a resolved unit, with utilities derived from it.
@@ -2,7 +2,6 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
@@ -67,19 +66,21 @@ class N {}
class N {}
''');
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFilesWithDiagnostics({
a: r'''
export 'lib1.dart';
part 'b.dart';
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
''',
b: r'''
part of 'a.dart';
export 'lib2.dart';
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [error(diag.ambiguousExport, 25, 11)]);
// ^^^^^^^^^^^
// [diag.ambiguousExport] The name 'N' is defined in the libraries 'package:test/lib1.dart' and 'package:test/lib2.dart'.
''',
});
}
test_part_part() async {
@@ -91,25 +92,25 @@ class N {}
class N {}
''');
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var c = getFile('$testPackageLibPath/c.dart');
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
part 'c.dart';
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
''',
b: r'''
part of 'a.dart';
export 'lib1.dart';
''');
var c = newFile('$testPackageLibPath/c.dart', r'''
''',
c: r'''
part of 'a.dart';
export 'lib2.dart';
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, []);
await assertErrorsInFile2(c, [error(diag.ambiguousExport, 25, 11)]);
// ^^^^^^^^^^^
// [diag.ambiguousExport] The name 'N' is defined in the libraries 'package:test/lib1.dart' and 'package:test/lib2.dart'.
''',
});
}
}
@@ -222,9 +222,9 @@ abstract class A {
test_noHintsInTestDir() async {
// Code that is in a test dir should not trigger the hint.
// (See:https://github.com/dart-lang/sdk/issues/45594)
var result = await resolveFileCode(
'$testPackageRootPath/test/test.dart',
r'''
var file = getFile('$testPackageRootPath/test/test.dart');
await resolveFileWithDiagnostics(file, r'''
import 'package:meta/meta.dart';
class A {
@@ -235,9 +235,7 @@ class A {
class B {
String f = A().v;
}
''',
);
assertNoErrorsInTestResult(result);
''');
}
test_tearOff() async {
@@ -2,14 +2,15 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
import '../dart/resolution/node_text_expectations.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(ConflictingFieldAndMethodTest);
defineReflectiveTests(UpdateNodeTextExpectations);
});
}
@@ -43,36 +44,22 @@ class B extends A {
@SkippedTest() // TODO(scheglov): implement augmentation
test_class_inSuper_getter_withAugmentation_inAugmentation() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
await resolveTestCodeWithDiagnostics(r'''
class A {
void foo() {}
}
class B extends A {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
part of 'a.dart';
augment class B {
int get foo => 0;
}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [
error(diag.conflictingFieldAndMethod, 47, 3),
]);
}
@SkippedTest() // TODO(scheglov): implement augmentation
test_class_inSuper_getter_withAugmentation_inDeclaration() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
await resolveTestCodeWithDiagnostics(r'''
class A {
void foo() {}
}
@@ -80,19 +67,9 @@ class A {
class B {
int get foo => 0;
}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
part of 'a.dart';
augment class B extends A {}
''');
await assertErrorsInFile2(a, [
error(diag.conflictingFieldAndMethod, 65, 3),
]);
await assertErrorsInFile2(b, []);
}
test_class_inSuper_setter() async {
@@ -140,36 +117,22 @@ enum E with M {
@SkippedTest() // TODO(scheglov): implement augmentation
test_enum_inMixin_getter_withAugmentation_inAugmentation() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
await resolveTestCodeWithDiagnostics(r'''
mixin M {
void foo() {}
}
enum E with M {v}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
part of 'a.dart';
augment enum E {;
int get foo => 0;
}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [
error(diag.conflictingFieldAndMethod, 47, 3),
]);
}
@SkippedTest() // TODO(scheglov): implement augmentation
test_enum_inMixin_getter_withAugmentation_inDeclaration() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
await resolveTestCodeWithDiagnostics(r'''
mixin M {
void foo() {}
}
@@ -178,19 +141,9 @@ enum E {
v;
int get foo => 0;
}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
part of 'a.dart';
augment enum E with M {}
''');
await assertErrorsInFile2(a, [
error(diag.conflictingFieldAndMethod, 69, 3),
]);
await assertErrorsInFile2(b, []);
}
test_enum_inMixin_setter() async {
@@ -234,36 +187,22 @@ extension type B(int it) implements A {
@SkippedTest() // TODO(scheglov): implement augmentation
test_mixin_inSuper_getter_withAugmentation_inAugmentation() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
await resolveTestCodeWithDiagnostics(r'''
class A {
void foo() {}
}
mixin B on A {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
part of 'a.dart';
augment mixin B {
int get foo => 0;
}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [
error(diag.conflictingFieldAndMethod, 47, 3),
]);
}
@SkippedTest() // TODO(scheglov): implement augmentation
test_mixin_inSuper_getter_withAugmentation_inDeclaration() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
await resolveTestCodeWithDiagnostics(r'''
class A {
void foo() {}
}
@@ -271,18 +210,8 @@ class A {
mixin B {
int get foo => 0;
}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
part of 'a.dart';
augment mixin B on A {}
''');
await assertErrorsInFile2(a, [
error(diag.conflictingFieldAndMethod, 65, 3),
]);
await assertErrorsInFile2(b, []);
}
}
@@ -2,14 +2,15 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
import '../dart/resolution/node_text_expectations.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(ConflictingGenericInterfacesTest);
defineReflectiveTests(UpdateNodeTextExpectations);
});
}
@@ -17,25 +18,12 @@ main() {
class ConflictingGenericInterfacesTest extends PubPackageResolutionTest {
@SkippedTest() // TODO(scheglov): implement augmentation
test_class_extends_augmentation_implements() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part of 'test.dart';
augment class B implements I<String> {}
''');
newFile(testFile.path, '''
part 'a.dart';
await resolveTestCodeWithDiagnostics('''
class I<T> {}
class A implements I<int> {}
class B extends A {}
augment class B implements I<String> {}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(testFile, [
error(diag.conflictingGenericInterfaces, 65, 1),
]);
}
test_class_extends_implements() async {
@@ -2,14 +2,15 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
import '../dart/resolution/node_text_expectations.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(ConflictingMethodAndFieldTest);
defineReflectiveTests(UpdateNodeTextExpectations);
});
}
@@ -43,36 +44,22 @@ class B extends A {
@SkippedTest() // TODO(scheglov): implement augmentation
test_class_inSuper_getter_hasAugmentation_inAugmentation() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
await resolveTestCodeWithDiagnostics(r'''
class A {
int get foo => 0;
}
class B extends A {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
part of 'a.dart';
augment class B {
void foo() {}
}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [
error(diag.conflictingMethodAndField, 44, 3),
]);
}
@SkippedTest() // TODO(scheglov): implement augmentation
test_class_inSuper_getter_hasAugmentation_inDeclaration() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
await resolveTestCodeWithDiagnostics(r'''
class A {
int get foo => 0;
}
@@ -80,19 +67,9 @@ class A {
class B extends A {
void foo() {}
}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
part of 'a.dart';
augment class B {}
''');
await assertErrorsInFile2(a, [
error(diag.conflictingMethodAndField, 76, 3),
]);
await assertErrorsInFile2(b, []);
}
test_class_inSuper_setter() async {
@@ -140,36 +117,22 @@ enum E with M {
@SkippedTest() // TODO(scheglov): implement augmentation
test_enum_inMixin_getter_hasAugmentation_inAugmentation() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
await resolveTestCodeWithDiagnostics(r'''
mixin M {
int get foo => 0;
}
enum E with M {v}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
part of 'a.dart';
augment enum E {;
void foo() {}
}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [
error(diag.conflictingMethodAndField, 44, 3),
]);
}
@SkippedTest() // TODO(scheglov): implement augmentation
test_enum_inMixin_getter_hasAugmentation_inDeclaration() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
await resolveTestCodeWithDiagnostics(r'''
mixin M {
int get foo => 0;
}
@@ -178,19 +141,9 @@ enum E with M {
v;
void foo() {}
}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
part of 'a.dart';
augment enum E {}
''');
await assertErrorsInFile2(a, [
error(diag.conflictingMethodAndField, 77, 3),
]);
await assertErrorsInFile2(b, []);
}
test_enum_inMixin_setter() async {
@@ -3900,24 +3900,22 @@ set f(int value) {}
}
test_topLevel_setter_setter_inPart() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part of 'test.dart';
set f(int value) {}
''');
var a = getFile('$testPackageLibPath/a.dart');
await resolveTestCodeWithDiagnostics(r'''
await resolveFilesWithDiagnostics({
testFile: r'''
part 'a.dart';
set f(int value) {}
''');
await assertErrorsInFile2(a, [
error(
diag.duplicateDefinition,
25,
1,
contextMessages: [message(testFile, 19, 1)],
),
]);
// ^
// [context 1] The first definition of this name.
''',
a: r'''
part of 'test.dart';
set f(int value) {}
// ^
// [diag.duplicateDefinition][context 1] The name 'f=' is already defined.
''',
});
}
test_typeParameters_class() async {
@@ -2,14 +2,15 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
import '../dart/resolution/node_text_expectations.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(DuplicateHiddenNameTest);
defineReflectiveTests(UpdateNodeTextExpectations);
});
}
@@ -28,17 +29,19 @@ export 'lib1.dart' hide A, B, A;
}
test_part_hidden() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
''');
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
''',
b: r'''
part of 'a.dart';
export 'dart:math' hide pi, Random, pi;
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [error(diag.duplicateHiddenName, 54, 2)]);
// ^^
// [diag.duplicateHiddenName] Duplicate hidden name.
''',
});
}
}
@@ -2,15 +2,16 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
import '../dart/resolution/node_text_expectations.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(DuplicateExportTest);
defineReflectiveTests(DuplicateImportTest);
defineReflectiveTests(UpdateNodeTextExpectations);
});
}
@@ -54,19 +55,21 @@ export 'lib1.dart' show A;
}
test_part_duplicateExport() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
''');
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
''',
b: r'''
part of 'a.dart';
export 'dart:math';
export 'dart:math';
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [error(diag.duplicateExport, 45, 11)]);
// ^^^^^^^^^^^
// [diag.duplicateExport] Duplicate export.
''',
});
}
}
@@ -118,114 +121,119 @@ final a = A();
}
test_library_importsHaveIdenticalShowHide() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
library lib1;
class A {}
class B {}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
library L;
import 'lib1.dart' as M show A hide B;
// ^^^^^^^^^^^^^
// [diag.multipleCombinators] Using multiple 'hide' or 'show' combinators is never necessary and often produces surprising results.
import 'lib1.dart' as M show A hide B;
// ^^^^^^^^^^^
// [diag.duplicateImport] Duplicate import.
// ^^^^^^^^^^^^^
// [diag.multipleCombinators] Using multiple 'hide' or 'show' combinators is never necessary and often produces surprising results.
M.A a = M.A();
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, [
error(diag.multipleCombinators, 35, 13),
error(diag.duplicateImport, 57, 11),
error(diag.multipleCombinators, 74, 13),
]);
}
test_library_oneImportHasHide() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
library lib1;
class A {}
class B {}''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
library L;
import 'lib1.dart';
import 'lib1.dart' hide A;
B b = B();
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, []);
}
test_library_oneImportHasShow() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
library lib1;
class A {}
class B {}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
library L;
import 'lib1.dart';
import 'lib1.dart' show A; // ignore: unnecessary_import
A a = A();
B b = B();
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, []);
}
test_library_oneImportUsesAs() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
library lib1;
class A {}''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
library L;
import 'lib1.dart';
import 'lib1.dart' as one;
A a = A();
one.A a2 = one.A();
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, []);
}
test_library_twoDuplicateImports() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
library lib1;
class A {}''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
library L;
import 'lib1.dart';
import 'lib1.dart';
// ^^^^^^^^^^^
// [diag.duplicateImport] Duplicate import.
import 'lib1.dart';
// ^^^^^^^^^^^
// [diag.duplicateImport] Duplicate import.
A a = A();
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, [
error(diag.duplicateImport, 38, 11),
error(diag.duplicateImport, 58, 11),
]);
}
test_part_duplicateImport() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
''');
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
''',
b: r'''
part of 'a.dart';
import 'dart:math';
import 'dart:math';
// ^^^^^^^^^^^
// [diag.duplicateImport] Duplicate import.
void f(Random _) {}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [error(diag.duplicateImport, 45, 11)]);
''',
});
}
}
@@ -2,14 +2,15 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
import '../dart/resolution/node_text_expectations.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(DuplicatePartTest);
defineReflectiveTests(UpdateNodeTextExpectations);
});
}
@@ -57,17 +58,19 @@ part 'part2.dart';
}
test_part_includesSelf() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
''');
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
''',
b: r'''
part of 'a.dart';
part 'b.dart';
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [error(diag.duplicatePart, 23, 8)]);
// ^^^^^^^^
// [diag.duplicatePart] The library already contains a part with the URI 'package:test/b.dart'.
''',
});
}
}
@@ -2,14 +2,15 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
import '../dart/resolution/node_text_expectations.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(DuplicateShownNameTest);
defineReflectiveTests(UpdateNodeTextExpectations);
});
}
@@ -28,17 +29,19 @@ export 'lib1.dart' show A, B, A;
}
test_part_shown() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
''');
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
''',
b: r'''
part of 'a.dart';
export 'dart:math' show pi, Random, pi;
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [error(diag.duplicateShownName, 54, 2)]);
// ^^
// [diag.duplicateShownName] Duplicate shown name.
''',
});
}
}
@@ -2,14 +2,15 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
import '../dart/resolution/node_text_expectations.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(EnumWithoutConstantsTest);
defineReflectiveTests(UpdateNodeTextExpectations);
});
}
@@ -17,16 +18,11 @@ main() {
class EnumWithoutConstantsTest extends PubPackageResolutionTest {
@SkippedTest() // TODO(scheglov): implement augmentation
test_hasConstants_inAugmentation() async {
newFile('$testPackageLibPath/a.dart', r'''
part of 'test.dart';
await resolveTestCodeWithDiagnostics(r'''
enum E {}
augment enum E {
v
}
''');
await resolveTestCodeWithDiagnostics(r'''
part 'a.dart';
enum E {}
''');
}
@@ -40,18 +36,9 @@ enum E {}
@SkippedTest() // TODO(scheglov): implement augmentation
test_noConstants_hasAugmentation() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
await resolveTestCodeWithDiagnostics(r'''
enum E {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
part of 'a.dart';
augment enum E {}
''');
await assertErrorsInFile2(a, [error(diag.enumWithoutConstants, 20, 1)]);
await assertErrorsInFile2(b, []);
}
}
@@ -2,14 +2,15 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
import '../dart/resolution/node_text_expectations.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(ExtendsDisallowedClassTest);
defineReflectiveTests(UpdateNodeTextExpectations);
});
}
@@ -110,18 +111,10 @@ class A extends String {}
@SkippedTest() // TODO(scheglov): implement augmentation
test_class_String_inAugmentation() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
await resolveTestCodeWithDiagnostics(r'''
class A {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
part of 'a.dart';
augment class A extends String {}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [error(diag.extendsDisallowedClass, 42, 6)]);
}
test_classTypeAlias_bool() async {
@@ -2,14 +2,15 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
import '../dart/resolution/node_text_expectations.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(ImplementsDisallowedClassTest);
defineReflectiveTests(UpdateNodeTextExpectations);
});
}
@@ -134,20 +135,10 @@ class A implements String {}
@SkippedTest() // TODO(scheglov): implement augmentation
test_class_String_inAugmentation() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
await resolveTestCodeWithDiagnostics(r'''
class A {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
part of 'a.dart';
augment class A implements String {}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [
error(diag.implementsDisallowedClass, 45, 6),
]);
}
test_class_String_num() async {
@@ -2,14 +2,15 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
import '../dart/resolution/node_text_expectations.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(ImplementsRepeatedTest);
defineReflectiveTests(UpdateNodeTextExpectations);
});
}
@@ -41,22 +42,11 @@ ImplementsClause
@SkippedTest() // TODO(scheglov): implement augmentation
test_class_implements_2times_augmentation() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
await resolveTestCodeWithDiagnostics(r'''
class A {}
class B implements A {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
part of 'a.dart';
augment class B implements A {}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [error(diag.implementsRepeated, 46, 1)]);
}
test_class_implements_2times_viaTypeAlias() async {
@@ -126,22 +116,11 @@ ImplementsClause
@SkippedTest() // TODO(scheglov): implement augmentation
test_enum_implements_2times_augmentation() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
await resolveTestCodeWithDiagnostics(r'''
class A {}
enum E implements A {v}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
part of 'a.dart';
augment enum E implements A {}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [error(diag.implementsRepeated, 45, 1)]);
}
test_enum_implements_2times_viaTypeAlias() async {
@@ -212,21 +191,10 @@ ImplementsClause
@SkippedTest() // TODO(scheglov): implement augmentation
test_extensionType_implements_2times_augmentation() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
await resolveTestCodeWithDiagnostics(r'''
extension type A(int it) implements int {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
part of 'a.dart';
augment extension type A implements int {}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [error(diag.implementsRepeated, 63, 3)]);
}
test_extensionType_implements_2times_viaTypeAlias() async {
@@ -277,22 +245,11 @@ mixin M implements A, A {}
@SkippedTest() // TODO(scheglov): implement augmentation
test_mixin_implements_2times_augmentation() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
await resolveTestCodeWithDiagnostics(r'''
class A {}
mixin M implements A {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
part of 'a.dart';
augment mixin M implements A {}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [error(diag.implementsRepeated, 46, 1)]);
}
test_mixin_implements_4times() async {
@@ -2,21 +2,27 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
import '../dart/resolution/node_text_expectations.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(InconsistentInheritanceTest);
defineReflectiveTests(UpdateNodeTextExpectations);
});
}
@reflectiveTest
class InconsistentInheritanceTest extends PubPackageResolutionTest {
test_class_augmentWithInterface_augmentWithMixin() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var c = getFile('$testPackageLibPath/c.dart');
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
part 'c.dart';
@@ -29,27 +35,33 @@ abstract class B {
}
abstract class C extends Object {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
// ^
// [diag.inconsistentInheritance] Superinterfaces don't have a valid override for 'foo': A.foo (void Function(int)), B.foo (void Function(String)).
''',
b: r'''
part of 'a.dart';
augment abstract class C implements B {}
''');
var c = newFile('$testPackageLibPath/c.dart', r'''
// ^
// [diag.inconsistentInheritance] Superinterfaces don't have a valid override for 'foo': A.foo (void Function(int)), B.foo (void Function(String)).
''',
c: r'''
part of 'a.dart';
augment abstract class C with A {}
''');
await assertErrorsInFile2(a, [error(diag.inconsistentInheritance, 122, 1)]);
await assertErrorsInFile2(b, [error(diag.inconsistentInheritance, 42, 1)]);
await assertErrorsInFile2(c, [error(diag.inconsistentInheritance, 42, 1)]);
// ^
// [diag.inconsistentInheritance] Superinterfaces don't have a valid override for 'foo': A.foo (void Function(int)), B.foo (void Function(String)).
''',
});
}
test_class_augmentWithMixin_augmentWithInterface() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var c = getFile('$testPackageLibPath/c.dart');
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
part 'c.dart';
@@ -62,23 +74,24 @@ abstract class B {
}
abstract class C extends Object {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
// ^
// [diag.inconsistentInheritance] Superinterfaces don't have a valid override for 'foo': A.foo (void Function(int)), B.foo (void Function(String)).
''',
b: r'''
part of 'a.dart';
augment abstract class C with A {}
''');
var c = newFile('$testPackageLibPath/c.dart', r'''
// ^
// [diag.inconsistentInheritance] Superinterfaces don't have a valid override for 'foo': A.foo (void Function(int)), B.foo (void Function(String)).
''',
c: r'''
part of 'a.dart';
augment abstract class C implements B {}
''');
await assertErrorsInFile2(a, [error(diag.inconsistentInheritance, 122, 1)]);
await assertErrorsInFile2(b, [error(diag.inconsistentInheritance, 42, 1)]);
await assertErrorsInFile2(c, [error(diag.inconsistentInheritance, 42, 1)]);
// ^
// [diag.inconsistentInheritance] Superinterfaces don't have a valid override for 'foo': A.foo (void Function(int)), B.foo (void Function(String)).
''',
});
}
test_class_augmentWithMixin_sameFile() async {
@@ -2,193 +2,198 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
import '../dart/resolution/node_text_expectations.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(InconsistentLanguageVersionOverrideTest);
defineReflectiveTests(UpdateNodeTextExpectations);
});
}
@reflectiveTest
class InconsistentLanguageVersionOverrideTest extends PubPackageResolutionTest {
test_0_00_000_AAA() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var c = getFile('$testPackageLibPath/c.dart');
await resolveFilesWithDiagnostics({
a: r'''
// @dart = 3.10
part 'b.dart';
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
''',
b: r'''
// @dart = 3.10
part of 'a.dart';
part 'c.dart';
''');
var c = newFile('$testPackageLibPath/c.dart', r'''
''',
c: r'''
// @dart = 3.10
part of 'b.dart';
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, []);
await assertErrorsInFile2(c, []);
''',
});
}
test_0_00_000_AAB() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var c = getFile('$testPackageLibPath/c.dart');
await resolveFilesWithDiagnostics({
a: r'''
// @dart = 3.10
part 'b.dart';
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
''',
b: r'''
// @dart = 3.10
part of 'a.dart';
part 'c.dart';
''');
var c = newFile('$testPackageLibPath/c.dart', r'''
// ^^^^^^^^
// [diag.inconsistentLanguageVersionOverride] Parts must have exactly the same language version override as the library.
''',
c: r'''
// @dart = 3.11
part of 'b.dart';
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [
error(diag.inconsistentLanguageVersionOverride, 39, 8),
]);
await assertErrorsInFile2(c, []);
''',
});
}
test_0_00_000_AAN() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var c = getFile('$testPackageLibPath/c.dart');
await resolveFilesWithDiagnostics({
a: r'''
// @dart = 3.10
part 'b.dart';
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
''',
b: r'''
// @dart = 3.10
part of 'a.dart';
part 'c.dart';
''');
var c = newFile('$testPackageLibPath/c.dart', r'''
// ^^^^^^^^
// [diag.inconsistentLanguageVersionOverride] Parts must have exactly the same language version override as the library.
''',
c: r'''
part of 'b.dart';
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [
error(diag.inconsistentLanguageVersionOverride, 39, 8),
]);
await assertErrorsInFile2(c, []);
''',
});
}
test_0_00_000_ABB() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var c = getFile('$testPackageLibPath/c.dart');
await resolveFilesWithDiagnostics({
a: r'''
// @dart = 3.10
part 'b.dart';
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
// ^^^^^^^^
// [diag.inconsistentLanguageVersionOverride] Parts must have exactly the same language version override as the library.
''',
b: r'''
// @dart = 3.11
part of 'a.dart';
part 'c.dart';
''');
var c = newFile('$testPackageLibPath/c.dart', r'''
''',
c: r'''
// @dart = 3.11
part of 'b.dart';
''');
await assertErrorsInFile2(a, [
error(diag.inconsistentLanguageVersionOverride, 21, 8),
]);
await assertErrorsInFile2(b, []);
await assertErrorsInFile2(c, []);
''',
});
}
test_0_00_000_NAA() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
''');
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var c = getFile('$testPackageLibPath/c.dart');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
// ^^^^^^^^
// [diag.inconsistentLanguageVersionOverride] Parts must have exactly the same language version override as the library.
''',
b: r'''
// @dart = 3.10
part of 'a.dart';
part 'c.dart';
''');
var c = newFile('$testPackageLibPath/c.dart', r'''
''',
c: r'''
// @dart = 3.10
part of 'b.dart';
''');
await assertErrorsInFile2(a, [
error(diag.inconsistentLanguageVersionOverride, 5, 8),
]);
await assertErrorsInFile2(b, []);
await assertErrorsInFile2(c, []);
''',
});
}
test_0_00_AA() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFilesWithDiagnostics({
a: r'''
// @dart = 3.2
part 'b.dart';
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
''',
b: r'''
// @dart = 3.2
part of 'a.dart';
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, []);
''',
});
}
test_0_00_AB() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFilesWithDiagnostics({
a: r'''
// @dart = 3.1
part 'b.dart';
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
// ^^^^^^^^
// [diag.inconsistentLanguageVersionOverride] Parts must have exactly the same language version override as the library.
''',
b: r'''
// @dart = 3.2
part of 'a.dart';
''');
await assertErrorsInFile2(a, [
error(diag.inconsistentLanguageVersionOverride, 20, 8),
]);
await assertErrorsInFile2(b, []);
''',
});
}
test_0_00_NA() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
''');
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
// ^^^^^^^^
// [diag.inconsistentLanguageVersionOverride] Parts must have exactly the same language version override as the library.
''',
b: r'''
// @dart = 3.1
part of 'a.dart';
''');
await assertErrorsInFile2(a, [
error(diag.inconsistentLanguageVersionOverride, 5, 8),
]);
await assertErrorsInFile2(b, []);
''',
});
}
test_0_00_NN() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
''',
b: r'''
part of 'a.dart';
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, []);
''',
});
}
}
@@ -2,14 +2,15 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
import '../dart/resolution/node_text_expectations.dart';
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(InvalidDoNotSubmitMemberTest);
defineReflectiveTests(UpdateNodeTextExpectations);
});
}
@@ -25,7 +26,9 @@ class InvalidDoNotSubmitMemberTest extends PubPackageResolutionTest {
}
test_constructor() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFileWithDiagnostics(a, r'''
import 'package:meta/meta.dart';
class A {
@@ -34,22 +37,21 @@ class A {
}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFileWithDiagnostics(b, r'''
import 'a.dart';
void b() {
A();
//^
// [diag.invalidUseOfDoNotSubmitMember] Uses of 'A' should not be submitted to source control.
}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [
error(diag.invalidUseOfDoNotSubmitMember, 31, 1),
]);
}
test_constructor_primary() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFileWithDiagnostics(a, r'''
import 'package:meta/meta.dart';
class A() {
@@ -58,20 +60,19 @@ class A() {
}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFileWithDiagnostics(b, r'''
import 'a.dart';
var a = A();
// ^
// [diag.invalidUseOfDoNotSubmitMember] Uses of 'A' should not be submitted to source control.
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [
error(diag.invalidUseOfDoNotSubmitMember, 26, 1),
]);
}
test_constructorFactory() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFileWithDiagnostics(a, r'''
import 'package:meta/meta.dart';
class A {
@@ -81,29 +82,28 @@ class A {
}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFileWithDiagnostics(b, r'''
import 'a.dart';
void b() {
A();
//^
// [diag.invalidUseOfDoNotSubmitMember] Uses of 'A' should not be submitted to source control.
}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [
error(diag.invalidUseOfDoNotSubmitMember, 31, 1),
]);
}
test_exceptionDoNotSubmitMethodReferencingAnotherDoNotSubmitMethod() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFileWithDiagnostics(a, r'''
import 'package:meta/meta.dart';
@doNotSubmit
void a() {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFileWithDiagnostics(b, r'''
import 'package:meta/meta.dart';
import 'a.dart';
@@ -124,13 +124,11 @@ void b() {
}
}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, []);
}
test_exceptionParameterFromParentFunction() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
await resolveFileWithDiagnostics(a, r'''
import 'package:meta/meta.dart';
void a({@doNotSubmit int? a}) {
@@ -140,24 +138,22 @@ void a({@doNotSubmit int? a}) {
c();
}
''');
await assertErrorsInFile2(a, []);
}
test_exceptionParameterFromSameFunction() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
await resolveFileWithDiagnostics(a, r'''
import 'package:meta/meta.dart';
void a({@doNotSubmit int? a}) {
print(a);
}
''');
await assertErrorsInFile2(a, []);
}
test_exceptionParameterFromSameMethod() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
await resolveFileWithDiagnostics(a, r'''
import 'package:meta/meta.dart';
class A {
@@ -167,12 +163,12 @@ class A {
}
}
''');
await assertErrorsInFile2(a, []);
}
test_extensionGetter() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFileWithDiagnostics(a, r'''
import 'package:meta/meta.dart';
extension A on int {
@@ -181,22 +177,21 @@ extension A on int {
}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFileWithDiagnostics(b, r'''
import 'a.dart';
void b() {
print(0.a);
// ^
// [diag.invalidUseOfDoNotSubmitMember] Uses of 'a' should not be submitted to source control.
}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [
error(diag.invalidUseOfDoNotSubmitMember, 39, 1),
]);
}
test_extensionMethod() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFileWithDiagnostics(a, r'''
import 'package:meta/meta.dart';
extension A on int {
@@ -205,22 +200,21 @@ extension A on int {
}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFileWithDiagnostics(b, r'''
import 'a.dart';
void b() {
0.a();
// ^
// [diag.invalidUseOfDoNotSubmitMember] Uses of 'a' should not be submitted to source control.
}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [
error(diag.invalidUseOfDoNotSubmitMember, 33, 1),
]);
}
test_extensionSetter() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFileWithDiagnostics(a, r'''
import 'package:meta/meta.dart';
extension A on int {
@@ -229,42 +223,40 @@ extension A on int {
}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFileWithDiagnostics(b, r'''
import 'a.dart';
void b() {
0.a = 0;
// ^
// [diag.invalidUseOfDoNotSubmitMember] Uses of 'a' should not be submitted to source control.
}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [
error(diag.invalidUseOfDoNotSubmitMember, 33, 1),
]);
}
test_function() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFileWithDiagnostics(a, r'''
import 'package:meta/meta.dart';
@doNotSubmit
void a() {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFileWithDiagnostics(b, r'''
import 'a.dart';
void b() => a();
// ^
// [diag.invalidUseOfDoNotSubmitMember] Uses of 'a' should not be submitted to source control.
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [
error(diag.invalidUseOfDoNotSubmitMember, 30, 1),
]);
}
test_getter() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFileWithDiagnostics(a, r'''
import 'package:meta/meta.dart';
class A {
@@ -273,45 +265,44 @@ class A {
}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFileWithDiagnostics(b, r'''
import 'a.dart';
void b() {
var a = A();
print(a.a);
// ^
// [diag.invalidUseOfDoNotSubmitMember] Uses of 'a' should not be submitted to source control.
}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [
error(diag.invalidUseOfDoNotSubmitMember, 54, 1),
]);
}
test_invalidTargetOfClass() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFileWithDiagnostics(a, r'''
import 'package:meta/meta.dart';
@doNotSubmit
// [diag.invalidAnnotationTarget][column 2][length 11] The annotation 'doNotSubmit' can only be used on constructors, getters, methods, optional parameters, setters, top-level functions, or top-level variables.
class A {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFileWithDiagnostics(b, r'''
import 'a.dart';
void b() {
A();
//^
// [diag.invalidUseOfDoNotSubmitMember] Uses of 'A' should not be submitted to source control.
}
''');
await assertErrorsInFile2(a, [error(diag.invalidAnnotationTarget, 35, 11)]);
await assertErrorsInFile2(b, [
error(diag.invalidUseOfDoNotSubmitMember, 31, 1),
]);
}
test_method() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFileWithDiagnostics(a, r'''
import 'package:meta/meta.dart';
class A {
@@ -320,99 +311,94 @@ class A {
}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFileWithDiagnostics(b, r'''
import 'a.dart';
void b() {
var a = A();
a.a();
// ^
// [diag.invalidUseOfDoNotSubmitMember] Uses of 'a' should not be submitted to source control.
}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [
error(diag.invalidUseOfDoNotSubmitMember, 48, 1),
]);
}
test_namedParameter() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFileWithDiagnostics(a, r'''
import 'package:meta/meta.dart';
void a({@doNotSubmit int? p}) {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFileWithDiagnostics(b, r'''
import 'a.dart';
void b() {
a(p: 0);
// ^
// [diag.invalidUseOfDoNotSubmitMember] Uses of 'p' should not be submitted to source control.
}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [
error(diag.invalidUseOfDoNotSubmitMember, 33, 1),
]);
}
test_parameter_inPrimaryConstructor() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFileWithDiagnostics(a, r'''
import 'package:meta/meta.dart';
class A([@doNotSubmit int x = 0]);
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFileWithDiagnostics(b, r'''
import 'a.dart';
var a = A(1);
// ^
// [diag.invalidUseOfDoNotSubmitMember] Uses of 'x' should not be submitted to source control.
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [
error(diag.invalidUseOfDoNotSubmitMember, 28, 1),
]);
}
test_positionalParameter() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFileWithDiagnostics(a, r'''
import 'package:meta/meta.dart';
void a([@doNotSubmit int? p]) {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFileWithDiagnostics(b, r'''
import 'a.dart';
void b() {
a(0);
// ^
// [diag.invalidUseOfDoNotSubmitMember] Uses of 'p' should not be submitted to source control.
}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [
error(diag.invalidUseOfDoNotSubmitMember, 33, 1),
]);
}
test_sameLibrary() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
await resolveFileWithDiagnostics(a, r'''
import 'package:meta/meta.dart';
@doNotSubmit
void a() {}
void b() => a();
// ^
// [diag.invalidUseOfDoNotSubmitMember] Uses of 'a' should not be submitted to source control.
''');
await assertErrorsInFile2(a, [
error(diag.invalidUseOfDoNotSubmitMember, 72, 1),
]);
}
test_setter() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFileWithDiagnostics(a, r'''
import 'package:meta/meta.dart';
class A {
@@ -421,38 +407,34 @@ class A {
}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFileWithDiagnostics(b, r'''
import 'a.dart';
void b() {
var a = A();
a.a = 0;
// ^
// [diag.invalidUseOfDoNotSubmitMember] Uses of 'a' should not be submitted to source control.
}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [
error(diag.invalidUseOfDoNotSubmitMember, 48, 1),
]);
}
test_topLevelVarable() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
test_topLevelVariable() async {
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFileWithDiagnostics(a, r'''
import 'package:meta/meta.dart';
@doNotSubmit
int a = 0;
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFileWithDiagnostics(b, r'''
import 'a.dart';
void b() => print(a);
// ^
// [diag.invalidUseOfDoNotSubmitMember] Uses of 'a' should not be submitted to source control.
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [
error(diag.invalidUseOfDoNotSubmitMember, 36, 1),
]);
}
}
@@ -6,10 +6,12 @@ import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
import '../dart/resolution/node_text_expectations.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(InvalidOverrideTest);
defineReflectiveTests(UpdateNodeTextExpectations);
});
}
@@ -31,7 +33,11 @@ abstract class C implements B {
}
test_class_augment_method_covariant_multiFile_invalid() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
class A {
@@ -39,22 +45,25 @@ class A {
}
class B extends A {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
''',
b: r'''
part of 'a.dart';
augment class B {
void foo(covariant String a) {}
// ^^^
// [diag.invalidOverride] 'B.foo' ('void Function(String)') isn't a valid override of 'A.foo' ('void Function(num)').
}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [error(diag.invalidOverride, 44, 3)]);
''',
});
}
test_class_augment_method_covariant_multiFile_valid() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
class A {
@@ -62,18 +71,15 @@ class A {
}
class B extends A {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
''',
b: r'''
part of 'a.dart';
augment class B {
void foo(covariant int a) {}
}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, []);
''',
});
}
test_class_augment_method_covariant_singleFile_invalid() async {
@@ -107,28 +113,31 @@ augment class B {
}
test_class_augment_method_multiFile() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
class A {
int foo() => 0;
// ^^^
// [context 1] The member being overridden.
}
class B extends A {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
''',
b: r'''
part of 'a.dart';
augment class B {
String foo() => '';
// ^^^
// [diag.invalidOverride][context 1] 'B.foo' ('String Function()') isn't a valid override of 'A.foo' ('int Function()').
}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [
error(diag.invalidOverride, 46, 3, contextMessages: [message(a, 32, 3)]),
]);
''',
});
}
test_class_augment_method_singleFile() async {
@@ -150,33 +159,31 @@ augment class B {
}
test_class_augment_setter_multiFile() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
class A {
void set foo(int value) {}
// ^^^
// [context 1] The setter being overridden.
}
class B extends A {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
''',
b: r'''
part of 'a.dart';
augment class B {
void set foo(String value) {}
// ^^^
// [diag.invalidOverrideSetter][context 1] The setter 'B.foo' ('void Function(String)') isn't a valid override of 'A.foo' ('void Function(int)').
}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [
error(
diag.invalidOverrideSetter,
48,
3,
contextMessages: [message(a, 37, 3)],
),
]);
''',
});
}
test_class_augment_setter_singleFile() async {
@@ -198,7 +205,12 @@ augment class B {
}
test_class_augment_withClause_multiFile__declaration0_augment1_augment1() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var c = getFile('$testPackageLibPath/c.dart');
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
part 'c.dart';
@@ -206,63 +218,60 @@ mixin M1 {}
mixin M2 {}
class A {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
''',
b: r'''
part of 'a.dart';
augment class A with M1 {}
''');
var c = newFile('$testPackageLibPath/c.dart', r'''
''',
c: r'''
part of 'a.dart';
augment class A with M2 {}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, []);
await assertErrorsInFile2(c, []);
''',
});
}
test_class_augment_withClause_multiFile_declaration0_augment2() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
mixin M1 {}
mixin M2 {}
class A {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
''',
b: r'''
part of 'a.dart';
augment class A with M1, M2 {}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, []);
''',
});
}
test_class_augment_withClause_multiFile_declaration1_augment1() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
mixin M1 {}
mixin M2 {}
class A with M1 {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
''',
b: r'''
part of 'a.dart';
augment class A with M2 {}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, []);
''',
});
}
test_class_augment_withClause_singleFile_declaration0_augment1() async {
@@ -311,22 +320,23 @@ augment class A with M2 {}
}
test_class_augment_withClause_twoFiles_declaration0_augment1() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
mixin M {}
class A {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
''',
b: r'''
part of 'a.dart';
augment class A with M {}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, []);
''',
});
}
test_external_field_covariant_inheritance() async {
@@ -2,14 +2,15 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
import '../dart/resolution/node_text_expectations.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(InvalidUseOfProtectedMemberTest);
defineReflectiveTests(UpdateNodeTextExpectations);
});
}
@@ -22,7 +23,10 @@ class InvalidUseOfProtectedMemberTest extends PubPackageResolutionTest {
}
test_closure() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:meta/meta.dart';
class A {
@@ -30,25 +34,17 @@ class A {
int a() => 42;
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
void main() {
var leak = new A().a;
// ^
// [diag.invalidUseOfProtectedMember] The member 'a' can only be used within instance members of subclasses of 'A'.
print(leak);
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, [
error(
diag.invalidUseOfProtectedMember,
56,
1,
text:
"The member 'a' can only be used within instance members of subclasses of 'A'.",
),
]);
}
test_extendingSubclass() async {
@@ -64,26 +60,27 @@ class B extends A {
}
test_extension_outsideClassAndFile() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:meta/meta.dart';
class A {
@protected
void a(int i) {}
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
extension E on A {
e() {
a(7);
// ^
// [diag.invalidUseOfProtectedMember] The member 'a' can only be used within instance members of subclasses of 'A'.
}
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, [
error(diag.invalidUseOfProtectedMember, 51, 1),
]);
}
test_extensionType_implementedMember() async {
@@ -102,7 +99,10 @@ void main() {
}
test_extensionType_implementedMember_outsideClassAndLibrary() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:meta/meta.dart';
class C {
@protected
@@ -110,16 +110,15 @@ class C {
}
extension type E(C c) implements C { }
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
void main() {
E(C()).f();
// ^
// [diag.invalidUseOfProtectedMember] The member 'f' can only be used within instance members of subclasses of 'C'.
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, [
error(diag.invalidUseOfProtectedMember, 43, 1),
]);
}
test_extensionType_member() async {
@@ -136,23 +135,25 @@ void main() {
}
test_extensionType_member_outsideClassAndLibrary() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:meta/meta.dart';
extension type E(int i) {
@protected
void f(){}
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
void main() {
E(1).f();
// ^
// [diag.invalidUseOfProtectedMember] The member 'f' can only be used within instance members of subclasses of 'E'.
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, [
error(diag.invalidUseOfProtectedMember, 41, 1),
]);
}
test_field() async {
@@ -169,42 +170,44 @@ class B extends A {
}
test_field_outsideClassAndLibrary() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:meta/meta.dart';
class A {
@protected
int f = 0;
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
abstract class B {
int m(A a) => a.f;
// ^
// [diag.invalidUseOfProtectedMember] The member 'f' can only be used within instance members of subclasses of 'A'.
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, [
error(diag.invalidUseOfProtectedMember, 57, 1),
]);
}
test_field_outsideClassAndLibrary_originPrimaryConstructor() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:meta/meta.dart';
class A(@protected var int f);
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
abstract class B {
int m(A a) => a.f;
// ^
// [diag.invalidUseOfProtectedMember] The member 'f' can only be used within instance members of subclasses of 'A'.
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, [
error(diag.invalidUseOfProtectedMember, 57, 1),
]);
}
test_field_subclassAndSameLibrary() async {
@@ -220,14 +223,18 @@ abstract class B implements A {
}
test_fromSuperclassConstraint() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:meta/meta.dart';
abstract class A {
@protected
void foo() {}
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
mixin M on A {
@override
@@ -236,31 +243,29 @@ mixin M on A {
}
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, []);
}
test_function_outsideClassAndLibrary() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:meta/meta.dart';
class A {
@protected
void a(){ }
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
main() {
new A().a();
// ^
// [diag.invalidUseOfProtectedMember] The member 'a' can only be used within instance members of subclasses of 'A'.
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, [
error(diag.invalidUseOfProtectedMember, 40, 1),
]);
}
test_function_sameLibrary() async {
@@ -302,48 +307,50 @@ class B extends A {
}
test_getter_outsideClassAndLibrary() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:meta/meta.dart';
class A {
@protected
int get a => 42;
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
class B {
A a = A();
int b() => a.a;
// ^
// [diag.invalidUseOfProtectedMember] The member 'a' can only be used within instance members of subclasses of 'A'.
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, [
error(diag.invalidUseOfProtectedMember, 58, 1),
]);
}
test_getter_outsideClassAndLibrary_inObjectPattern() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:meta/meta.dart';
class A {
@protected
int get a => 42;
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
void f(Object o) {
switch (o) {
case A(a: 7): print('yes');
// ^
// [diag.invalidUseOfProtectedMember] The member 'a' can only be used within instance members of subclasses of 'A'.
}
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, [
error(diag.invalidUseOfProtectedMember, 65, 1),
]);
}
test_getter_subclass() async {
@@ -359,7 +366,10 @@ abstract class B implements A {
}
test_inDocs() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:meta/meta.dart';
class A {
@@ -373,36 +383,35 @@ class A {
int a() => 0;
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
/// OK: [A.a], [A.b], [A.c].
f() {}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, []);
}
test_method_outsideClassAndLibrary() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:meta/meta.dart';
class A {
@protected
void a() {}
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
class B {
void b() => new A().a();
// ^
// [diag.invalidUseOfProtectedMember] The member 'a' can only be used within instance members of subclasses of 'A'.
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, [
error(diag.invalidUseOfProtectedMember, 53, 1),
]);
}
test_method_subclass() async {
@@ -470,27 +479,28 @@ main() {
// TODO(srawlins): This test verifies that the analyzer **allows**
// protected members to be called on objects other than `this`, which
// violates the protected spec.
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:meta/meta.dart';
class A {
@protected
void set a(int i) { }
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
class B {
A a = A();
b(int i) {
a.a = i;
// ^
// [diag.invalidUseOfProtectedMember] The member 'a' can only be used within instance members of subclasses of 'A'.
}
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, [
error(diag.invalidUseOfProtectedMember, 62, 1),
]);
}
test_setter_sameClass() async {
@@ -2,15 +2,16 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:analyzer_testing/package_config_file_builder.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
import '../dart/resolution/node_text_expectations.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(InvalidUseOfVisibleForTemplateMemberTest);
defineReflectiveTests(UpdateNodeTextExpectations);
});
}
@@ -29,76 +30,86 @@ class InvalidUseOfVisibleForTemplateMemberTest
}
test_class_constructor_named() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
class A {
int _x;
// ^^
// [diag.unusedField] The value of the field '_x' isn't used.
@visibleForTemplate
A.forTemplate(this._x);
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
void f() {
new A.forTemplate(0);
// ^^^^^^^^^^^^^
// [diag.invalidUseOfVisibleForTemplateMember] The member 'A.forTemplate' can only be used within 'package:test/lib1.dart' or a template library.
}
''');
await assertErrorsInFile2(lib1, [error(diag.unusedField, 66, 2)]);
await assertErrorsInFile2(lib2, [
error(diag.invalidUseOfVisibleForTemplateMember, 38, 13),
]);
}
test_class_constructor_unnamed() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
class A {
int _x;
// ^^
// [diag.unusedField] The value of the field '_x' isn't used.
@visibleForTemplate
A(this._x);
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
void f() {
new A(0);
// ^
// [diag.invalidUseOfVisibleForTemplateMember] The member 'A' can only be used within 'package:test/lib1.dart' or a template library.
}
''');
await assertErrorsInFile2(lib1, [error(diag.unusedField, 66, 2)]);
await assertErrorsInFile2(lib2, [
error(diag.invalidUseOfVisibleForTemplateMember, 38, 1),
]);
}
test_class_declaration() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
@visibleForTemplate
class A {}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
void f() {
A;
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, []);
}
test_class_getter() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
class A {
@@ -106,22 +117,23 @@ class A {
int get foo => 7;
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
void f(A a) {
a.foo;
// ^^^
// [diag.invalidUseOfVisibleForTemplateMember] The member 'foo' can only be used within 'package:test/lib1.dart' or a template library.
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, [
error(diag.invalidUseOfVisibleForTemplateMember, 39, 3),
]);
}
test_class_getter_withVisibleOutsideTemplate() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
@visibleForTemplate
@@ -133,20 +145,21 @@ class A {
int get foo => 7;
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
void f(A a) {
a.foo;
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, []);
}
test_class_method() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
@visibleForTemplate
@@ -154,22 +167,23 @@ class A {
int foo() => 1;
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
void f(A a) {
a.foo();
// ^^^
// [diag.invalidUseOfVisibleForTemplateMember] The member 'foo' can only be used within 'package:test/lib1.dart' or a template library.
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, [
error(diag.invalidUseOfVisibleForTemplateMember, 39, 3),
]);
}
test_class_method_fromTemplate() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var template = getFile('$testPackageLibPath/lib1.template.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
class A {
@@ -177,20 +191,21 @@ class A {
void foo() {}
}
''');
var template = newFile('$testPackageLibPath/lib1.template.dart', r'''
await resolveFileWithDiagnostics(template, r'''
import 'lib1.dart';
class B {
void b(A a) => a.foo();
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(template, []);
}
test_class_method_inMixin() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
@visibleForTemplate
@@ -199,22 +214,23 @@ mixin M {
}
class C with M {}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
void f(C c) {
c.foo();
// ^^^
// [diag.invalidUseOfVisibleForTemplateMember] The member 'foo' can only be used within 'package:test/lib1.dart' or a template library.
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, [
error(diag.invalidUseOfVisibleForTemplateMember, 39, 3),
]);
}
test_class_method_inMixin_withVisibleOutsideTemplate() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
@visibleForTemplate
@@ -224,20 +240,21 @@ mixin M {
}
class C with M {}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
void f(C c) {
c.foo();
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, []);
}
test_class_method_parameter_withVisibleOutsideTemplate() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
@visibleForTemplate
@@ -250,20 +267,21 @@ class A {
}
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
void f(A a) {
a.foo(bar: true);
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, []);
}
test_class_method_withVisibleOutsideTemplate() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
@visibleForTemplate
@@ -272,20 +290,21 @@ class A {
int foo() => 1;
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
void f(A a) {
a.foo();
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, []);
}
test_class_setter() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
@visibleForTemplate
@@ -293,22 +312,23 @@ class A {
set bar(_) => 7;
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
void f(A a) {
a.bar = 6;
// ^^^
// [diag.invalidUseOfVisibleForTemplateMember] The member 'bar' can only be used within 'package:test/lib1.dart' or a template library.
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, [
error(diag.invalidUseOfVisibleForTemplateMember, 39, 3),
]);
}
test_class_setter_withVisibleOutsideTemplate() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
@visibleForTemplate
@@ -317,20 +337,21 @@ class A {
set bar(_) => 7;
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
void f(A a) {
a.bar = 6;
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, []);
}
test_enum_constant() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
@visibleForTemplate
@@ -339,22 +360,23 @@ enum E {
b,
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
void f() {
E.a;
// ^
// [diag.invalidUseOfVisibleForTemplateMember] The member 'a' can only be used within 'package:test/lib1.dart' or a template library.
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, [
error(diag.invalidUseOfVisibleForTemplateMember, 36, 1),
]);
}
test_enum_constant_withVisibleOutsideTemplate() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
@visibleForTemplate
@@ -364,20 +386,21 @@ enum E {
b,
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
void f() {
E.a;
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, []);
}
test_enum_declaration() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
@visibleForTemplate
@@ -385,35 +408,37 @@ enum E {
a,
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
void f() {
E;
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, []);
}
test_export() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
@visibleForTemplate
int foo() => 1;
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
export 'lib1.dart' show foo;
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, []);
}
test_extend_class() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
@visibleForTemplate
@@ -421,7 +446,8 @@ class A {
int foo() => 1;
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
class B extends A {
@@ -429,17 +455,17 @@ class B extends A {
void f() {
var b = B();
b.foo();
// ^^^
// [diag.invalidUseOfVisibleForTemplateMember] The member 'foo' can only be used within 'package:test/lib1.dart' or a template library.
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, [
error(diag.invalidUseOfVisibleForTemplateMember, 73, 3),
]);
}
test_extend_class_super() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
@visibleForTemplate
@@ -447,22 +473,23 @@ class A {
int foo() => 1;
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
class B extends A {
void bar() => super.foo();
// ^^^
// [diag.invalidUseOfVisibleForTemplateMember] The member 'foo' can only be used within 'package:test/lib1.dart' or a template library.
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, [
error(diag.invalidUseOfVisibleForTemplateMember, 63, 3),
]);
}
test_extend_class_withOverride() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
@visibleForTemplate
@@ -470,7 +497,8 @@ class A {
int foo() => 1;
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
class B extends A {
@@ -482,13 +510,13 @@ void f() {
b.foo();
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, []);
}
test_extend_class_withProtected() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
import 'package:meta/meta.dart';
@@ -499,7 +527,8 @@ class A {
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
class B extends A {
@@ -510,13 +539,13 @@ void f() {
b.foo();
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, []);
}
test_function_inExtension() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
extension E on List {
@@ -524,22 +553,23 @@ extension E on List {
int foo() => 1;
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
void f() {
E([]).foo();
// ^^^
// [diag.invalidUseOfVisibleForTemplateMember] The member 'foo' can only be used within 'package:test/lib1.dart' or a template library.
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, [
error(diag.invalidUseOfVisibleForTemplateMember, 40, 3),
]);
}
test_function_inExtension_fromTemplate() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var template = getFile('$testPackageLibPath/lib1.template.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
extension E on List {
@@ -547,20 +577,21 @@ extension E on List {
int foo() => 1;
}
''');
var template = newFile('$testPackageLibPath/lib1.template.dart', r'''
await resolveFileWithDiagnostics(template, r'''
import 'lib1.dart';
void f() {
E([]).foo();
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(template, []);
}
test_protectedAndForTemplate_usedAsProtected() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
import 'package:meta/meta.dart';
@@ -570,20 +601,21 @@ class A {
void a(){ }
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
class B extends A {
void b() => new A().a();
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, []);
}
test_protectedAndForTemplate_usedAsTemplate() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var template = getFile('$testPackageLibPath/lib1.template.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
import 'package:meta/meta.dart';
@@ -593,20 +625,21 @@ class A {
void foo() {}
}
''');
var template = newFile('$testPackageLibPath/lib1.template.dart', r'''
await resolveFileWithDiagnostics(template, r'''
import 'lib1.dart';
void f(A a) {
a.foo();
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(template, []);
}
test_static_class_member_withVisibleOutsideTemplate() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
@visibleForTemplate
@@ -615,77 +648,78 @@ class C {
static int foo() => 1;
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
void f() {
C.foo();
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, []);
}
test_supertype_method() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
@visibleForTemplate
class A {}
var a = A();
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
void f() {
print(a.hashCode);
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, []);
}
test_topLevelFunction() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
@visibleForTemplate
int foo() => 1;
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
void f() {
foo();
//^^^
// [diag.invalidUseOfVisibleForTemplateMember] The member 'foo' can only be used within 'package:test/lib1.dart' or a template library.
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, [
error(diag.invalidUseOfVisibleForTemplateMember, 34, 3),
]);
}
test_topLevelVariable() async {
var lib1 = newFile('$testPackageLibPath/lib1.dart', r'''
var lib1 = getFile('$testPackageLibPath/lib1.dart');
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib1, r'''
import 'package:angular_meta/angular_meta.dart';
@visibleForTemplate
int foo = 7;
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
void f() {
foo;
//^^^
// [diag.invalidUseOfVisibleForTemplateMember] The member 'foo' can only be used within 'package:test/lib1.dart' or a template library.
}
''');
await assertErrorsInFile2(lib1, []);
await assertErrorsInFile2(lib2, [
error(diag.invalidUseOfVisibleForTemplateMember, 34, 3),
]);
}
}
@@ -2,10 +2,10 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
import '../dart/resolution/node_text_expectations.dart';
main() {
defineReflectiveSuite(() {
@@ -13,6 +13,7 @@ main() {
defineReflectiveTests(
InvalidUseOfVisibleForTestingMemberWithTestInAncestorPathTest,
);
defineReflectiveTests(UpdateNodeTextExpectations);
});
}
@@ -84,12 +85,12 @@ class A {
void a() {}
}
''');
var test = newFile('$testPackageRootPath/integration_test/test.dart', r'''
var file = getFile('$testPackageRootPath/integration_test/test.dart');
await resolveFileWithDiagnostics(file, r'''
import 'package:test/lib1.dart';
void f() => A().a();
''');
await assertErrorsInFile2(test, []);
}
test_fromTestDirectory() async {
@@ -100,12 +101,12 @@ class A {
void a() {}
}
''');
var test = newFile('$testPackageRootPath/test/test.dart', r'''
var file = getFile('$testPackageRootPath/test/test.dart');
await resolveFileWithDiagnostics(file, r'''
import 'package:test/lib1.dart';
void f() => A().a();
''');
await assertErrorsInFile2(test, []);
}
test_fromTestDriverDirectory() async {
@@ -116,12 +117,12 @@ class A {
void a() {}
}
''');
var test = newFile('$testPackageRootPath/test_driver/test.dart', r'''
var file = getFile('$testPackageRootPath/test_driver/test.dart');
await resolveFileWithDiagnostics(file, r'''
import 'package:test/lib1.dart';
void f() => A().a();
''');
await assertErrorsInFile2(test, []);
}
test_fromTestingDirectory() async {
@@ -132,12 +133,12 @@ class A {
void a() {}
}
''');
var lib2 = newFile('$testPackageRootPath/testing/lib2.dart', r'''
var lib2 = getFile('$testPackageRootPath/testing/lib2.dart');
await resolveFileWithDiagnostics(lib2, r'''
import 'package:test/lib1.dart';
void f() => A().a();
''');
await assertErrorsInFile2(lib2, []);
}
test_functionInExtension() async {
@@ -166,14 +167,14 @@ extension E on List {
int m() => 1;
}
''');
var test = newFile('$testPackageRootPath/test/test.dart', r'''
var file = getFile('$testPackageRootPath/test/test.dart');
await resolveFileWithDiagnostics(file, r'''
import 'package:test/lib1.dart';
void f() {
E([]).m();
}
''');
await assertErrorsInFile2(test, []);
}
test_getter() async {
@@ -202,18 +203,18 @@ class A {
int get g => 7;
}
''');
var lib2 = newFile('$testPackageLibPath/lib2.dart', r'''
var lib2 = getFile('$testPackageLibPath/lib2.dart');
await resolveFileWithDiagnostics(lib2, r'''
import 'lib1.dart';
void f(Object o) {
switch (o) {
case A(g: 7): print('yes');
// ^
// [diag.invalidUseOfVisibleForTestingMember] The member 'g' can only be used within 'package:test/lib1.dart' or a test.
}
}
''');
await assertErrorsInFile2(lib2, [
error(diag.invalidUseOfVisibleForTestingMember, 65, 1),
]);
}
test_import_hide() async {
@@ -317,14 +318,13 @@ extension type E(int i) {
}
''');
var test = newFile('$testPackageRootPath/test/test.dart', r'''
var file = getFile('$testPackageRootPath/test/test.dart');
await resolveFileWithDiagnostics(file, r'''
import 'package:test/lib1.dart';
void f() {
E(1).m();
}
''');
await assertErrorsInFile2(test, []);
}
test_mixin() async {
@@ -393,14 +393,13 @@ class A {
}
''');
var test = newFile('$testPackageRootPath/test/test.dart', r'''
var file = getFile('$testPackageRootPath/test/test.dart');
await resolveFileWithDiagnostics(file, r'''
import 'package:test/lib1.dart';
void f() {
A().a();
}
''');
await assertErrorsInFile2(test, []);
}
test_setter() async {
@@ -79,18 +79,10 @@ class A extends Object with int {}
@SkippedTest() // TODO(scheglov): implement augmentation
test_class_int_inAugmentation() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
await resolveTestCodeWithDiagnostics(r'''
class A {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
part of 'a.dart';
augment class A with int {}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, []);
}
test_class_Null() async {
@@ -212,17 +204,9 @@ enum E with int {
@SkippedTest() // TODO(scheglov): implement augmentation
test_enum_int_inAugmentation() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
await resolveTestCodeWithDiagnostics(r'''
enum A {v}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
part of 'a.dart';
augment enum A with int {}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, []);
}
}
@@ -45,18 +45,10 @@ MixinOnClause
@SkippedTest() // TODO(scheglov): implement augmentation
test_in_inAugmentation() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
await resolveTestCodeWithDiagnostics(r'''
mixin A {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
part of 'a.dart';
augment mixin A on int {}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, []);
}
test_int() async {
@@ -2,7 +2,6 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
@@ -126,7 +125,11 @@ class C extends B {}
}
test_augment_withClause_crossFile_error_nonAbstractClassInheritsAbstractMember() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
mixin M {
@@ -134,20 +137,17 @@ mixin M {
}
class A {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
// ^
// [diag.nonAbstractClassInheritsAbstractMemberOne] Missing concrete implementation of 'M.foo'.
''',
b: r'''
part of 'a.dart';
augment class A with M {}
''');
await assertErrorsInFile2(a, [
error(diag.nonAbstractClassInheritsAbstractMemberOne, 48, 1),
]);
await assertErrorsInFile2(b, [
error(diag.nonAbstractClassInheritsAbstractMemberOne, 33, 1),
]);
// ^
// [diag.nonAbstractClassInheritsAbstractMemberOne] Missing concrete implementation of 'M.foo'.
''',
});
}
test_augment_withClause_sameFile_error_nonAbstractClassInheritsAbstractMember() async {
@@ -2,7 +2,6 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
@@ -28,22 +27,11 @@ mixin M on A, A {}
@SkippedTest() // TODO(scheglov): implement augmentation
test_2times_augmentation() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
await resolveTestCodeWithDiagnostics(r'''
class A {}
mixin M on A {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
part of 'a.dart';
augment mixin M on A {}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [error(diag.onRepeated, 38, 1)]);
}
test_2times_viaTypeAlias() async {
@@ -43,9 +43,9 @@ class A {
test_noHintsInTestDir() async {
// Code that is in a test dir should not trigger the hint.
// (See:https://github.com/dart-lang/sdk/issues/45594)
var result = await resolveFileCode(
'$testPackageRootPath/test/test.dart',
r'''
var file = getFile('$testPackageRootPath/test/test.dart');
await resolveFileWithDiagnostics(file, r'''
import 'package:meta/meta.dart';
@doNotStore
@@ -59,9 +59,7 @@ String f() {
String g() {
return _v;
}
''',
);
assertNoErrorsInTestResult(result);
''');
}
test_returnFromClosureInFunction() async {
@@ -2,7 +2,6 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -188,15 +187,19 @@ f(A a1, p.A a2, B b) {}
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/61877')
test_library_export_and_export() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var c = getFile('$testPackageLibPath/c.dart');
await resolveFileWithDiagnostics(a, r'''
class C {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFileWithDiagnostics(b, r'''
export 'a.dart';
''');
var c = newFile('$testPackageLibPath/c.dart', r'''
await resolveFileWithDiagnostics(c, r'''
export 'a.dart';
''');
@@ -206,9 +209,6 @@ import 'c.dart';
method() => C();
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, []);
await assertErrorsInFile2(c, []);
// Import of 'c.dart' is not marked as unused even though it could be
// removed.
var result = await resolveFile(d);
@@ -386,11 +386,14 @@ f(A a, B b) {}
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/61877')
test_library_import_and_export() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFileWithDiagnostics(a, r'''
class C {}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFileWithDiagnostics(b, r'''
export 'a.dart';
''');
@@ -400,8 +403,6 @@ import 'b.dart';
method() => C();
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, []);
// Import of 'b.dart' is not marked as unused even though it could be
// removed.
var result = await resolveFile(c);
@@ -492,20 +493,22 @@ class A {}
class B {}
''');
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
''');
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
''',
b: r'''
part of 'a.dart';
import 'x.dart' hide B;
// ^^^^^^^^
// [diag.unnecessaryImport] The import of 'x.dart' is unnecessary because all of the used elements are also provided by the import of 'x.dart'.
import 'x.dart';
void f(A _, B _) {}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [error(diag.unnecessaryImport, 25, 8)]);
''',
});
}
test_part_inside_unnecessary_prefixed() async {
@@ -514,19 +517,21 @@ class A {}
class B {}
''');
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
''');
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
''',
b: r'''
part of 'a.dart';
import 'x.dart' as prefix hide B;
// ^^^^^^^^
// [diag.unnecessaryImport] The import of 'x.dart' is unnecessary because all of the used elements are also provided by the import of 'x.dart'.
import 'x.dart' as prefix;
void f(prefix.A _, prefix.B _) {}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [error(diag.unnecessaryImport, 25, 8)]);
''',
});
}
}
@@ -2,7 +2,6 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
@@ -200,21 +199,22 @@ extension E on int {
}
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
var b = getFile('$testPackageLibPath/b.dart');
var c = getFile('$testPackageLibPath/c.dart');
await resolveFilesWithDiagnostics({
b: r'''
import 'a.dart';
part 'c.dart';
''');
var c = newFile('$testPackageLibPath/c.dart', r'''
''',
c: r'''
part of 'b.dart';
void f() {
0.foo();
}
''');
await assertErrorsInFile2(b, []);
await assertErrorsInFile2(c, []);
''',
});
}
test_library_extension_instance_operator_binary() async {
@@ -590,20 +590,21 @@ extension E on int {
}
''');
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFilesWithDiagnostics({
a: r'''
import 'x.dart';
part 'b.dart';
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
''',
b: r'''
part of 'a.dart';
void f() {
0.foo();
}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, []);
''',
});
}
test_part_extension_usedPartImport() async {
@@ -613,20 +614,21 @@ extension E on int {
}
''');
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
''');
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
''',
b: r'''
part of 'a.dart';
import 'x.dart';
void f() {
0.foo();
}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, []);
''',
});
}
test_part_extension_usedPartImport_inNestedPart() async {
@@ -636,124 +638,131 @@ extension E on int {
}
''');
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
''');
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var c = getFile('$testPackageLibPath/c.dart');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
''',
b: r'''
part of 'a.dart';
import 'x.dart';
part 'c.dart';
''');
var c = newFile('$testPackageLibPath/c.dart', r'''
''',
c: r'''
part of 'b.dart';
void f() {
0.foo();
}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, []);
await assertErrorsInFile2(c, []);
''',
});
}
test_part_notUsedPartImport() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
''');
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
''',
b: r'''
part of 'a.dart';
import 'dart:math';
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, [error(diag.unusedImport, 25, 11)]);
// ^^^^^^^^^^^
// [diag.unusedImport] Unused import: 'dart:math'.
''',
});
}
test_part_usedLibraryImport() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFilesWithDiagnostics({
a: r'''
import 'dart:math';
part 'b.dart';
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
''',
b: r'''
part of 'a.dart';
void f(Random _) {}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, []);
''',
});
}
test_part_usedLibraryImport_usedPartImport() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
await resolveFilesWithDiagnostics({
a: r'''
import 'dart:math';
part 'b.dart';
''');
var b = newFile('$testPackageLibPath/b.dart', r'''
''',
b: r'''
part of 'a.dart';
import 'dart:async';
void f(Random _, Future<int> _) {}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, []);
''',
});
}
test_part_usedPartImport() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
''');
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
''',
b: r'''
part of 'a.dart';
import 'dart:math';
void f(Random _) {}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, []);
''',
});
}
test_part_usedPartImport_inNestedPart() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
''');
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var c = getFile('$testPackageLibPath/c.dart');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFilesWithDiagnostics({
a: r'''
part 'b.dart';
''',
b: r'''
part of 'a.dart';
import 'dart:math';
part 'c.dart';
''');
var c = newFile('$testPackageLibPath/c.dart', r'''
''',
c: r'''
part of 'b.dart';
void f(Random _) {}
''');
await assertErrorsInFile2(a, []);
await assertErrorsInFile2(b, []);
await assertErrorsInFile2(c, []);
''',
});
}
test_part_usedPartImport_notUsedLibraryImport() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
import 'dart:math';
part 'b.dart';
''');
var a = getFile('$testPackageLibPath/a.dart');
var b = getFile('$testPackageLibPath/b.dart');
var b = newFile('$testPackageLibPath/b.dart', r'''
await resolveFilesWithDiagnostics({
a: r'''
import 'dart:math';
// ^^^^^^^^^^^
// [diag.unusedImport] Unused import: 'dart:math'.
part 'b.dart';
''',
b: r'''
part of 'a.dart';
import 'dart:math';
void f(Random _) {}
''');
await assertErrorsInFile2(a, [error(diag.unusedImport, 7, 11)]);
await assertErrorsInFile2(b, []);
''',
});
}
}
@@ -2,7 +2,6 @@
// 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:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:analyzer_testing/utilities/utilities.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -273,27 +272,31 @@ int y = (0 as int);
}
test_undefinedFunctionWithinFlutterCanBeIgnored() async {
await assertErrorsInFile('$workspaceRootPath/flutterlib/flutter.dart', '''
var file = getFile('$workspaceRootPath/flutter/lib/flutter.dart');
await resolveFileWithDiagnostics(file, '''
// ignore: undefined_function
f() => g();
''', []);
''');
}
test_undefinedFunctionWithinFlutterWithoutIgnore() async {
await assertErrorsInFile(
'$workspaceRootPath/flutterlib/flutter.dart',
'''
var file = getFile('$workspaceRootPath/flutter/lib/flutter.dart');
await resolveFileWithDiagnostics(file, '''
f() => g();
''',
[error(diag.undefinedFunction, 7, 1)],
);
// ^
// [diag.undefinedFunction] The function 'g' isn't defined.
''');
}
test_undefinedPrefixedNameWithinFlutterCanBeIgnored() async {
await assertErrorsInFile('$workspaceRootPath/flutterlib/flutter.dart', '''
var file = getFile('$workspaceRootPath/flutter/lib/flutter.dart');
await resolveFileWithDiagnostics(file, '''
import 'dart:collection' as c;
// ignore: undefined_prefixed_name
f() => c.g;
''', []);
''');
}
}
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/diagnostic/diagnostic.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/source/line_info.dart';
import 'package:analyzer_testing/utilities/extensions/diagnostic_code.dart';
@@ -51,6 +52,88 @@ String updateExpectedDiagnostics({
return _ExpectedDiagnosticsUpdater(content).update(actualDiagnostics);
}
/// Returns each file's content with canonical diagnostic expectation markers.
///
/// This is the multi-file form of [updateExpectedDiagnostics]. It supports
/// diagnostics whose context messages are located in another file in
/// [contentByFile].
Map<File, String> updateExpectedDiagnosticsForFiles({
required Map<File, String> contentByFile,
required Map<File, List<Diagnostic>> actualDiagnosticsByFile,
}) {
return _ExpectedDiagnosticsForFilesUpdater(
contentByFile,
).update(actualDiagnosticsByFile);
}
final class _ExpectedDiagnosticsForFilesUpdater {
final Map<File, _ExpectedDiagnosticsUpdater> updatersByFile = {};
final Map<String, _ExpectedDiagnosticsUpdater> updatersByPath = {};
int nextMarkerIndex = 0;
int nextContextId = 1;
_ExpectedDiagnosticsForFilesUpdater(Map<File, String> contentByFile) {
for (var entry in contentByFile.entries) {
var updater = _ExpectedDiagnosticsUpdater(entry.value);
updatersByFile[entry.key] = updater;
updatersByPath[entry.key.path] = updater;
}
}
Map<File, String> update(
Map<File, List<Diagnostic>> actualDiagnosticsByFile,
) {
for (var entry in actualDiagnosticsByFile.entries) {
var updater = _updaterForPath(entry.key.path);
var sortedDiagnostics = entry.value.toList()
..sort((first, second) => first.offset.compareTo(second.offset));
for (var diagnostic in sortedDiagnostics) {
_generateDiagnosticMarkers(updater, diagnostic);
}
}
return {
for (var entry in updatersByFile.entries)
entry.key: entry.value._writeContent(),
};
}
void _generateDiagnosticMarkers(
_ExpectedDiagnosticsUpdater diagnosticUpdater,
Diagnostic diagnostic,
) {
var contextRefs = <int>[];
for (var contextMessage in diagnostic.contextMessages) {
var contextUpdater = _updaterForPath(contextMessage.filePath);
var id = nextContextId++;
contextRefs.add(id);
contextUpdater._addContextMessageMarker(
contextMessage,
id: id,
index: nextMarkerIndex++,
);
}
diagnosticUpdater._addDiagnosticMarker(
diagnostic,
index: nextMarkerIndex++,
contextRefs: contextRefs,
);
}
_ExpectedDiagnosticsUpdater _updaterForPath(String path) {
var updater = updatersByPath[path];
if (updater == null) {
throw StateError(
'Cannot generate diagnostic expectations for $path: '
'no content was provided.',
);
}
return updater;
}
}
final class _ExpectedDiagnosticsUpdater {
final List<_Line> lines;
final LineInfo lineInfo;
@@ -77,6 +160,61 @@ final class _ExpectedDiagnosticsUpdater {
return _writeContent();
}
void _addContextMessageMarker(
DiagnosticMessage contextMessage, {
required int id,
required int index,
}) {
var location = _markerLocation(offset: contextMessage.offset);
var line = lines[location.lineNumber - 1];
var presentation = _markerPresentation(
line,
column: location.column,
length: contextMessage.length,
);
_addMarker(
location.lineNumber,
_GeneratedMarker.context(
offset: contextMessage.offset,
index: index,
id: id,
column: location.column,
length: contextMessage.length,
caretLength: presentation.caretLength,
includeExplicitLocation: presentation.includeExplicitLocation,
message: _messageText(contextMessage),
),
);
}
void _addDiagnosticMarker(
Diagnostic diagnostic, {
required int index,
required List<int> contextRefs,
}) {
var location = _markerLocation(offset: diagnostic.offset);
var line = lines[location.lineNumber - 1];
var presentation = _markerPresentation(
line,
column: location.column,
length: diagnostic.length,
);
_addMarker(
location.lineNumber,
_GeneratedMarker.diagnostic(
offset: diagnostic.offset,
index: index,
constantName: diagnostic.diagnosticCode.constantName,
column: location.column,
length: diagnostic.length,
caretLength: presentation.caretLength,
includeExplicitLocation: presentation.includeExplicitLocation,
contextRefs: contextRefs,
message: _messageText(diagnostic.problemMessage),
),
);
}
void _addMarker(int lineNumber, _GeneratedMarker marker) {
markersByLine.putIfAbsent(lineNumber, () => []).add(marker);
}
@@ -90,58 +228,25 @@ final class _ExpectedDiagnosticsUpdater {
var contextRefs = <int>[];
for (var contextMessage in diagnostic.contextMessages) {
if (contextMessage.filePath != diagnostic.problemMessage.filePath) {
// TODO(scheglov): Support generating expectations for context
// messages in other files.
throw StateError(
'Cannot generate a diagnostic expectation with a context message '
'in another file.',
'in another file. Use updateExpectedDiagnosticsForFiles instead.',
);
}
var id = nextContextId++;
contextRefs.add(id);
var location = _markerLocation(offset: contextMessage.offset);
var line = lines[location.lineNumber - 1];
var presentation = _markerPresentation(
line,
column: location.column,
length: contextMessage.length,
);
_addMarker(
location.lineNumber,
_GeneratedMarker.context(
offset: contextMessage.offset,
index: nextMarkerIndex++,
id: id,
column: location.column,
length: contextMessage.length,
caretLength: presentation.caretLength,
includeExplicitLocation: presentation.includeExplicitLocation,
message: _messageText(contextMessage),
),
_addContextMessageMarker(
contextMessage,
id: id,
index: nextMarkerIndex++,
);
}
var location = _markerLocation(offset: diagnostic.offset);
var line = lines[location.lineNumber - 1];
var presentation = _markerPresentation(
line,
column: location.column,
length: diagnostic.length,
);
_addMarker(
location.lineNumber,
_GeneratedMarker.diagnostic(
offset: diagnostic.offset,
index: nextMarkerIndex++,
constantName: diagnostic.diagnosticCode.constantName,
column: location.column,
length: diagnostic.length,
caretLength: presentation.caretLength,
includeExplicitLocation: presentation.includeExplicitLocation,
contextRefs: contextRefs,
message: _messageText(diagnostic.problemMessage),
),
_addDiagnosticMarker(
diagnostic,
index: nextMarkerIndex++,
contextRefs: contextRefs,
);
}