Skip to content

Commit 6968295

Browse files
scheglovCommit Queue
authored and
Commit Queue
committed
Extension type. Mark private representation fields promotable.
Change-Id: I502f82ed272856bdbd6642c06f0e54ddef4d5b01 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/330990 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent dd3b0aa commit 6968295

File tree

3 files changed

+76
-0
lines changed

3 files changed

+76
-0
lines changed

pkg/analyzer/lib/src/summary2/library_builder.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,6 +1220,14 @@ class _FieldPromotability extends FieldPromotability<InterfaceElement,
12201220
for (var mixin_ in unitElement.mixins) {
12211221
_handleMembers(addClass(mixin_, isAbstract: true), mixin_);
12221222
}
1223+
// Private representation fields of extension types are always promotable.
1224+
// They also don't affect promotability of any other fields.
1225+
for (final extensionType in unitElement.extensionTypes) {
1226+
final representation = extensionType.representation;
1227+
if (representation.name.startsWith('_')) {
1228+
representation.isPromotable = true;
1229+
}
1230+
}
12231231
}
12241232

12251233
// Compute the set of field names that are not promotable.

pkg/analyzer/test/src/dart/resolution/field_promotion_test.dart

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,33 @@ PrefixedIdentifier
712712
''');
713713
}
714714

715+
test_extensionType_field_representation() async {
716+
await assertNoErrorsInCode('''
717+
extension type A(int? _it) {}
718+
719+
void f(A a) {
720+
if (a._it != null) {
721+
a._it;
722+
}
723+
}
724+
''');
725+
final node = findNode.prefixed('a._it;');
726+
assertResolvedNodeText(node, r'''
727+
PrefixedIdentifier
728+
prefix: SimpleIdentifier
729+
token: a
730+
staticElement: self::@function::f::@parameter::a
731+
staticType: A
732+
period: .
733+
identifier: SimpleIdentifier
734+
token: _it
735+
staticElement: self::@extensionType::A::@getter::_it
736+
staticType: int
737+
staticElement: self::@extensionType::A::@getter::_it
738+
staticType: int
739+
''');
740+
}
741+
715742
test_external_field() async {
716743
// External final fields should not be promotable.
717744
await assertNoErrorsInCode('''

pkg/analyzer/test/src/summary/elements_test.dart

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49290,6 +49290,44 @@ library
4929049290
''');
4929149291
}
4929249292

49293+
test_isPromotable_representationField_private() async {
49294+
var library = await buildLibrary(r'''
49295+
extension type A(int? _it) {}
49296+
49297+
class B {
49298+
int _it = 0;
49299+
}
49300+
49301+
class C {
49302+
int get _it => 0;
49303+
}
49304+
''');
49305+
49306+
configuration
49307+
..forPromotableFields(extensionTypeNames: {'A'})
49308+
..withConstructors = false;
49309+
checkElementText(library, r'''
49310+
library
49311+
definingUnit
49312+
extensionTypes
49313+
A @15
49314+
representation: self::@extensionType::A::@field::_it
49315+
primaryConstructor: self::@extensionType::A::@constructor::new
49316+
typeErasure: int?
49317+
interfaces
49318+
Object?
49319+
fields
49320+
final promotable _it @22
49321+
type: int?
49322+
fieldNameNonPromotabilityInfo
49323+
_it
49324+
conflictingFields
49325+
self::@class::B::@field::_it
49326+
conflictingGetters
49327+
self::@class::C::@getter::_it
49328+
''');
49329+
}
49330+
4929349331
test_metadata() async {
4929449332
newFile('$testPackageLibPath/a.dart', r'''
4929549333
const foo = 0;
@@ -52179,6 +52217,7 @@ extension on ElementTextConfiguration {
5217952217
void forPromotableFields({
5218052218
Set<String> classNames = const {},
5218152219
Set<String> enumNames = const {},
52220+
Set<String> extensionTypeNames = const {},
5218252221
Set<String> mixinNames = const {},
5218352222
Set<String> fieldNames = const {},
5218452223
}) {
@@ -52189,6 +52228,8 @@ extension on ElementTextConfiguration {
5218952228
return false;
5219052229
} else if (e is EnumElement) {
5219152230
return enumNames.contains(e.name);
52231+
} else if (e is ExtensionTypeElement) {
52232+
return extensionTypeNames.contains(e.name);
5219252233
} else if (e is FieldElement) {
5219352234
return fieldNames.isEmpty || fieldNames.contains(e.name);
5219452235
} else if (e is MixinElement) {

0 commit comments

Comments
 (0)