Ejemplo n.º 1
0
        Result GetResult(AstNode node)
        {
            if (node is BlockStatement)
            {
                return(GetResultFromBlock((BlockStatement)node));
            }
            Result result = new Result();

            for (AstNode child = node.FirstChild; child != null; child = child.NextSibling)
            {
                Result childResult = GetResult(child);
                result.CostInCheckedContext            += childResult.CostInCheckedContext;
                result.NodesToInsertInCheckedContext   += childResult.NodesToInsertInCheckedContext;
                result.CostInUncheckedContext          += childResult.CostInUncheckedContext;
                result.NodesToInsertInUncheckedContext += childResult.NodesToInsertInUncheckedContext;
            }
            Expression expr = node as Expression;

            if (expr != null)
            {
                CheckedUncheckedAnnotation annotation = expr.Annotation <CheckedUncheckedAnnotation>();
                if (annotation != null)
                {
                    // If the annotation requires this node to be in a specific context, add a huge cost to the other context
                    // That huge cost gives us the option to ignore a required checked/unchecked expression when there wouldn't be any
                    // solution otherwise. (e.g. "for (checked(M().x += 1); true; unchecked(M().x += 2)) {}")
                    if (annotation.IsChecked)
                    {
                        result.CostInUncheckedContext += new Cost(10000, 0);
                    }
                    else
                    {
                        result.CostInCheckedContext += new Cost(10000, 0);
                    }
                }
                // Embed this node in an checked/unchecked expression:
                if (expr.Parent is ExpressionStatement)
                {
                    // We cannot use checked/unchecked for top-level-expressions.
                }
                else if (expr.Role.IsValid(Expression.Null))
                {
                    // We use '<' so that expressions are introduced on the deepest level possible (goal 3)
                    var costIfWrapWithChecked   = result.CostInCheckedContext.WrapInCheckedExpr();
                    var costIfWrapWithUnchecked = result.CostInUncheckedContext.WrapInCheckedExpr();
                    if (costIfWrapWithChecked < result.CostInUncheckedContext)
                    {
                        result.CostInUncheckedContext          = costIfWrapWithChecked;
                        result.NodesToInsertInUncheckedContext = result.NodesToInsertInCheckedContext + new InsertedExpression(expr, true);
                    }
                    else if (costIfWrapWithUnchecked < result.CostInCheckedContext)
                    {
                        result.CostInCheckedContext          = costIfWrapWithUnchecked;
                        result.NodesToInsertInCheckedContext = result.NodesToInsertInUncheckedContext + new InsertedExpression(expr, false);
                    }
                }
            }
            return(result);
        }
Ejemplo n.º 2
0
        Result GetResult(AstNode node)
        {
            if (node is BlockStatement)
            {
                return(GetResultFromBlock((BlockStatement)node));
            }
            Result result = new Result();

            for (AstNode child = node.FirstChild; child != null; child = child.NextSibling)
            {
                Result childResult = GetResult(child);
                result.CostInCheckedContext            += childResult.CostInCheckedContext;
                result.NodesToInsertInCheckedContext   += childResult.NodesToInsertInCheckedContext;
                result.CostInUncheckedContext          += childResult.CostInUncheckedContext;
                result.NodesToInsertInUncheckedContext += childResult.NodesToInsertInUncheckedContext;
            }
            Expression expr = node as Expression;

            if (expr != null)
            {
                CheckedUncheckedAnnotation annotation = expr.Annotation <CheckedUncheckedAnnotation>();
                if (annotation != null)
                {
                    // If the annotation requires this node to be in a specific context, set the cost of the other context to infinite.
                    if (annotation.IsChecked)
                    {
                        result.CostInUncheckedContext = Cost.Infinite;
                    }
                    else
                    {
                        result.CostInCheckedContext = Cost.Infinite;
                    }
                }
                // Embed this node in an checked/unchecked expression:
                // We use '<' so that expressions are introduced on the deepest level possible (goal 3)
                if (result.CostInCheckedContext + new Cost(0, 1) < result.CostInUncheckedContext)
                {
                    result.CostInUncheckedContext          = result.CostInCheckedContext + new Cost(0, 1);
                    result.NodesToInsertInUncheckedContext = result.NodesToInsertInCheckedContext + new InsertedExpression(expr, true);
                }
                else if (result.CostInUncheckedContext + new Cost(0, 1) < result.CostInCheckedContext)
                {
                    result.CostInCheckedContext          = result.CostInUncheckedContext + new Cost(0, 1);
                    result.NodesToInsertInCheckedContext = result.NodesToInsertInUncheckedContext + new InsertedExpression(expr, false);
                }
            }
            return(result);
        }
Ejemplo n.º 3
0
        Result GetResult(AstNode node)
        {
            if (node is BlockStatement)
            {
                return(GetResultFromBlock((BlockStatement)node));
            }
            Result result = new Result();

            for (AstNode child = node.FirstChild; child != null; child = child.NextSibling)
            {
                Result childResult = GetResult(child);
                result.CostInCheckedContext            += childResult.CostInCheckedContext;
                result.NodesToInsertInCheckedContext   += childResult.NodesToInsertInCheckedContext;
                result.CostInUncheckedContext          += childResult.CostInUncheckedContext;
                result.NodesToInsertInUncheckedContext += childResult.NodesToInsertInUncheckedContext;
            }
            Expression expr = node as Expression;

            if (expr != null)
            {
                CheckedUncheckedAnnotation annotation = expr.Annotation <CheckedUncheckedAnnotation>();
                if (annotation != null)
                {
                    // If the annotation requires this node to be in a specific context, add a huge cost to the other context
                    // That huge cost gives us the option to ignore a required checked/unchecked expression when there wouldn't be any
                    // solution otherwise. (e.g. "for (checked(M().x += 1); true; unchecked(M().x += 2)) {}")
                    if (annotation.IsChecked)
                    {
                        result.CostInUncheckedContext += new Cost(10000, 0);
                    }
                    else
                    {
                        result.CostInCheckedContext += new Cost(10000, 0);
                    }
                }
                // Embed this node in an checked/unchecked expression:
                if (expr.Parent is ExpressionStatement)
                {
                    // We cannot use checked/unchecked for top-level-expressions.
                    // However, we could try converting a compound assignment (checked(a+=b);) or unary operator (checked(a++);)
                    // back to its old form.
                    if (expr.Annotation <ReplaceMethodCallsWithOperators.RestoreOriginalAssignOperatorAnnotation>() != null)
                    {
                        // We use '<' so that expressions are introduced on the deepest level possible (goal 3)
                        if (result.CostInCheckedContext + new Cost(1, 1) < result.CostInUncheckedContext)
                        {
                            result.CostInUncheckedContext          = result.CostInCheckedContext + new Cost(1, 1);
                            result.NodesToInsertInUncheckedContext = result.NodesToInsertInCheckedContext + new ConvertCompoundAssignment(expr, true);
                        }
                        else if (result.CostInUncheckedContext + new Cost(1, 1) < result.CostInCheckedContext)
                        {
                            result.CostInCheckedContext          = result.CostInUncheckedContext + new Cost(1, 1);
                            result.NodesToInsertInCheckedContext = result.NodesToInsertInUncheckedContext + new ConvertCompoundAssignment(expr, false);
                        }
                    }
                }
                else if (expr.Role.IsValid(Expression.Null))
                {
                    // We use '<' so that expressions are introduced on the deepest level possible (goal 3)
                    if (result.CostInCheckedContext + new Cost(0, 1) < result.CostInUncheckedContext)
                    {
                        result.CostInUncheckedContext          = result.CostInCheckedContext + new Cost(0, 1);
                        result.NodesToInsertInUncheckedContext = result.NodesToInsertInCheckedContext + new InsertedExpression(expr, true);
                    }
                    else if (result.CostInUncheckedContext + new Cost(0, 1) < result.CostInCheckedContext)
                    {
                        result.CostInCheckedContext          = result.CostInUncheckedContext + new Cost(0, 1);
                        result.NodesToInsertInCheckedContext = result.NodesToInsertInUncheckedContext + new InsertedExpression(expr, false);
                    }
                }
            }
            return(result);
        }