Example #1
0
 private static void WriteClone(IAbstractEmitterBlock block, int insertPosition, bool nullable)
 {
     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 + "()");
     }
 }
Example #2
0
        public static void CheckValueTypeClone(ResolveResult resolveResult, Expression expression, IAbstractEmitterBlock block, int insertPosition)
        {
            if (resolveResult == null || resolveResult.IsError)
            {
                return;
            }

            if (block.Emitter.IsAssignment)
            {
                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 nullable = resolveResult.Type.IsKnownType(KnownTypeCode.NullableOfT);
            var type = nullable ? ((ParameterizedType)resolveResult.Type).TypeArguments[0] : resolveResult.Type;
            if (type.Kind == TypeKind.Struct)
            {
                var typeDef = block.Emitter.GetTypeDefinition(type);
                if (block.Emitter.Validator.IsIgnoreType(typeDef) || block.Emitter.Validator.IsImmutableType(typeDef))
                {
                    return;
                }

                var mutableFields = type.GetFields(f => !f.IsReadOnly && !f.IsConst, GetMemberOptions.IgnoreInheritedMembers);
                var autoProps = typeDef.Properties.Where(Helpers.IsAutoProperty);
                var autoEvents = type.GetEvents(null, GetMemberOptions.IgnoreInheritedMembers);

                if (!mutableFields.Any() && !autoProps.Any() && !autoEvents.Any())
                {
                    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, "Bridge.Nullable.lift1(\"$clone\", ");
                        block.WriteCloseParentheses();
                    }
                    else
                    {
                        block.Write(".$clone()");
                    }

                    return;
                }

                if (expression == null ||
                    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)
                {
                    if (expression.Parent is InvocationExpression)
                    {
                        var invocationExpression = (InvocationExpression)expression.Parent;
                        if (invocationExpression.Target == expression)
                        {
                            return;
                        }
                    }

                    if (nullable)
                    {
                        block.Emitter.Output.Insert(insertPosition, "Bridge.Nullable.lift1(\"$clone\", ");
                        block.WriteCloseParentheses();
                    }
                    else
                    {
                        block.Write(".$clone()");
                    }
                }
            }
        }
Example #3
0
        public static void CheckValueTypeClone(ResolveResult resolveResult, Expression expression, IAbstractEmitterBlock block, int insertPosition)
        {
            if (resolveResult == null || resolveResult.IsError)
            {
                return;
            }

            if (block.Emitter.IsAssignment)
            {
                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;
                }

                if (ret)
                {
                    return;
                }
            }

            var nullable = resolveResult.Type.IsKnownType(KnownTypeCode.NullableOfT);
            var type = nullable ? ((ParameterizedType)resolveResult.Type).TypeArguments[0] : resolveResult.Type;
            if (type.Kind == TypeKind.Struct)
            {
                var typeDef = block.Emitter.GetTypeDefinition(type);
                if (block.Emitter.Validator.IsIgnoreType(typeDef))
                {
                    return;
                }

                var mutableFields = type.GetFields(f => !f.IsReadOnly && !f.IsConst, GetMemberOptions.IgnoreInheritedMembers);
                var autoProps = typeDef.Properties.Where(Helpers.IsAutoProperty);
                var autoEvents = type.GetEvents(null, GetMemberOptions.IgnoreInheritedMembers);

                if (!mutableFields.Any() && !autoProps.Any() && !autoEvents.Any())
                {
                    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, "Bridge.Nullable.lift1(\"$clone\", ");
                        block.WriteCloseParentheses();
                    }
                    else
                    {
                        block.Write(":__clone__()");    
                    }
                    
                    return;
                }

                if (expression == null ||
                    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)
                {
                    if (expression.Parent is InvocationExpression)
                    {
                        var invocationExpression = (InvocationExpression)expression.Parent;
                        if (invocationExpression.Target == expression)
                        {
                            return;
                        }
                    }

                    if (nullable)
                    {
                        block.Emitter.Output.Insert(insertPosition, "Bridge.Nullable.lift1(\"$clone\", ");
                        block.WriteCloseParentheses();
                    }
                    else
                    {
                        block.Write(":__clone__()");
                    }
                }
            }
        }
Example #4
0
        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 + "()");
                    }
                }
            }
        }