Example #1
0
        public static IEnumerable<ReplaceAction> GetSimplifications(ForEachStatementSyntax forLoop, ISemanticModel model, Assumptions assume, CancellationToken cancellationToken = default(CancellationToken))
        {
            // loop uses iterator once?
            var declaredSymbol = model.GetDeclaredSymbol(forLoop);
            var singleRead = forLoop.Statement.DescendantNodes()
                             .OfType<SimpleNameSyntax>()
                             .Where(e => model.GetSymbolInfo(e).Symbol == declaredSymbol)
                             .SingleOrDefaultAllowMany();
            if (singleRead == null) yield break;

            // safe iterator projection?
            var guaranteedProjectionPerIteration = forLoop.Statement.CompleteExecutionGuaranteesChildExecutedExactlyOnce(singleRead);
            var projection = singleRead.AncestorsAndSelf()
                             .TakeWhile(e => !(e is StatementSyntax))
                             .OfType<ExpressionSyntax>()
                             .TakeWhile(e => model.GetTypeInfo(e).Type.SpecialType != SpecialType.System_Void)
                             .TakeWhile(e => guaranteedProjectionPerIteration == true || e.HasSideEffects(model, assume) == false)
                             .LastOrDefault();
            if (projection == null) yield break;
            if (projection.TryEvalAlternativeComparison(singleRead, model, assume) == true) yield break;

            // build replacement loop
            var projectedCollection = forLoop.Expression
                                      .Accessing("Select")
                                      .Invoking(forLoop.Identifier.Lambdad(projection).Args1());
            var newBody = forLoop.Statement.ReplaceNode(projection, singleRead);
            var replacedLoop = forLoop.WithExpression(projectedCollection).WithStatement(newBody);

            // expose as code action/issue
            yield return new ReplaceAction(
                "Project collection",
                forLoop,
                replacedLoop);
        }
 private void AssertNoOptimization(Assumptions assumptions, string pars, string collection, string body)
 {
     var tree1 = ("void f(" + pars + ") { foreach (var e in " + collection + ") { " + body + " }").ParseFunctionTreeFromStringUsingStandard();
     var statements1 = (ForEachStatementSyntax)tree1.TestGetParsedFunctionStatements().Single();
     var model = tree1.GetTestSemanticModel();
     Assert.IsTrue(ForEachToFirstLast.GetSimplifications(statements1, model, assumptions).Count() == 0);
 }
Example #3
0
        public static IEnumerable<ReplaceAction> GetSimplifications(ForEachStatementSyntax forLoop, ISemanticModel model, Assumptions assume, CancellationToken cancellationToken = default(CancellationToken))
        {
            var body = forLoop.Statement.Statements();
            if (body.None()) yield break;

            var unconditionalStatements = body.Skip(1);
            var conditionalStatement = body.First() as IfStatementSyntax;
            if (conditionalStatement == null) yield break;

            var trueBranch = conditionalStatement.Statement.Statements().AppendUnlessJumps(unconditionalStatements).Block();
            var falseBranch = conditionalStatement.ElseStatementOrEmptyBlock().Statements().AppendUnlessJumps(unconditionalStatements).Block();

            var falseIsEmpty = falseBranch.HasSideEffects(model, assume) == false;
            var trueIsEmpty = trueBranch.HasSideEffects(model, assume) == false;
            if (falseIsEmpty == trueIsEmpty) yield break;

            var condition = falseIsEmpty ? conditionalStatement.Condition : conditionalStatement.Condition.Inverted();
            var conditionalActions = falseIsEmpty ? trueBranch : falseBranch;

            var query = forLoop.Expression.Accessing("Where").Invoking(forLoop.Identifier.Lambdad(condition).Args1());

            var forWhereDo = forLoop.WithExpression(query).WithStatement(conditionalActions);

            yield return new ReplaceAction(
                "Filter collection",
                forLoop,
                forWhereDo);
        }
Example #4
0
 private void AssertOptimizes(Assumptions assumptions, string pars, string collection, string body, string newBody = null)
 {
     var tree1 = ("void f(" + pars + ") { foreach (var e in " + collection + ") { " + body + " }").ParseFunctionTreeFromStringUsingStandard();
     var tree2 = ("void f(" + pars + ") { if (" + collection + ".Any()) { " + (newBody ?? body) + " }").ParseFunctionTreeFromStringUsingStandard();
     var statements1 = (ForEachStatementSyntax)tree1.TestGetParsedFunctionStatements().Single();
     var statements2 = (IfStatementSyntax)tree2.TestGetParsedFunctionStatements().Single();
     var model = tree1.GetTestSemanticModel();
     TestUtil.AssertSameSyntax(ForEachToAny.GetSimplifications(statements1, model, assumptions).Single().NewNode, statements2);
 }
        public static IEnumerable<ReplaceAction> GetSimplifications(BinaryExpressionSyntax b, ISemanticModel model, Assumptions assume, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (!b.Left.DefinitelyHasBooleanType(model)) yield break;
            if (!b.Right.DefinitelyHasBooleanType(model)) yield break;

            // prep basic analysis
            var leftEffects = b.Left.HasSideEffects(model, assume) != false;
            var rightEffects = b.Right.HasSideEffects(model, assume) != false;
            var lv = b.Left.TryGetConstBoolValue();
            var rv = b.Right.TryGetConstBoolValue();
            var cmp = b.Left.TryEvalAlternativeComparison(b.Right, model, assume);

            // prep utility funcs for adding simplifications
            var actions = new List<ReplaceAction>();
            Action<String, ExpressionSyntax> include = (desc, rep) =>
                actions.Add(new ReplaceAction(desc, b, rep));
            Action<bool> useRight = v => {
                if (!leftEffects)
                    include(v ? "rhs" : "!rhs", b.Right.MaybeInverted(!v));
            };
            Action<bool> useLeft = v => {
                if (!rightEffects)
                    include(v ? "lhs" : "!lhs", b.Left.MaybeInverted(!v));
            };
            Action<bool> useBool = v => {
                if (!leftEffects && !rightEffects) {
                    actions.Clear(); // override left/right
                    include(v + "", v.AsLiteral());
                }
            };

            // try to simplify equality operators ==, !=, ^
            bool? equality = null;
            if (b.Kind == SyntaxKind.EqualsExpression) equality = true;
            if (b.Kind == SyntaxKind.ExclusiveOrExpression || b.Kind == SyntaxKind.NotEqualsExpression) equality = false;
            if (equality != null) {
                if (lv != null) useRight(lv == equality);
                if (rv != null) useLeft(rv == equality);
                if (cmp != null) useBool(cmp == equality);
            }

            // try to simplify and/or operators &&, &, ||, |
            var sticky = b.Kind.IsAndBL() ? false
                       : b.Kind.IsOrBL() ? true
                       : (bool?)null;
            if (sticky != null) {
                if (b.Kind.IsShortCircuitingLogic() && lv == sticky) rightEffects = false; // short-circuit prevents effects
                if (cmp == true || lv == !sticky) useRight(true);
                if (cmp == true || rv == !sticky) useLeft(true);
                if (cmp == false || lv == sticky || rv == sticky) useBool(sticky.Value);
            }

            // expose simplifications as code issues/actions
            foreach (var action in actions)
                yield return action;
        }
Example #6
0
 public static IEnumerable<ReplaceAction> GetSimplifications(VariableDeclarationSyntax declaration, ISemanticModel model, Assumptions assume, CancellationToken cancellationToken = default(CancellationToken))
 {
     if (declaration.Variables.Count != 1) yield break;
     var v = declaration.Variables.Single();
     if (v.Initializer == null) yield break;
     if (declaration.Type.IsVar) yield break;
     var declaredType = model.GetTypeInfo(declaration.Type);
     var valueType = model.GetTypeInfo(v.Initializer.Value);
     if (!declaredType.Equals(valueType)) yield break;
     yield return new ReplaceAction("Use 'var'", declaration.Type, Syntax.IdentifierName("var"));
 }
Example #7
0
        public static IEnumerable<ReplaceAction> GetSimplifications(ForEachStatementSyntax loop, ISemanticModel model, Assumptions assume, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (loop.Type.IsVar) yield break;
            var declaredType = model.GetTypeInfo(loop.Type).Type as ITypeSymbol;
            var collectionType = model.GetTypeInfo(loop.Expression).Type as ITypeSymbol;
            if (declaredType == null || collectionType == null) yield break;
            var allInterfaces = new List<INamedTypeSymbol>();
            allInterfaces.AddRange(collectionType.AllInterfaces);
            if (collectionType is INamedTypeSymbol) allInterfaces.Add((INamedTypeSymbol)collectionType);
            var enumerableTypes = allInterfaces
                                  .Where(e => e.OriginalDefinition.SpecialType == SpecialType.System_Collections_Generic_IEnumerable_T)
                                  .ToArray();
            if (enumerableTypes.Count() != 1) yield break;
            var itemType = enumerableTypes.Single().TypeArguments.Single();

            if (!declaredType.Equals(itemType)) yield break;
            yield return new ReplaceAction("Use 'var'", loop.Type, Syntax.IdentifierName("var"));
        }
Example #8
0
        public static IEnumerable<ReplaceAction> GetSimplifications(ForEachStatementSyntax forLoop, ISemanticModel model, Assumptions assumptions, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (forLoop.IsAnyIterationSufficient(model, assumptions) == true)
                yield break; // a more appropriate code issue handles this case

            // can the loop be replaced by its first or last iteration?
            var isFirstSufficient = forLoop.IsFirstIterationSufficient(model, assumptions) == true;
            var isLastSufficient = forLoop.IsLastIterationSufficient(model, assumptions) == true;
            var firstVsLast = isFirstSufficient ? "First"
                            : isLastSufficient ? "Last"
                            : null;
            if (firstVsLast == null) yield break;

            // do we know how to translate?
            var loopStatements = forLoop.Statement.Statements();
            var rawThenStatements = loopStatements.SkipLast(loopStatements.Last().IsIntraLoopJump() ? 1 : 0).ToArray();
            if (rawThenStatements.Any(e => e.HasTopLevelIntraLoopJumps())) yield break; // don't know how to translate jumps that aren't at the end

            // wrap collection items in a type with a new null value (so that a null result definitively indicates an empty collection)
            var iteratorType = ((LocalSymbol)model.GetDeclaredSymbol(forLoop)).Type;
            var nuller = GetNullabledQueryAndValueGetter(iteratorType, forLoop.Identifier, forLoop.Expression);
            var nullableQuery = nuller.Item1;
            var valueGetter = nuller.Item2;
            var tempNullableLocalName = Syntax.Identifier("_" + forLoop.Identifier.ValueText);
            var tempNullableLocalGet = Syntax.IdentifierName(tempNullableLocalName);

            // build replacement
            var iteratorReads = forLoop.Statement.ReadsOfLocalVariable(forLoop.Identifier).ToArray();
            var desiredIterationQuery = nullableQuery.Accessing(firstVsLast + "OrDefault").Invoking();
            var condition = tempNullableLocalGet.BOpNotEquals(Syntax.LiteralExpression(SyntaxKind.NullLiteralExpression));
            var useDenulledLocal = iteratorReads.Length > 2;
            var thenStatement = useDenulledLocal
                              ? rawThenStatements.Prepend(forLoop.Identifier.VarInit(valueGetter(tempNullableLocalGet))).Block()
                              : rawThenStatements.Select(e => e.ReplaceNodes(iteratorReads, (n, a) => valueGetter(tempNullableLocalGet))).Block();
            var replacementStatements = new StatementSyntax[] {
                tempNullableLocalName.VarInit(desiredIterationQuery),
                condition.IfThen(thenStatement)
            };

            // expose as code action/issue
            yield return forLoop.MakeReplaceStatementWithManyAction(
                replacementStatements,
                "Execute " + firstVsLast + " if any");
        }
Example #9
0
 public static IEnumerable<ReplaceAction> GetSimplifications(LocalDeclarationStatementSyntax declaration, ISemanticModel model, Assumptions assume, CancellationToken cancellationToken = default(CancellationToken))
 {
     var scope = declaration.Ancestors().OfType<BlockSyntax>().First();
     var i = scope.Statements.IndexOf(declaration);
     foreach (var v in declaration.Declaration.Variables) {
         if (v.Initializer != null) {
             if (v.Initializer.Value.HasSideEffects(model, assume) != false) continue;
             var anyEffects = declaration.Declaration.Variables.Where(e => e.Initializer != null && e.Initializer.Value.HasSideEffects(model, assume) != false).Any();
             if (v.Initializer.Value.IsConst(model) != true && anyEffects) continue;
         }
         var r = WithDeclarationMoved(scope, declaration, v, model, assume, cancellationToken);
         if (r == null) continue;
         var reducedDeclaration = declaration.Declaration.Variables.Count == 1
                                 ? new LocalDeclarationStatementSyntax[0]
                                 : new[] { declaration.WithDeclaration(declaration.Declaration.WithVariables(declaration.Declaration.Variables.Without(v))) };
         var newScopeWithReducedDeclaration = r.WithStatements(r.Statements.TakeSkipPutTake(i, 1, reducedDeclaration).List());
         yield return new ReplaceAction("Reduce scope", scope, newScopeWithReducedDeclaration, v.Identifier.Span);
     }
 }
Example #10
0
        public static IEnumerable<ReplaceAction> GetSimplifications(ForEachStatementSyntax forLoop, ISemanticModel model, Assumptions assumptions, CancellationToken cancellationToken = default(CancellationToken))
        {
            // loop body idempotent and independent of the iterator?
            if (forLoop.IsAnyIterationSufficient(model, assumptions) != true) yield break;

            // build replacement if statement, if possible
            var loopStatements = forLoop.Statement.Statements();
            if (loopStatements.None()) yield break;
            var ifBody = loopStatements.SkipLast(loopStatements.Last().IsIntraLoopJump() ? 1 : 0).Block();
            if (ifBody.HasTopLevelIntraLoopJumps()) yield break;
            var ifCondition = forLoop.Expression.Accessing("Any").Invoking();
            var rawReplacement = Syntax.IfStatement(
                condition: ifCondition,
                statement: ifBody);
            var replacement = rawReplacement.IncludingTriviaSurrounding(forLoop, TrivialTransforms.Placement.Around);

            // expose as code action/issue
            yield return new ReplaceAction(
                "Execute once if any",
                forLoop,
                replacement);
        }
        public static IEnumerable<ReplaceAction> GetSimplifications(ConditionalExpressionSyntax ternaryNode, ISemanticModel model, Assumptions assume, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (!ternaryNode.DefinitelyHasBooleanType(model)) yield break;
            var whenTrueFalseCmp = ternaryNode.WhenTrue.TryEvalAlternativeComparison(ternaryNode.WhenFalse, model, assume);

            if (whenTrueFalseCmp == true) {
                // (c ? b : b) --> b
                yield return new ReplaceAction(
                    "Simplify",
                    ternaryNode,
                    ternaryNode.WhenTrue);

                // if condition has side effects we may need to keep it
                // (c ? b : b) --> ((c && false) || b)
                if (ternaryNode.Condition.HasSideEffects(model, assume) != false) {
                    var replacement = ternaryNode.Condition
                                      .BracketedOrProtected()
                                      .BOpLogicalAnd(false.AsLiteral())
                                      .Bracketed()
                                      .BOpLogicalOr(ternaryNode.WhenTrue);
                    yield return new ReplaceAction(
                        "Simplify (keeping condition evaluation)",
                        ternaryNode,
                        replacement);
                }
            }
            if (whenTrueFalseCmp == false) {
                // (c ? b : !b) --> (c == b)
                var replacement = ternaryNode.Condition
                                  .BracketedOrProtected()
                                  .BOpEquals(ternaryNode.WhenTrue);
                yield return new ReplaceAction(
                    "Simplify",
                    ternaryNode,
                    replacement);
            }
        }
Example #12
0
        public void ConfigureServices(IServiceCollection services)
        {
            var cultureInfo = new CultureInfo("en-GB");

            CultureInfo.DefaultThreadCurrentCulture   = cultureInfo;
            CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;

            services.AddApplicationInsightsTelemetry("5df2bfe9-d72c-4622-9fed-adbee51c0a02");

            services.AddControllers(options => { options.InputFormatters.Insert(0, new TextPlainInputFormatter()); });
            services.AddControllers().AddNewtonsoftJson();

            services.AddSingleton <ITaxSystem, TwentyTwentyTaxSystem>();
            services.AddSingleton <IIncomeTaxCalculator, IncomeTaxCalculator>();
            services.AddSingleton <ITaxCalculatorDomainInterface, TaxCalculatorDomainInterface>();
            services.AddSingleton <IDateProvider, DateProvider>();
            services.AddSingleton <IPensionAgeCalc, PensionAgeCalc>();
            services.AddSingleton <IStatePensionAmountCalculator, StatePensionAmountCalculator>();
            services.AddTransient <IAssumptions>(x => Assumptions.SafeWithdrawalNoInflationTake25Assumptions());
            services.AddSingleton <IRetirementCalculator, RetirementIncrementalApproachCalculator>();
            services.AddSingleton <IRetirementDomainInterface, RetirementDomainInterface>();

            services.AddControllers();
        }
Example #13
0
    private static bool? IsLastIterationSufficient_Helper(this ExpressionSyntax syntax, ISemanticModel model, Assumptions assume, ISymbol iteratorVariable)
    {
        Contract.Requires(syntax != null);
        Contract.Requires(model != null);
        Contract.Requires(iteratorVariable != null);

        var isConst = syntax.IsConst(model);
        if (isConst == true) return true;
        if (syntax is IdentifierNameSyntax && model.GetSymbolInfo(syntax).Symbol == iteratorVariable) return true;
        if (syntax.Kind == SyntaxKind.AssignExpression) {
            var b = (BinaryExpressionSyntax)syntax;
            if (b.Left is IdentifierNameSyntax) {
                return b.Right.IsLastIterationSufficient_Helper2(model, assume, iteratorVariable);
            }
        }
        return null;
    }
Example #14
0
    private static bool? IsLastIterationSufficient_Helper(this StatementSyntax syntax, ISemanticModel model, Assumptions assume, ISymbol iteratorVariable)
    {
        Contract.Requires(syntax != null);
        Contract.Requires(model != null);
        Contract.Requires(iteratorVariable != null);

        if (syntax is ContinueStatementSyntax) return true;
        if (syntax is BlockSyntax) {
            var b = (BlockSyntax)syntax;
            if (b.Statements.Count == 0) return true;
            if (b.Statements.Count == 1) return b.Statements.Single().IsLastIterationSufficient_Helper(model, assume, iteratorVariable);
            var m = syntax.Statements().Min(e => e.IsLastIterationSufficient_Helper(model, assume, iteratorVariable));
            if (m != true) return m;
            var assigned = syntax.DescendantNodes()
                           .Where(e => e.Kind == SyntaxKind.AssignExpression)
                           .Cast<BinaryExpressionSyntax>()
                           .Select(e => e.Left)
                           .ToArray();
            var assignedSymbols = assigned.Select(e => model.GetSymbolInfo(e));
            var reads = syntax.DescendantNodes()
                        .Except(assigned)
                        .Select(e => model.GetSymbolInfo(e));
            if (!reads.Intersect(assignedSymbols).Any()) return true;
        }
        if (syntax is ExpressionStatementSyntax)
            return ((ExpressionStatementSyntax)syntax).Expression.IsLastIterationSufficient_Helper(model, assume, iteratorVariable);
        return null;
    }
Example #15
0
 public static ImplicitSingleStatementBranches TryGetImplicitBranchSingleStatements(this IfStatementSyntax syntax, ISemanticModel model, Assumptions assume)
 {
     return TryGetIfStatementBranches_BothSingle(syntax)
         ?? TryGetIfStatementBranches_ConditionalJump(syntax)
         ?? TryGetIfStatementBranches_OverwritePrev(syntax, model, assume);
 }
Example #16
0
    public static ImplicitSingleStatementBranches TryGetIfStatementBranches_OverwritePrev(IfStatementSyntax syntax, ISemanticModel model, Assumptions assume)
    {
        var trueAction = syntax.Statement.CollapsedStatements().SingleOrDefaultAllowMany();
        if (trueAction == null) return null;

        if (syntax.Else != null) return null;
        var prev = syntax.TryGetPrevStatement();
        if (prev == null) return null;

        if (trueAction.EffectsOverwriteEffectsOf(prev, model, assume) != true) return null;
        return new ImplicitSingleStatementBranches(trueAction, prev, prev);
    }
Example #17
0
    public static bool? TryEvalAlternativeComparison(this ExpressionSyntax expression, ExpressionSyntax other, ISemanticModel model, Assumptions assume)
    {
        var val1 = expression.TryGetConstBoolValue();
        var val2 = other.TryGetConstBoolValue();
        if (val1.HasValue != val2.HasValue) return null;
        if (val1.HasValue) return val1.Value == val2.Value;

        if (expression is ParenthesizedExpressionSyntax) return ((ParenthesizedExpressionSyntax)expression).Expression.TryEvalAlternativeComparison(other, model, assume);
        if (other is ParenthesizedExpressionSyntax) return expression.TryEvalAlternativeComparison(((ParenthesizedExpressionSyntax)other).Expression, model, assume);
        if (expression.Kind == SyntaxKind.LogicalNotExpression) return !((PrefixUnaryExpressionSyntax)expression).Operand.TryEvalAlternativeComparison(other, model, assume);
        if (other.Kind == SyntaxKind.LogicalNotExpression) return !expression.TryEvalAlternativeComparison(((PrefixUnaryExpressionSyntax)other).Operand, model, assume);

        if (expression.HasSideEffects(model, assume) == false
            && expression.WithoutAnyTriviaOrInternalTrivia().ToString() == other.WithoutAnyTriviaOrInternalTrivia().ToString())
            return true;

        return null;
    }
Example #18
0
    ///<summary>Determines if the effects of executing the statement with/without the given previous statement are equivalent.</summary>
    public static bool? EffectsOverwriteEffectsOf(this StatementSyntax syntax, StatementSyntax prev, ISemanticModel model, Assumptions assume)
    {
        if (prev.IsGuaranteedToJumpOut()) return false;
        if (prev.HasSideEffects(model, assume) == false) return null;

        if (prev.IsAssignmentOrSingleInitialization()) {
            var rhs = prev.TryGetRHSOfAssignmentOrInit();
            if (rhs.HasSideEffects(model, assume) == false && syntax.HasMatchingLHSOrRet(prev, model, assume))
                return true;
            return null;
        }
        return null;
    }
Example #19
0
 public ActionResult SetAssumptions(Assumptions model)
 {
     // do something meaningful with the assumptions values for tax rates
     return RedirectToRoute("ReportWizardStep", new {token = model.Token, stepNumber = 5});
 }
Example #20
0
 private bool? Effects(string pars, string statement, Assumptions? assume = null)
 {
     var tree = ("void f(" + pars + ") {" + statement + "}").ParseFunctionTreeFromString();
     var statementN = tree.TestGetParsedFunctionBody();
     return statementN.HasSideEffects(tree.GetTestSemanticModel(), assume ?? Assumptions.All);
 }
 private void AssertOptimizes(Assumptions assumptions, string pars, string collection, string body, string result)
 {
     var tree1 = ("void f(" + pars + ") { foreach (var e in " + collection + ") { " + body + " }").ParseFunctionTreeFromStringUsingStandard();
     var tree2 = ("void f(" + pars + ") { " + result + "}").ParseFunctionTreeFromStringUsingStandard();
     var statement1 = (ForEachStatementSyntax)tree1.TestGetParsedFunctionStatements().Single();
     var body2 = tree2.TestGetParsedFunctionBody();
     var model = tree1.GetTestSemanticModel();
     var simplifications = ForEachToFirstLast.GetSimplifications(statement1, model, assumptions).ToArray();
     TestUtil.AssertSameSyntax(simplifications.Single().NewNode, body2);
 }
Example #22
0
 public bool IsEmpty()
 {
     return(!FixedVariables.Any() && !Assumptions.Any());
 }
Example #23
0
    public static bool? IsAnyIterationSufficient(this ForEachStatementSyntax syntax, ISemanticModel model, Assumptions assume)
    {
        Contract.Requires(syntax != null);
        Contract.Requires(model != null);

        if (!assume.IterationHasNoSideEffects) return null;

        // shouldn't depend on iterator value
        if (model.AnalyzeStatementDataFlow(syntax.Statement).ReadInside.Contains(model.GetDeclaredSymbol(syntax)))
            return null; // probably false, but uses might happen to cancel
        // always jumping out of the loop on the first iteration, and independence from iterator value, should mean equivalence
        // unless the collection iterator has side-effects... but that's bad form, so probably true
        if (syntax.IsGuaranteedToJumpOut(includeContinue: false))
            return true;
        return syntax.Statement.IsIdempotent(model, assume);
    }
Example #24
0
 public static bool? HasSideEffects(this StatementSyntax statement, ISemanticModel model, Assumptions assume)
 {
     if (statement is EmptyStatementSyntax) return false;
     var block = statement as BlockSyntax;
     if (statement is BlockSyntax) {
         if (((BlockSyntax)statement).Statements.Count == 0) return false;
         return ((BlockSyntax)statement).Statements.Select(e => e.HasSideEffects(model, assume)).Max();
     }
     if (statement is ExpressionStatementSyntax) {
         return ((ExpressionStatementSyntax)statement).Expression.HasSideEffects(model, assume);
     }
     if (statement is IfStatementSyntax) {
         var s = (IfStatementSyntax)statement;
         return new[] {
             s.Condition.HasSideEffects(model, assume),
             s.Statement.HasSideEffects(model, assume),
             s.Else == null ? false : s.Else.Statement.HasSideEffects(model, assume)
         }.Max();
     }
     return null;
 }
Example #25
0
 public static bool? HasSideEffects(this ExpressionSyntax expression, ISemanticModel model, Assumptions assume)
 {
     if (expression is IdentifierNameSyntax) return false;
     if (expression is LiteralExpressionSyntax) return false;
     if (expression is DefaultExpressionSyntax) return false;
     if (expression is MemberAccessExpressionSyntax) {
         var m = (MemberAccessExpressionSyntax)expression;
         if (!assume.PropertyGettersHaveNoSideEffects) return null;
         return m.Expression.HasSideEffects(model, assume);
     }
     if (expression is InvocationExpressionSyntax) {
         var i = (InvocationExpressionSyntax)expression;
         if (i.ArgumentList.Arguments.Any(e => e.RefOrOutKeyword != null)) return true;
         return i.ArgumentList.Arguments.Select(e => e.Expression.HasSideEffects(model, assume)).Append(i.Expression.HasSideEffects(model, assume), null).Max();
     }
     if (expression is PostfixUnaryExpressionSyntax) {
         var u = (PostfixUnaryExpressionSyntax)expression;
         var unsafeOperators = new[] { SyntaxKind.PostDecrementExpression, SyntaxKind.PostIncrementExpression };
         if (unsafeOperators.Contains(u.Kind)) return true;
         return null;
     }
     if (expression is PrefixUnaryExpressionSyntax) {
         var u = (PrefixUnaryExpressionSyntax)expression;
         var shouldBeSafeOperators = new[] {
             SyntaxKind.LogicalNotExpression,
             SyntaxKind.BitwiseNotExpression,
             SyntaxKind.NegateExpression,
         };
         var unsafeOperators = new[] { SyntaxKind.PreDecrementExpression, SyntaxKind.PreIncrementExpression };
         if (unsafeOperators.Contains(u.Kind)) return true;
         var ns = assume.OperatorsHaveNoSideEffects || _SpecialTypesWithSafeOperators.Contains(model.GetTypeInfo(u.Operand).Type.SpecialType);
         var op = ns && shouldBeSafeOperators.Contains(u.Kind)
                ? (bool?)false
                : null;
         return op.Max(u.Operand.HasSideEffects(model, assume));
     }
     if (expression is BinaryExpressionSyntax) {
         var b = (BinaryExpressionSyntax)expression;
         if (AssignmentOperatorKinds.Contains(b.Kind)) return null; //probably true, but some cases like x += 0 are fine.
         var ns = assume.OperatorsHaveNoSideEffects
             || new[] {b.Left, b.Right}.All(e => _SpecialTypesWithSafeOperators.Contains(model.GetTypeInfo(e).Type.SpecialType));
         var op = ns && ProbablySafeBinaryOperators.Contains(b.Kind)
                ? (bool?)false
                : null;
         return new[] { op, b.Left.HasSideEffects(model, assume), b.Right.HasSideEffects(model, assume) }.Max();
     }
     if (expression is ParenthesizedExpressionSyntax) {
         return ((ParenthesizedExpressionSyntax)expression).Expression.HasSideEffects(model, assume);
     }
     if (expression is ConditionalExpressionSyntax) {
         var e = (ConditionalExpressionSyntax)expression;
         return new[] { e.Condition, e.WhenTrue, e.WhenFalse }.Select(x => x.HasSideEffects(model, assume)).Max();
     }
     if (expression is ObjectCreationExpressionSyntax) {
         if (!assume.ConstructorsHaveNoSideEffects) return null;
         var e = (ObjectCreationExpressionSyntax)expression;
         return e.ArgumentList.Arguments.Select(a => a.Expression.HasSideEffects(model, assume)).Max();
     }
     return null;
 }
Example #26
0
 public static bool HasMatchingLHSOrRet(this StatementSyntax expression, StatementSyntax other, ISemanticModel model, Assumptions assume)
 {
     Contract.Requires(model != null);
     if (expression == null) return false;
     if (other == null) return false;
     if (expression.IsReturnValue() && other.IsReturnValue()) return true;
     var lhs1 = expression.TryGetLHSExpOfAssignmentOrInit();
     var lhs2 = other.TryGetLHSExpOfAssignmentOrInit();
     if (lhs1 == null || lhs2 == null) return false;
     return lhs1.IsMatchingLHS(lhs2, model, assume);
 }
Example #27
0
    private static bool? IsLastIterationSufficient_Helper2(this ExpressionSyntax syntax, ISemanticModel model, Assumptions assume, ISymbol iteratorVariable)
    {
        Contract.Requires(syntax != null);
        Contract.Requires(model != null);
        Contract.Requires(iteratorVariable != null);

        var isConst = syntax.IsConst(model);
        if (isConst == true) return true;
        if (syntax is IdentifierNameSyntax && model.GetSymbolInfo(syntax).Symbol == iteratorVariable) return true;
        return null;
    }
Example #28
0
        /// <summary>
        /// Query on Wolfram Alpha using the specified
        /// </summary>
        /// <param name="query">The query you would like to search for on Wolfram Alpha</param>
        /// <returns>The results of the query</returns>
        public QueryResult Query(string query)
        {
            //http://api.wolframalpha.com/v2/query?input=xx&appid=xxxxx
            RestRequest request = CreateRequest("query", query);

            //Output
            if (Formats.HasElements())
            {
                request.AddParameter("format", string.Join(",", Formats));
            }

            if (OutputUnit != Unit.NotSet)
            {
                request.AddParameter("units", OutputUnit.ToString().ToLower());
            }

            if (Assumptions.HasElements())
            {
                foreach (string assumption in Assumptions)
                {
                    request.AddParameter("assumption", assumption);
                }
            }

            //Filtering
            if (IncludePodIDs.HasElements())
            {
                foreach (string include in IncludePodIDs)
                {
                    request.AddParameter("includepodid", include);
                }
            }

            if (ExcludePodIDs.HasElements())
            {
                foreach (string exclude in ExcludePodIDs)
                {
                    request.AddParameter("excludepodid", exclude);
                }
            }

            if (PodTitles.HasElements())
            {
                foreach (string podTitle in PodTitles)
                {
                    request.AddParameter("podtitle", podTitle);
                }
            }

            if (PodIndex.HasElements())
            {
                request.AddParameter("podindex", string.Join(",", PodIndex));
            }

            if (Scanners.HasElements())
            {
                request.AddParameter("scanner", string.Join(",", Scanners));
            }

            //Timeout
            if (ParseTimeout >= Epsilon)
            {
                request.AddParameter("parsetimeout", ParseTimeout.ToString(_culture));
            }

            if (ScanTimeout >= Epsilon)
            {
                request.AddParameter("scantimeout", ScanTimeout.ToString(_culture));
            }

            if (PodTimeout >= Epsilon)
            {
                request.AddParameter("podtimeout", PodTimeout.ToString(_culture));
            }

            if (FormatTimeout >= Epsilon)
            {
                request.AddParameter("formattimeout", FormatTimeout.ToString(_culture));
            }

            //Async
            if (UseAsync)
            {
                request.AddParameter("async", UseAsync.ToString().ToLower());
            }

            //Location
            if (IpAddress != null)
            {
                request.AddParameter("ip", IpAddress.ToString());
            }

            if (!string.IsNullOrEmpty(Location))
            {
                request.AddParameter("location", Location);
            }

            if (GPSLocation != null)
            {
                request.AddParameter("latlong", GPSLocation.ToString());
            }

            //Size
            if (Width >= 1f)
            {
                request.AddParameter("width", Width);
            }

            if (MaxWidth >= 1f)
            {
                request.AddParameter("maxwidth", MaxWidth);
            }

            if (PlotWidth >= 1f)
            {
                request.AddParameter("plotwidth", PlotWidth);
            }

            if (Magnification >= 0.1f)
            {
                request.AddParameter("mag", Magnification.ToString(_culture));
            }

            //Misc
            if (!string.IsNullOrEmpty(Signature))
            {
                request.AddParameter("sig", Signature);
            }

            if (ReInterpret.HasValue)
            {
                request.AddParameter("reinterpret", ReInterpret.ToString().ToLower());
            }

            if (IgnoreCase.HasValue)
            {
                request.AddParameter("ignorecase", IgnoreCase.ToString().ToLower());
            }

            if (EnableTranslate.HasValue)
            {
                request.AddParameter("translation", EnableTranslate.ToString().ToLower());
            }

            QueryResult results = GetResponse <QueryResult>(request);

            return(results);
        }
Example #29
0
 public QueryExecutionTypeTest(Assumptions expected)
 {
     this._expected = expected;
 }
Example #30
0
    public static bool? IsIdempotent(this StatementSyntax syntax, ISemanticModel model, Assumptions assume)
    {
        if (syntax is EmptyStatementSyntax) return true;
        if (syntax.IsGuaranteedToJumpOut()) return true;

        if (syntax is BlockSyntax) {
            var b = (BlockSyntax)syntax;
            if (b.Statements.Count == 0) return true;
            if (b.Statements.Count == 1) return b.Statements.Single().IsIdempotent(model, assume);
            var m = syntax.Statements().Min(e => e.IsIdempotent(model, assume));
            if (m != true) return m;
            var assigned = syntax.DescendantNodes()
                           .Where(e => e.Kind == SyntaxKind.AssignExpression)
                           .Cast<BinaryExpressionSyntax>()
                           .Select(e => e.Left)
                           .ToArray();
            var assignedSymbols = assigned.Select(e => model.GetSymbolInfo(e));
            var reads = syntax.DescendantNodes()
                        .Except(assigned)
                        .Select(e => model.GetSymbolInfo(e));
            if (reads.Intersect(assignedSymbols).Any()) return null;
            return true;
        }
        if (syntax is ExpressionStatementSyntax)
            return ((ExpressionStatementSyntax)syntax).Expression.IsIdempotent(model, assume);
        return null;
    }
Example #31
0
    public static bool IsMatchingLHS(this ExpressionSyntax lhs1, ExpressionSyntax lhs2, ISemanticModel model, Assumptions assume)
    {
        Contract.Requires(lhs1 != null);
        Contract.Requires(lhs2 != null);
        Contract.Requires(model != null);

        if (lhs1.Kind != lhs2.Kind) return false;
        if (lhs1.HasSideEffects(model, assume) != false) return false;

        if (lhs1 is SimpleNameSyntax) return ((SimpleNameSyntax)lhs1).PlainName == ((SimpleNameSyntax)lhs2).PlainName;

        var s1 = model.GetSymbolInfo(lhs1);
        var s2 = model.GetSymbolInfo(lhs2);
        if (s1.Symbol != s2.Symbol) return false;

        var inv1 = lhs1 as InvocationExpressionSyntax;
        var inv2 = lhs2 as InvocationExpressionSyntax;
        if (inv1 != null) {
            return inv1.Expression.IsMatchingLHS(inv2.Expression, model, assume)
                && inv1.ArgumentList.Arguments.Count == inv2.ArgumentList.Arguments.Count
                && inv1.ArgumentList.Arguments.Zip(
                        inv2.ArgumentList.Arguments,
                        (e1, e2) => e1.NameColon == null
                                && e2.NameColon == null
                                && e1.Expression.IsMatchingLHS(e2.Expression, model, assume)
                    ).All(e => e);
        }

        if (lhs1 is MemberAccessExpressionSyntax)
            return ((MemberAccessExpressionSyntax)lhs1).Expression.IsMatchingLHS(((MemberAccessExpressionSyntax)lhs2).Expression, model, assume);

        return false;
    }
Example #32
0
    public static bool? IsIdempotent(this ExpressionSyntax syntax, ISemanticModel model, Assumptions assume)
    {
        if (syntax is ParenthesizedExpressionSyntax) return ((ParenthesizedExpressionSyntax)syntax).Expression.IsIdempotent(model, assume);
        if (syntax is IdentifierNameSyntax) return true;
        if (syntax is InvocationExpressionSyntax) return null;
        if (syntax is MemberAccessExpressionSyntax) {
            var m = (MemberAccessExpressionSyntax)syntax;
            if (!assume.PropertyGettersHaveNoSideEffects) return null;
            return m.Expression.IsIdempotent(model, assume);
        };
        if (syntax.Kind == SyntaxKind.AssignExpression) {
            var b = (BinaryExpressionSyntax)syntax;
            if (b.Left is IdentifierNameSyntax) {
                var effects = b.Right.HasSideEffects(model, assume);
                if (effects == false) return true;
            }
            return null;
        } else if (AssignmentOperatorKinds.Contains(syntax.Kind)) {
            return null;
        }

        var isConst = syntax.IsConst(model);
        if (isConst == true) return true;

        return null;
    }
Example #33
0
    public static bool? IsLastIterationSufficient(this ForEachStatementSyntax syntax, ISemanticModel model, Assumptions assume)
    {
        Contract.Requires(syntax != null);
        Contract.Requires(model != null);

        if (!assume.IterationHasNoSideEffects) return null;

        // any iteration works? then so does the last one
        var anyIsGood = syntax.IsAnyIterationSufficient(model, assume);
        if (anyIsGood == true) return true;

        if (syntax.DescendantNodes(e => e is StatementSyntax).Any(e => e is BreakStatementSyntax || e is ReturnStatementSyntax || e is ThrowStatementSyntax))
            return null; //loop might end before last iteration

        return syntax.Statement.IsLastIterationSufficient_Helper(model, assume, model.GetDeclaredSymbol(syntax));
    }
Example #34
0
    public static bool? IsFirstIterationSufficient(this ForEachStatementSyntax syntax, ISemanticModel model, Assumptions assume)
    {
        Contract.Requires(syntax != null);
        Contract.Requires(model != null);

        if (!assume.IterationHasNoSideEffects) return null;

        // always breaks outs? then only the first iteration CAN happen
        if (syntax.Statement.IsGuaranteedToJumpOut(includeContinue: false)) return true;

        // any iteration works? then so does the first one
        var anyIsGood = syntax.IsAnyIterationSufficient(model, assume);
        if (anyIsGood == true) return true;

        return null;
    }
Example #35
0
 private static object[] Verify(Assumptions assumptions)
 {
     return(new object[] { assumptions });
 }