public void VisitNode(JSInvocationExpression invocation) { FunctionAnalysis2ndPass sa = null; if (invocation.JSMethod != null) sa = FunctionSource.GetSecondPass(invocation.JSMethod); var parms = invocation.Parameters.ToArray(); for (int i = 0, c = parms.Length; i < c; i++) { var pd = parms[i].Key; var argument = parms[i].Value; string parameterName = null; if (pd != null) parameterName = pd.Name; GenericParameter relevantParameter; if (IsParameterCopyNeeded(sa, parameterName, argument, out relevantParameter)) { if (Tracing) Debug.WriteLine(String.Format("struct copy introduced for argument #{0}: {1}", i, argument)); invocation.Arguments[i] = MakeCopyForExpression(argument, relevantParameter); } else { if (Tracing && TypeUtil.IsStruct(argument.GetActualType(TypeSystem))) Debug.WriteLine(String.Format("struct copy elided for argument #{0}: {1}", i, argument)); } } var thisReference = invocation.ThisReference; if ( (thisReference != null) && (sa != null) && sa.ViolatesThisReferenceImmutability && !(ParentNode is JSCommaExpression) ) { // The method we're calling violates immutability so we need to clone the this-reference // before we call it. var thisReferenceType = thisReference.GetActualType(TypeSystem); if (TypeUtil.IsStruct(thisReferenceType)) { if (!(thisReference is JSVariable) && !(thisReference is JSFieldAccess)) throw new NotImplementedException("Unsupported invocation of method that reassigns this within an immutable struct: " + invocation.ToString()); var cloneExpr = new JSBinaryOperatorExpression( JSOperator.Assignment, thisReference, new JSStructCopyExpression(thisReference), thisReferenceType ); var commaExpression = new JSCommaExpression(cloneExpr, invocation); ParentNode.ReplaceChild(invocation, commaExpression); VisitReplacement(commaExpression); return; } } VisitChildren(invocation); }
public void VisitNode (JSInvocationExpression invocation) { FunctionAnalysis2ndPass sa = null; if (invocation.JSMethod != null) sa = GetSecondPass(invocation.JSMethod); CloneArgumentsIfNecessary(invocation.Parameters, invocation.Arguments, sa); var thisReference = invocation.ThisReference; if ( (thisReference != null) && (sa != null) && sa.ViolatesThisReferenceImmutability && !(ParentNode is JSCommaExpression) ) { // The method we're calling violates immutability so we need to clone the this-reference // before we call it. var thisReferenceType = thisReference.GetActualType(TypeSystem); if (TypeUtil.IsStruct(thisReferenceType)) { if (!(thisReference is JSVariable) && !(thisReference is JSFieldAccess)) throw new NotImplementedException("Unsupported invocation of method that reassigns this within an immutable struct: " + invocation.ToString()); var cloneExpr = new JSBinaryOperatorExpression( JSOperator.Assignment, thisReference, new JSStructCopyExpression(thisReference), thisReferenceType ); var commaExpression = new JSCommaExpression(cloneExpr, invocation); ParentNode.ReplaceChild(invocation, commaExpression); VisitReplacement(commaExpression); return; } } VisitChildren(invocation); }
public void VisitNode(JSInvocationExpression invocation) { FunctionAnalysis2ndPass sa = null; if (invocation.JSMethod != null) { sa = GetSecondPass(invocation.JSMethod); } CloneArgumentsIfNecessary(invocation.Parameters, invocation.Arguments, sa); var thisReference = invocation.ThisReference; if ( (thisReference != null) && (sa != null) && sa.ViolatesThisReferenceImmutability && !(ParentNode is JSCommaExpression) ) { // The method we're calling violates immutability so we need to clone the this-reference // before we call it. var thisReferenceType = thisReference.GetActualType(TypeSystem); if (TypeUtil.IsStruct(thisReferenceType)) { if (!(thisReference is JSVariable) && !(thisReference is JSFieldAccess)) { throw new NotImplementedException("Unsupported invocation of method that reassigns this within an immutable struct: " + invocation.ToString()); } var cloneExpr = new JSBinaryOperatorExpression( JSOperator.Assignment, thisReference, new JSStructCopyExpression(thisReference), thisReferenceType ); var commaExpression = new JSCommaExpression(cloneExpr, invocation); ParentNode.ReplaceChild(invocation, commaExpression); VisitReplacement(commaExpression); return; } } VisitChildren(invocation); }