Skip to content

Commit bc6cdf5

Browse files
stereotype441commit-bot@chromium.org
authored andcommitted
Flow analysis: track property get targets.
These targets are needed for "why not promoted" error messages, and it's easier to have flow analysis keep track of them than to have the analyzer and CFE try to reconstruct them at the time of reporting the error. Bug: #44898 Change-Id: Ia8ef4a7ce13cc30860e59b7369e6230d233e252d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/193832 Commit-Queue: Paul Berry <[email protected]> Reviewed-by: Johnni Winther <[email protected]> Reviewed-by: Konstantin Shcheglov <[email protected]>
1 parent a15e9bc commit bc6cdf5

File tree

13 files changed

+121
-121
lines changed

13 files changed

+121
-121
lines changed

pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -736,8 +736,13 @@ abstract class FlowAnalysis<Node extends Object, Statement extends Node,
736736
/// expression to the left hand side of the `.`, and [propertyName] should be
737737
/// the identifier to the right hand side of the `.`. [staticType] should be
738738
/// the static type of the value returned by the property get.
739+
///
740+
/// [propertyMember] should be whatever data structure the client uses to keep
741+
/// track of the field or property being accessed. In the event of
742+
/// non-promotion of a property get, this value can be retrieved from
743+
/// [PropertyNotPromoted.propertyMember].
739744
void propertyGet(Expression wholeExpression, Expression target,
740-
String propertyName, Type staticType);
745+
String propertyName, Object? propertyMember, Type staticType);
741746

742747
/// Retrieves the SSA node associated with [variable], or `null` if [variable]
743748
/// is not associated with an SSA node because it is write captured. For
@@ -788,8 +793,13 @@ abstract class FlowAnalysis<Node extends Object, Statement extends Node,
788793
/// the whole property get, and [propertyName] should be the name of the
789794
/// property being read. [staticType] should be the static type of the value
790795
/// returned by the property get.
791-
void thisOrSuperPropertyGet(
792-
Expression expression, String propertyName, Type staticType);
796+
///
797+
/// [propertyMember] should be whatever data structure the client uses to keep
798+
/// track of the field or property being accessed. In the event of
799+
/// non-promotion of a property get, this value can be retrieved from
800+
/// [PropertyNotPromoted.propertyMember].
801+
void thisOrSuperPropertyGet(Expression expression, String propertyName,
802+
Object? propertyMember, Type staticType);
793803

794804
/// Call this method just before visiting the body of a "try/catch" statement.
795805
///
@@ -1339,11 +1349,12 @@ class FlowAnalysisDebug<Node extends Object, Statement extends Node,
13391349

13401350
@override
13411351
void propertyGet(Expression wholeExpression, Expression target,
1342-
String propertyName, Type staticType) {
1352+
String propertyName, Object? propertyMember, Type staticType) {
13431353
_wrap(
1344-
'propertyGet($wholeExpression, $target, $propertyName, $staticType)',
1354+
'propertyGet($wholeExpression, $target, $propertyName, '
1355+
'$propertyMember, $staticType)',
13451356
() => _wrapped.propertyGet(
1346-
wholeExpression, target, propertyName, staticType));
1357+
wholeExpression, target, propertyName, propertyMember, staticType));
13471358
}
13481359

13491360
@override
@@ -1378,12 +1389,13 @@ class FlowAnalysisDebug<Node extends Object, Statement extends Node,
13781389
}
13791390

13801391
@override
1381-
void thisOrSuperPropertyGet(
1382-
Expression expression, String propertyName, Type staticType) {
1392+
void thisOrSuperPropertyGet(Expression expression, String propertyName,
1393+
Object? propertyMember, Type staticType) {
13831394
_wrap(
1384-
'thisOrSuperPropertyGet($expression, $propertyName, $staticType)',
1395+
'thisOrSuperPropertyGet($expression, $propertyName, $propertyMember, '
1396+
'$staticType)',
13851397
() => _wrapped.thisOrSuperPropertyGet(
1386-
expression, propertyName, staticType));
1398+
expression, propertyName, propertyMember, staticType));
13871399
}
13881400

13891401
@override
@@ -2334,12 +2346,17 @@ class PropertyNotPromoted<Type extends Object> extends NonPromotionReason {
23342346
/// The name of the property.
23352347
final String propertyName;
23362348

2349+
/// The field or property being accessed. This matches a `propertyMember`
2350+
/// value that was passed to either [FlowAnalysis.propertyGet] or
2351+
/// [FlowAnalysis.thisOrSuperPropertyGet].
2352+
final Object? propertyMember;
2353+
23372354
/// The static type of the property at the time of the access. This is the
23382355
/// type that was passed to [FlowAnalysis.whyNotPromoted]; it is provided to
23392356
/// the client as a convenience for ID testing.
23402357
final Type staticType;
23412358

2342-
PropertyNotPromoted(this.propertyName, this.staticType);
2359+
PropertyNotPromoted(this.propertyName, this.propertyMember, this.staticType);
23432360

23442361
@override
23452362
String get documentationLink => 'http://dart.dev/go/non-promo-property';
@@ -2517,8 +2534,10 @@ abstract class Reference<Variable extends Object, Type extends Object> {
25172534

25182535
/// Creates a reference representing a get of a property called [propertyName]
25192536
/// on the reference represented by `this`.
2520-
Reference<Variable, Type> propertyGet(String propertyName) =>
2521-
new _PropertyGetReference<Variable, Type>(this, propertyName);
2537+
Reference<Variable, Type> propertyGet(
2538+
String propertyName, Object? propertyMember) =>
2539+
new _PropertyGetReference<Variable, Type>(
2540+
this, propertyName, propertyMember);
25222541

25232542
/// Stores info for this reference in [variableInfo].
25242543
void storeInfo(Map<Variable?, VariableModel<Variable, Type>> variableInfo,
@@ -3952,14 +3971,14 @@ class _FlowAnalysisImpl<Node extends Object, Statement extends Node,
39523971

39533972
@override
39543973
void propertyGet(Expression wholeExpression, Expression target,
3955-
String propertyName, Type staticType) {
3974+
String propertyName, Object? propertyMember, Type staticType) {
39563975
Reference<Variable, Type>? reference =
39573976
_getExpressionReference(target)?.reference;
39583977
if (reference != null) {
39593978
_storeExpressionReference(
39603979
wholeExpression,
39613980
new ReferenceWithType<Variable, Type>(
3962-
reference.propertyGet(propertyName), staticType));
3981+
reference.propertyGet(propertyName, propertyMember), staticType));
39633982
}
39643983
}
39653984

@@ -4016,12 +4035,13 @@ class _FlowAnalysisImpl<Node extends Object, Statement extends Node,
40164035
}
40174036

40184037
@override
4019-
void thisOrSuperPropertyGet(
4020-
Expression expression, String propertyName, Type staticType) {
4038+
void thisOrSuperPropertyGet(Expression expression, String propertyName,
4039+
Object? propertyMember, Type staticType) {
40214040
_storeExpressionReference(
40224041
expression,
40234042
new ReferenceWithType<Variable, Type>(
4024-
new _ThisReference<Variable, Type>().propertyGet(propertyName),
4043+
new _ThisReference<Variable, Type>()
4044+
.propertyGet(propertyName, propertyMember),
40254045
staticType));
40264046
}
40274047

@@ -4686,7 +4706,7 @@ class _LegacyTypePromotion<Node extends Object, Statement extends Node,
46864706

46874707
@override
46884708
void propertyGet(Expression wholeExpression, Expression target,
4689-
String propertyName, Type staticType) {}
4709+
String propertyName, Object? propertyMember, Type staticType) {}
46904710

46914711
@override
46924712
SsaNode<Variable, Type>? ssaNodeForTesting(Variable variable) {
@@ -4706,8 +4726,8 @@ class _LegacyTypePromotion<Node extends Object, Statement extends Node,
47064726
void thisOrSuper(Expression expression, Type staticType) {}
47074727

47084728
@override
4709-
void thisOrSuperPropertyGet(
4710-
Expression expression, String propertyName, Type staticType) {}
4729+
void thisOrSuperPropertyGet(Expression expression, String propertyName,
4730+
Object? propertyMember, Type staticType) {}
47114731

47124732
@override
47134733
void tryCatchStatement_bodyBegin() {}
@@ -4908,7 +4928,12 @@ class _PropertyGetReference<Variable extends Object, Type extends Object>
49084928
/// The name of the property.
49094929
final String propertyName;
49104930

4911-
_PropertyGetReference(this.target, this.propertyName);
4931+
/// The field or property being accessed. This matches a `propertyMember`
4932+
/// value that was passed to either [FlowAnalysis.propertyGet] or
4933+
/// [FlowAnalysis.thisOrSuperPropertyGet].
4934+
final Object? propertyMember;
4935+
4936+
_PropertyGetReference(this.target, this.propertyName, this.propertyMember);
49124937

49134938
@override
49144939
Map<Type, NonPromotionReason> Function() getNonPromotionReasons(
@@ -4920,7 +4945,8 @@ class _PropertyGetReference<Variable extends Object, Type extends Object>
49204945
return () {
49214946
Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
49224947
for (Type type in promotedTypes) {
4923-
result[type] = new PropertyNotPromoted(propertyName, staticType);
4948+
result[type] =
4949+
new PropertyNotPromoted(propertyName, propertyMember, staticType);
49244950
}
49254951
return result;
49264952
};

pkg/_fe_analyzer_shared/test/mini_ast.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1510,7 +1510,7 @@ class _Property extends LValue {
15101510
Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
15111511
var targetType = target._visit(h, flow);
15121512
var propertyType = h.getMember(targetType, propertyName);
1513-
flow.propertyGet(this, target, propertyName, propertyType);
1513+
flow.propertyGet(this, target, propertyName, propertyName, propertyType);
15141514
return propertyType;
15151515
}
15161516

@@ -1614,7 +1614,7 @@ class _ThisOrSuperPropertyGet extends Expression {
16141614
@override
16151615
Type _visit(
16161616
Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
1617-
flow.thisOrSuperPropertyGet(this, propertyName, type);
1617+
flow.thisOrSuperPropertyGet(this, propertyName, propertyName, type);
16181618
return type;
16191619
}
16201620
}

pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,7 @@ class AssignmentExpressionResolver {
121121
CompileTimeErrorCode.INVALID_ASSIGNMENT,
122122
right,
123123
[rightType, writeType],
124-
_resolver.computeWhyNotPromotedMessages(
125-
right, right, whyNotPromoted?.call()),
124+
_resolver.computeWhyNotPromotedMessages(right, whyNotPromoted?.call()),
126125
);
127126
}
128127

pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,11 @@ class MethodInvocationResolver {
807807
);
808808
}
809809
_resolver.flowAnalysis?.flow?.propertyGet(
810-
functionExpression, target, node.methodName.name, getterReturnType);
810+
functionExpression,
811+
target,
812+
node.methodName.name,
813+
node.methodName.staticElement,
814+
getterReturnType);
811815
functionExpression.staticType = targetType;
812816
}
813817

pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,8 @@ class PropertyElementResolver {
203203
readElementRequested = readLookup.requested;
204204
if (readElementRequested is PropertyAccessorElement &&
205205
!readElementRequested.isStatic) {
206-
_resolver.flowAnalysis?.flow?.thisOrSuperPropertyGet(
207-
node, node.name, readElementRequested.returnType);
206+
_resolver.flowAnalysis?.flow?.thisOrSuperPropertyGet(node, node.name,
207+
readElementRequested, readElementRequested.returnType);
208208
}
209209
_resolver.checkReadOfNotAssignedLocalVariable(node, readElementRequested);
210210
}
@@ -373,7 +373,11 @@ class PropertyElementResolver {
373373
nameErrorEntity: propertyName,
374374
);
375375

376-
_resolver.flowAnalysis?.flow?.propertyGet(node, target, propertyName.name,
376+
_resolver.flowAnalysis?.flow?.propertyGet(
377+
node,
378+
target,
379+
propertyName.name,
380+
result.getter,
377381
result.getter?.returnType ?? _typeSystem.typeProvider.dynamicType);
378382

379383
if (hasRead && result.needsGetterError) {
@@ -653,6 +657,7 @@ class PropertyElementResolver {
653657
node,
654658
target,
655659
propertyName.name,
660+
readElement,
656661
readElement?.returnType ?? _typeSystem.typeProvider.dynamicType);
657662
}
658663

pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,11 @@ class TypePropertyResolver {
130130
if (flow != null) {
131131
if (receiver != null) {
132132
messages = _resolver.computeWhyNotPromotedMessages(
133-
receiver, nameErrorEntity, flow.whyNotPromoted(receiver)());
133+
nameErrorEntity, flow.whyNotPromoted(receiver)());
134134
} else {
135135
var thisType = _resolver.thisType;
136136
if (thisType != null) {
137-
messages = _resolver.computeWhyNotPromotedMessages(receiver,
137+
messages = _resolver.computeWhyNotPromotedMessages(
138138
nameErrorEntity, flow.whyNotPromotedImplicitThis(thisType)());
139139
}
140140
}

pkg/analyzer/lib/src/error/bool_expression_verifier.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class BoolExpressionVerifier {
5757
errorCode: CompileTimeErrorCode
5858
.UNCHECKED_USE_OF_NULLABLE_VALUE_AS_CONDITION,
5959
messages: _resolver.computeWhyNotPromotedMessages(
60-
expression, expression, whyNotPromoted?.call()));
60+
expression, whyNotPromoted?.call()));
6161
} else {
6262
_errorReporter.reportErrorForNode(errorCode, expression, arguments);
6363
}

pkg/analyzer/lib/src/error/nullable_dereference_verifier.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ class NullableDereferenceVerifier {
7676

7777
List<DiagnosticMessage>? messages;
7878
if (errorNode is Expression) {
79-
messages = _resolver.computeWhyNotPromotedMessages(errorNode, errorNode,
80-
_resolver.flowAnalysis?.flow?.whyNotPromoted(errorNode)());
79+
messages = _resolver.computeWhyNotPromotedMessages(
80+
errorNode, _resolver.flowAnalysis?.flow?.whyNotPromoted(errorNode)());
8181
}
8282
report(errorNode, receiverType, errorCode: errorCode, messages: messages);
8383
return true;

pkg/analyzer/lib/src/generated/error_detection_helpers.dart

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ mixin ErrorDetectionHelpers {
8585
}
8686
return;
8787
}
88-
var messages = computeWhyNotPromotedMessages(
89-
expression, expression, whyNotPromoted?.call());
88+
var messages =
89+
computeWhyNotPromotedMessages(expression, whyNotPromoted?.call());
9090
// report problem
9191
if (isConstConstructor) {
9292
// TODO(paulberry): this error should be based on the actual type of the
@@ -229,7 +229,6 @@ mixin ErrorDetectionHelpers {
229229
/// [whyNotPromoted] should be the non-promotion details returned by the flow
230230
/// analysis engine.
231231
List<DiagnosticMessage> computeWhyNotPromotedMessages(
232-
Expression? expression,
233232
SyntacticEntity errorEntity,
234233
Map<DartType, NonPromotionReason>? whyNotPromoted);
235234

@@ -313,8 +312,7 @@ mixin ErrorDetectionHelpers {
313312
errorCode,
314313
getErrorNode(expression),
315314
[actualStaticType, expectedStaticType],
316-
computeWhyNotPromotedMessages(
317-
expression, expression, whyNotPromoted?.call()),
315+
computeWhyNotPromotedMessages(expression, whyNotPromoted?.call()),
318316
);
319317
return false;
320318
}

pkg/analyzer/lib/src/generated/error_verifier.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,6 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
312312

313313
@override
314314
List<DiagnosticMessage> computeWhyNotPromotedMessages(
315-
Expression? expression,
316315
SyntacticEntity errorEntity,
317316
Map<DartType, NonPromotionReason>? whyNotPromoted) {
318317
return [];

pkg/analyzer/lib/src/generated/resolver.dart

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -533,17 +533,13 @@ class ResolverVisitor extends ScopedVisitor with ErrorDetectionHelpers {
533533

534534
@override
535535
List<DiagnosticMessage> computeWhyNotPromotedMessages(
536-
Expression? expression,
537536
SyntacticEntity errorEntity,
538537
Map<DartType, NonPromotionReason>? whyNotPromoted) {
539-
if (expression is NamedExpression) {
540-
expression = expression.expression;
541-
}
542538
List<DiagnosticMessage> messages = [];
543539
if (whyNotPromoted != null) {
544540
for (var entry in whyNotPromoted.entries) {
545541
var whyNotPromotedVisitor = _WhyNotPromotedVisitor(
546-
source, expression, errorEntity, flowAnalysis!.dataForTesting);
542+
source, errorEntity, flowAnalysis!.dataForTesting);
547543
if (typeSystem.isPotentiallyNullable(entry.key)) continue;
548544
var message = entry.value.accept(whyNotPromotedVisitor);
549545
if (message != null) {
@@ -3447,10 +3443,6 @@ class _WhyNotPromotedVisitor
34473443
PromotableElement, DartType> {
34483444
final Source source;
34493445

3450-
/// The expression that was not promoted, or `null` if the thing that was not
3451-
/// promoted was an implicit `this`.
3452-
final Expression? _expression;
3453-
34543446
final SyntacticEntity _errorEntity;
34553447

34563448
final FlowAnalysisDataForTesting? _dataForTesting;
@@ -3459,8 +3451,7 @@ class _WhyNotPromotedVisitor
34593451

34603452
DartType? propertyType;
34613453

3462-
_WhyNotPromotedVisitor(
3463-
this.source, this._expression, this._errorEntity, this._dataForTesting);
3454+
_WhyNotPromotedVisitor(this.source, this._errorEntity, this._dataForTesting);
34643455

34653456
@override
34663457
DiagnosticMessage? visitDemoteViaExplicitWrite(
@@ -3480,18 +3471,7 @@ class _WhyNotPromotedVisitor
34803471
@override
34813472
DiagnosticMessage? visitPropertyNotPromoted(
34823473
PropertyNotPromoted<DartType> reason) {
3483-
var expression = _expression;
3484-
Element? receiverElement;
3485-
if (expression is SimpleIdentifier) {
3486-
receiverElement = expression.staticElement;
3487-
} else if (expression is PropertyAccess) {
3488-
receiverElement = expression.propertyName.staticElement;
3489-
} else if (expression is PrefixedIdentifier) {
3490-
receiverElement = expression.identifier.staticElement;
3491-
} else {
3492-
assert(false,
3493-
'Unrecognized property access expression: ${expression.runtimeType}');
3494-
}
3474+
var receiverElement = reason.propertyMember;
34953475
if (receiverElement is PropertyAccessorElement) {
34963476
propertyReference = receiverElement;
34973477
propertyType = reason.staticType;

0 commit comments

Comments
 (0)