Revert "Flow analysis: track property get targets."

This reverts commit bc6cdf54fd.

Reason for revert: Broke Golem benchmarks - https://golem.corp.goog/PerformanceChanges?repository=dart&revision=91561

Original change's description:
> 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: https://github.com/dart-lang/sdk/issues/44898
> Change-Id: Ia8ef4a7ce13cc30860e59b7369e6230d233e252d
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/193832
> Commit-Queue: Paul Berry <paulberry@google.com>
> Reviewed-by: Johnni Winther <johnniwinther@google.com>
> Reviewed-by: Konstantin Shcheglov <scheglov@google.com>

TBR=paulberry@google.com,scheglov@google.com,johnniwinther@google.com

Change-Id: Ic2b66b1db621c0f4e4c5398acfe2ae61bd7625ca
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: https://github.com/dart-lang/sdk/issues/44898
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/194104
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This commit is contained in:
Paul Berry
2021-04-06 11:49:09 +00:00
committed by commit-bot@chromium.org
parent fc349bdbb5
commit cf7587a160
13 changed files with 121 additions and 121 deletions
@@ -736,13 +736,8 @@ abstract class FlowAnalysis<Node extends Object, Statement extends Node,
/// expression to the left hand side of the `.`, and [propertyName] should be
/// the identifier to the right hand side of the `.`. [staticType] should be
/// the static type of the value returned by the property get.
///
/// [propertyMember] should be whatever data structure the client uses to keep
/// track of the field or property being accessed. In the event of
/// non-promotion of a property get, this value can be retrieved from
/// [PropertyNotPromoted.propertyMember].
void propertyGet(Expression wholeExpression, Expression target,
String propertyName, Object? propertyMember, Type staticType);
String propertyName, Type staticType);
/// Retrieves the SSA node associated with [variable], or `null` if [variable]
/// is not associated with an SSA node because it is write captured. For
@@ -793,13 +788,8 @@ abstract class FlowAnalysis<Node extends Object, Statement extends Node,
/// the whole property get, and [propertyName] should be the name of the
/// property being read. [staticType] should be the static type of the value
/// returned by the property get.
///
/// [propertyMember] should be whatever data structure the client uses to keep
/// track of the field or property being accessed. In the event of
/// non-promotion of a property get, this value can be retrieved from
/// [PropertyNotPromoted.propertyMember].
void thisOrSuperPropertyGet(Expression expression, String propertyName,
Object? propertyMember, Type staticType);
void thisOrSuperPropertyGet(
Expression expression, String propertyName, Type staticType);
/// Call this method just before visiting the body of a "try/catch" statement.
///
@@ -1349,12 +1339,11 @@ class FlowAnalysisDebug<Node extends Object, Statement extends Node,
@override
void propertyGet(Expression wholeExpression, Expression target,
String propertyName, Object? propertyMember, Type staticType) {
String propertyName, Type staticType) {
_wrap(
'propertyGet($wholeExpression, $target, $propertyName, '
'$propertyMember, $staticType)',
'propertyGet($wholeExpression, $target, $propertyName, $staticType)',
() => _wrapped.propertyGet(
wholeExpression, target, propertyName, propertyMember, staticType));
wholeExpression, target, propertyName, staticType));
}
@override
@@ -1389,13 +1378,12 @@ class FlowAnalysisDebug<Node extends Object, Statement extends Node,
}
@override
void thisOrSuperPropertyGet(Expression expression, String propertyName,
Object? propertyMember, Type staticType) {
void thisOrSuperPropertyGet(
Expression expression, String propertyName, Type staticType) {
_wrap(
'thisOrSuperPropertyGet($expression, $propertyName, $propertyMember, '
'$staticType)',
'thisOrSuperPropertyGet($expression, $propertyName, $staticType)',
() => _wrapped.thisOrSuperPropertyGet(
expression, propertyName, propertyMember, staticType));
expression, propertyName, staticType));
}
@override
@@ -2346,17 +2334,12 @@ class PropertyNotPromoted<Type extends Object> extends NonPromotionReason {
/// The name of the property.
final String propertyName;
/// The field or property being accessed. This matches a `propertyMember`
/// value that was passed to either [FlowAnalysis.propertyGet] or
/// [FlowAnalysis.thisOrSuperPropertyGet].
final Object? propertyMember;
/// The static type of the property at the time of the access. This is the
/// type that was passed to [FlowAnalysis.whyNotPromoted]; it is provided to
/// the client as a convenience for ID testing.
final Type staticType;
PropertyNotPromoted(this.propertyName, this.propertyMember, this.staticType);
PropertyNotPromoted(this.propertyName, this.staticType);
@override
String get documentationLink => 'http://dart.dev/go/non-promo-property';
@@ -2534,10 +2517,8 @@ abstract class Reference<Variable extends Object, Type extends Object> {
/// Creates a reference representing a get of a property called [propertyName]
/// on the reference represented by `this`.
Reference<Variable, Type> propertyGet(
String propertyName, Object? propertyMember) =>
new _PropertyGetReference<Variable, Type>(
this, propertyName, propertyMember);
Reference<Variable, Type> propertyGet(String propertyName) =>
new _PropertyGetReference<Variable, Type>(this, propertyName);
/// Stores info for this reference in [variableInfo].
void storeInfo(Map<Variable?, VariableModel<Variable, Type>> variableInfo,
@@ -3971,14 +3952,14 @@ class _FlowAnalysisImpl<Node extends Object, Statement extends Node,
@override
void propertyGet(Expression wholeExpression, Expression target,
String propertyName, Object? propertyMember, Type staticType) {
String propertyName, Type staticType) {
Reference<Variable, Type>? reference =
_getExpressionReference(target)?.reference;
if (reference != null) {
_storeExpressionReference(
wholeExpression,
new ReferenceWithType<Variable, Type>(
reference.propertyGet(propertyName, propertyMember), staticType));
reference.propertyGet(propertyName), staticType));
}
}
@@ -4035,13 +4016,12 @@ class _FlowAnalysisImpl<Node extends Object, Statement extends Node,
}
@override
void thisOrSuperPropertyGet(Expression expression, String propertyName,
Object? propertyMember, Type staticType) {
void thisOrSuperPropertyGet(
Expression expression, String propertyName, Type staticType) {
_storeExpressionReference(
expression,
new ReferenceWithType<Variable, Type>(
new _ThisReference<Variable, Type>()
.propertyGet(propertyName, propertyMember),
new _ThisReference<Variable, Type>().propertyGet(propertyName),
staticType));
}
@@ -4706,7 +4686,7 @@ class _LegacyTypePromotion<Node extends Object, Statement extends Node,
@override
void propertyGet(Expression wholeExpression, Expression target,
String propertyName, Object? propertyMember, Type staticType) {}
String propertyName, Type staticType) {}
@override
SsaNode<Variable, Type>? ssaNodeForTesting(Variable variable) {
@@ -4726,8 +4706,8 @@ class _LegacyTypePromotion<Node extends Object, Statement extends Node,
void thisOrSuper(Expression expression, Type staticType) {}
@override
void thisOrSuperPropertyGet(Expression expression, String propertyName,
Object? propertyMember, Type staticType) {}
void thisOrSuperPropertyGet(
Expression expression, String propertyName, Type staticType) {}
@override
void tryCatchStatement_bodyBegin() {}
@@ -4928,12 +4908,7 @@ class _PropertyGetReference<Variable extends Object, Type extends Object>
/// The name of the property.
final String propertyName;
/// The field or property being accessed. This matches a `propertyMember`
/// value that was passed to either [FlowAnalysis.propertyGet] or
/// [FlowAnalysis.thisOrSuperPropertyGet].
final Object? propertyMember;
_PropertyGetReference(this.target, this.propertyName, this.propertyMember);
_PropertyGetReference(this.target, this.propertyName);
@override
Map<Type, NonPromotionReason> Function() getNonPromotionReasons(
@@ -4945,8 +4920,7 @@ class _PropertyGetReference<Variable extends Object, Type extends Object>
return () {
Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
for (Type type in promotedTypes) {
result[type] =
new PropertyNotPromoted(propertyName, propertyMember, staticType);
result[type] = new PropertyNotPromoted(propertyName, staticType);
}
return result;
};
+2 -2
View File
@@ -1510,7 +1510,7 @@ class _Property extends LValue {
Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
var targetType = target._visit(h, flow);
var propertyType = h.getMember(targetType, propertyName);
flow.propertyGet(this, target, propertyName, propertyName, propertyType);
flow.propertyGet(this, target, propertyName, propertyType);
return propertyType;
}
@@ -1614,7 +1614,7 @@ class _ThisOrSuperPropertyGet extends Expression {
@override
Type _visit(
Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
flow.thisOrSuperPropertyGet(this, propertyName, propertyName, type);
flow.thisOrSuperPropertyGet(this, propertyName, type);
return type;
}
}
@@ -121,7 +121,8 @@ class AssignmentExpressionResolver {
CompileTimeErrorCode.INVALID_ASSIGNMENT,
right,
[rightType, writeType],
_resolver.computeWhyNotPromotedMessages(right, whyNotPromoted?.call()),
_resolver.computeWhyNotPromotedMessages(
right, right, whyNotPromoted?.call()),
);
}
@@ -807,11 +807,7 @@ class MethodInvocationResolver {
);
}
_resolver.flowAnalysis?.flow?.propertyGet(
functionExpression,
target,
node.methodName.name,
node.methodName.staticElement,
getterReturnType);
functionExpression, target, node.methodName.name, getterReturnType);
functionExpression.staticType = targetType;
}
@@ -203,8 +203,8 @@ class PropertyElementResolver {
readElementRequested = readLookup.requested;
if (readElementRequested is PropertyAccessorElement &&
!readElementRequested.isStatic) {
_resolver.flowAnalysis?.flow?.thisOrSuperPropertyGet(node, node.name,
readElementRequested, readElementRequested.returnType);
_resolver.flowAnalysis?.flow?.thisOrSuperPropertyGet(
node, node.name, readElementRequested.returnType);
}
_resolver.checkReadOfNotAssignedLocalVariable(node, readElementRequested);
}
@@ -373,11 +373,7 @@ class PropertyElementResolver {
nameErrorEntity: propertyName,
);
_resolver.flowAnalysis?.flow?.propertyGet(
node,
target,
propertyName.name,
result.getter,
_resolver.flowAnalysis?.flow?.propertyGet(node, target, propertyName.name,
result.getter?.returnType ?? _typeSystem.typeProvider.dynamicType);
if (hasRead && result.needsGetterError) {
@@ -657,7 +653,6 @@ class PropertyElementResolver {
node,
target,
propertyName.name,
readElement,
readElement?.returnType ?? _typeSystem.typeProvider.dynamicType);
}
@@ -130,11 +130,11 @@ class TypePropertyResolver {
if (flow != null) {
if (receiver != null) {
messages = _resolver.computeWhyNotPromotedMessages(
nameErrorEntity, flow.whyNotPromoted(receiver)());
receiver, nameErrorEntity, flow.whyNotPromoted(receiver)());
} else {
var thisType = _resolver.thisType;
if (thisType != null) {
messages = _resolver.computeWhyNotPromotedMessages(
messages = _resolver.computeWhyNotPromotedMessages(receiver,
nameErrorEntity, flow.whyNotPromotedImplicitThis(thisType)());
}
}
@@ -57,7 +57,7 @@ class BoolExpressionVerifier {
errorCode: CompileTimeErrorCode
.UNCHECKED_USE_OF_NULLABLE_VALUE_AS_CONDITION,
messages: _resolver.computeWhyNotPromotedMessages(
expression, whyNotPromoted?.call()));
expression, expression, whyNotPromoted?.call()));
} else {
_errorReporter.reportErrorForNode(errorCode, expression, arguments);
}
@@ -76,8 +76,8 @@ class NullableDereferenceVerifier {
List<DiagnosticMessage>? messages;
if (errorNode is Expression) {
messages = _resolver.computeWhyNotPromotedMessages(
errorNode, _resolver.flowAnalysis?.flow?.whyNotPromoted(errorNode)());
messages = _resolver.computeWhyNotPromotedMessages(errorNode, errorNode,
_resolver.flowAnalysis?.flow?.whyNotPromoted(errorNode)());
}
report(errorNode, receiverType, errorCode: errorCode, messages: messages);
return true;
@@ -85,8 +85,8 @@ mixin ErrorDetectionHelpers {
}
return;
}
var messages =
computeWhyNotPromotedMessages(expression, whyNotPromoted?.call());
var messages = computeWhyNotPromotedMessages(
expression, expression, whyNotPromoted?.call());
// report problem
if (isConstConstructor) {
// TODO(paulberry): this error should be based on the actual type of the
@@ -229,6 +229,7 @@ mixin ErrorDetectionHelpers {
/// [whyNotPromoted] should be the non-promotion details returned by the flow
/// analysis engine.
List<DiagnosticMessage> computeWhyNotPromotedMessages(
Expression? expression,
SyntacticEntity errorEntity,
Map<DartType, NonPromotionReason>? whyNotPromoted);
@@ -312,7 +313,8 @@ mixin ErrorDetectionHelpers {
errorCode,
getErrorNode(expression),
[actualStaticType, expectedStaticType],
computeWhyNotPromotedMessages(expression, whyNotPromoted?.call()),
computeWhyNotPromotedMessages(
expression, expression, whyNotPromoted?.call()),
);
return false;
}
@@ -312,6 +312,7 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
@override
List<DiagnosticMessage> computeWhyNotPromotedMessages(
Expression? expression,
SyntacticEntity errorEntity,
Map<DartType, NonPromotionReason>? whyNotPromoted) {
return [];
+23 -3
View File
@@ -533,13 +533,17 @@ class ResolverVisitor extends ScopedVisitor with ErrorDetectionHelpers {
@override
List<DiagnosticMessage> computeWhyNotPromotedMessages(
Expression? expression,
SyntacticEntity errorEntity,
Map<DartType, NonPromotionReason>? whyNotPromoted) {
if (expression is NamedExpression) {
expression = expression.expression;
}
List<DiagnosticMessage> messages = [];
if (whyNotPromoted != null) {
for (var entry in whyNotPromoted.entries) {
var whyNotPromotedVisitor = _WhyNotPromotedVisitor(
source, errorEntity, flowAnalysis!.dataForTesting);
source, expression, errorEntity, flowAnalysis!.dataForTesting);
if (typeSystem.isPotentiallyNullable(entry.key)) continue;
var message = entry.value.accept(whyNotPromotedVisitor);
if (message != null) {
@@ -3443,6 +3447,10 @@ class _WhyNotPromotedVisitor
PromotableElement, DartType> {
final Source source;
/// The expression that was not promoted, or `null` if the thing that was not
/// promoted was an implicit `this`.
final Expression? _expression;
final SyntacticEntity _errorEntity;
final FlowAnalysisDataForTesting? _dataForTesting;
@@ -3451,7 +3459,8 @@ class _WhyNotPromotedVisitor
DartType? propertyType;
_WhyNotPromotedVisitor(this.source, this._errorEntity, this._dataForTesting);
_WhyNotPromotedVisitor(
this.source, this._expression, this._errorEntity, this._dataForTesting);
@override
DiagnosticMessage? visitDemoteViaExplicitWrite(
@@ -3471,7 +3480,18 @@ class _WhyNotPromotedVisitor
@override
DiagnosticMessage? visitPropertyNotPromoted(
PropertyNotPromoted<DartType> reason) {
var receiverElement = reason.propertyMember;
var expression = _expression;
Element? receiverElement;
if (expression is SimpleIdentifier) {
receiverElement = expression.staticElement;
} else if (expression is PropertyAccess) {
receiverElement = expression.propertyName.staticElement;
} else if (expression is PrefixedIdentifier) {
receiverElement = expression.identifier.staticElement;
} else {
assert(false,
'Unrecognized property access expression: ${expression.runtimeType}');
}
if (receiverElement is PropertyAccessorElement) {
propertyReference = receiverElement;
propertyType = reason.staticType;
@@ -1480,6 +1480,7 @@ class InferenceVisitor
replacement = inferrer.helper.buildProblem(
messageNullableSpreadError, receiver.fileOffset, 1,
context: inferrer.getWhyNotPromotedContext(
receiver,
inferrer.flowAnalysis?.whyNotPromoted(receiver)(),
element,
(type) => !type.isPotentiallyNullable));
@@ -1549,6 +1550,7 @@ class InferenceVisitor
replacement = inferrer.helper.buildProblem(
messageNullableSpreadError, receiver.fileOffset, 1,
context: inferrer.getWhyNotPromotedContext(
receiver,
inferrer.flowAnalysis?.whyNotPromoted(receiver)(),
element,
(type) => !type.isPotentiallyNullable));
@@ -1986,6 +1988,7 @@ class InferenceVisitor
Expression problem = inferrer.helper.buildProblem(
messageNullableSpreadError, receiver.fileOffset, 1,
context: inferrer.getWhyNotPromotedContext(
receiver,
inferrer.flowAnalysis?.whyNotPromoted(receiver)(),
entry,
(type) => !type.isPotentiallyNullable));
@@ -2005,6 +2008,7 @@ class InferenceVisitor
receiver.fileOffset,
1,
context: inferrer.getWhyNotPromotedContext(
receiver,
inferrer.flowAnalysis?.whyNotPromoted(receiver)(),
entry,
(type) => !type.isPotentiallyNullable));
@@ -2115,6 +2119,7 @@ class InferenceVisitor
keyError = inferrer.helper.buildProblem(
messageNullableSpreadError, receiver.fileOffset, 1,
context: inferrer.getWhyNotPromotedContext(
receiver,
inferrer.flowAnalysis?.whyNotPromoted(receiver)(),
entry,
(type) => !type.isPotentiallyNullable));
@@ -2879,9 +2884,8 @@ class InferenceVisitor
}
ExpressionInferenceResult readResult = _computePropertyGet(node.readOffset,
readReceiver, receiverType, node.propertyName, const UnknownType(),
isThisReceiver: node.receiver is ThisExpression)
.expressionInferenceResult;
readReceiver, receiverType, node.propertyName, const UnknownType(),
isThisReceiver: node.receiver is ThisExpression);
Expression read = readResult.expression;
DartType readType = readResult.inferredType;
@@ -2937,9 +2941,8 @@ class InferenceVisitor
Expression writeReceiver = createVariableGet(receiverVariable);
ExpressionInferenceResult readResult = _computePropertyGet(node.readOffset,
readReceiver, receiverType, node.propertyName, const UnknownType(),
isThisReceiver: node.receiver is ThisExpression)
.expressionInferenceResult;
readReceiver, receiverType, node.propertyName, const UnknownType(),
isThisReceiver: node.receiver is ThisExpression);
reportNonNullableInNullAwareWarningIfNeeded(
readResult.inferredType, "??=", node.readOffset);
@@ -4692,7 +4695,7 @@ class InferenceVisitor
/// [typeContext] is used to create implicit generic tearoff instantiation
/// if necessary. [isThisReceiver] must be set to `true` if the receiver is a
/// `this` expression.
PropertyGetInferenceResult _computePropertyGet(
ExpressionInferenceResult _computePropertyGet(
int fileOffset,
Expression receiver,
DartType receiverType,
@@ -4876,11 +4879,12 @@ class InferenceVisitor
read.fileOffset,
propertyName.text.length,
context: inferrer.getWhyNotPromotedContext(
receiver,
inferrer.flowAnalysis?.whyNotPromoted(receiver)(),
read,
(type) => !type.isPotentiallyNullable));
}
return new PropertyGetInferenceResult(readResult, readTarget.member);
return readResult;
}
/// Creates a property set operation of [writeTarget] on [receiver] using
@@ -5212,13 +5216,12 @@ class InferenceVisitor
DartType nonNullReceiverType = receiverType.toNonNull();
ExpressionInferenceResult readResult = _computePropertyGet(
node.readOffset,
readReceiver,
nonNullReceiverType,
node.propertyName,
const UnknownType(),
isThisReceiver: node.receiver is ThisExpression)
.expressionInferenceResult;
node.readOffset,
readReceiver,
nonNullReceiverType,
node.propertyName,
const UnknownType(),
isThisReceiver: node.receiver is ThisExpression);
Expression read = readResult.expression;
DartType readType = readResult.inferredType;
@@ -5749,9 +5752,8 @@ class InferenceVisitor
DartType nonNullReceiverType = receiverType.toNonNull();
ExpressionInferenceResult readResult = _computePropertyGet(node.readOffset,
readReceiver, nonNullReceiverType, node.name, typeContext,
isThisReceiver: node.receiver is ThisExpression)
.expressionInferenceResult;
readReceiver, nonNullReceiverType, node.name, typeContext,
isThisReceiver: node.receiver is ThisExpression);
Expression read = readResult.expression;
DartType readType = readResult.inferredType;
inferrer.flowAnalysis.ifNullExpression_rightBegin(read, readType);
@@ -5843,13 +5845,11 @@ class InferenceVisitor
DartType receiverType = result.nullAwareActionType;
node.receiver = receiver..parent = node;
PropertyGetInferenceResult propertyGetInferenceResult = _computePropertyGet(
ExpressionInferenceResult readResult = _computePropertyGet(
node.fileOffset, receiver, receiverType, node.name, typeContext,
isThisReceiver: node.receiver is ThisExpression);
ExpressionInferenceResult readResult =
propertyGetInferenceResult.expressionInferenceResult;
inferrer.flowAnalysis.propertyGet(node, node.receiver, node.name.text,
propertyGetInferenceResult.member, readResult.inferredType);
inferrer.flowAnalysis.propertyGet(
node, node.receiver, node.name.text, readResult.inferredType);
ExpressionInferenceResult expressionInferenceResult =
inferrer.createNullAwareExpressionInferenceResult(
readResult.inferredType, readResult.expression, nullAwareGuards);
@@ -290,13 +290,14 @@ class TypeInferrerImpl implements TypeInferrer {
/// promoted, to be used when reporting an error for a larger expression
/// containing [receiver]. [node] is the containing tree node.
List<LocatedMessage> getWhyNotPromotedContext(
Expression receiver,
Map<DartType, NonPromotionReason> whyNotPromoted,
TreeNode node,
bool Function(DartType) typeFilter) {
List<LocatedMessage> context;
if (whyNotPromoted != null && whyNotPromoted.isNotEmpty) {
_WhyNotPromotedVisitor whyNotPromotedVisitor =
new _WhyNotPromotedVisitor(this);
new _WhyNotPromotedVisitor(this, receiver);
for (core.MapEntry<DartType, NonPromotionReason> entry
in whyNotPromoted.entries) {
if (!typeFilter(entry.key)) continue;
@@ -614,6 +615,7 @@ class TypeInferrerImpl implements TypeInferrer {
nullabilityErrorTemplate.withArguments(expressionType,
declaredContextType ?? contextType, isNonNullableByDefault),
context: getWhyNotPromotedContext(
expression,
flowAnalysis?.whyNotPromoted(expression)(),
expression,
(type) => typeSchemaEnvironment.isSubtypeOf(type,
@@ -2824,6 +2826,7 @@ class TypeInferrerImpl implements TypeInferrer {
// void Function() get call => () {};
// }
List<LocatedMessage> context = getWhyNotPromotedContext(
receiver,
flowAnalysis?.whyNotPromoted(receiver)(),
staticInvocation,
(type) => !type.isPotentiallyNullable);
@@ -2855,6 +2858,7 @@ class TypeInferrerImpl implements TypeInferrer {
Expression replacement = result.applyResult(staticInvocation);
if (!isTopLevel && target.isNullable) {
List<LocatedMessage> context = getWhyNotPromotedContext(
receiver,
flowAnalysis?.whyNotPromoted(receiver)(),
staticInvocation,
(type) => !type.isPotentiallyNullable);
@@ -2968,6 +2972,7 @@ class TypeInferrerImpl implements TypeInferrer {
Expression replacement = result.applyResult(expression);
if (!isTopLevel && target.isNullableCallFunction) {
List<LocatedMessage> context = getWhyNotPromotedContext(
receiver,
flowAnalysis?.whyNotPromoted(receiver)(),
expression,
(type) => !type.isPotentiallyNullable);
@@ -3142,6 +3147,7 @@ class TypeInferrerImpl implements TypeInferrer {
replacement = result.applyResult(replacement);
if (!isTopLevel && target.isNullable) {
List<LocatedMessage> context = getWhyNotPromotedContext(
receiver,
flowAnalysis?.whyNotPromoted(receiver)(),
expression,
(type) => !type.isPotentiallyNullable);
@@ -3302,6 +3308,7 @@ class TypeInferrerImpl implements TypeInferrer {
// void Function() get foo => () {};
// }
List<LocatedMessage> context = getWhyNotPromotedContext(
receiver,
flowAnalysis?.whyNotPromoted(receiver)(),
invocationResult.expression,
(type) => !type.isPotentiallyNullable);
@@ -3458,8 +3465,8 @@ class TypeInferrerImpl implements TypeInferrer {
new PropertyGet(originalReceiver, originalName, originalTarget)
..fileOffset = fileOffset;
}
flowAnalysis.propertyGet(originalPropertyGet, originalReceiver,
originalName.text, originalTarget, calleeType);
flowAnalysis.propertyGet(
originalPropertyGet, originalReceiver, originalName.text, calleeType);
Expression propertyGet = originalPropertyGet;
if (receiver is! ThisExpression &&
calleeType is! DynamicType &&
@@ -3511,8 +3518,11 @@ class TypeInferrerImpl implements TypeInferrer {
// }
// TODO(paulberry): would it be better to report NullableMethodCallError
// in this scenario?
List<LocatedMessage> context = getWhyNotPromotedContext(whyNotPromoted(),
invocationResult.expression, (type) => !type.isPotentiallyNullable);
List<LocatedMessage> context = getWhyNotPromotedContext(
receiver,
whyNotPromoted(),
invocationResult.expression,
(type) => !type.isPotentiallyNullable);
invocationResult = wrapExpressionInferenceResultInProblem(
invocationResult,
templateNullableExpressionCallError.withArguments(
@@ -3843,7 +3853,7 @@ class TypeInferrerImpl implements TypeInferrer {
return instantiateTearOff(inferredType, typeContext, expression);
}
flowAnalysis.thisOrSuperPropertyGet(
expression, expression.name.name, member, inferredType);
expression, expression.name.name, inferredType);
return new ExpressionInferenceResult(inferredType, expression);
}
@@ -4634,17 +4644,6 @@ class WrapInProblemInferenceResult implements InvocationInferenceResult {
}
}
/// The result of inference of a property get expression.
class PropertyGetInferenceResult {
/// The main inference result.
final ExpressionInferenceResult expressionInferenceResult;
/// The property that was looked up, or `null` if no property was found.
final Member member;
PropertyGetInferenceResult(this.expressionInferenceResult, this.member);
}
/// The result of an expression inference.
class ExpressionInferenceResult {
/// The inferred type of the expression.
@@ -5135,11 +5134,13 @@ class _WhyNotPromotedVisitor
DartType> {
final TypeInferrerImpl inferrer;
final Expression receiver;
Member propertyReference;
DartType propertyType;
_WhyNotPromotedVisitor(this.inferrer);
_WhyNotPromotedVisitor(this.inferrer, this.receiver);
@override
LocatedMessage visitDemoteViaExplicitWrite(
@@ -5157,16 +5158,26 @@ class _WhyNotPromotedVisitor
@override
LocatedMessage visitPropertyNotPromoted(PropertyNotPromoted reason) {
Object member = reason.propertyMember;
if (member is Member) {
Member member;
Expression receiver = this.receiver;
if (receiver is InstanceGet) {
member = receiver.interfaceTarget;
} else if (receiver is SuperPropertyGet) {
member = receiver.interfaceTarget;
} else if (receiver is StaticInvocation) {
member = receiver.target;
} else if (receiver is PropertyGet) {
member = receiver.interfaceTarget;
} else {
assert(false, 'Unrecognized receiver: ${receiver.runtimeType}');
}
if (member != null) {
propertyReference = member;
propertyType = reason.staticType;
return templateFieldNotPromoted
.withArguments(reason.propertyName, reason.documentationLink)
.withLocation(member.fileUri, member.fileOffset, noLength);
} else {
assert(member == null,
'Unrecognized property member: ${member.runtimeType}');
return null;
}
}