[cfe] Adjust error location for const constructors with late fields

Closes #43354.

Bug: https://github.com/dart-lang/sdk/issues/43354
Change-Id: Idc8f4757a5589638eb4e3ce08cda2c5afa8d5202
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/165604
Commit-Queue: Dmitry Stefantsov <dmitryas@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Dmitry Stefantsov 2020-10-02 08:30:16 +00:00 committed by commit-bot@chromium.org
parent 8881446fea
commit 0c8109c964
19 changed files with 473 additions and 47 deletions

View file

@ -1111,17 +1111,17 @@ const Code<Null> codeConstConstructorLateFinalFieldCause =
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const MessageCode messageConstConstructorLateFinalFieldCause =
const MessageCode("ConstConstructorLateFinalFieldCause",
severity: Severity.context,
message: r"""Field is late, but constructor is 'const'.""");
severity: Severity.context, message: r"""This constructor is const.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeConstConstructorLateFinalFieldError =
messageConstConstructorLateFinalFieldError;
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const MessageCode messageConstConstructorLateFinalFieldError =
const MessageCode("ConstConstructorLateFinalFieldError",
message: r"""Constructor is marked 'const' so fields can't be late.""");
const MessageCode messageConstConstructorLateFinalFieldError = const MessageCode(
"ConstConstructorLateFinalFieldError",
message:
r"""Can't have a late final field in a class with a const constructor.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeConstConstructorNonFinalField =

View file

@ -932,13 +932,14 @@ class KernelTarget extends TargetImplementation {
SourceLibraryBuilder library = builder.library;
if (library.isNonNullableByDefault) {
if (constructor.isConst && lateFinalFields.isNotEmpty) {
builder.addProblem(messageConstConstructorLateFinalFieldError,
constructor.fileOffset, noLength,
context: lateFinalFields
.map((field) =>
messageConstConstructorLateFinalFieldCause.withLocation(
field.fileUri, field.charOffset, noLength))
.toList());
for (FieldBuilder field in lateFinalFields) {
builder.addProblem(messageConstConstructorLateFinalFieldError,
field.charOffset, noLength,
context: [
messageConstConstructorLateFinalFieldCause.withLocation(
constructor.fileUri, constructor.fileOffset, noLength)
]);
}
lateFinalFields.clear();
}
}

View file

@ -2960,10 +2960,10 @@ ConstConstructorNonFinalFieldCause:
severity: CONTEXT
ConstConstructorLateFinalFieldError:
template: "Constructor is marked 'const' so fields can't be late."
template: "Can't have a late final field in a class with a const constructor."
ConstConstructorLateFinalFieldCause:
template: "Field is late, but constructor is 'const'."
template: "This constructor is const."
severity: CONTEXT
ConstConstructorRedirectionToNonConst:

View file

@ -55,12 +55,12 @@ library /*isNonNullableByDefault*/;
// late String s2 = '${fisk}${await hest()}${fisk}'; // Error.
// ^^^^^
//
// pkg/front_end/testcases/late_lowering/later.dart:48:9: Error: Constructor is marked 'const' so fields can't be late.
// const B(); // Error: B has late final fields.
// ^
// pkg/front_end/testcases/late_lowering/later.dart:46:18: Context: Field is late, but constructor is 'const'.
// pkg/front_end/testcases/late_lowering/later.dart:46:18: Error: Can't have a late final field in a class with a const constructor.
// late final int x = 42;
// ^
// pkg/front_end/testcases/late_lowering/later.dart:48:9: Context: This constructor is const.
// const B(); // Error: B has late final fields.
// ^
//
import self as self;
import "dart:core" as core;

View file

@ -55,12 +55,12 @@ library /*isNonNullableByDefault*/;
// late String s2 = '${fisk}${await hest()}${fisk}'; // Error.
// ^^^^^
//
// pkg/front_end/testcases/late_lowering/later.dart:48:9: Error: Constructor is marked 'const' so fields can't be late.
// const B(); // Error: B has late final fields.
// ^
// pkg/front_end/testcases/late_lowering/later.dart:46:18: Context: Field is late, but constructor is 'const'.
// pkg/front_end/testcases/late_lowering/later.dart:46:18: Error: Can't have a late final field in a class with a const constructor.
// late final int x = 42;
// ^
// pkg/front_end/testcases/late_lowering/later.dart:48:9: Context: This constructor is const.
// const B(); // Error: B has late final fields.
// ^
//
import self as self;
import "dart:core" as core;

View file

@ -55,12 +55,12 @@ library /*isNonNullableByDefault*/;
// late String s2 = '${fisk}${await hest()}${fisk}'; // Error.
// ^^^^^
//
// pkg/front_end/testcases/late_lowering/later.dart:48:9: Error: Constructor is marked 'const' so fields can't be late.
// const B(); // Error: B has late final fields.
// ^
// pkg/front_end/testcases/late_lowering/later.dart:46:18: Context: Field is late, but constructor is 'const'.
// pkg/front_end/testcases/late_lowering/later.dart:46:18: Error: Can't have a late final field in a class with a const constructor.
// late final int x = 42;
// ^
// pkg/front_end/testcases/late_lowering/later.dart:48:9: Context: This constructor is const.
// const B(); // Error: B has late final fields.
// ^
//
import self as self;
import "dart:core" as core;

View file

@ -55,12 +55,12 @@ library /*isNonNullableByDefault*/;
// late String s2 = '${fisk}${await hest()}${fisk}'; // Error.
// ^^^^^
//
// pkg/front_end/testcases/late_lowering/later.dart:48:9: Error: Constructor is marked 'const' so fields can't be late.
// const B(); // Error: B has late final fields.
// ^
// pkg/front_end/testcases/late_lowering/later.dart:46:18: Context: Field is late, but constructor is 'const'.
// pkg/front_end/testcases/late_lowering/later.dart:46:18: Error: Can't have a late final field in a class with a const constructor.
// late final int x = 42;
// ^
// pkg/front_end/testcases/late_lowering/later.dart:48:9: Context: This constructor is const.
// const B(); // Error: B has late final fields.
// ^
//
import self as self;
import "dart:core" as core;

View file

@ -0,0 +1,31 @@
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// The error should be reported on the field, not the constructor.
class A {
late final int foo = 42;
const A();
}
class B {
late final int foo = 42;
late final String bar = "foobar";
const B();
}
class C {
late final int foo = 42;
const C();
const C.another();
}
class D {
late final int foo = 42;
late final String bar = "foobar";
const D();
const D.another();
}
main() {}

View file

@ -0,0 +1,38 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
class A extends core::Object /*hasConstConstructor*/ {
late final field core::int foo = 42;
const constructor •() → self::A
: super core::Object::•()
;
}
class B extends core::Object /*hasConstConstructor*/ {
late final field core::int foo = 42;
late final field core::String bar = "foobar";
const constructor •() → self::B
: super core::Object::•()
;
}
class C extends core::Object /*hasConstConstructor*/ {
late final field core::int foo = 42;
const constructor •() → self::C
: super core::Object::•()
;
const constructor another() → self::C
: super core::Object::•()
;
}
class D extends core::Object /*hasConstConstructor*/ {
late final field core::int foo = 42;
late final field core::String bar = "foobar";
const constructor •() → self::D
: super core::Object::•()
;
const constructor another() → self::D
: super core::Object::•()
;
}
static method main() → dynamic
;

View file

@ -0,0 +1,82 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/nnbd/issue43354.dart:8:18: Error: Can't have a late final field in a class with a const constructor.
// late final int foo = 42;
// ^
// pkg/front_end/testcases/nnbd/issue43354.dart:9:9: Context: This constructor is const.
// const A();
// ^
//
// pkg/front_end/testcases/nnbd/issue43354.dart:13:18: Error: Can't have a late final field in a class with a const constructor.
// late final int foo = 42;
// ^
// pkg/front_end/testcases/nnbd/issue43354.dart:15:9: Context: This constructor is const.
// const B();
// ^
//
// pkg/front_end/testcases/nnbd/issue43354.dart:14:21: Error: Can't have a late final field in a class with a const constructor.
// late final String bar = "foobar";
// ^
// pkg/front_end/testcases/nnbd/issue43354.dart:15:9: Context: This constructor is const.
// const B();
// ^
//
// pkg/front_end/testcases/nnbd/issue43354.dart:19:18: Error: Can't have a late final field in a class with a const constructor.
// late final int foo = 42;
// ^
// pkg/front_end/testcases/nnbd/issue43354.dart:20:9: Context: This constructor is const.
// const C();
// ^
//
// pkg/front_end/testcases/nnbd/issue43354.dart:25:18: Error: Can't have a late final field in a class with a const constructor.
// late final int foo = 42;
// ^
// pkg/front_end/testcases/nnbd/issue43354.dart:27:9: Context: This constructor is const.
// const D();
// ^
//
// pkg/front_end/testcases/nnbd/issue43354.dart:26:21: Error: Can't have a late final field in a class with a const constructor.
// late final String bar = "foobar";
// ^
// pkg/front_end/testcases/nnbd/issue43354.dart:27:9: Context: This constructor is const.
// const D();
// ^
//
import self as self;
import "dart:core" as core;
class A extends core::Object /*hasConstConstructor*/ {
late final field core::int foo = 42;
const constructor •() → self::A
: super core::Object::•()
;
}
class B extends core::Object /*hasConstConstructor*/ {
late final field core::int foo = 42;
late final field core::String bar = "foobar";
const constructor •() → self::B
: super core::Object::•()
;
}
class C extends core::Object /*hasConstConstructor*/ {
late final field core::int foo = 42;
const constructor •() → self::C
: super core::Object::•()
;
const constructor another() → self::C
: super core::Object::•()
;
}
class D extends core::Object /*hasConstConstructor*/ {
late final field core::int foo = 42;
late final field core::String bar = "foobar";
const constructor •() → self::D
: super core::Object::•()
;
const constructor another() → self::D
: super core::Object::•()
;
}
static method main() → dynamic {}

View file

@ -0,0 +1,82 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/nnbd/issue43354.dart:8:18: Error: Can't have a late final field in a class with a const constructor.
// late final int foo = 42;
// ^
// pkg/front_end/testcases/nnbd/issue43354.dart:9:9: Context: This constructor is const.
// const A();
// ^
//
// pkg/front_end/testcases/nnbd/issue43354.dart:13:18: Error: Can't have a late final field in a class with a const constructor.
// late final int foo = 42;
// ^
// pkg/front_end/testcases/nnbd/issue43354.dart:15:9: Context: This constructor is const.
// const B();
// ^
//
// pkg/front_end/testcases/nnbd/issue43354.dart:14:21: Error: Can't have a late final field in a class with a const constructor.
// late final String bar = "foobar";
// ^
// pkg/front_end/testcases/nnbd/issue43354.dart:15:9: Context: This constructor is const.
// const B();
// ^
//
// pkg/front_end/testcases/nnbd/issue43354.dart:19:18: Error: Can't have a late final field in a class with a const constructor.
// late final int foo = 42;
// ^
// pkg/front_end/testcases/nnbd/issue43354.dart:20:9: Context: This constructor is const.
// const C();
// ^
//
// pkg/front_end/testcases/nnbd/issue43354.dart:25:18: Error: Can't have a late final field in a class with a const constructor.
// late final int foo = 42;
// ^
// pkg/front_end/testcases/nnbd/issue43354.dart:27:9: Context: This constructor is const.
// const D();
// ^
//
// pkg/front_end/testcases/nnbd/issue43354.dart:26:21: Error: Can't have a late final field in a class with a const constructor.
// late final String bar = "foobar";
// ^
// pkg/front_end/testcases/nnbd/issue43354.dart:27:9: Context: This constructor is const.
// const D();
// ^
//
import self as self;
import "dart:core" as core;
class A extends core::Object /*hasConstConstructor*/ {
late final field core::int foo = 42;
const constructor •() → self::A
: super core::Object::•()
;
}
class B extends core::Object /*hasConstConstructor*/ {
late final field core::int foo = 42;
late final field core::String bar = "foobar";
const constructor •() → self::B
: super core::Object::•()
;
}
class C extends core::Object /*hasConstConstructor*/ {
late final field core::int foo = 42;
const constructor •() → self::C
: super core::Object::•()
;
const constructor another() → self::C
: super core::Object::•()
;
}
class D extends core::Object /*hasConstConstructor*/ {
late final field core::int foo = 42;
late final field core::String bar = "foobar";
const constructor •() → self::D
: super core::Object::•()
;
const constructor another() → self::D
: super core::Object::•()
;
}
static method main() → dynamic {}

View file

@ -0,0 +1,27 @@
class A {
late ;
final int foo = 42;
const A();
}
class B {
late ;
final int foo = 42;
late ;
final String bar = "foobar";
const B();
}
class C {
late ;
final int foo = 42;
const C();
const C.another();
}
class D {
late ;
final int foo = 42;
late ;
final String bar = "foobar";
const D();
const D.another();
}
main() {}

View file

@ -0,0 +1,82 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/nnbd/issue43354.dart:8:18: Error: Can't have a late final field in a class with a const constructor.
// late final int foo = 42;
// ^
// pkg/front_end/testcases/nnbd/issue43354.dart:9:9: Context: This constructor is const.
// const A();
// ^
//
// pkg/front_end/testcases/nnbd/issue43354.dart:13:18: Error: Can't have a late final field in a class with a const constructor.
// late final int foo = 42;
// ^
// pkg/front_end/testcases/nnbd/issue43354.dart:15:9: Context: This constructor is const.
// const B();
// ^
//
// pkg/front_end/testcases/nnbd/issue43354.dart:14:21: Error: Can't have a late final field in a class with a const constructor.
// late final String bar = "foobar";
// ^
// pkg/front_end/testcases/nnbd/issue43354.dart:15:9: Context: This constructor is const.
// const B();
// ^
//
// pkg/front_end/testcases/nnbd/issue43354.dart:19:18: Error: Can't have a late final field in a class with a const constructor.
// late final int foo = 42;
// ^
// pkg/front_end/testcases/nnbd/issue43354.dart:20:9: Context: This constructor is const.
// const C();
// ^
//
// pkg/front_end/testcases/nnbd/issue43354.dart:25:18: Error: Can't have a late final field in a class with a const constructor.
// late final int foo = 42;
// ^
// pkg/front_end/testcases/nnbd/issue43354.dart:27:9: Context: This constructor is const.
// const D();
// ^
//
// pkg/front_end/testcases/nnbd/issue43354.dart:26:21: Error: Can't have a late final field in a class with a const constructor.
// late final String bar = "foobar";
// ^
// pkg/front_end/testcases/nnbd/issue43354.dart:27:9: Context: This constructor is const.
// const D();
// ^
//
import self as self;
import "dart:core" as core;
class A extends core::Object /*hasConstConstructor*/ {
late final field core::int foo = 42;
const constructor •() → self::A
: super core::Object::•()
;
}
class B extends core::Object /*hasConstConstructor*/ {
late final field core::int foo = 42;
late final field core::String bar = "foobar";
const constructor •() → self::B
: super core::Object::•()
;
}
class C extends core::Object /*hasConstConstructor*/ {
late final field core::int foo = 42;
const constructor •() → self::C
: super core::Object::•()
;
const constructor another() → self::C
: super core::Object::•()
;
}
class D extends core::Object /*hasConstConstructor*/ {
late final field core::int foo = 42;
late final field core::String bar = "foobar";
const constructor •() → self::D
: super core::Object::•()
;
const constructor another() → self::D
: super core::Object::•()
;
}
static method main() → dynamic {}

View file

@ -0,0 +1,82 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/nnbd/issue43354.dart:8:18: Error: Can't have a late final field in a class with a const constructor.
// late final int foo = 42;
// ^
// pkg/front_end/testcases/nnbd/issue43354.dart:9:9: Context: This constructor is const.
// const A();
// ^
//
// pkg/front_end/testcases/nnbd/issue43354.dart:13:18: Error: Can't have a late final field in a class with a const constructor.
// late final int foo = 42;
// ^
// pkg/front_end/testcases/nnbd/issue43354.dart:15:9: Context: This constructor is const.
// const B();
// ^
//
// pkg/front_end/testcases/nnbd/issue43354.dart:14:21: Error: Can't have a late final field in a class with a const constructor.
// late final String bar = "foobar";
// ^
// pkg/front_end/testcases/nnbd/issue43354.dart:15:9: Context: This constructor is const.
// const B();
// ^
//
// pkg/front_end/testcases/nnbd/issue43354.dart:19:18: Error: Can't have a late final field in a class with a const constructor.
// late final int foo = 42;
// ^
// pkg/front_end/testcases/nnbd/issue43354.dart:20:9: Context: This constructor is const.
// const C();
// ^
//
// pkg/front_end/testcases/nnbd/issue43354.dart:25:18: Error: Can't have a late final field in a class with a const constructor.
// late final int foo = 42;
// ^
// pkg/front_end/testcases/nnbd/issue43354.dart:27:9: Context: This constructor is const.
// const D();
// ^
//
// pkg/front_end/testcases/nnbd/issue43354.dart:26:21: Error: Can't have a late final field in a class with a const constructor.
// late final String bar = "foobar";
// ^
// pkg/front_end/testcases/nnbd/issue43354.dart:27:9: Context: This constructor is const.
// const D();
// ^
//
import self as self;
import "dart:core" as core;
class A extends core::Object /*hasConstConstructor*/ {
late final field core::int foo = 42;
const constructor •() → self::A
: super core::Object::•()
;
}
class B extends core::Object /*hasConstConstructor*/ {
late final field core::int foo = 42;
late final field core::String bar = "foobar";
const constructor •() → self::B
: super core::Object::•()
;
}
class C extends core::Object /*hasConstConstructor*/ {
late final field core::int foo = 42;
const constructor •() → self::C
: super core::Object::•()
;
const constructor another() → self::C
: super core::Object::•()
;
}
class D extends core::Object /*hasConstConstructor*/ {
late final field core::int foo = 42;
late final field core::String bar = "foobar";
const constructor •() → self::D
: super core::Object::•()
;
const constructor another() → self::D
: super core::Object::•()
;
}
static method main() → dynamic {}

View file

@ -55,12 +55,12 @@ library /*isNonNullableByDefault*/;
// late String s2 = '${fisk}${await hest()}${fisk}';
// ^^^^^
//
// pkg/front_end/testcases/nnbd/later.dart:46:9: Error: Constructor is marked 'const' so fields can't be late.
// const B();
// ^
// pkg/front_end/testcases/nnbd/later.dart:44:18: Context: Field is late, but constructor is 'const'.
// pkg/front_end/testcases/nnbd/later.dart:44:18: Error: Can't have a late final field in a class with a const constructor.
// late final int x = 42;
// ^
// pkg/front_end/testcases/nnbd/later.dart:46:9: Context: This constructor is const.
// const B();
// ^
//
import self as self;
import "dart:core" as core;

View file

@ -55,12 +55,12 @@ library /*isNonNullableByDefault*/;
// late String s2 = '${fisk}${await hest()}${fisk}';
// ^^^^^
//
// pkg/front_end/testcases/nnbd/later.dart:46:9: Error: Constructor is marked 'const' so fields can't be late.
// const B();
// ^
// pkg/front_end/testcases/nnbd/later.dart:44:18: Context: Field is late, but constructor is 'const'.
// pkg/front_end/testcases/nnbd/later.dart:44:18: Error: Can't have a late final field in a class with a const constructor.
// late final int x = 42;
// ^
// pkg/front_end/testcases/nnbd/later.dart:46:9: Context: This constructor is const.
// const B();
// ^
//
import self as self;
import "dart:core" as core;

View file

@ -55,12 +55,12 @@ library /*isNonNullableByDefault*/;
// late String s2 = '${fisk}${await hest()}${fisk}';
// ^^^^^
//
// pkg/front_end/testcases/nnbd/later.dart:46:9: Error: Constructor is marked 'const' so fields can't be late.
// const B();
// ^
// pkg/front_end/testcases/nnbd/later.dart:44:18: Context: Field is late, but constructor is 'const'.
// pkg/front_end/testcases/nnbd/later.dart:44:18: Error: Can't have a late final field in a class with a const constructor.
// late final int x = 42;
// ^
// pkg/front_end/testcases/nnbd/later.dart:46:9: Context: This constructor is const.
// const B();
// ^
//
import self as self;
import "dart:core" as core;

View file

@ -55,12 +55,12 @@ library /*isNonNullableByDefault*/;
// late String s2 = '${fisk}${await hest()}${fisk}';
// ^^^^^
//
// pkg/front_end/testcases/nnbd/later.dart:46:9: Error: Constructor is marked 'const' so fields can't be late.
// const B();
// ^
// pkg/front_end/testcases/nnbd/later.dart:44:18: Context: Field is late, but constructor is 'const'.
// pkg/front_end/testcases/nnbd/later.dart:44:18: Error: Can't have a late final field in a class with a const constructor.
// late final int x = 42;
// ^
// pkg/front_end/testcases/nnbd/later.dart:46:9: Context: This constructor is const.
// const B();
// ^
//
import self as self;
import "dart:core" as core;

View file

@ -161,8 +161,8 @@ late_lowering/late_nullable_field_without_initializer: FormatterCrash
late_lowering/later: FormatterCrash
late_lowering/override: FormatterCrash
late_lowering/override_getter_setter: FormatterCrash
late_lowering_sentinel/late_fields: FormatterCrash
late_lowering/uninitialized_non_nullable_late_fields: FormatterCrash
late_lowering_sentinel/late_fields: FormatterCrash
nnbd/abstract_field_errors: FormatterCrash
nnbd/covariant_late_field: FormatterCrash
nnbd/extension_bounds: FormatterCrash
@ -177,6 +177,7 @@ nnbd/issue41349: FormatterCrash
nnbd/issue41597: FormatterCrash
nnbd/issue42967: FormatterCrash
nnbd/issue43278: FormatterCrash
nnbd/issue43354: FormatterCrash
nnbd/late: FormatterCrash
nnbd/later: FormatterCrash
nnbd/no_null_shorting_explicit_extension: FormatterCrash