Augment. Support for abstract top-level variables and static fields.
Change-Id: Idf0ce319492c405dd06364cb6feb81e000a7c741 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/506606 Commit-Queue: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com> Reviewed-by: Paul Berry <paulberry@google.com>
This commit is contained in:
committed by
dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
6f804b8121
commit
a898adf8b7
@@ -44,7 +44,7 @@
|
||||
# issue created for it.
|
||||
#
|
||||
# Stats:
|
||||
# - 78 "needsEvaluation"
|
||||
# - 82 "needsEvaluation"
|
||||
# - 302 "needsFix"
|
||||
# - 525 "hasFix"
|
||||
# - 487 "noFix"
|
||||
@@ -914,6 +914,14 @@ implicit_this_reference_in_initializer:
|
||||
status: hasFix
|
||||
implicit_super_initializer_missing_arguments:
|
||||
status: hasFix
|
||||
induced_getter_not_complete_after_augmentations:
|
||||
status: needsEvaluation
|
||||
induced_getter_without_body:
|
||||
status: needsEvaluation
|
||||
induced_setter_not_complete_after_augmentations:
|
||||
status: needsEvaluation
|
||||
induced_setter_without_body:
|
||||
status: needsEvaluation
|
||||
import_internal_library:
|
||||
status: hasFix
|
||||
import_of_non_library:
|
||||
|
||||
@@ -210,6 +210,7 @@ class _UnitApiSignatureComputer {
|
||||
}
|
||||
|
||||
void _topLevelVariableDeclaration(TopLevelVariableDeclaration node) {
|
||||
_addToken(node.abstractKeyword);
|
||||
_addToken(node.augmentKeyword);
|
||||
_addToken(node.externalKeyword);
|
||||
_addNodeList(node.metadata);
|
||||
|
||||
@@ -7525,6 +7525,74 @@ inconsistentPatternVariableLogicalOr = DiagnosticWithArguments(
|
||||
expectedTypes: [ExpectedType.string],
|
||||
);
|
||||
|
||||
/// Parameters:
|
||||
/// String name: the name of the variable inducing the getter
|
||||
const DiagnosticWithArguments<
|
||||
LocatableDiagnostic Function({required String name})
|
||||
>
|
||||
inducedGetterNotCompleteAfterAugmentations = DiagnosticWithArguments(
|
||||
name: 'induced_getter_not_complete_after_augmentations',
|
||||
problemMessage:
|
||||
"The getter induced by '{0}' must have a body after all augmentations are "
|
||||
"applied.",
|
||||
correctionMessage:
|
||||
"Try adding an initializer or providing an augmentation with a getter "
|
||||
"body.",
|
||||
type: DiagnosticType.COMPILE_TIME_ERROR,
|
||||
uniqueName: 'induced_getter_not_complete_after_augmentations',
|
||||
withArguments: _withArgumentsInducedGetterNotCompleteAfterAugmentations,
|
||||
expectedTypes: [ExpectedType.string],
|
||||
);
|
||||
|
||||
/// Parameters:
|
||||
/// String name: the name of the variable inducing the getter
|
||||
const DiagnosticWithArguments<
|
||||
LocatableDiagnostic Function({required String name})
|
||||
>
|
||||
inducedGetterWithoutBody = DiagnosticWithArguments(
|
||||
name: 'induced_getter_without_body',
|
||||
problemMessage: "The getter induced by '{0}' must have a body.",
|
||||
correctionMessage: "Try removing 'abstract' and adding an initializer.",
|
||||
type: DiagnosticType.COMPILE_TIME_ERROR,
|
||||
uniqueName: 'induced_getter_without_body',
|
||||
withArguments: _withArgumentsInducedGetterWithoutBody,
|
||||
expectedTypes: [ExpectedType.string],
|
||||
);
|
||||
|
||||
/// Parameters:
|
||||
/// String name: the name of the variable inducing the setter
|
||||
const DiagnosticWithArguments<
|
||||
LocatableDiagnostic Function({required String name})
|
||||
>
|
||||
inducedSetterNotCompleteAfterAugmentations = DiagnosticWithArguments(
|
||||
name: 'induced_setter_not_complete_after_augmentations',
|
||||
problemMessage:
|
||||
"The setter induced by '{0}' must have a body after all augmentations are "
|
||||
"applied.",
|
||||
correctionMessage:
|
||||
"Try adding an initializer or providing an augmentation with a setter "
|
||||
"body.",
|
||||
type: DiagnosticType.COMPILE_TIME_ERROR,
|
||||
uniqueName: 'induced_setter_not_complete_after_augmentations',
|
||||
withArguments: _withArgumentsInducedSetterNotCompleteAfterAugmentations,
|
||||
expectedTypes: [ExpectedType.string],
|
||||
);
|
||||
|
||||
/// Parameters:
|
||||
/// String name: the name of the variable inducing the setter
|
||||
const DiagnosticWithArguments<
|
||||
LocatableDiagnostic Function({required String name})
|
||||
>
|
||||
inducedSetterWithoutBody = DiagnosticWithArguments(
|
||||
name: 'induced_setter_without_body',
|
||||
problemMessage: "The setter induced by '{0}' must have a body.",
|
||||
correctionMessage: "Try removing 'abstract' and adding an initializer.",
|
||||
type: DiagnosticType.COMPILE_TIME_ERROR,
|
||||
uniqueName: 'induced_setter_without_body',
|
||||
withArguments: _withArgumentsInducedSetterWithoutBody,
|
||||
expectedTypes: [ExpectedType.string],
|
||||
);
|
||||
|
||||
/// When "strict-inference" is enabled, collection literal types must be
|
||||
/// inferred via the context type, or have type arguments.
|
||||
///
|
||||
@@ -19899,6 +19967,36 @@ LocatableDiagnostic _withArgumentsInconsistentPatternVariableLogicalOr({
|
||||
]);
|
||||
}
|
||||
|
||||
LocatableDiagnostic _withArgumentsInducedGetterNotCompleteAfterAugmentations({
|
||||
required String name,
|
||||
}) {
|
||||
return LocatableDiagnosticImpl(
|
||||
diag.inducedGetterNotCompleteAfterAugmentations,
|
||||
[name],
|
||||
);
|
||||
}
|
||||
|
||||
LocatableDiagnostic _withArgumentsInducedGetterWithoutBody({
|
||||
required String name,
|
||||
}) {
|
||||
return LocatableDiagnosticImpl(diag.inducedGetterWithoutBody, [name]);
|
||||
}
|
||||
|
||||
LocatableDiagnostic _withArgumentsInducedSetterNotCompleteAfterAugmentations({
|
||||
required String name,
|
||||
}) {
|
||||
return LocatableDiagnosticImpl(
|
||||
diag.inducedSetterNotCompleteAfterAugmentations,
|
||||
[name],
|
||||
);
|
||||
}
|
||||
|
||||
LocatableDiagnostic _withArgumentsInducedSetterWithoutBody({
|
||||
required String name,
|
||||
}) {
|
||||
return LocatableDiagnosticImpl(diag.inducedSetterWithoutBody, [name]);
|
||||
}
|
||||
|
||||
LocatableDiagnostic _withArgumentsInferenceFailureOnCollectionLiteral({
|
||||
required String collection,
|
||||
}) {
|
||||
|
||||
@@ -489,6 +489,10 @@ const List<DiagnosticCode> diagnosticCodeValues = [
|
||||
diag.inconsistentInheritanceGetterAndMethod,
|
||||
diag.inconsistentLanguageVersionOverride,
|
||||
diag.inconsistentPatternVariableLogicalOr,
|
||||
diag.inducedGetterNotCompleteAfterAugmentations,
|
||||
diag.inducedGetterWithoutBody,
|
||||
diag.inducedSetterNotCompleteAfterAugmentations,
|
||||
diag.inducedSetterWithoutBody,
|
||||
diag.inferenceFailureOnCollectionLiteral,
|
||||
diag.inferenceFailureOnFunctionInvocation,
|
||||
diag.inferenceFailureOnFunctionReturnType,
|
||||
|
||||
@@ -1056,6 +1056,16 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
|
||||
}
|
||||
}
|
||||
|
||||
if (node.isStatic && node.abstractKeyword != null) {
|
||||
for (var variable in node.fields.variables) {
|
||||
var declaredFragment = variable.declaredFragment! as FieldFragmentImpl;
|
||||
_checkForIncompleteInducedAccessors(
|
||||
nameToken: variable.name,
|
||||
fragment: declaredFragment,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!node.isStatic) {
|
||||
if (node.fields.isConst) {
|
||||
diagnosticReporter.report(
|
||||
@@ -2043,7 +2053,9 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if (node.externalKeyword == null && !variableList.isLate) {
|
||||
} else if (node.abstractKeyword == null &&
|
||||
node.externalKeyword == null &&
|
||||
!variableList.isLate) {
|
||||
for (var variable in variableList.variables) {
|
||||
if (variable.initializer == null) {
|
||||
if (variableList.isFinal) {
|
||||
@@ -2069,6 +2081,12 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
|
||||
for (var variable in node.variables.variables) {
|
||||
var fragment = variable.declaredFragment;
|
||||
fragment as TopLevelVariableFragmentImpl;
|
||||
if (node.abstractKeyword != null) {
|
||||
_checkForIncompleteInducedAccessors(
|
||||
nameToken: variable.name,
|
||||
fragment: fragment,
|
||||
);
|
||||
}
|
||||
_checkForMainFunction1(variable.name, fragment);
|
||||
}
|
||||
|
||||
@@ -4908,6 +4926,47 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
|
||||
);
|
||||
}
|
||||
|
||||
void _checkForIncompleteInducedAccessors({
|
||||
required Token nameToken,
|
||||
required PropertyInducingFragmentImpl fragment,
|
||||
}) {
|
||||
if (!_featureSet.isEnabled(Feature.augmentations)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fragment.isAugmentation) {
|
||||
return;
|
||||
}
|
||||
|
||||
var getter = fragment.inducedGetter;
|
||||
var setter = fragment.inducedSetter;
|
||||
var hasAugmentations =
|
||||
(getter?.element.fragments.length ?? 0) > 1 ||
|
||||
(setter?.element.fragments.length ?? 0) > 1;
|
||||
|
||||
if (getter != null) {
|
||||
if (getter.element.fragments.none((f) => f.isCompleteDeclaration)) {
|
||||
var diagnostic = hasAugmentations
|
||||
? diag.inducedGetterNotCompleteAfterAugmentations
|
||||
: diag.inducedGetterWithoutBody;
|
||||
diagnosticReporter.report(
|
||||
diagnostic.withArguments(name: nameToken.lexeme).at(nameToken),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (setter != null) {
|
||||
if (setter.element.fragments.none((f) => f.isCompleteDeclaration)) {
|
||||
var diagnostic = hasAugmentations
|
||||
? diag.inducedSetterNotCompleteAfterAugmentations
|
||||
: diag.inducedSetterWithoutBody;
|
||||
diagnosticReporter.report(
|
||||
diagnostic.withArguments(name: nameToken.lexeme).at(nameToken),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Check that the given [typeReference] is not a type reference and that then
|
||||
/// the [name] is reference to an instance member.
|
||||
///
|
||||
|
||||
@@ -5074,6 +5074,38 @@ CompileTimeErrorCode:
|
||||
problemMessage: "The function or member '#name' must have a body after all augmentations are applied."
|
||||
correctionMessage: "Try adding a body to the introductory declaration, or providing an augmentation with a body."
|
||||
hasPublishedDocs: false
|
||||
inducedGetterWithoutBody:
|
||||
type: compileTimeError
|
||||
parameters:
|
||||
String name: the name of the variable inducing the getter
|
||||
experiment: augmentations
|
||||
problemMessage: "The getter induced by '#name' must have a body."
|
||||
correctionMessage: "Try removing 'abstract' and adding an initializer."
|
||||
hasPublishedDocs: false
|
||||
inducedSetterWithoutBody:
|
||||
type: compileTimeError
|
||||
parameters:
|
||||
String name: the name of the variable inducing the setter
|
||||
experiment: augmentations
|
||||
problemMessage: "The setter induced by '#name' must have a body."
|
||||
correctionMessage: "Try removing 'abstract' and adding an initializer."
|
||||
hasPublishedDocs: false
|
||||
inducedGetterNotCompleteAfterAugmentations:
|
||||
type: compileTimeError
|
||||
parameters:
|
||||
String name: the name of the variable inducing the getter
|
||||
experiment: augmentations
|
||||
problemMessage: "The getter induced by '#name' must have a body after all augmentations are applied."
|
||||
correctionMessage: "Try adding an initializer or providing an augmentation with a getter body."
|
||||
hasPublishedDocs: false
|
||||
inducedSetterNotCompleteAfterAugmentations:
|
||||
type: compileTimeError
|
||||
parameters:
|
||||
String name: the name of the variable inducing the setter
|
||||
experiment: augmentations
|
||||
problemMessage: "The setter induced by '#name' must have a body after all augmentations are applied."
|
||||
correctionMessage: "Try adding an initializer or providing an augmentation with a setter body."
|
||||
hasPublishedDocs: false
|
||||
factoryNotCompleteAfterAugmentations:
|
||||
type: compileTimeError
|
||||
parameters:
|
||||
|
||||
@@ -2132,6 +2132,28 @@ int foo() {
|
||||
);
|
||||
}
|
||||
|
||||
test_topLevelVariable_abstract_add() {
|
||||
_assertNotSameSignature(
|
||||
r'''
|
||||
int foo;
|
||||
''',
|
||||
r'''
|
||||
abstract int foo;
|
||||
''',
|
||||
);
|
||||
}
|
||||
|
||||
test_topLevelVariable_abstract_remove() {
|
||||
_assertNotSameSignature(
|
||||
r'''
|
||||
abstract int foo;
|
||||
''',
|
||||
r'''
|
||||
int foo;
|
||||
''',
|
||||
);
|
||||
}
|
||||
|
||||
test_topLevelVariable_augment_add() {
|
||||
_assertNotSameSignature(
|
||||
r'''
|
||||
|
||||
@@ -308,7 +308,6 @@ int? get foo => 0;
|
||||
augment abstract final String? foo;
|
||||
// ^^^
|
||||
// [diag.augmentationInducedGetterReturnTypeMismatch] The getter induced by this augmentation has return type 'String?', but the getter being augmented has return type 'int?'.
|
||||
// [diag.finalNotInitialized] The final variable 'foo' must be initialized.
|
||||
''');
|
||||
}
|
||||
|
||||
|
||||
@@ -1225,8 +1225,6 @@ augment abstract int? foo;
|
||||
int? get foo => 0;
|
||||
|
||||
augment abstract final int? foo;
|
||||
// ^^^
|
||||
// [diag.finalNotInitialized] The final variable 'foo' must be initialized.
|
||||
''');
|
||||
}
|
||||
|
||||
@@ -1239,7 +1237,6 @@ set foo(int? _) {}
|
||||
augment abstract final int? foo;
|
||||
// ^^^
|
||||
// [diag.augmentationWithoutGetterDeclaration][context 1] This augmentation induces a getter, but no getter declaration named 'foo' exists to augment.
|
||||
// [diag.finalNotInitialized] The final variable 'foo' must be initialized.
|
||||
''');
|
||||
}
|
||||
|
||||
@@ -1248,8 +1245,6 @@ augment abstract final int? foo;
|
||||
final int? foo = 0;
|
||||
|
||||
augment abstract final int? foo;
|
||||
// ^^^
|
||||
// [diag.finalNotInitialized] The final variable 'foo' must be initialized.
|
||||
''');
|
||||
}
|
||||
|
||||
|
||||
@@ -4354,12 +4354,9 @@ int foo = 42;
|
||||
}
|
||||
|
||||
test_topLevelVariable_topLevelVariable_augment() async {
|
||||
// TODO(augmentations): Should not have notInitializedNonNullableVariable
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
int foo = 0;
|
||||
augment abstract int foo;
|
||||
// ^^^
|
||||
// [diag.notInitializedNonNullableVariable] The non-nullable variable 'foo' must be initialized.
|
||||
''');
|
||||
}
|
||||
|
||||
|
||||
@@ -641,6 +641,90 @@ class A {
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_staticField_abstract() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
class A {
|
||||
static abstract int foo;
|
||||
// ^^^
|
||||
// [diag.inducedGetterWithoutBody] The getter induced by 'foo' must have a body.
|
||||
// [diag.inducedSetterWithoutBody] The setter induced by 'foo' must have a body.
|
||||
}
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_staticField_abstract_completeAfterAugmentations() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
class A {
|
||||
static abstract int foo;
|
||||
augment static int get foo => 0;
|
||||
augment static set foo(int _) {}
|
||||
}
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_staticField_abstract_incompleteGetterAfterAugmentations() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
class A {
|
||||
static abstract int foo;
|
||||
// ^^^
|
||||
// [diag.inducedGetterNotCompleteAfterAugmentations] The getter induced by 'foo' must have a body after all augmentations are applied.
|
||||
augment static set foo(int _) {}
|
||||
}
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_staticField_abstract_incompleteSetterAfterAugmentations() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
class A {
|
||||
static abstract int foo;
|
||||
// ^^^
|
||||
// [diag.inducedSetterNotCompleteAfterAugmentations] The setter induced by 'foo' must have a body after all augmentations are applied.
|
||||
augment static int get foo => 0;
|
||||
}
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_staticField_abstract_language305() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
// @dart = 3.5
|
||||
class A {
|
||||
static abstract int foo;
|
||||
// ^^^^^^^^
|
||||
// [diag.abstractStaticField] Static fields can't be declared 'abstract'.
|
||||
}
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_staticField_abstractFinal() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
class A {
|
||||
static abstract final int foo;
|
||||
// ^^^
|
||||
// [diag.inducedGetterWithoutBody] The getter induced by 'foo' must have a body.
|
||||
}
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_staticField_abstractFinal_completeAfterAugmentations() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
class A {
|
||||
static abstract final int foo;
|
||||
augment static int get foo => 0;
|
||||
}
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_staticField_abstractFinal_incompleteGetterAfterAugmentations() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
class A {
|
||||
static abstract final int foo;
|
||||
// ^^^
|
||||
// [diag.inducedGetterNotCompleteAfterAugmentations] The getter induced by 'foo' must have a body after all augmentations are applied.
|
||||
augment static abstract final int foo;
|
||||
}
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_staticGetter_hasBody_augmentation_staticField() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
class A {
|
||||
@@ -2319,8 +2403,6 @@ augment int foo = 1;
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
int get foo => 0;
|
||||
augment abstract final int foo;
|
||||
// ^^^
|
||||
// [diag.finalNotInitialized] The final variable 'foo' must be initialized.
|
||||
''');
|
||||
}
|
||||
|
||||
@@ -2362,8 +2444,6 @@ augment int foo = 1;
|
||||
int get foo => 0;
|
||||
set foo(int _) {}
|
||||
augment abstract int foo;
|
||||
// ^^^
|
||||
// [diag.notInitializedNonNullableVariable] The non-nullable variable 'foo' must be initialized.
|
||||
''');
|
||||
}
|
||||
|
||||
@@ -2478,6 +2558,73 @@ set foo(int _);
|
||||
set foo(int _);
|
||||
// ^
|
||||
// [diag.missingFunctionBody] A function body must be provided.
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevel_variable_abstract() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
abstract int foo;
|
||||
// ^^^
|
||||
// [diag.inducedGetterWithoutBody] The getter induced by 'foo' must have a body.
|
||||
// [diag.inducedSetterWithoutBody] The setter induced by 'foo' must have a body.
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevel_variable_abstract_completeAfterAugmentations() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
abstract int foo;
|
||||
augment int get foo => 0;
|
||||
augment set foo(int _) {}
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevel_variable_abstract_incompleteGetterAfterAugmentations() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
abstract int foo;
|
||||
// ^^^
|
||||
// [diag.inducedGetterNotCompleteAfterAugmentations] The getter induced by 'foo' must have a body after all augmentations are applied.
|
||||
augment set foo(int _) {}
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevel_variable_abstract_incompleteSetterAfterAugmentations() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
abstract int foo;
|
||||
// ^^^
|
||||
// [diag.inducedSetterNotCompleteAfterAugmentations] The setter induced by 'foo' must have a body after all augmentations are applied.
|
||||
augment int get foo => 0;
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevel_variable_abstract_language305() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
// @dart = 3.5
|
||||
abstract int foo;
|
||||
// [diag.extraneousModifier][column 1][length 8] Can't have modifier 'abstract' here.
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevel_variable_abstractFinal() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
abstract final int foo;
|
||||
// ^^^
|
||||
// [diag.inducedGetterWithoutBody] The getter induced by 'foo' must have a body.
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevel_variable_abstractFinal_completeAfterAugmentations() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
abstract final int foo;
|
||||
augment int get foo => 0;
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevel_variable_abstractFinal_incompleteGetterAfterAugmentations() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
abstract final int foo;
|
||||
// ^^^
|
||||
// [diag.inducedGetterNotCompleteAfterAugmentations] The getter induced by 'foo' must have a body after all augmentations are applied.
|
||||
augment abstract final int foo;
|
||||
''');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,15 +378,11 @@ part 'test.dart';
|
||||
int Xx = 1;
|
||||
''');
|
||||
|
||||
// TODO(augmentations): Should not have notInitializedNonNullableVariable
|
||||
await assertDiagnostics(
|
||||
r'''
|
||||
await assertNoDiagnostics(r'''
|
||||
part of 'a.dart';
|
||||
|
||||
augment abstract int Xx;
|
||||
''',
|
||||
[error(diag.notInitializedNonNullableVariable, 40, 2)],
|
||||
);
|
||||
''');
|
||||
}
|
||||
|
||||
@FailingTest(issue: 'https://github.com/dart-lang/linter/issues/5048')
|
||||
|
||||
@@ -43,7 +43,6 @@ final abstract class FinalAbstract {}
|
||||
// [cfe] Expected ';' after this.
|
||||
// [cfe] The modifier 'abstract' should be before the modifier 'final'.
|
||||
// ^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.FINAL_NOT_INITIALIZED
|
||||
// [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
|
||||
// [cfe] Expected an identifier, but got 'class'.
|
||||
base abstract class BaseAbstract {}
|
||||
|
||||
Reference in New Issue
Block a user