public static void CheckValueTypeClone(ResolveResult resolveResult, Expression expression, IAbstractEmitterBlock block, int insertPosition) { if (resolveResult == null || resolveResult.IsError) { return; } if (block.Emitter.IsAssignment) { return; } var conversion = block.Emitter.Resolver.Resolver.GetConversion(expression); if (conversion.IsBoxingConversion || conversion.IsUnboxingConversion) { return; } if (resolveResult is InvocationResolveResult) { bool ret = true; if (expression.Parent is InvocationExpression) { var invocationExpression = (InvocationExpression)expression.Parent; if (invocationExpression.Arguments.Any(a => a == expression)) { ret = false; } } else if (expression.Parent is AssignmentExpression) { ret = false; } else if (expression.Parent is VariableInitializer) { ret = false; } if (ret) { return; } } var rrtype = resolveResult.Type; var forEachResolveResult = resolveResult as ForEachResolveResult; if (forEachResolveResult != null) { rrtype = forEachResolveResult.ElementType; } var nullable = rrtype.IsKnownType(KnownTypeCode.NullableOfT); var type = nullable ? ((ParameterizedType)rrtype).TypeArguments[0] : rrtype; if (type.Kind == TypeKind.Struct) { if (Helpers.IsImmutableStruct(block.Emitter, type)) { return; } var memberResult = resolveResult as MemberResolveResult; var field = memberResult != null ? memberResult.Member as DefaultResolvedField : null; if (field != null && field.IsReadOnly) { if (nullable) { block.Emitter.Output.Insert(insertPosition, JS.Types.SYSTEM_NULLABLE + "." + JS.Funcs.Math.LIFT1 + "(\"" + JS.Funcs.CLONE + "\", "); block.WriteCloseParentheses(); } else { block.Write("." + JS.Funcs.CLONE + "()"); } return; } var isOperator = false; if (expression != null && (expression.Parent is BinaryOperatorExpression || expression.Parent is UnaryOperatorExpression)) { var orr = block.Emitter.Resolver.ResolveNode(expression.Parent, block.Emitter) as OperatorResolveResult; isOperator = orr != null && orr.UserDefinedOperatorMethod != null; } if (expression == null || isOperator || expression.Parent is NamedExpression || expression.Parent is ObjectCreateExpression || expression.Parent is ArrayInitializerExpression || expression.Parent is ReturnStatement || expression.Parent is InvocationExpression || expression.Parent is AssignmentExpression || expression.Parent is VariableInitializer || expression.Parent is ForeachStatement && resolveResult is ForEachResolveResult) { if (expression != null && expression.Parent is InvocationExpression) { var invocationExpression = (InvocationExpression)expression.Parent; if (invocationExpression.Target == expression) { return; } } if (nullable) { block.Emitter.Output.Insert(insertPosition, JS.Types.SYSTEM_NULLABLE + "." + JS.Funcs.Math.LIFT1 + "(\"" + JS.Funcs.CLONE + "\", "); block.WriteCloseParentheses(); } else { block.Write("." + JS.Funcs.CLONE + "()"); } } } }