private Expression WidenType <T>(Expression source)
        {
            var tref = ShaderDefinition.ToCecil(typeof(T));
            var n    = new ObjectCreateExpression(AstBuilder.ConvertType(tref), new[] { source.Clone() });

            return(n);
        }
Example #2
0
        private void WritePart(Expression expression, bool toString, ResolveResult rr)
        {
            if (toString)
            {
                var toStringMethod = rr.Type.GetMembers().FirstOrDefault(m =>
                {
                    if (m.Name == "ToString" && !m.IsStatic && m.ReturnType.IsKnownType(KnownTypeCode.String) && m.IsOverride)
                    {
                        var method = m as IMethod;

                        if (method != null && method.Parameters.Count == 0 && method.TypeParameters.Count == 0)
                        {
                            return(true);
                        }
                    }

                    return(false);
                });

                if (toStringMethod != null)
                {
                    var inline = this.Emitter.GetInline(toStringMethod);

                    if (inline != null)
                    {
                        var writer = new Writer
                        {
                            InlineCode = inline,
                            Output     = this.Emitter.Output,
                            IsNewLine  = this.Emitter.IsNewLine
                        };
                        this.Emitter.IsNewLine = false;
                        this.Emitter.Output    = new StringBuilder();

                        expression.AcceptVisitor(this.Emitter);

                        string result = this.Emitter.Output.ToString();
                        this.Emitter.Output    = writer.Output;
                        this.Emitter.IsNewLine = writer.IsNewLine;

                        var argsInfo = new ArgumentsInfo(this.Emitter, expression, rr);
                        argsInfo.ArgumentsExpressions = new Expression[] { expression };
                        argsInfo.ArgumentsNames       = new string[] { "this" };
                        argsInfo.ThisArgument         = result;
                        new InlineArgumentsBlock(this.Emitter, argsInfo, writer.InlineCode).Emit();

                        //result = writer.InlineCode.Replace("{this}", result);
                        //this.Write(result);

                        return;
                    }
                }

                expression.AcceptVisitor(this.Emitter);
            }
            else
            {
                expression.AcceptVisitor(this.Emitter);
            }
        }
        protected internal Init(NRefactory.VariableInitializer variableInitializer, IScope scope, INRefcatoryExpressionVisitor visitor)
            : base(scope, visitor)
        {
            NRefactory.Expression initializer = null;

            _variableInitializer = variableInitializer;
            initializer          = variableInitializer.Initializer;
        }
        private object EvaluateBinaryOperatorExpression(ICSharpCode.NRefactory.CSharp.Expression result, CodeContext codeContext)
        {
            ICSharpCode.NRefactory.CSharp.BinaryOperatorExpression binaryExpression = result as
                                                                                      ICSharpCode.NRefactory.CSharp.BinaryOperatorExpression;

            object left  = EvaluateExpression(binaryExpression.Left, codeContext);
            object right = EvaluateExpression(binaryExpression.Right, codeContext);

            switch (binaryExpression.Operator)
            {
            case BinaryOperatorType.Add:
                return(PrimitiveOperationManager.Self.AddObjects(left, right));

            case BinaryOperatorType.ConditionalAnd:
                return((bool)left && (bool)right);

            case BinaryOperatorType.ConditionalOr:
                return((bool)left || (bool)right);

            case BinaryOperatorType.Divide:
                return(PrimitiveOperationManager.Self.DivideObjects(left, right));

            case BinaryOperatorType.Equality:
                return(left == right);

            case BinaryOperatorType.GreaterThan:
                return(PrimitiveOperationManager.Self.GreaterThan(left, right));

            case BinaryOperatorType.GreaterThanOrEqual:
                return(left == right ||
                       PrimitiveOperationManager.Self.GreaterThan(left, right));

            case BinaryOperatorType.InEquality:
                return(left != right);

            case BinaryOperatorType.LessThan:
                return(PrimitiveOperationManager.Self.LessThan(left, right));

            case BinaryOperatorType.LessThanOrEqual:
                return(left == right ||
                       PrimitiveOperationManager.Self.LessThan(left, right));

            case BinaryOperatorType.Multiply:
                return(PrimitiveOperationManager.Self.MultiplyObjects(left, right));

            case BinaryOperatorType.Subtract:
                return(PrimitiveOperationManager.Self.SubtractObjects(left, right));

            default:
                return(null);
            }
        }
Example #5
0
            void DecompileQueries(AstNode node)
            {
                Expression query = DecompileQuery(node as InvocationExpression);

                if (query != null)
                {
                    node.ReplaceWith(query);
                }
                for (AstNode child = (query ?? node).FirstChild; child != null; child = child.NextSibling)
                {
                    DecompileQueries(child);
                }
            }
        private object GetCaller(ICSharpCode.NRefactory.CSharp.Expression expression, CodeContext codeContext)
        {
            object caller;

            if (expression is MemberReferenceExpression)
            {
                MemberReferenceExpression mre = expression as MemberReferenceExpression;


                caller = EvaluateExpression(mre.Target, codeContext);

                if (caller == null)
                {
                    Type type = TypeManager.GetTypeFromString(mre.Target.GetText());
                    if (type != null)
                    {
                        TypeReference typeReference = new TypeReference();
                        typeReference.Type = type;

                        caller = typeReference;
                    }
                }


                if (caller == null)
                {
                    caller = codeContext.ContainerInstance;
                }


                return(caller);
            }
            else if (expression is InvocationExpression)
            {
                return(codeContext.ContainerInstance);
            }
            else if (expression is IdentifierExpression)
            {
                return(codeContext.ContainerInstance);
            }
            else
            {
                return(null);
            }
        }
Example #7
0
            /// <summary>Matches simple lambdas of the form "a => b"</summary>
            bool MatchSimpleLambda(Expression expr, out string parameterName, out Expression body)
            {
                expr = StripCastAndParenthasis(expr);
                LambdaExpression lambda = expr as LambdaExpression;

                if (lambda != null && lambda.Parameters.Count == 1 && lambda.Body is Expression)
                {
                    ParameterDeclaration p = lambda.Parameters.Single();
                    if (p.ParameterModifier == ParameterModifier.None)
                    {
                        parameterName = p.Name;
                        body          = (Expression)lambda.Body;
                        return(true);
                    }
                }
                parameterName = null;
                body          = null;
                return(false);
            }
Example #8
0
            private static Expression StripCastAndParenthasis(Expression expr)
            {
                var ce = expr as CastExpression;
                var pe = expr as ParenthesizedExpression;

                while (ce != null || pe != null)
                {
                    if (ce != null)
                    {
                        expr = ce.Expression;
                        ce   = expr as CastExpression;
                        pe   = expr as ParenthesizedExpression;
                    }
                    if (pe != null)
                    {
                        expr = pe.Expression;
                        pe   = expr as ParenthesizedExpression;
                        ce   = expr as CastExpression;
                    }
                }
                return(expr);
            }
        protected internal New(NRefactory.ObjectCreateExpression objectCreation, IScope scope, INRefcatoryExpressionVisitor visitor)
            : base(scope, visitor)
        {
            _objectCreation = objectCreation;

            if (!objectCreation.Type.IsNull)
            {
                InternalType = objectCreation.Type.AcceptVisitor(Visitor, ParentScope).Type;

                if (objectCreation.Initializer != null)
                {
                    if (objectCreation.Arguments.Count == 2)
                    {
                        Expression            expression;
                        NRefactory.Expression @this = objectCreation.Arguments.First();
                        NRefactory.Expression func  = objectCreation.Arguments.Last();

                        if (TryHandleAnonymousMethod(@this, func as NRefactory.InvocationExpression, out expression))
                        {
                            Expression = expression;
                            return;
                        }
                    }

                    if (objectCreation.Initializer != NRefactory.ArrayInitializerExpression.Null)
                    {
                        Expression = objectCreation.Initializer.AcceptVisitor(Visitor, ParentScope);
                        return;
                    }
                }

                Expression = BuildConstructor();
            }
            else
            {
                Expression = HandleAnonymousType();
            }
        }
        private bool TryHandleAnonymousMethod(NRefactory.Expression @this, NRefactory.InvocationExpression func, out Expression outExpression)
        {
            MethodReference methodReference = null;

            NRefactory.IdentifierExpression methodIdentifier = null;

            outExpression = null;

            if (func != null)
            {
                methodIdentifier = func.Arguments.Single() as NRefactory.IdentifierExpression;
                methodReference  = methodIdentifier.Annotation <MethodReference>();

                if (methodReference != null)
                {
                    object   target     = null;
                    Delegate @delegate  = null;
                    var      methodInfo = methodReference.GetActualMethod() as MethodInfo;

                    if (!methodInfo.IsStatic)
                    {
                        var context = RootScope.Context;

                        if (context != null)
                        {
                            target = context.Value;
                        }
                    }

                    @delegate     = methodInfo.CreateDelegate(InternalType, target);
                    outExpression = Expression.Constant(@delegate);
                    return(true);
                }
            }

            return(false);
        }
Example #11
0
            bool TryRemoveTransparentIdentifier(QueryExpression query, QueryFromClause fromClause, QueryExpression innerQuery)
            {
                if (!IsTransparentIdentifier(fromClause.Identifier))
                {
                    return(false);
                }
                Match match = selectTransparentIdentifierPattern.Match(innerQuery.Clauses.Last());

                if (!match.Success)
                {
                    return(false);
                }
                QuerySelectClause selectClause = (QuerySelectClause)innerQuery.Clauses.Last();
                NamedExpression   nae1         = match.Get <NamedExpression>("nae1").SingleOrDefault();
                NamedExpression   nae2         = match.Get <NamedExpression>("nae2").SingleOrDefault();

                if (nae1 != null && nae1.Name != ((IdentifierExpression)nae1.Expression).Identifier)
                {
                    return(false);
                }
                Expression           nae2Expr      = match.Get <Expression>("nae2Expr").Single();
                IdentifierExpression nae2IdentExpr = nae2Expr as IdentifierExpression;

                if (nae2IdentExpr != null && (nae2 == null || nae2.Name == nae2IdentExpr.Identifier))
                {
                    // from * in (from x in ... select new { x = x, y = y }) ...
                    // =>
                    // from x in ... ...
                    fromClause.Remove();
                    selectClause.Remove();
                    // Move clauses from innerQuery to query
                    QueryClause insertionPos = null;
                    foreach (var clause in innerQuery.Clauses)
                    {
                        query.Clauses.InsertAfter(insertionPos, insertionPos = Detach(clause));
                    }
                }
                else
                {
                    // from * in (from x in ... select new { x = x, y = expr }) ...
                    // =>
                    // from x in ... let y = expr ...
                    fromClause.Remove();
                    selectClause.Remove();
                    // Move clauses from innerQuery to query
                    QueryClause insertionPos = null;
                    foreach (var clause in innerQuery.Clauses)
                    {
                        query.Clauses.InsertAfter(insertionPos, insertionPos = Detach(clause));
                    }
                    string ident;
                    if (nae2 != null)
                    {
                        ident = nae2.Name;
                    }
                    else if (nae2Expr is MemberReferenceExpression)
                    {
                        ident = ((MemberReferenceExpression)nae2Expr).MemberName;
                    }
                    else
                    {
                        throw new InvalidOperationException("Could not infer name from initializer in AnonymousTypeCreateExpression");
                    }
                    query.Clauses.InsertAfter(insertionPos, new QueryLetClause {
                        Identifier = ident, Expression = Detach(nae2Expr)
                    });
                }
                return(true);
            }
Example #12
0
            QueryExpression DecompileQuery(InvocationExpression invocation)
            {
                if (invocation == null)
                {
                    return(null);
                }
                if (invocation.Parent is ParenthesizedExpression == false &&
                    invocation.Parent is QueryClause == false)
                {
                    return(null);
                }
                MemberReferenceExpression mre = invocation.Target as MemberReferenceExpression;

                if (mre == null)
                {
                    return(null);
                }
                switch (mre.MemberName)
                {
                case "Select":
                {
                    if (invocation.Arguments.Count != 1)
                    {
                        return(null);
                    }
                    string     parameterName;
                    Expression body;
                    if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out body))
                    {
                        QueryExpression query = new QueryExpression();
                        query.Clauses.Add(new QueryFromClause {
                                Identifier = parameterName, Expression = Detach(mre.Target)
                            });
                        query.Clauses.Add(new QuerySelectClause {
                                Expression = Detach(body)
                            });
                        return(query);
                    }
                    return(null);
                }

                case "GroupBy":
                {
                    if (invocation.Arguments.Count == 2)
                    {
                        string     parameterName1, parameterName2;
                        Expression keySelector, elementSelector;
                        if (MatchSimpleLambda(invocation.Arguments.ElementAt(0), out parameterName1, out keySelector) &&
                            MatchSimpleLambda(invocation.Arguments.ElementAt(1), out parameterName2, out elementSelector) &&
                            parameterName1 == parameterName2)
                        {
                            QueryExpression query = new QueryExpression();
                            query.Clauses.Add(new QueryFromClause {
                                    Identifier = parameterName1, Expression = Detach(mre.Target)
                                });
                            query.Clauses.Add(new QueryGroupClause {
                                    Projection = Detach(elementSelector), Key = Detach(keySelector)
                                });
                            return(query);
                        }
                    }
                    else if (invocation.Arguments.Count == 1)
                    {
                        string     parameterName;
                        Expression keySelector;
                        if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out keySelector))
                        {
                            QueryExpression query = new QueryExpression();
                            query.Clauses.Add(new QueryFromClause {
                                    Identifier = parameterName, Expression = Detach(mre.Target)
                                });
                            query.Clauses.Add(new QueryGroupClause {
                                    Projection = new IdentifierExpression(parameterName), Key = Detach(keySelector)
                                });
                            return(query);
                        }
                    }
                    return(null);
                }

                case "SelectMany":
                {
                    if (invocation.Arguments.Count != 2)
                    {
                        return(null);
                    }
                    string     parameterName;
                    Expression collectionSelector;
                    if (!MatchSimpleLambda(invocation.Arguments.ElementAt(0), out parameterName, out collectionSelector))
                    {
                        return(null);
                    }
                    LambdaExpression lambda = invocation.Arguments.ElementAt(1) as LambdaExpression;
                    if (lambda != null && lambda.Parameters.Count == 2 && lambda.Body is Expression)
                    {
                        ParameterDeclaration p1 = lambda.Parameters.ElementAt(0);
                        ParameterDeclaration p2 = lambda.Parameters.ElementAt(1);
                        if (p1.Name == parameterName)
                        {
                            QueryExpression query = new QueryExpression();
                            query.Clauses.Add(new QueryFromClause {
                                    Identifier = p1.Name, Expression = Detach(mre.Target)
                                });
                            query.Clauses.Add(new QueryFromClause {
                                    Identifier = p2.Name, Expression = Detach(collectionSelector)
                                });
                            query.Clauses.Add(new QuerySelectClause {
                                    Expression = Detach(((Expression)lambda.Body))
                                });
                            return(query);
                        }
                    }
                    return(null);
                }

                case "Where":
                {
                    if (invocation.Arguments.Count != 1)
                    {
                        return(null);
                    }
                    string     parameterName;
                    Expression body;
                    if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out body))
                    {
                        QueryExpression query = new QueryExpression();
                        query.Clauses.Add(new QueryFromClause {
                                Identifier = parameterName, Expression = Detach(mre.Target)
                            });
                        query.Clauses.Add(new QueryWhereClause {
                                Condition = Detach(body)
                            });
                        return(query);
                    }
                    return(null);
                }

                case "OrderBy":
                case "OrderByDescending":
                case "ThenBy":
                case "ThenByDescending":
                {
                    if (invocation.Arguments.Count != 1)
                    {
                        return(null);
                    }
                    string     parameterName;
                    Expression orderExpression;
                    if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out orderExpression))
                    {
                        if (ValidateThenByChain(invocation, parameterName))
                        {
                            QueryOrderClause     orderClause = new QueryOrderClause();
                            InvocationExpression tmp         = invocation;
                            while (mre.MemberName == "ThenBy" || mre.MemberName == "ThenByDescending")
                            {
                                // insert new ordering at beginning
                                orderClause.Orderings.InsertAfter(
                                    null, new QueryOrdering
                                    {
                                        Expression = Detach(orderExpression),
                                        Direction  = (mre.MemberName == "ThenBy" ? QueryOrderingDirection.None : QueryOrderingDirection.Descending)
                                    });

                                tmp = (InvocationExpression)mre.Target;
                                mre = (MemberReferenceExpression)tmp.Target;
                                MatchSimpleLambda(tmp.Arguments.Single(), out parameterName, out orderExpression);
                            }
                            // insert new ordering at beginning
                            orderClause.Orderings.InsertAfter(
                                null, new QueryOrdering
                                {
                                    Expression = Detach(orderExpression),
                                    Direction  = (mre.MemberName == "OrderBy" ? QueryOrderingDirection.None : QueryOrderingDirection.Descending)
                                });

                            QueryExpression query = new QueryExpression();
                            query.Clauses.Add(new QueryFromClause {
                                    Identifier = parameterName, Expression = Detach(mre.Target)
                                });
                            query.Clauses.Add(orderClause);
                            return(query);
                        }
                    }
                    return(null);
                }

                case "Join":
                case "GroupJoin":
                {
                    if (invocation.Arguments.Count != 4)
                    {
                        return(null);
                    }
                    Expression source1 = mre.Target;
                    Expression source2 = invocation.Arguments.ElementAt(0);
                    string     elementName1, elementName2;
                    Expression key1, key2;
                    if (!MatchSimpleLambda(invocation.Arguments.ElementAt(1), out elementName1, out key1))
                    {
                        return(null);
                    }
                    if (!MatchSimpleLambda(invocation.Arguments.ElementAt(2), out elementName2, out key2))
                    {
                        return(null);
                    }
                    LambdaExpression lambda = invocation.Arguments.ElementAt(3) as LambdaExpression;
                    if (lambda != null && lambda.Parameters.Count == 2 && lambda.Body is Expression)
                    {
                        ParameterDeclaration p1 = lambda.Parameters.ElementAt(0);
                        ParameterDeclaration p2 = lambda.Parameters.ElementAt(1);
                        if (p1.Name == elementName1 && (p2.Name == elementName2 || mre.MemberName == "GroupJoin"))
                        {
                            QueryExpression query = new QueryExpression();
                            query.Clauses.Add(new QueryFromClause {
                                    Identifier = elementName1, Expression = Detach(source1)
                                });
                            QueryJoinClause joinClause = new QueryJoinClause();
                            joinClause.JoinIdentifier   = elementName2;         // join elementName2
                            joinClause.InExpression     = Detach(source2);      // in source2
                            joinClause.OnExpression     = Detach(key1);         // on key1
                            joinClause.EqualsExpression = Detach(key2);         // equals key2
                            if (mre.MemberName == "GroupJoin")
                            {
                                joinClause.IntoIdentifier = p2.Name;         // into p2.Name
                            }
                            query.Clauses.Add(joinClause);
                            query.Clauses.Add(new QuerySelectClause {
                                    Expression = Detach(((Expression)lambda.Body))
                                });
                            return(query);
                        }
                    }
                    return(null);
                }

                default:
                    return(null);
                }
            }
Example #13
0
        private void WritePart(Expression expression, bool toString, ResolveResult rr, bool isCoalescing = false)
        {
            if (isCoalescing)
            {
                ConversionBlock.expressionInWork.Add(expression);
            }

            bool wrapString = false;

            if (this.NullStringCheck && rr.Type.IsKnownType(KnownTypeCode.String))
            {
                wrapString = !(expression is BinaryOperatorExpression) && !(expression is PrimitiveExpression || rr.Type.IsReferenceType != null && !rr.Type.IsReferenceType.Value);
            }

            if (toString)
            {
                var toStringMethod = rr.Type.GetMembers().FirstOrDefault(m =>
                {
                    if (m.Name == CS.Methods.TOSTRING && !m.IsStatic && m.ReturnType.IsKnownType(KnownTypeCode.String) && m.IsOverride)
                    {
                        var method = m as IMethod;

                        if (method != null && method.Parameters.Count == 0 && method.TypeParameters.Count == 0)
                        {
                            return(true);
                        }
                    }

                    return(false);
                });

                if (toStringMethod != null)
                {
                    var inline = this.Emitter.GetInline(toStringMethod);

                    if (inline != null)
                    {
                        var writer = new Writer
                        {
                            InlineCode = inline,
                            Output     = this.Emitter.Output,
                            IsNewLine  = this.Emitter.IsNewLine
                        };
                        this.Emitter.IsNewLine = false;
                        this.Emitter.Output    = new StringBuilder();

                        expression.AcceptVisitor(this.Emitter);

                        string result = this.Emitter.Output.ToString();
                        this.Emitter.Output    = writer.Output;
                        this.Emitter.IsNewLine = writer.IsNewLine;

                        var argsInfo = new ArgumentsInfo(this.Emitter, expression, (IMethod)toStringMethod);
                        argsInfo.ArgumentsExpressions = new Expression[] { expression };
                        argsInfo.ArgumentsNames       = new string[] { "this" };
                        argsInfo.ThisArgument         = result;
                        new InlineArgumentsBlock(this.Emitter, argsInfo, writer.InlineCode).Emit();
                        return;
                    }
                }
            }

            if (wrapString)
            {
                this.Write("(");
            }

            expression.AcceptVisitor(this.Emitter);

            if (wrapString)
            {
                this.Write(" || \"\")");
            }

            if (isCoalescing)
            {
                ConversionBlock.expressionInWork.Remove(expression);
            }
        }
        private void GetMethodInfo(ICSharpCode.NRefactory.CSharp.Expression expression, List <object> argumentValues, Type[] types, CodeContext codeContext, string invocation, object container, out MethodInfo methodInfo)
        {
            methodInfo = null;



            if (expression is ICSharpCode.NRefactory.CSharp.IdentifierExpression)
            {
                methodInfo = container.GetType().GetMethod(invocation, types);
            }
            else if (expression is ICSharpCode.NRefactory.CSharp.MemberReferenceExpression)
            {
                ICSharpCode.NRefactory.CSharp.MemberReferenceExpression mre = expression as ICSharpCode.NRefactory.CSharp.MemberReferenceExpression;

                bool doTypesHaveNull = false;
                foreach (var item in types)
                {
                    if (item == null)
                    {
                        doTypesHaveNull = true;
                    }
                }

                Type typeToCallGetMethodOn;

                if (container is Type)
                {
                    typeToCallGetMethodOn = (container as Type);
                }
                else if (container is TypeReference)
                {
                    typeToCallGetMethodOn = (container as TypeReference).Type;
                }
                else
                {
                    typeToCallGetMethodOn = container.GetType();
                }
                if (doTypesHaveNull)
                {
                    // Let's hope there's no ambiguity or else we're in trouble...
                    methodInfo = typeToCallGetMethodOn.GetMethod(mre.MemberName);
                }
                else
                {
                    bool shouldTryAgain = false;;
                    try
                    {
                        methodInfo = typeToCallGetMethodOn.GetMethod(mre.MemberName, types);
                    }
                    catch
                    {
                        shouldTryAgain = true;
                    }
                    if (shouldTryAgain || methodInfo == null)
                    {
                        // The method doesn't exist, but it could be because
                        // the parser evaluated the types as one type (like int)
                        // but they are really of another type (like float).
                        var candidates = typeToCallGetMethodOn.GetMethods();
                        foreach (var candidate in candidates)
                        {
                            if (candidate.Name == mre.MemberName &&
                                candidate.GetParameters().Length == types.Length)
                            {
                                methodInfo = candidate;
                                break;
                            }
                        }
                    }
                }
            }
            else if (expression is InvocationExpression)
            {
                InvocationExpression ie = expression as InvocationExpression;

                if (container is Type)
                {
                    methodInfo = (container as Type).GetMethod(ie.Target.GetText(), types);
                }
                else
                {
                    methodInfo = container.GetType().GetMethod(ie.Target.GetText(), types);
                }
            }
            else
            {
                throw new NotImplementedException();
            }
        }
Example #15
0
 private Expression GetExpression(ICSharpCode.NRefactory.CSharp.Expression expression, ILTranslationContext data)
 => expression?.IsNull != false ? null : expression.AcceptVisitor(this, data).Cast <Expression>().Single();
Example #16
0
        public override AstNode VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression)
        {
            if (this.Rules.Integer == IntegerRule.Managed && (unaryOperatorExpression.Operator == UnaryOperatorType.Increment ||
                                                              unaryOperatorExpression.Operator == UnaryOperatorType.PostIncrement ||
                                                              unaryOperatorExpression.Operator == UnaryOperatorType.Decrement ||
                                                              unaryOperatorExpression.Operator == UnaryOperatorType.PostDecrement))
            {
                var rr            = this.Resolver.ResolveNode(unaryOperatorExpression, null);
                var expression_rr = this.Resolver.ResolveNode(unaryOperatorExpression.Expression, null);

                if (rr is ErrorResolveResult)
                {
                    UnaryOperatorExpression clonUnaryOperatorExpression = (UnaryOperatorExpression)base.VisitUnaryOperatorExpression(unaryOperatorExpression);
                    if (clonUnaryOperatorExpression == null)
                    {
                        clonUnaryOperatorExpression = (UnaryOperatorExpression)unaryOperatorExpression.Clone();
                    }

                    bool isPost = clonUnaryOperatorExpression.Operator == UnaryOperatorType.PostDecrement ||
                                  clonUnaryOperatorExpression.Operator == UnaryOperatorType.PostIncrement;

                    var isStatement = unaryOperatorExpression.Parent is ExpressionStatement;
                    var isIncr      = clonUnaryOperatorExpression.Operator == UnaryOperatorType.Increment || clonUnaryOperatorExpression.Operator == UnaryOperatorType.PostIncrement;
                    AssignmentExpression ae;

                    ae = new AssignmentExpression(clonUnaryOperatorExpression.Expression.Clone(), new BinaryOperatorExpression(clonUnaryOperatorExpression.Expression.Clone(), isIncr ? BinaryOperatorType.Add : BinaryOperatorType.Subtract, new PrimitiveExpression(1)));

                    if (isPost && !isStatement)
                    {
                        return(new InvocationExpression(new MemberReferenceExpression(new MemberReferenceExpression(new TypeReferenceExpression(new MemberType(new SimpleType("global"), CS.NS.BRIDGE)
                        {
                            IsDoubleColon = true
                        }), "Script"), "Identity"), clonUnaryOperatorExpression.Expression.Clone(), ae));
                    }
                    else
                    {
                        if (isStatement)
                        {
                            return(ae);
                        }

                        return(new ParenthesizedExpression(ae));
                    }
                }
                else
                {
                    var orr = (OperatorResolveResult)rr;

                    if (Helpers.IsFloatType(orr.Type, this.Resolver) || Helpers.Is64Type(orr.Type, this.Resolver))
                    {
                        return(base.VisitUnaryOperatorExpression(unaryOperatorExpression));
                    }

                    UnaryOperatorExpression clonUnaryOperatorExpression = (UnaryOperatorExpression)base.VisitUnaryOperatorExpression(unaryOperatorExpression);
                    if (clonUnaryOperatorExpression == null)
                    {
                        clonUnaryOperatorExpression = (UnaryOperatorExpression)unaryOperatorExpression.Clone();
                    }

                    bool isPost = clonUnaryOperatorExpression.Operator == UnaryOperatorType.PostDecrement ||
                                  clonUnaryOperatorExpression.Operator == UnaryOperatorType.PostIncrement;

                    var isStatement        = unaryOperatorExpression.Parent is ExpressionStatement;
                    var isIncr             = clonUnaryOperatorExpression.Operator == UnaryOperatorType.Increment || clonUnaryOperatorExpression.Operator == UnaryOperatorType.PostIncrement;
                    var needReturnOriginal = isPost && !isStatement;

                    Expression expression      = clonUnaryOperatorExpression.Expression.Clone();
                    Expression expressionAfter = clonUnaryOperatorExpression.Expression.Clone();

                    AssignmentExpression ae = null;

                    if (orr.UserDefinedOperatorMethod != null)
                    {
                        ae = new AssignmentExpression(expressionAfter.Clone(), clonUnaryOperatorExpression);
                    }
                    else if (clonUnaryOperatorExpression.Expression is MemberReferenceExpression mre && expression_rr is MemberResolveResult member_rr)
                    {
                        if (needReturnOriginal)
                        {
                            bool isSimple = (member_rr != null &&
                                             (member_rr.TargetResult is ThisResolveResult ||
                                              member_rr.TargetResult is LocalResolveResult ||
                                              member_rr.TargetResult is TypeResolveResult ||
                                              member_rr.TargetResult is ConstantResolveResult));

                            expression = isSimple ? mre.Clone() : new MemberReferenceExpression(new InvocationExpression(new MemberReferenceExpression(new MemberReferenceExpression(new TypeReferenceExpression(new MemberType(new SimpleType("global"), CS.NS.BRIDGE)
                            {
                                IsDoubleColon = true
                            }), "Script"), "ToTemp"), new PrimitiveExpression("idx" + tempKey), mre.Target.Clone()), mre.MemberName);
                            expressionAfter = new InvocationExpression(new MemberReferenceExpression(new MemberReferenceExpression(new TypeReferenceExpression(new MemberType(new SimpleType("global"), CS.NS.BRIDGE)
                            {
                                IsDoubleColon = true
                            }), "Script"), "FromTemp"), new PrimitiveExpression("idx" + tempKey++), mre.Target.Clone());
                        }
                        else
                        {
                            expressionAfter = null;
                        }

                        ae = BuildMemberReferenceReplacement(isIncr ? BinaryOperatorType.Add : BinaryOperatorType.Subtract, mre, member_rr, expressionAfter);
                    }
                    else if (clonUnaryOperatorExpression.Expression is IndexerExpression ie && expression_rr is ArrayAccessResolveResult array_rr)
                    {
                        IndexerExpression cacheIndexer = null;
                        if (needReturnOriginal)
                        {
                            var  array_target_rr = array_rr.Array as MemberResolveResult;
                            bool isSimpleTarget  = (array_target_rr != null && array_target_rr.Member is IField &&
                                                    (array_target_rr.TargetResult is ThisResolveResult ||
                                                     array_target_rr.TargetResult is LocalResolveResult ||
                                                     array_target_rr.TargetResult is TypeResolveResult ||
                                                     array_target_rr.TargetResult is ConstantResolveResult)) ||
                                                   (array_rr.Array is ThisResolveResult ||
                                                    array_rr.Array is LocalResolveResult ||
                                                    array_rr.Array is ConstantResolveResult);

                            bool simpleIndex = true;

                            foreach (var index in array_rr.Indexes)
                            {
                                var  indexMemberTargetrr = index as MemberResolveResult;
                                bool isIndexSimple       = (indexMemberTargetrr != null && indexMemberTargetrr.Member is IField &&
                                                            (indexMemberTargetrr.TargetResult is ThisResolveResult ||
                                                             indexMemberTargetrr.TargetResult is LocalResolveResult)) || index is ThisResolveResult || index is LocalResolveResult || index is ConstantResolveResult;

                                if (!isIndexSimple)
                                {
                                    simpleIndex = false;
                                    break;
                                }
                            }
                            var leftIndexerArgs  = new List <Expression>();
                            var rightIndexerArgs = new List <Expression>();

                            foreach (var index in ie.Arguments)
                            {
                                var expr = simpleIndex ? index.Clone() : new InvocationExpression(new MemberReferenceExpression(new MemberReferenceExpression(new TypeReferenceExpression(new MemberType(new SimpleType("global"), CS.NS.BRIDGE)
                                {
                                    IsDoubleColon = true
                                }), "Script"), "ToTemp"), new PrimitiveExpression("idx" + tempKey), index.Clone());
                                leftIndexerArgs.Add(expr);

                                expr = simpleIndex ? index.Clone() : new InvocationExpression(new MemberReferenceExpression(new MemberReferenceExpression(new TypeReferenceExpression(new MemberType(new SimpleType("global"), CS.NS.BRIDGE)
                                {
                                    IsDoubleColon = true
                                }), "Script"), "FromTemp"), new PrimitiveExpression("idx" + tempKey++), index.Clone());
                                rightIndexerArgs.Add(expr);
                            }

                            var leftExpr = new InvocationExpression(new MemberReferenceExpression(new MemberReferenceExpression(new TypeReferenceExpression(new MemberType(new SimpleType("global"), CS.NS.BRIDGE)
                            {
                                IsDoubleColon = true
                            }), "Script"), "ToTemp"), new PrimitiveExpression("idx" + tempKey), ie.Target.Clone());
                            var rightExpr = new InvocationExpression(new MemberReferenceExpression(new MemberReferenceExpression(new TypeReferenceExpression(new MemberType(new SimpleType("global"), CS.NS.BRIDGE)
                            {
                                IsDoubleColon = true
                            }), "Script"), "FromTemp"), new PrimitiveExpression("idx" + tempKey++), ie.Target.Clone());

                            var leftIndexer  = new IndexerExpression(isSimpleTarget ? ie.Target.Clone() : leftExpr, leftIndexerArgs);
                            var rightIndexer = new IndexerExpression(isSimpleTarget ? ie.Target.Clone() : rightExpr, rightIndexerArgs);

                            expression   = leftIndexer;
                            cacheIndexer = rightIndexer;
                        }

                        ae = BuildIndexerReplacement(isStatement, isIncr ? BinaryOperatorType.Add : BinaryOperatorType.Subtract, ie, array_rr, cacheIndexer);
                    }