Skip to content

Commit

Permalink
[cfe] Report errors on private fields in records
Browse files Browse the repository at this point in the history
Closes #50144

Change-Id: I7cbf2fd30773269b5f839299f948da719f3eecc4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/263781
Auto-Submit: Chloe Stefantsova <[email protected]>
Commit-Queue: Chloe Stefantsova <[email protected]>
Reviewed-by: Johnni Winther <[email protected]>
  • Loading branch information
chloestefantsova authored and Commit Queue committed Oct 28, 2022
1 parent 41e04fc commit a9a915e
Show file tree
Hide file tree
Showing 13 changed files with 211 additions and 0 deletions.
10 changes: 10 additions & 0 deletions pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10162,6 +10162,16 @@ const MessageCode messagePrivateNamedParameter = const MessageCode(
analyzerCodes: <String>["PRIVATE_OPTIONAL_PARAMETER"],
problemMessage: r"""An optional named parameter can't start with '_'.""");

// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeRecordFieldsCantBePrivate =
messageRecordFieldsCantBePrivate;

// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const MessageCode messageRecordFieldsCantBePrivate = const MessageCode(
"RecordFieldsCantBePrivate",
analyzerCodes: <String>["INVALID_FIELD_NAME"],
problemMessage: r"""Record field names can't be private.""");

// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeRecordLiteralOnePositionalFieldNoTrailingComma =
messageRecordLiteralOnePositionalFieldNoTrailingComma;
Expand Down
14 changes: 14 additions & 0 deletions pkg/front_end/lib/src/fasta/builder/record_type_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:kernel/src/unaliasing.dart';
import '../fasta_codes.dart'
show
messageObjectMemberNameUsedForRecordField,
messageRecordFieldsCantBePrivate,
messageSupertypeIsFunction,
noLength,
templateDuplicatedRecordTypeFieldName,
Expand Down Expand Up @@ -145,6 +146,12 @@ abstract class RecordTypeBuilder extends TypeBuilder {
positionalEntries.add(type);
String? fieldName = field.name;
if (fieldName != null) {
if (fieldName.startsWith("_")) {
library.addProblem(messageRecordFieldsCantBePrivate,
field.charOffset, fieldName.length, fileUri);
hasErrors = true;
continue;
}
RecordTypeFieldBuilder? existingField = fieldsMap[fieldName];
if (existingField != null) {
library.addProblem(
Expand All @@ -159,6 +166,7 @@ abstract class RecordTypeBuilder extends TypeBuilder {
fileUri, existingField.charOffset, fieldName.length)
]);
hasErrors = true;
continue;
} else {
fieldsMap[fieldName] = field;
}
Expand Down Expand Up @@ -186,6 +194,12 @@ abstract class RecordTypeBuilder extends TypeBuilder {
hasErrors = true;
continue;
}
if (name.startsWith("_")) {
library.addProblem(messageRecordFieldsCantBePrivate, field.charOffset,
name.length, fileUri);
hasErrors = true;
continue;
}
RecordTypeFieldBuilder? existingField = fieldsMap[name];
if (existingField != null) {
library.addProblem(
Expand Down
4 changes: 4 additions & 0 deletions pkg/front_end/lib/src/fasta/kernel/body_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4231,6 +4231,10 @@ class BodyBuilder extends StackListenerImpl
element.name.length,
uri);
}
if (element.name.startsWith("_")) {
libraryBuilder.addProblem(fasta.messageRecordFieldsCantBePrivate,
element.fileOffset, element.name.length, uri);
}
namedElements ??= {};
NamedExpression? existingExpression = namedElements[element.name];
if (existingExpression != null) {
Expand Down
7 changes: 7 additions & 0 deletions pkg/front_end/messages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5947,3 +5947,10 @@ NameNotFoundInRecordNameGet:

ObjectMemberNameUsedForRecordField:
problemMessage: "Record field names can't be the same as a member from 'Object'."

RecordFieldsCantBePrivate:
problemMessage: "Record field names can't be private."
analyzerCode: INVALID_FIELD_NAME
experiments: records
script: |
foo() => (_bar: 1);
9 changes: 9 additions & 0 deletions pkg/front_end/testcases/records/private_field_names.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright (c) 2022, 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.

(int _foo,) foo1() => throw 0; // Error.
({int _foo}) foo2() => throw 0; // Error.
foo3() => (_foo: 1); // Error.

main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/records/private_field_names.dart:5:6: Error: Record field names can't be private.
// (int _foo,) foo1() => throw 0; // Error.
// ^^^^
//
// pkg/front_end/testcases/records/private_field_names.dart:6:7: Error: Record field names can't be private.
// ({int _foo}) foo2() => throw 0; // Error.
// ^^^^
//
// pkg/front_end/testcases/records/private_field_names.dart:7:12: Error: Record field names can't be private.
// foo3() => (_foo: 1); // Error.
// ^^^^
//
import self as self;
import "dart:core" as core;

static method foo1() → invalid-type
return throw 0;
static method foo2() → invalid-type
return throw 0;
static method foo3() → dynamic
return ({_foo: 1});
static method main() → dynamic {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/records/private_field_names.dart:5:6: Error: Record field names can't be private.
// (int _foo,) foo1() => throw 0; // Error.
// ^^^^
//
// pkg/front_end/testcases/records/private_field_names.dart:6:7: Error: Record field names can't be private.
// ({int _foo}) foo2() => throw 0; // Error.
// ^^^^
//
// pkg/front_end/testcases/records/private_field_names.dart:7:12: Error: Record field names can't be private.
// foo3() => (_foo: 1); // Error.
// ^^^^
//
import self as self;
import "dart:core" as core;

static method foo1() → invalid-type
return throw 0;
static method foo2() → invalid-type
return throw 0;
static method foo3() → dynamic
return ({_foo: 1});
static method main() → dynamic {}


Extra constant evaluation status:
Evaluated: RecordLiteral @ org-dartlang-testcase:///private_field_names.dart:7:11 -> RecordConstant(const ({_foo: 1}))
Extra constant evaluation: evaluated: 3, effectively constant: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(int _foo,) foo1() => throw 0;
({int _foo}) foo2() => throw 0;
foo3() => (_foo: 1);
main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/records/private_field_names.dart:5:6: Error: Record field names can't be private.
// (int _foo,) foo1() => throw 0; // Error.
// ^^^^
//
// pkg/front_end/testcases/records/private_field_names.dart:6:7: Error: Record field names can't be private.
// ({int _foo}) foo2() => throw 0; // Error.
// ^^^^
//
// pkg/front_end/testcases/records/private_field_names.dart:7:12: Error: Record field names can't be private.
// foo3() => (_foo: 1); // Error.
// ^^^^
//
import self as self;
import "dart:core" as core;

static method foo1() → invalid-type
return throw 0;
static method foo2() → invalid-type
return throw 0;
static method foo3() → dynamic
return ({_foo: 1});
static method main() → dynamic {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/records/private_field_names.dart:5:6: Error: Record field names can't be private.
// (int _foo,) foo1() => throw 0; // Error.
// ^^^^
//
// pkg/front_end/testcases/records/private_field_names.dart:6:7: Error: Record field names can't be private.
// ({int _foo}) foo2() => throw 0; // Error.
// ^^^^
//
// pkg/front_end/testcases/records/private_field_names.dart:7:12: Error: Record field names can't be private.
// foo3() => (_foo: 1); // Error.
// ^^^^
//
import self as self;
import "dart:core" as core;

static method foo1() → invalid-type
return throw 0;
static method foo2() → invalid-type
return throw 0;
static method foo3() → dynamic
return ({_foo: 1});
static method main() → dynamic {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/records/private_field_names.dart:5:6: Error: Record field names can't be private.
// (int _foo,) foo1() => throw 0; // Error.
// ^^^^
//
// pkg/front_end/testcases/records/private_field_names.dart:6:7: Error: Record field names can't be private.
// ({int _foo}) foo2() => throw 0; // Error.
// ^^^^
//
import self as self;

static method foo1() → invalid-type
;
static method foo2() → invalid-type
;
static method foo3() → dynamic
;
static method main() → dynamic
;
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/records/private_field_names.dart:5:6: Error: Record field names can't be private.
// (int _foo,) foo1() => throw 0; // Error.
// ^^^^
//
// pkg/front_end/testcases/records/private_field_names.dart:6:7: Error: Record field names can't be private.
// ({int _foo}) foo2() => throw 0; // Error.
// ^^^^
//
// pkg/front_end/testcases/records/private_field_names.dart:7:12: Error: Record field names can't be private.
// foo3() => (_foo: 1); // Error.
// ^^^^
//
import self as self;
import "dart:core" as core;

static method foo1() → invalid-type
return throw 0;
static method foo2() → invalid-type
return throw 0;
static method foo3() → dynamic
return ({_foo: 1});
static method main() → dynamic {}


Extra constant evaluation status:
Evaluated: RecordLiteral @ org-dartlang-testcase:///private_field_names.dart:7:11 -> RecordConstant(const ({_foo: 1}))
Extra constant evaluation: evaluated: 3, effectively constant: 1
1 change: 1 addition & 0 deletions pkg/front_end/testcases/textual_outline.status
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ records/duplicated_name_errors: FormatterCrash
records/issue50132: FormatterCrash
records/issue50133: FormatterCrash
records/null_shorting: FormatterCrash
records/private_field_names: FormatterCrash
records/record_literal_errors: FormatterCrash
records/record_type: FormatterCrash
records/record_type_errors: FormatterCrash
Expand Down

0 comments on commit a9a915e

Please sign in to comment.