@@ -3154,6 +3154,66 @@ class InferenceVisitor
31543154 return new ExpressionInferenceResult (readType, read);
31553155 }
31563156
3157+ /// Creates a property set operation of [writeTarget] on [receiver] using
3158+ /// [value] as the right-hand side.
3159+ ///
3160+ /// [fileOffset] is used as the file offset for created nodes. [propertyName]
3161+ /// is used for error reporting. [receiverType] is the already inferred type
3162+ /// of the [receiver] expression. The inferred type of [value] must already
3163+ /// have been computed.
3164+ ///
3165+ /// If [forEffect] the resulting expression is ensured to return the [value]
3166+ /// of static type [valueType] . This is needed for extension setters which are
3167+ /// encoded as static method calls that do not implicitly return the value.
3168+ Expression _computePropertySet (
3169+ int fileOffset,
3170+ Expression receiver,
3171+ DartType receiverType,
3172+ Name propertyName,
3173+ ObjectAccessTarget writeTarget,
3174+ Expression value,
3175+ {DartType valueType,
3176+ bool forEffect}) {
3177+ assert (forEffect != null );
3178+ assert (forEffect || valueType != null ,
3179+ "No value type provided for property set needed for value." );
3180+ Expression write;
3181+ if (writeTarget.isMissing) {
3182+ write = inferrer.helper.buildProblem (
3183+ templateUndefinedSetter.withArguments (
3184+ propertyName.name, inferrer.resolveTypeParameter (receiverType)),
3185+ fileOffset,
3186+ propertyName.name.length);
3187+ } else if (writeTarget.isExtensionMember) {
3188+ if (forEffect) {
3189+ write = new StaticInvocation (
3190+ writeTarget.member,
3191+ new Arguments (< Expression > [receiver, value],
3192+ types: writeTarget.inferredExtensionTypeArguments)
3193+ ..fileOffset = fileOffset)
3194+ ..fileOffset = fileOffset;
3195+ } else {
3196+ VariableDeclaration valueVariable = createVariable (value, valueType);
3197+ VariableDeclaration assignmentVariable = createVariable (
3198+ new StaticInvocation (
3199+ writeTarget.member,
3200+ new Arguments (
3201+ < Expression > [receiver, createVariableGet (valueVariable)],
3202+ types: writeTarget.inferredExtensionTypeArguments)
3203+ ..fileOffset = fileOffset)
3204+ ..fileOffset = fileOffset,
3205+ const VoidType ());
3206+ write = createLet (valueVariable,
3207+ createLet (assignmentVariable, createVariableGet (valueVariable)))
3208+ ..fileOffset = fileOffset;
3209+ }
3210+ } else {
3211+ write = new PropertySet (receiver, propertyName, value, writeTarget.member)
3212+ ..fileOffset = fileOffset;
3213+ }
3214+ return write;
3215+ }
3216+
31573217 ExpressionInferenceResult visitCompoundIndexSet (
31583218 CompoundIndexSet node, DartType typeContext) {
31593219 ExpressionInferenceResult receiverResult = inferrer.inferExpression (
@@ -3358,26 +3418,9 @@ class InferenceVisitor
33583418 valueExpression = createVariableGet (valueVariable);
33593419 }
33603420
3361- Expression write;
3362-
3363- if (writeTarget.isMissing) {
3364- write = inferrer.helper.buildProblem (
3365- templateUndefinedMethod.withArguments (
3366- node.propertyName.name, receiverType),
3367- node.writeOffset,
3368- node.propertyName.name.length);
3369- } else if (writeTarget.isExtensionMember) {
3370- write = new StaticInvocation (
3371- writeTarget.member,
3372- new Arguments (< Expression > [writeReceiver, valueExpression],
3373- types: writeTarget.inferredExtensionTypeArguments)
3374- ..fileOffset = node.writeOffset)
3375- ..fileOffset = node.writeOffset;
3376- } else {
3377- write = new PropertySet (
3378- writeReceiver, node.propertyName, valueExpression, writeTarget.member)
3379- ..fileOffset = node.writeOffset;
3380- }
3421+ Expression write = _computePropertySet (node.writeOffset, writeReceiver,
3422+ receiverType, node.propertyName, writeTarget, valueExpression,
3423+ forEffect: true );
33813424
33823425 DartType resultType = node.forPostIncDec ? readType : binaryType;
33833426
@@ -3783,8 +3826,6 @@ class InferenceVisitor
37833826 ObjectAccessTarget target = inferrer.findInterfaceMember (
37843827 receiverType, node.name, node.fileOffset,
37853828 setter: true , instrumented: true , includeExtensionMethods: true );
3786- Expression error = inferrer.reportMissingInterfaceMember (target,
3787- receiverType, node.name, node.fileOffset, templateUndefinedSetter);
37883829 if (target.isInstanceMember) {
37893830 if (inferrer.instrumentation != null &&
37903831 receiverType == const DynamicType ()) {
@@ -3803,48 +3844,11 @@ class InferenceVisitor
38033844 DartType rhsType = rhsResult.inferredType;
38043845 Expression rhs = inferrer.ensureAssignableResult (writeContext, rhsResult,
38053846 fileOffset: node.fileOffset, isVoidAllowed: writeContext is VoidType );
3806- if (error != null ) {
3807- return new ExpressionInferenceResult (const DynamicType (), error);
3808- }
3809- Expression replacement;
3810- if (target.isExtensionMember) {
3811- if (node.forEffect) {
3812- replacement = new StaticInvocation (
3813- target.member,
3814- new Arguments (< Expression > [receiver, rhs],
3815- types: target.inferredExtensionTypeArguments)
3816- ..fileOffset = node.fileOffset)
3817- ..fileOffset = node.fileOffset;
3818- } else {
3819- VariableDeclaration receiverVariable;
3820- if (node.readOnlyReceiver) {
3821- // No need for a receiver variable.
3822- } else {
3823- receiverVariable = createVariable (receiver, receiverType);
3824- receiver = createVariableGet (receiverVariable);
3825- }
3826- VariableDeclaration valueVariable = createVariable (rhs, rhsType);
3827- VariableDeclaration assignmentVariable = createVariable (
3828- new StaticInvocation (
3829- target.member,
3830- new Arguments (
3831- < Expression > [receiver, createVariableGet (valueVariable)],
3832- types: target.inferredExtensionTypeArguments)
3833- ..fileOffset = node.fileOffset)
3834- ..fileOffset = node.fileOffset,
3835- const VoidType ());
3836- replacement = createLet (valueVariable,
3837- createLet (assignmentVariable, createVariableGet (valueVariable)));
3838- if (receiverVariable != null ) {
3839- replacement = createLet (receiverVariable, replacement);
3840- }
3841- replacement..fileOffset = node.fileOffset;
3842- }
3843- } else {
3844- node.receiver = receiver..parent = node;
3845- node.value = rhs..parent = node;
3846- replacement = node;
3847- }
3847+
3848+ Expression replacement = _computePropertySet (
3849+ node.fileOffset, receiver, receiverType, node.name, target, rhs,
3850+ valueType: rhsType, forEffect: node.forEffect);
3851+
38483852 return new ExpressionInferenceResult .nullAware (
38493853 rhsType, replacement, nullAwareGuard);
38503854 }
@@ -3890,43 +3894,9 @@ class InferenceVisitor
38903894 .inferExpression (node.value, valueType, true , isVoidAllowed: true );
38913895 Expression value = inferrer.ensureAssignableResult (valueType, valueResult);
38923896
3893- Expression write;
3894-
3895- if (writeTarget.isMissing) {
3896- write = inferrer.helper.buildProblem (
3897- templateUndefinedMethod.withArguments (node.name.name, receiverType),
3898- node.writeOffset,
3899- node.name.name.length);
3900- } else if (writeTarget.isExtensionMember) {
3901- if (node.forEffect) {
3902- write = new StaticInvocation (
3903- writeTarget.member,
3904- new Arguments (< Expression > [writeReceiver, value],
3905- types: writeTarget.inferredExtensionTypeArguments)
3906- ..fileOffset = node.writeOffset)
3907- ..fileOffset = node.writeOffset;
3908- } else {
3909- VariableDeclaration valueVariable =
3910- createVariable (value, valueResult.inferredType);
3911- VariableDeclaration assignmentVariable = createVariable (
3912- new StaticInvocation (
3913- writeTarget.member,
3914- new Arguments (< Expression > [
3915- writeReceiver,
3916- createVariableGet (valueVariable)
3917- ], types: writeTarget.inferredExtensionTypeArguments)
3918- ..fileOffset = node.writeOffset)
3919- ..fileOffset = node.writeOffset,
3920- const VoidType ());
3921- write = createLet (valueVariable,
3922- createLet (assignmentVariable, createVariableGet (valueVariable)))
3923- ..fileOffset = node.writeOffset;
3924- }
3925- } else {
3926- write =
3927- new PropertySet (writeReceiver, node.name, value, writeTarget.member)
3928- ..fileOffset = node.writeOffset;
3929- }
3897+ Expression write = _computePropertySet (node.writeOffset, writeReceiver,
3898+ receiverType, node.name, writeTarget, value,
3899+ valueType: valueResult.inferredType, forEffect: node.forEffect);
39303900
39313901 DartType inferredType = inferrer.typeSchemaEnvironment
39323902 .getStandardUpperBound (readType, valueResult.inferredType);
0 commit comments