// generateLocalAssignment generates the expression source for a local assignment. func (eg *expressionGenerator) generateLocalAssignment(localAssign *codedom.LocalAssignmentNode, context generationContext) esbuilder.ExpressionBuilder { value := eg.generateExpression(localAssign.Value, context) assignment := esbuilder.Assignment(esbuilder.Identifier(localAssign.Target), value) // If this assignment is under an async expression wrapper, then we add it to the wrapper itself, // rather than doing the assignment inline. This ensures that the variable's value is updated when // expected in the async flow, rather than once all the promises have returned. if wrapper, hasWrapper := eg.currentAsyncWrapper(); hasWrapper { wrapper.addIntermediateExpression(assignment) return esbuilder.Identifier(localAssign.Target) } return assignment }
// generateMemberAssignment generates the expression source for a member assignment. func (eg *expressionGenerator) generateMemberAssignment(memberAssign *codedom.MemberAssignmentNode, context generationContext) esbuilder.ExpressionBuilder { basisNode := memberAssign.BasisNode() // If the target member is an operator, then we need to invoke it as a function call, with the first // argument being the argument to the child call, and the second argument being the assigned child // expression. if memberAssign.Target.IsOperator() { childCall := memberAssign.NameExpression.(*codedom.MemberCallNode) memberRef := childCall.ChildExpression.(*codedom.MemberReferenceNode) // If this is a native operator, change it into a native indexing and assignment. if memberAssign.Target.IsNative() { nativeAssign := codedom.NativeAssign( codedom.NativeIndexing(memberRef.ChildExpression, childCall.Arguments[0], basisNode), memberAssign.Value, basisNode) return eg.generateExpression(nativeAssign, context) } else { memberCall := codedom.MemberCall( codedom.NativeAccess(memberRef.ChildExpression, eg.pather.GetMemberName(memberAssign.Target), memberRef.BasisNode()), memberAssign.Target, []codedom.Expression{childCall.Arguments[0], memberAssign.Value}, basisNode) return eg.generateExpression(memberCall, context) } } // If the target member is implicitly called, then this is a property that needs to be assigned via a call. if memberAssign.Target.IsImplicitlyCalled() { memberRef := memberAssign.NameExpression.(*codedom.MemberReferenceNode) memberCall := codedom.MemberCall( codedom.NativeAccess(memberRef.ChildExpression, eg.pather.GetSetterName(memberRef.Member), memberRef.BasisNode()), memberAssign.Target, []codedom.Expression{memberAssign.Value}, basisNode) return eg.generateExpression(memberCall, context) } value := eg.generateExpression(memberAssign.Value, context) targetExpr := eg.generateExpression(memberAssign.NameExpression, context) return esbuilder.Assignment(targetExpr, value) }
// generateNativeAccess generates the expression source for a native assign. func (eg *expressionGenerator) generateNativeAssign(nativeAssign *codedom.NativeAssignNode, context generationContext) esbuilder.ExpressionBuilder { target := eg.generateExpression(nativeAssign.TargetExpression, context) value := eg.generateExpression(nativeAssign.ValueExpression, context) return esbuilder.Assignment(target, value) }