Func <Expression, bool> GetChecker(Expression expression, IList <IdentifierExpression> identifiers)
            {
                // TODO: This only works for simple cases.
                IList <IMember>   members;
                IList <IVariable> locals;
                var identifierResolveResults = identifiers.Select(identifier => context.Resolve(identifier)).ToList();

                SplitResolveResults(identifierResolveResults, out members, out locals);

                if (expression is InvocationExpression || expression is ObjectCreateExpression)
                {
                    return(node =>
                    {
                        if (node is InvocationExpression || node is ObjectCreateExpression)
                        {
                            // We don't know what these might do, so assume it will change the initializer
                            return true;
                        }
                        var binaryOperator = node as BinaryOperatorExpression;
                        if (binaryOperator != null)
                        {
                            var resolveResult = context.Resolve(binaryOperator) as OperatorResolveResult;
                            if (resolveResult == null)
                            {
                                return false;
                            }
                            // Built-in operators are ok, user defined ones not so much
                            return resolveResult.UserDefinedOperatorMethod != null;
                        }
                        return IsConflictingAssignment(node, identifiers, members, locals);
                    });
                }
                else if (expression is IdentifierExpression)
                {
                    var initializerDependsOnMembers       = identifierResolveResults.Any(result => result is MemberResolveResult);
                    var initializerDependsOnReferenceType = identifierResolveResults.Any(result => result.Type.IsReferenceType == true);
                    return(node =>
                    {
                        if ((node is InvocationExpression || node is ObjectCreateExpression) &&
                            (initializerDependsOnMembers || initializerDependsOnReferenceType))
                        {
                            // Anything can happen...
                            return true;
                        }
                        var binaryOperator = node as BinaryOperatorExpression;
                        if (binaryOperator != null)
                        {
                            var resolveResult = context.Resolve(binaryOperator) as OperatorResolveResult;
                            if (resolveResult == null)
                            {
                                return false;
                            }
                            return resolveResult.UserDefinedOperatorMethod != null;
                        }
                        return IsConflictingAssignment(node, identifiers, members, locals);
                    });
                }

                return(node => false);
            }
Beispiel #2
0
            void HandlePotentialWrite(Expression expression)
            {
                var variableResolveResult = ctx.Resolve(expression) as LocalResolveResult;

                if (variableResolveResult == null)
                {
                    return;
                }
                variableWritten |= variableResolveResult.Equals(parameter);
            }
Beispiel #3
0
            bool IsSafeExpression(Expression expression, BaseSemanticModel context)
            {
                var components = expression.DescendantsAndSelf;

                foreach (var c in components)
                {
                    if (c is AssignmentExpression)
                    {
                        return(false);
                    }
                    else if (c is UnaryOperatorExpression)
                    {
                        var ope = ((UnaryOperatorExpression)c).Operator;
                        if (ope == UnaryOperatorType.Decrement || ope == UnaryOperatorType.Increment ||
                            ope == UnaryOperatorType.PostDecrement || ope == UnaryOperatorType.PostIncrement)
                        {
                            return(false);
                        }
                    }
                    else if (c is IdentifierExpression)
                    {
                        var result = context.Resolve(c);
                        if (result.IsError)
                        {
                            return(false);
                        }
                        if (!(result is LocalResolveResult))
                        {
                            return(false);
                        }
                        if ((((LocalResolveResult)result).IsParameter))
                        {
                            return(false);
                        }
                    }
                }
                return(true);
            }
        static IType GetReturnType(BaseSemanticModel context, AstNode currentFunction)
        {
            var resolveResult = context.Resolve(currentFunction);

            return(resolveResult.IsError ? null : resolveResult.Type);
        }