DeCo. Issue 63214. Add new tests for primary constructors and warnings.
Bug: https://github.com/dart-lang/sdk/issues/63214 Change-Id: I2054315eaddc87e0370f82ca8d2a1ebf140d4d18 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/497140 Commit-Queue: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
committed by
dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
e1d540f0d2
commit
9d75d4db0d
@@ -584,17 +584,26 @@ class AnnotationVerifier {
|
||||
reportInvalidAnnotation(fieldName);
|
||||
}
|
||||
}
|
||||
} else if (parent.declaredFragment?.element case var declaredElement?) {
|
||||
if (element.isVisibleForOverriding &&
|
||||
(!declaredElement.isInstanceMember ||
|
||||
declaredElement.enclosingElement is ExtensionTypeElement)) {
|
||||
// This is reported by `_checkKinds`.
|
||||
return;
|
||||
} else {
|
||||
Element? declaredElement;
|
||||
if (parent is PrimaryConstructorBody) {
|
||||
declaredElement = parent.declaration?.declaredFragment?.element;
|
||||
} else {
|
||||
declaredElement = parent.declaredFragment?.element;
|
||||
}
|
||||
|
||||
var name = declaredElement.name;
|
||||
if (name != null && Identifier.isPrivateName(name)) {
|
||||
reportInvalidAnnotation(name);
|
||||
if (declaredElement != null) {
|
||||
if (element.isVisibleForOverriding &&
|
||||
(!declaredElement.isInstanceMember ||
|
||||
declaredElement.enclosingElement is ExtensionTypeElement)) {
|
||||
// This is reported by `_checkKinds`.
|
||||
return;
|
||||
}
|
||||
|
||||
var name = declaredElement.name;
|
||||
if (name != null && Identifier.isPrivateName(name)) {
|
||||
reportInvalidAnnotation(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,29 @@ class C {
|
||||
''');
|
||||
}
|
||||
|
||||
test_primaryConstructor_private() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
import 'package:meta/meta.dart';
|
||||
class C._() {
|
||||
@visibleForTesting
|
||||
this;
|
||||
}
|
||||
''',
|
||||
[error(diag.invalidVisibilityAnnotation, 50, 17)],
|
||||
);
|
||||
}
|
||||
|
||||
test_primaryConstructor_public() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
import 'package:meta/meta.dart';
|
||||
class C.named() {
|
||||
@visibleForTesting
|
||||
this;
|
||||
}
|
||||
''');
|
||||
}
|
||||
|
||||
test_privateClass() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
@@ -75,18 +98,6 @@ import 'package:meta/meta.dart';
|
||||
);
|
||||
}
|
||||
|
||||
test_privateConstructor() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
import 'package:meta/meta.dart';
|
||||
class C {
|
||||
@visibleForTesting C._() {}
|
||||
}
|
||||
''',
|
||||
[error(diag.invalidVisibilityAnnotation, 46, 17)],
|
||||
);
|
||||
}
|
||||
|
||||
test_privateEnum() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
@@ -193,6 +204,29 @@ import 'package:meta/meta.dart';
|
||||
);
|
||||
}
|
||||
|
||||
test_secondaryConstructor_private() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
import 'package:meta/meta.dart';
|
||||
class C {
|
||||
@visibleForTesting
|
||||
C._() {}
|
||||
}
|
||||
''',
|
||||
[error(diag.invalidVisibilityAnnotation, 46, 17)],
|
||||
);
|
||||
}
|
||||
|
||||
test_secondaryConstructor_public() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
import 'package:meta/meta.dart';
|
||||
class C {
|
||||
@visibleForTesting
|
||||
C.named() {}
|
||||
}
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevelVariable_multipleMixed() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
|
||||
@@ -21,78 +21,46 @@ class NonConstCallToLiteralConstructorTest extends PubPackageResolutionTest {
|
||||
writeTestPackageConfigWithMeta();
|
||||
}
|
||||
|
||||
test_constConstructor() async {
|
||||
test_class_primaryConstructor_constContext() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
import 'package:meta/meta.dart';
|
||||
class A {
|
||||
class const A() {
|
||||
@literal
|
||||
const A();
|
||||
}
|
||||
''');
|
||||
}
|
||||
|
||||
test_constContextCreation() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
import 'package:meta/meta.dart';
|
||||
class A {
|
||||
@literal
|
||||
const A();
|
||||
this;
|
||||
}
|
||||
const a = A();
|
||||
''');
|
||||
}
|
||||
|
||||
test_constCreation() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
import 'package:meta/meta.dart';
|
||||
class A {
|
||||
@literal
|
||||
const A();
|
||||
}
|
||||
const a = const A();
|
||||
''');
|
||||
}
|
||||
|
||||
test_constCreation_extensionType() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
import 'package:meta/meta.dart';
|
||||
extension type const E(int i) {
|
||||
@literal
|
||||
const E.zero(): this(0);
|
||||
}
|
||||
E e = const E.zero();
|
||||
''');
|
||||
}
|
||||
|
||||
test_dotShorthand_namedConstructor() async {
|
||||
test_class_primaryConstructor_dotShorthand_unnamed() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
import 'package:meta/meta.dart';
|
||||
class A {
|
||||
class const A() {
|
||||
@literal
|
||||
const A.named();
|
||||
}
|
||||
A a = .named();
|
||||
''',
|
||||
[error(diag.nonConstCallToLiteralConstructor, 81, 8)],
|
||||
);
|
||||
}
|
||||
|
||||
test_dotShorthand_unnamedConstructor() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
import 'package:meta/meta.dart';
|
||||
class A {
|
||||
@literal
|
||||
const A();
|
||||
this;
|
||||
}
|
||||
A a = .new();
|
||||
''',
|
||||
[error(diag.nonConstCallToLiteralConstructor, 75, 6)],
|
||||
[error(diag.nonConstCallToLiteralConstructor, 78, 6)],
|
||||
);
|
||||
}
|
||||
|
||||
test_namedConstructor() async {
|
||||
test_class_primaryConstructor_nonConstContext() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
import 'package:meta/meta.dart';
|
||||
class const A() {
|
||||
@literal
|
||||
this;
|
||||
}
|
||||
var a = A();
|
||||
''',
|
||||
[error(diag.nonConstCallToLiteralConstructor, 80, 3)],
|
||||
);
|
||||
}
|
||||
|
||||
test_class_secondaryConstructor() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
import 'package:meta/meta.dart';
|
||||
@@ -106,7 +74,67 @@ var a = A.named();
|
||||
);
|
||||
}
|
||||
|
||||
test_nonConstContext() async {
|
||||
test_class_secondaryConstructor_const() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
import 'package:meta/meta.dart';
|
||||
class A {
|
||||
@literal
|
||||
const A();
|
||||
}
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_secondaryConstructor_constContextCreation() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
import 'package:meta/meta.dart';
|
||||
class A {
|
||||
@literal
|
||||
const A();
|
||||
}
|
||||
const a = A();
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_secondaryConstructor_constCreation() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
import 'package:meta/meta.dart';
|
||||
class A {
|
||||
@literal
|
||||
const A();
|
||||
}
|
||||
const a = const A();
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_secondaryConstructor_dotShorthand() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
import 'package:meta/meta.dart';
|
||||
class A {
|
||||
@literal
|
||||
const A.named();
|
||||
}
|
||||
A a = .named();
|
||||
''',
|
||||
[error(diag.nonConstCallToLiteralConstructor, 81, 8)],
|
||||
);
|
||||
}
|
||||
|
||||
test_class_secondaryConstructor_dotShorthand_unnamed() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
import 'package:meta/meta.dart';
|
||||
class A {
|
||||
@literal
|
||||
const A();
|
||||
}
|
||||
A a = .new();
|
||||
''',
|
||||
[error(diag.nonConstCallToLiteralConstructor, 75, 6)],
|
||||
);
|
||||
}
|
||||
|
||||
test_class_secondaryConstructor_nonConstContext() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
import 'package:meta/meta.dart';
|
||||
@@ -120,7 +148,7 @@ var a = A();
|
||||
);
|
||||
}
|
||||
|
||||
test_unconstableCreation() async {
|
||||
test_class_secondaryConstructor_unconstableCreation() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
import 'package:meta/meta.dart';
|
||||
class A {
|
||||
@@ -131,7 +159,7 @@ var a = A(new List.filled(1, ''));
|
||||
''');
|
||||
}
|
||||
|
||||
test_usingNew() async {
|
||||
test_class_secondaryConstructor_usingNew() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
import 'package:meta/meta.dart';
|
||||
@@ -145,17 +173,28 @@ var a = new A();
|
||||
);
|
||||
}
|
||||
|
||||
test_usingNew_extensionType() async {
|
||||
test_extensionType_constCreation() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
import 'package:meta/meta.dart';
|
||||
extension type const E(int i) {
|
||||
@literal
|
||||
const E.zero(): this(0);
|
||||
}
|
||||
E e = const E.zero();
|
||||
''');
|
||||
}
|
||||
|
||||
test_extensionType_usingNew() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
import 'package:meta/meta.dart';
|
||||
extension type const E(int i) {
|
||||
extension type const E(int i) {
|
||||
@literal
|
||||
const E.zero(): this(0);
|
||||
}
|
||||
E e = E.zero();
|
||||
''',
|
||||
[error(diag.nonConstCallToLiteralConstructor, 112, 8)],
|
||||
[error(diag.nonConstCallToLiteralConstructor, 111, 8)],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,42 +21,7 @@ class TearoffWithMustBeConstParameterTest extends PubPackageResolutionTest {
|
||||
writeTestPackageConfigWithMeta();
|
||||
}
|
||||
|
||||
test_constructor_invocation() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
import 'package:meta/meta.dart';
|
||||
var g = C.new(1);
|
||||
class C {
|
||||
// ignore: experimental_member_use
|
||||
C(@mustBeConst int x);
|
||||
}
|
||||
''');
|
||||
}
|
||||
|
||||
test_constructor_tearoff() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
import 'package:meta/meta.dart';
|
||||
var g = C.new;
|
||||
class C {
|
||||
// ignore: experimental_member_use
|
||||
C(@mustBeConst int x);
|
||||
}
|
||||
''',
|
||||
[error(diag.tearoffWithMustBeConstParameter, 41, 5)],
|
||||
);
|
||||
}
|
||||
|
||||
test_function_commentReference() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
import 'package:meta/meta.dart';
|
||||
/// Reference to [f].
|
||||
var a = 1;
|
||||
// ignore: experimental_member_use
|
||||
void f(@mustBeConst int x) {}
|
||||
''');
|
||||
}
|
||||
|
||||
test_function_commentReference_threeNames() async {
|
||||
test_class_method_commentReference_threeNames() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
import 'package:meta/meta.dart';
|
||||
import '' as self;
|
||||
@@ -69,7 +34,7 @@ class C {
|
||||
''');
|
||||
}
|
||||
|
||||
test_function_commentReference_twoNames() async {
|
||||
test_class_method_commentReference_twoNames() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
import 'package:meta/meta.dart';
|
||||
/// Reference to [C.f].
|
||||
@@ -81,40 +46,7 @@ class C {
|
||||
''');
|
||||
}
|
||||
|
||||
test_function_invocation() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
import 'package:meta/meta.dart';
|
||||
var g = f(1);
|
||||
// ignore: experimental_member_use
|
||||
void f(@mustBeConst int x) {}
|
||||
''');
|
||||
}
|
||||
|
||||
test_function_tearoff() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
import 'package:meta/meta.dart';
|
||||
var g = f;
|
||||
// ignore: experimental_member_use
|
||||
void f(@mustBeConst int x) {}
|
||||
''',
|
||||
[error(diag.tearoffWithMustBeConstParameter, 41, 1)],
|
||||
);
|
||||
}
|
||||
|
||||
test_genericFunction_instantiated_tearoff() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
import 'package:meta/meta.dart';
|
||||
var g = f<int>;
|
||||
// ignore: experimental_member_use
|
||||
void f<T>(@mustBeConst T x) {}
|
||||
''',
|
||||
[error(diag.tearoffWithMustBeConstParameter, 41, 1)],
|
||||
);
|
||||
}
|
||||
|
||||
test_method_implicitThis_tearoff() async {
|
||||
test_class_method_implicitThis_tearoff() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
import 'package:meta/meta.dart';
|
||||
@@ -128,7 +60,7 @@ class C {
|
||||
);
|
||||
}
|
||||
|
||||
test_method_invocation() async {
|
||||
test_class_method_invocation() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
import 'package:meta/meta.dart';
|
||||
var g = C().m(1);
|
||||
@@ -139,7 +71,7 @@ class C {
|
||||
''');
|
||||
}
|
||||
|
||||
test_method_tearoff() async {
|
||||
test_class_method_tearoff() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
import 'package:meta/meta.dart';
|
||||
@@ -152,4 +84,119 @@ class C {
|
||||
[error(diag.tearoffWithMustBeConstParameter, 45, 1)],
|
||||
);
|
||||
}
|
||||
|
||||
test_class_primaryConstructor_named_tearoff() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
import 'package:meta/meta.dart';
|
||||
var g = C.named;
|
||||
// ignore: experimental_member_use
|
||||
class C.named(@mustBeConst int x);
|
||||
''',
|
||||
[error(diag.tearoffWithMustBeConstParameter, 41, 7)],
|
||||
);
|
||||
}
|
||||
|
||||
test_class_primaryConstructor_unnamed_invocation() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
import 'package:meta/meta.dart';
|
||||
var g = C(1);
|
||||
// ignore: experimental_member_use
|
||||
class C(@mustBeConst int x);
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_primaryConstructor_unnamed_tearoff() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
import 'package:meta/meta.dart';
|
||||
var g = C.new;
|
||||
// ignore: experimental_member_use
|
||||
class C(@mustBeConst int x);
|
||||
''',
|
||||
[error(diag.tearoffWithMustBeConstParameter, 41, 5)],
|
||||
);
|
||||
}
|
||||
|
||||
test_class_secondaryConstructor_named_tearoff() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
import 'package:meta/meta.dart';
|
||||
var g = C.named;
|
||||
class C {
|
||||
// ignore: experimental_member_use
|
||||
C.named(@mustBeConst int x);
|
||||
}
|
||||
''',
|
||||
[error(diag.tearoffWithMustBeConstParameter, 41, 7)],
|
||||
);
|
||||
}
|
||||
|
||||
test_class_secondaryConstructor_unnamed_invocation() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
import 'package:meta/meta.dart';
|
||||
var g = C.new(1);
|
||||
class C {
|
||||
// ignore: experimental_member_use
|
||||
C(@mustBeConst int x);
|
||||
}
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_secondaryConstructor_unnamed_tearoff() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
import 'package:meta/meta.dart';
|
||||
var g = C.new;
|
||||
class C {
|
||||
// ignore: experimental_member_use
|
||||
C(@mustBeConst int x);
|
||||
}
|
||||
''',
|
||||
[error(diag.tearoffWithMustBeConstParameter, 41, 5)],
|
||||
);
|
||||
}
|
||||
|
||||
test_topLevelFunction_commentReference() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
import 'package:meta/meta.dart';
|
||||
/// Reference to [f].
|
||||
var a = 1;
|
||||
// ignore: experimental_member_use
|
||||
void f(@mustBeConst int x) {}
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevelFunction_instantiated_tearoff() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
import 'package:meta/meta.dart';
|
||||
var g = f<int>;
|
||||
// ignore: experimental_member_use
|
||||
void f<T>(@mustBeConst T x) {}
|
||||
''',
|
||||
[error(diag.tearoffWithMustBeConstParameter, 41, 1)],
|
||||
);
|
||||
}
|
||||
|
||||
test_topLevelFunction_invocation() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
import 'package:meta/meta.dart';
|
||||
var g = f(1);
|
||||
// ignore: experimental_member_use
|
||||
void f(@mustBeConst int x) {}
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevelFunction_tearoff() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
import 'package:meta/meta.dart';
|
||||
var g = f;
|
||||
// ignore: experimental_member_use
|
||||
void f(@mustBeConst int x) {}
|
||||
''',
|
||||
[error(diag.tearoffWithMustBeConstParameter, 41, 1)],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user