Skip to content

Commit 0ab26a7

Browse files
scheglovCommit Queue
authored and
Commit Queue
committed
Extension type. Issue 53935. Update constant evaluation.
Bug: #53935 Bug: #53751 Change-Id: I514c79c79c9229b7fed313712b8f1d7a3ed91ca7 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/334862 Reviewed-by: Kallen Tu <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent 4dcdfc5 commit 0ab26a7

File tree

7 files changed

+308
-43
lines changed

7 files changed

+308
-43
lines changed

pkg/analyzer/lib/src/dart/constant/evaluation.dart

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ import 'package:analyzer/src/dart/element/element.dart';
2626
import 'package:analyzer/src/dart/element/member.dart';
2727
import 'package:analyzer/src/dart/element/type.dart';
2828
import 'package:analyzer/src/dart/element/type_algebra.dart';
29-
import 'package:analyzer/src/dart/element/type_system.dart' show TypeSystemImpl;
29+
import 'package:analyzer/src/dart/element/type_system.dart'
30+
show ExtensionTypeErasure, TypeSystemImpl;
3031
import 'package:analyzer/src/diagnostic/diagnostic.dart';
3132
import 'package:analyzer/src/error/codes.dart';
3233
import 'package:analyzer/src/generated/engine.dart';
@@ -2510,10 +2511,18 @@ class _InstanceCreationEvaluator {
25102511
return error;
25112512
}
25122513

2514+
var definingType = this.definingType;
2515+
if (definingType.element case final ExtensionTypeElement element) {
2516+
final representation = _fieldMap[element.representation.name];
2517+
if (representation != null) {
2518+
return representation;
2519+
}
2520+
}
2521+
25132522
return DartObjectImpl(
25142523
typeSystem,
25152524
definingType,
2516-
GenericState(definingType, _fieldMap, invocation: _invocation),
2525+
GenericState(_fieldMap, invocation: _invocation),
25172526
);
25182527
}
25192528

@@ -3131,6 +3140,7 @@ extension RuntimeExtensions on TypeSystemImpl {
31313140
DartObjectImpl obj,
31323141
DartType type,
31333142
) {
3143+
type = ExtensionTypeErasure().perform(type);
31343144
if (!isNonNullableByDefault) {
31353145
type = toLegacyTypeIfOptOut(type);
31363146
}

pkg/analyzer/lib/src/dart/constant/value.dart

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,20 @@ class DartObjectImpl implements DartObject, Constant {
181181
final VariableElementImpl? variable;
182182

183183
/// Initialize a newly created object to have the given [type] and [state].
184-
DartObjectImpl(this._typeSystem, this.type, this.state, {this.variable});
184+
factory DartObjectImpl(
185+
TypeSystemImpl typeSystem,
186+
DartType type,
187+
InstanceState state, {
188+
VariableElementImpl? variable,
189+
}) {
190+
type = ExtensionTypeErasure().perform(type);
191+
return DartObjectImpl._(
192+
typeSystem,
193+
type,
194+
state,
195+
variable: variable,
196+
);
197+
}
185198

186199
/// Creates a duplicate instance of [other], tied to [variable].
187200
factory DartObjectImpl.forVariable(
@@ -216,10 +229,17 @@ class DartObjectImpl implements DartObject, Constant {
216229
return DartObjectImpl(
217230
typeSystem,
218231
type,
219-
GenericState(type, {}, isUnknown: true),
232+
GenericState({}, isUnknown: true),
220233
);
221234
}
222235

236+
/// Initialize a newly created object to have the given [type] and [state].
237+
DartObjectImpl._(this._typeSystem, this.type, this.state, {this.variable}) {
238+
if (state case final GenericState state) {
239+
state._object = this;
240+
}
241+
}
242+
223243
Map<String, DartObjectImpl>? get fields => state.fields;
224244

225245
@override
@@ -1419,8 +1439,8 @@ class GenericState extends InstanceState {
14191439
/// Pseudo-field that we use to represent fields in the superclass.
14201440
static String SUPERCLASS_FIELD = "(super)";
14211441

1422-
/// The type of the object being represented.
1423-
final DartType _type;
1442+
/// The enclosing [DartObjectImpl].
1443+
late DartObjectImpl _object;
14241444

14251445
/// The values of the fields of this instance.
14261446
final Map<String, DartObjectImpl> _fieldMap;
@@ -1431,10 +1451,7 @@ class GenericState extends InstanceState {
14311451
@override
14321452
final bool isUnknown;
14331453

1434-
/// Initialize a newly created state to represent a newly created object. The
1435-
/// [fieldMap] contains the values of the fields of the instance.
14361454
GenericState(
1437-
this._type,
14381455
this._fieldMap, {
14391456
this.invocation,
14401457
this.isUnknown = false,
@@ -1486,7 +1503,7 @@ class GenericState extends InstanceState {
14861503

14871504
@override
14881505
bool hasPrimitiveEquality(FeatureSet featureSet) {
1489-
final type = _type;
1506+
final type = _object.type;
14901507
if (type is InterfaceType) {
14911508
bool isFromDartCoreObject(ExecutableElement? element) {
14921509
final enclosing = element?.enclosingElement;
@@ -2481,19 +2498,32 @@ class ListState extends InstanceState {
24812498
final DartType elementType;
24822499
final List<DartObjectImpl> elements;
24832500

2484-
/// Whether the list contains an element that has an unknown value.
2485-
final bool _isUnknown;
2501+
@override
2502+
final bool isUnknown;
24862503

2487-
ListState({
2488-
required this.elementType,
2489-
required this.elements,
2504+
factory ListState({
2505+
required DartType elementType,
2506+
required List<DartObjectImpl> elements,
24902507
bool isUnknown = false,
2491-
}) : _isUnknown = isUnknown;
2508+
}) {
2509+
elementType = ExtensionTypeErasure().perform(elementType);
2510+
return ListState._(
2511+
elementType: elementType,
2512+
elements: elements,
2513+
isUnknown: isUnknown,
2514+
);
2515+
}
24922516

24932517
/// Creates a state that represents a list whose value is not known.
24942518
factory ListState.unknown(DartType elementType) =>
24952519
ListState(elementType: elementType, elements: [], isUnknown: true);
24962520

2521+
ListState._({
2522+
required this.elementType,
2523+
required this.elements,
2524+
required this.isUnknown,
2525+
});
2526+
24972527
@override
24982528
int get hashCode {
24992529
int value = 0;
@@ -2504,9 +2534,6 @@ class ListState extends InstanceState {
25042534
return value;
25052535
}
25062536

2507-
@override
2508-
bool get isUnknown => _isUnknown;
2509-
25102537
@override
25112538
String get typeName => "List";
25122539

@@ -3077,8 +3104,14 @@ class TypeState extends InstanceState {
30773104
/// The element representing the type being modeled.
30783105
final DartType? _type;
30793106

3080-
/// Initialize a newly created state to represent the given [value].
3081-
TypeState(this._type);
3107+
factory TypeState(DartType? type) {
3108+
if (type != null) {
3109+
type = ExtensionTypeErasure().perform(type);
3110+
}
3111+
return TypeState._(type);
3112+
}
3113+
3114+
TypeState._(this._type);
30823115

30833116
@override
30843117
int get hashCode => _type?.hashCode ?? 0;

pkg/analyzer/lib/src/dart/element/type_system.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,22 @@ import 'package:analyzer/src/dart/element/well_bounded.dart';
3535
import 'package:analyzer/src/utilities/extensions/collection.dart';
3636
import 'package:meta/meta.dart';
3737

38+
class ExtensionTypeErasure extends ReplacementVisitor {
39+
DartType perform(DartType type) {
40+
return type.accept(this) ?? type;
41+
}
42+
43+
@override
44+
DartType? visitInterfaceType(covariant InterfaceTypeImpl type) {
45+
final typeErasure = type.representationTypeErasure;
46+
if (typeErasure != null) {
47+
return typeErasure;
48+
}
49+
50+
return super.visitInterfaceType(type);
51+
}
52+
}
53+
3854
/// Fresh type parameters created to unify two lists of type parameters.
3955
class RelatedTypeParameters {
4056
static final _empty = RelatedTypeParameters._(const [], const []);

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

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import 'package:analyzer/dart/element/type.dart';
77
import 'package:analyzer/src/dart/ast/ast.dart';
88
import 'package:analyzer/src/dart/ast/extensions.dart';
99
import 'package:analyzer/src/dart/element/element.dart';
10-
import 'package:analyzer/src/dart/element/replacement_visitor.dart';
1110
import 'package:analyzer/src/dart/element/type.dart';
11+
import 'package:analyzer/src/dart/element/type_system.dart';
1212
import 'package:analyzer/src/dart/element/type_visitor.dart';
1313
import 'package:analyzer/src/summary2/link.dart';
1414
import 'package:analyzer/src/utilities/extensions/collection.dart';
@@ -58,22 +58,6 @@ class _DependenciesCollector extends RecursiveTypeVisitor {
5858
}
5959
}
6060

61-
class _ExtensionTypeErasure extends ReplacementVisitor {
62-
DartType perform(DartType type) {
63-
return type.accept(this) ?? type;
64-
}
65-
66-
@override
67-
DartType? visitInterfaceType(covariant InterfaceTypeImpl type) {
68-
final typeErasure = type.representationTypeErasure;
69-
if (typeErasure != null) {
70-
return typeErasure;
71-
}
72-
73-
return super.visitInterfaceType(type);
74-
}
75-
}
76-
7761
class _ImplementsNode extends graph.Node<_ImplementsNode> {
7862
final _ImplementsWalker walker;
7963
final ExtensionTypeElementImpl element;
@@ -167,7 +151,7 @@ class _Node extends graph.Node<_Node> {
167151
final typeSystem = element.library.typeSystem;
168152

169153
element.representation.type = type;
170-
element.typeErasure = _ExtensionTypeErasure().perform(type);
154+
element.typeErasure = ExtensionTypeErasure().perform(type);
171155

172156
var interfaces = node.implementsClause?.interfaces
173157
.map((e) => e.type)

0 commit comments

Comments
 (0)