public void ConditionalStatementProducesIfWithEmptyThen()
        {
            var c = new ConditionalStatement();
            c.Condition = JS.Id("a");

            Assert.AreEqual("if(a);", c.ToString());
        }
Пример #2
0
        private bool ReplaceChainedShortCircuitBooleanPattern(List <IStatement> statements, int i)
        {
            ConditionalStatement conditionalStatement = (ConditionalStatement)statements[i];

            if (!this.ReplaceShortCircuitPattern(statements, i + 1))
            {
                if (!this.ReplaceShortCircuitPatternCreatedByCCI2(statements, i + 1))
                {
                    return(false);
                }
            }
            //if (!this.ReplaceShortCircuitPattern(statements, i+1)) return false;
            PushStatement /*?*/ push = statements[i + 1] as PushStatement;

            if (push == null)
            {
                return(false);
            }
            Conditional /*?*/ chainedConditional = push.ValueToPush as Conditional;

            if (chainedConditional == null)
            {
                return(false);
            }

            return(this.ReplaceShortCircuitPattern(statements, i));
        }
Пример #3
0
        public IStatement GenerateIf(FieldDefinition field, List <int> toStateIds, Epa epa, Dictionary <State, int> stateNumberMap)
        {
            var toStates = new List <State>();

            foreach (var kvp in stateNumberMap)
            {
                var id    = kvp.Value;
                var state = kvp.Key;
                if (toStateIds.Contains(id))
                {
                    toStates.Add(state);
                }
            }

            var conditions = GenerateStatesConditions(toStates);

            var stmt = new AssignmentGenerator().GenerateAssign(field, toStateIds[0]);

            for (var i = 1; i < toStateIds.Count; ++i)
            {
                stmt = new ConditionalStatement
                {
                    Condition   = conditions[i],
                    TrueBranch  = new AssignmentGenerator().GenerateAssign(field, toStateIds[i]),
                    FalseBranch = stmt
                };
            }
            return(stmt);
        }
Пример #4
0
        public void ConditionalStatementProducesIfWithEmptyThen()
        {
            var c = new ConditionalStatement();

            c.Condition = JS.Id("a");

            Assert.AreEqual("if(a);", c.ToString());
        }
        public void ConditionalStatementProducesIfThenElseIfThenElse()
        {
            var c1 = JS.If(a).Then(JS.Return(a));
            var c2 = new ConditionalStatement(JS.Not(a), null, null);
            c2.Parent = c1;
            c2.ThenStatement = JS.Return();
            c2.ElseStatement = JS.Return();

            Assert.AreEqual("if(a)return a; else if(!a)return; else return;", c2.ToString());
        }
Пример #6
0
        public void ConditionalStatementHelpersRequireStatement()
        {
            ConditionalStatement statement = null;

            Expect.Throw <ArgumentNullException>(() => statement.Then());
            Expect.Throw <ArgumentNullException>(() => statement.Then(new List <Statement>()));
            Expect.Throw <ArgumentNullException>(() => statement.Else());
            Expect.Throw <ArgumentNullException>(() => statement.Else(new List <Statement>()));
            Expect.Throw <ArgumentNullException>(() => statement.ElseIf(null));
        }
Пример #7
0
        private static void TestDeterminedLastElseClause(IfStatementSyntax conditionalNode, bool expected)
        {
            Assert.IsNotNull(conditionalNode, "Found node should be of type `{0}`!",
                             typeof(IfStatementSyntax).Name);

            ConditionalStatement conditionalStatement = new ConditionalStatement(conditionalNode);
            bool lastElsePresent = conditionalStatement.HasElseBlock;

            Assert.AreEqual(expected, lastElsePresent, "Expected last ELSE clause presence does not match!");
        }
Пример #8
0
        private static void TestRetrievedNumberOfBodies(IfStatementSyntax conditionalNode, int expected)
        {
            Assert.IsNotNull(conditionalNode, "Found node should be of type `{0}`!",
                             typeof(IfStatementSyntax).Name);

            ConditionalStatement conditionalStatement = new ConditionalStatement(conditionalNode);
            int blocksNumber = conditionalStatement.BlocksNumber;

            Assert.AreEqual(expected, blocksNumber, "Number of retrieved blocks does not match!");
        }
        /// <summary>
        /// Factory method for class <see cref="ConditionalStatementASTWalker"/>.
        /// </summary>
        /// <param name="node"><see cref="CSharpSyntaxNode"/> Used to initialize the walker.</param>
        /// <param name="semanticModel">The semantic model.</param>
        /// <returns></returns>
        public static ConditionalStatementASTWalker Create(CSharpSyntaxNode node, SemanticModel semanticModel = null)
        {
            // TODO: Use TranslationUnitFactory in order to have AST walkers decoupled from helpers
            //       via factories (which will be using helpers)

            ConditionalStatement helper = new ConditionalStatement(node as IfStatementSyntax);

            var statement = ConditionalStatementTranslationUnit.Create(helper.BlocksNumber, helper.HasElseBlock);

            return(new ConditionalStatementASTWalker(node, statement, semanticModel));
        }
Пример #10
0
        public void ConditionalStatementProducesIfThenElseIfThenElse()
        {
            var c1 = JS.If(a).Then(JS.Return(a));
            var c2 = new ConditionalStatement(JS.Not(a), null, null);

            c2.Parent        = c1;
            c2.ThenStatement = JS.Return();
            c2.ElseStatement = JS.Return();

            Assert.AreEqual("if(a)return a; else if(!a)return; else return;", c2.ToString());
        }
Пример #11
0
        private static void UpdateConditionalStatement(ConditionalStatement stmt)
        {
            var builder = (BoundSpillSequenceBuilder)stmt.Condition;

            Debug.Assert(stmt.ParentNode.NodeType == NodeType.Block);
            Debug.Assert(builder.Value.ExpressionType == My <TypeSystemServices> .Instance.BoolType);
            var spills     = new Block(builder.GetStatements().ToArray());
            var statements = ((Block)stmt.ParentNode).Statements;

            statements.Insert(statements.IndexOf(stmt), spills);
            stmt.Condition = builder.Value;
        }
Пример #12
0
        void OrlyStatement(out Statement stat)
        {
            ConditionalStatement cs = new ConditionalStatement(GetPragma(la)); stat = cs; ConditionalStatement cur = cs; Statement st; Expression e; cs.condition = new VariableLValue(GetPragma(la), GetVariable("IT"));

            Expect(33);
            Expect(34);
            Expect(23);
            SetEndPragma(cs);
            while (la.kind == 5)
            {
                Get();
            }
            if (la.kind == 35)
            {
                Get();
                Expect(34);
                while (la.kind == 5)
                {
                    Get();
                }
            }
            BeginScope();
            Statements(out cs.trueStatements);
            EndScope();
            while (la.kind == 36)
            {
                Get();
                cur.falseStatements = new ConditionalStatement(GetPragma(la));
                Expression(out e);
                (cur.falseStatements as ConditionalStatement).condition = e; SetEndPragma(cur.falseStatements); cur = (ConditionalStatement)cur.falseStatements; BeginScope();
                while (la.kind == 5)
                {
                    Get();
                }
                Statements(out cur.trueStatements);
                EndScope();
            }
            if (la.kind == 37)
            {
                Get();
                Expect(38);
                while (la.kind == 5)
                {
                    Get();
                }
                BeginScope();
                Statements(out cur.falseStatements);
                EndScope();
            }
            Expect(39);
        }
Пример #13
0
        /// <summary>
        /// Génère le code pour des statements conditionnels.
        /// </summary>
        /// <param name="statement"></param>
        /// <returns></returns>
        string GenerateConditionalStatement(ConditionalStatement statement)
        {
            StringBuilder builder = new StringBuilder();

            switch (statement.StatementType)
            {
            case ConditionalStatement.Type.If:
                builder.Append("if");
                break;

            case ConditionalStatement.Type.Elsif:
                builder.Append("else if");
                break;

            case ConditionalStatement.Type.Else:
                builder.Append("else");
                break;

            case ConditionalStatement.Type.While:
                builder.Append("while");
                break;

            default:
                throw new NotImplementedException();
            }

            // Ajout de la condition
            if (statement.StatementType != ConditionalStatement.Type.Else)
            {
                builder.Append("(");
                builder.Append(GenerateEvaluable(statement.Condition));
                builder.Append(")");
            }

            // Ajout du code
            builder.Append("\r\n{\r\n");
            foreach (Instruction inst in statement.Code)
            {
                builder.Append(Tools.StringUtils.Indent(GenerateInstruction(inst)));
            }
            builder.Append("\r\n}\r\n");

            return(builder.ToString());
        }
Пример #14
0
        public override IStatement VisitIfStatement(IfStatementSyntax node)
        {
            var e        = this.expressionVisitor.Visit(node.Condition);
            var thenStmt = this.Visit(node.Statement);
            var cond     = new ConditionalStatement()
            {
                Condition  = e,
                Locations  = Helper.SourceLocation(this.tree, node), //.Condition),
                TrueBranch = thenStmt,
            };
            IStatement elseStmt = new EmptyStatement();

            if (node.Else != null)
            {
                elseStmt = this.Visit(node.Else);
            }
            cond.FalseBranch = elseStmt;
            return(cond);
        }
Пример #15
0
        public override void RewriteChildren(ConditionalStatement conditionalStatement)
        {
            // exactly the same code as the base visitor. just need to reset stack
            // depth for each branch.

            this.RewriteChildren((Statement)conditionalStatement);

            conditionalStatement.Condition = this.Rewrite(conditionalStatement.Condition);

            var savedInThenBranch = this.inThenBranch;
            var savedInElseBranch = this.inElseBranch;

            this.inThenBranch = true;
            this.inElseBranch = false;

            var savedThenBranchPushes = this.thenBranchPushes;

            this.thenBranchPushes = new Dictionary <int, Assignment>();

            var savedStack = Copy(this.locals);

            conditionalStatement.TrueBranch = this.Rewrite(conditionalStatement.TrueBranch);
            var stackAfterTrue = Copy(this.locals);

            this.locals       = Copy(savedStack);
            this.inThenBranch = false;
            this.inElseBranch = true;
            conditionalStatement.FalseBranch = this.Rewrite(conditionalStatement.FalseBranch);

            Contract.Assume(stackAfterTrue.Count == this.locals.Count);
            // and that the things pushed in both branches are type-compatible
            // (one branch might push a bool and the other an int)

            // continuing on with the stack being the one from the else-branch.
            // is that okay? should it be the one from the then-branch?
            // currently it is important that it is the one from the else-branch
            // because of the fixup code in Rewrite(IPushStatement) that deals
            // with the bool/int confusion

            this.inThenBranch     = savedInThenBranch;
            this.inElseBranch     = savedInElseBranch;
            this.thenBranchPushes = savedThenBranchPushes;
        }
Пример #16
0
        // i   :  loc := e0;
        // i+1 :  if (loc) S0; else S1;
        //
        //  ==>
        //
        //        if (e0) S0; else S1;
        //
        // and delete statement i
        //
        // This is done only if loc is in this.branchConditionLocals
        //
        private void FindPattern(List <IStatement> statements)
        {
            for (int i = 0; i < statements.Count - 1; i++)
            {
                IExpressionStatement /*?*/ expressionStatement = statements[i] as IExpressionStatement;
                if (expressionStatement == null)
                {
                    continue;
                }
                IAssignment /*?*/ assignmentStatement = expressionStatement.Expression as IAssignment;
                if (assignmentStatement == null)
                {
                    continue;
                }
                if (assignmentStatement.Source is Pop)
                {
                    continue;
                }
                ILocalDefinition /*?*/ localDefinition = assignmentStatement.Target.Definition as ILocalDefinition;
                if (localDefinition == null)
                {
                    continue;
                }
                if (localDefinition.Type.TypeCode != PrimitiveTypeCode.Boolean)
                {
                    continue;                                                     // cheaper test than looking in the table
                }
                if (!this.branchConditionLocals.ContainsKey(localDefinition))
                {
                    continue;
                }

                IConditionalStatement /*?*/ conditional = statements[i + 1] as IConditionalStatement;
                if (conditional == null)
                {
                    continue;
                }
                BoundExpression /*?*/ boundExpression = conditional.Condition as BoundExpression;
                if (boundExpression == null)
                {
                    continue;
                }
                ILocalDefinition /*?*/ localDefinition2 = boundExpression.Definition as ILocalDefinition;
                if (localDefinition2 == null)
                {
                    continue;
                }
                if (localDefinition != localDefinition2)
                {
                    continue;
                }

                var newLocs = new List <ILocation>(expressionStatement.Locations);
                newLocs.AddRange(conditional.Locations);

                statements[i + 1] = new ConditionalStatement()
                {
                    Condition   = assignmentStatement.Source,
                    TrueBranch  = conditional.TrueBranch,
                    FalseBranch = conditional.FalseBranch,
                    Locations   = newLocs,
                };
                this.sourceMethodBody.numberOfAssignments[localDefinition]--;
                this.sourceMethodBody.numberOfReferences[localDefinition]--;

                statements.RemoveAt(i);
            }
        }
Пример #17
0
        /*
         * public static T First<T>(this List<T> available, string query){
         *      ConditionalStatement statement = Parse(query);
         *      if (statement == null)
         *              return available.PopLast();
         *      List<T> candidates = new List<T>(available.Where(o => statement.Evaluate(o)));
         *      return (candidates.Count > 0) ? candidates.PopLast() : available.PopLast();
         * }
         */

        /// <summary>
        /// Parse the input string s and extracts the conditional statement contained within
        /// </summary>
        /// <param name="s">The string to evaluate or null if the parsing failed.</param>
        public static ConditionalStatement Parse(string s)
        {
            // This far, unary operators and parentheses are not supported

            char type;
            ConditionalStatement statement = new ConditionalStatement();
            int    cc  = 0;
            int    bcc = cc;
            string next;

            // STEP 1: Read first element.
            next = ReadNext(s, ref cc, out type);
            // There are three valid options: identifier, unary and end $
            // Identifier resets cc and goes to Condition.Parse
            // Unary writes the operator in statement and expects Condition
            // Whatever other option has the same effect of end: terminate (return null).
            switch (type)
            {
            case 'i':
                cc          = bcc;
                statement.A = Condition.Parse(s, ref cc);
                break;

            case 'u':
                statement.Operator = next;
                statement.A        = Condition.Parse(s, ref cc);
                // As an unary operator works as a whole statement, the statement
                // is stacked and left clean.
                statement = new ConditionalStatement()
                {
                    A = statement
                };
                break;

            default:
                return(null);
            }

            while (cc < s.Length)
            {
                // STEP 2: Whatever happened before, either $ or a binary operator is expected;
                // Again, any other option works like end: termination (return null).
                next = ReadNext(s, ref cc, out type);
                if (type != 'b')
                {
                    return(statement);
                }
                statement.Operator = next;

                // STEP 3: Read second element.
                bcc  = cc;
                next = ReadNext(s, ref cc, out type);
                // Again, there are three valid options: identifier, unary and end $
                // Identifier resets cc and goes to Condition.Parse
                // Unary writes the operator in statement and expects Condition
                // Whatever other option has the same effect of end: terminate (return null).
                switch (type)
                {
                case 'i':
                    cc          = bcc;
                    statement.B = Condition.Parse(s, ref cc);
                    break;

                case 'u':
                    // As an unary operator works as a whole statement, another statement
                    // the negated conditional is stored as a statement within B
                    statement.B =
                        new ConditionalStatement()
                    {
                        Operator = next,
                        A        = Condition.Parse(s, ref cc)
                    };
                    break;

                default:
                    return(statement);
                }

                // The statement is complete, it is now stacked and we return to STEP 2;
                statement = new ConditionalStatement()
                {
                    A = statement
                };
            }
            return(statement);
        }
        public override void RewriteChildren(ConditionalStatement conditionalStatement)
        {
            base.RewriteChildren(conditionalStatement);
            var trueBlock = conditionalStatement.TrueBranch as BlockStatement;

            if (trueBlock == null || trueBlock.Statements.Count != 1)
            {
                return;
            }
            if (!(conditionalStatement.FalseBranch is IEmptyStatement))
            {
                return;
            }
            var equals = conditionalStatement.Condition as IEquality;

            if (equals == null || !(equals.RightOperand is IDefaultValue))
            {
                return;
            }
            var binding = equals.LeftOperand as IBoundExpression;

            if (binding == null)
            {
                return;
            }
            var exprStat = trueBlock.Statements[0] as IExpressionStatement;

            if (exprStat == null)
            {
                return;
            }
            var assignment = exprStat.Expression as IAssignment;

            if (assignment == null)
            {
                return;
            }
            var anonDel = assignment.Source as AnonymousDelegate;

            if (anonDel == null)
            {
                return;
            }
            if (!TypeHelper.TypesAreEquivalent(assignment.Type, binding.Type))
            {
                return;
            }
            var local = binding.Definition as LocalDefinition;

            if (local != null)
            {
                //Unfortunately the C# compiler does not mark such locals as being compiler generated.
                //So we'll use a heuristic to try and prevent us from deleting user written code.
                //The local should be (optionally) initialized to null and then assign the anonymous delegate
                uint numAssigns;
                if (!this.numberOfAssignmentsToLocal.TryGetValue(local, out numAssigns) || numAssigns > 2)
                {
                    return;
                }
                //The local should be tested for null and then used one more time to get the non-null value.
                uint numRefs;
                if (!this.numberOfReferencesToLocal.TryGetValue(local, out numRefs) || numRefs != 2)
                {
                    return;
                }
                if (this.delegatesCachedInLocals == null)
                {
                    this.delegatesCachedInLocals = new Hashtable <LocalDefinition, AnonymousDelegate>();
                }
                this.delegatesCachedInLocals.Add(local, anonDel);
            }
        }
Пример #19
0
 private Statement ParseIf(TokenSet followers)
   //^ requires this.currentToken == Token.If;
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   SourceLocationBuilder slb = new SourceLocationBuilder(this.scanner.CurrentSourceLocation);
   this.GetNextToken();
   Expression ifCondition = this.ParseExpression(followers|Token.Else|Token.EndIf|Parser.StatementStart|Token.EndOfLine);
   this.Skip(Token.EndOfLine);
   BlockStatement ifTrue = this.ParseStatementBlock(followers|Token.Else|Token.EndIf);
   Statement ifFalse;
   if (this.currentToken == Token.Else) {
     this.GetNextToken();
     this.Skip(Token.EndOfLine);
     ifFalse = this.ParseStatementBlock(followers|Token.EndIf);
   } else {
     ifFalse = new EmptyStatement(false, this.scanner.CurrentSourceLocation);
   }
   slb.UpdateToSpan(this.scanner.CurrentSourceLocation);
   Statement result = new ConditionalStatement(ifCondition, ifTrue, ifFalse, slb);
   this.SkipClosingKeyword(Token.EndIf, followers);
   return result;
 }
Пример #20
0
 private Statement ParseGoto(TokenSet followers)
   //^ requires this.currentToken == Token.Goto;
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   SourceLocationBuilder slb = new SourceLocationBuilder(this.scanner.CurrentSourceLocation);
   this.GetNextToken();
   SimpleName targetLabel = this.ParseSimpleName(followers|Token.EndOfLine|Token.If);
   Statement result = new GotoStatement(targetLabel, slb);
   slb.UpdateToSpan(targetLabel.SourceLocation);
   if (this.currentToken == Token.If) {
     this.GetNextToken();
     slb = new SourceLocationBuilder(slb.GetSourceLocation());
     Expression condition = this.ParseExpression(followers|Token.EndOfLine);
     slb.UpdateToSpan(condition.SourceLocation);
     result = new ConditionalStatement(condition, result, new EmptyStatement(false, this.scanner.CurrentSourceLocation), slb);
   }
   this.SkipOverTo(Token.EndOfLine, followers);
   return result;
 }
Пример #21
0
        public void ConditionalStatementProducesErrorWithMissingCondition()
        {
            var c = new ConditionalStatement();

            Expect.Throw <InvalidOperationException>(() => c.ToString());
        }
Пример #22
0
            public override void TraverseChildren(IMethodCall methodCall)
            {
                var resolvedMethod = Sink.Unspecialize(methodCall.MethodToCall).ResolvedMethod;

                var methodName = Microsoft.Cci.MemberHelper.GetMethodSignature(resolvedMethod);

                if (methodName.Equals("System.Object.GetHashCode") || methodName.Equals("System.Object.ToString"))
                {
                    base.TraverseChildren(methodCall);
                    return;
                }

                bool isEventAdd    = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("add_");
                bool isEventRemove = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("remove_");

                if (isEventAdd || isEventRemove)
                {
                    base.TraverseChildren(methodCall);
                    return;
                }

                if (!methodCall.IsVirtualCall)
                {
                    base.TraverseChildren(methodCall);
                    return;
                }
                var containingType = TypeHelper.UninstantiateAndUnspecialize(methodCall.MethodToCall.ContainingType);
                List <ITypeReference> subTypesOfContainingType;

                if (!this.subTypes.TryGetValue(containingType, out subTypesOfContainingType))
                {
                    base.TraverseChildren(methodCall);
                    return;
                }
                Contract.Assert(0 < subTypesOfContainingType.Count);
                Contract.Assert(!methodCall.IsStaticCall);
                Contract.Assert(!resolvedMethod.IsConstructor);
                var  overrides = FindOverrides(containingType, resolvedMethod);
                bool same      = true;

                foreach (var o in overrides)
                {
                    IMethodDefinition resolvedOverride = Sink.Unspecialize(o.Item2).ResolvedMethod;
                    if (resolvedOverride != resolvedMethod)
                    {
                        same = false;
                    }
                }
                if (!(containingType.ResolvedType.IsInterface) && (0 == overrides.Count || same))
                {
                    base.TraverseChildren(methodCall);
                    return;
                }

                Contract.Assume(1 <= overrides.Count);

                var getType = new Microsoft.Cci.MethodReference(
                    this.sink.host,
                    this.sink.host.PlatformType.SystemObject,
                    CallingConvention.HasThis,
                    this.sink.host.PlatformType.SystemType,
                    this.sink.host.NameTable.GetNameFor("GetType"), 0);
                var op_Type_Equality = new Microsoft.Cci.MethodReference(
                    this.sink.host,
                    this.sink.host.PlatformType.SystemType,
                    CallingConvention.Default,
                    this.sink.host.PlatformType.SystemBoolean,
                    this.sink.host.NameTable.GetNameFor("op_Equality"),
                    0,
                    this.sink.host.PlatformType.SystemType,
                    this.sink.host.PlatformType.SystemType);

                // Depending on whether the method is a void method or not
                // Turn into expression:
                //   (o.GetType() == typeof(T1)) ? ((T1)o).M(...) : ( (o.GetType() == typeof(T2)) ? ((T2)o).M(...) : ...
                // Or turn into statements:
                //   if (o.GetType() == typeof(T1)) ((T1)o).M(...) else if ...
                var        turnIntoStatements = resolvedMethod.Type.TypeCode == PrimitiveTypeCode.Void;
                IStatement elseStatement      = null;

                IExpression elseValue = new MethodCall()
                {
                    Arguments     = new List <IExpression>(methodCall.Arguments),
                    IsStaticCall  = false,
                    IsVirtualCall = false,
                    MethodToCall  = methodCall.MethodToCall,
                    ThisArgument  = methodCall.ThisArgument,
                    Type          = methodCall.Type,
                };

                if (turnIntoStatements)
                {
                    elseStatement = new ExpressionStatement()
                    {
                        Expression = elseValue,
                    }
                }
                ;

                Conditional          ifConditional = null;
                ConditionalStatement ifStatement   = null;

                foreach (var typeMethodPair in overrides)
                {
                    var t = typeMethodPair.Item1;
                    var m = typeMethodPair.Item2;

                    if (m.IsGeneric)
                    {
                        var baseMethod = m.ResolvedMethod;
                        m = new GenericMethodInstanceReference()
                        {
                            CallingConvention = baseMethod.CallingConvention,
                            ContainingType    = baseMethod.ContainingTypeDefinition,
                            GenericArguments  = new List <ITypeReference>(IteratorHelper.GetConversionEnumerable <IGenericMethodParameter, ITypeReference>(baseMethod.GenericParameters)),
                            GenericMethod     = baseMethod,
                            InternFactory     = this.sink.host.InternFactory,
                            Name       = baseMethod.Name,
                            Parameters = baseMethod.ParameterCount == 0 ? null : new List <IParameterTypeInformation>(baseMethod.Parameters),
                            Type       = baseMethod.Type,
                        };
                    }

                    var cond = new MethodCall()
                    {
                        Arguments = new List <IExpression>()
                        {
                            new MethodCall()
                            {
                                Arguments     = new List <IExpression>(),
                                IsStaticCall  = false,
                                IsVirtualCall = false,
                                MethodToCall  = getType,
                                ThisArgument  = methodCall.ThisArgument,
                            },
                            new TypeOf()
                            {
                                TypeToGet = t,
                            },
                        },
                        IsStaticCall  = true,
                        IsVirtualCall = false,
                        MethodToCall  = op_Type_Equality,
                        Type          = this.sink.host.PlatformType.SystemBoolean,
                    };
                    Expression thenValue = new MethodCall()
                    {
                        Arguments     = new List <IExpression>(methodCall.Arguments),
                        IsStaticCall  = false,
                        IsVirtualCall = false,
                        MethodToCall  = m,
                        ThisArgument  = methodCall.ThisArgument,
                        Type          = m.Type,
                    };
                    thenValue = new Conversion()
                    {
                        Type = m.Type,
                        TypeAfterConversion = methodCall.Type,
                        ValueToConvert      = thenValue,
                    };
                    if (turnIntoStatements)
                    {
                        ifStatement = new ConditionalStatement()
                        {
                            Condition   = cond,
                            FalseBranch = elseStatement,
                            TrueBranch  = new ExpressionStatement()
                            {
                                Expression = thenValue,
                            },
                        };
                        elseStatement = ifStatement;
                    }
                    else
                    {
                        ifConditional = new Conditional()
                        {
                            Condition     = cond,
                            ResultIfFalse = elseValue,
                            ResultIfTrue  = thenValue,
                        };
                        elseValue = ifConditional;
                    }
                }
                if (turnIntoStatements)
                {
                    Contract.Assume(ifStatement != null);
                    this.StmtTraverser.Traverse(ifStatement);
                }
                else
                {
                    Contract.Assume(ifConditional != null);
                    base.Traverse(ifConditional);
                }

                return;
            }
Пример #23
0
 void OrlyStatement(out Statement stat)
 {
     ConditionalStatement cs = new ConditionalStatement(GetPragma(la)); stat = cs; ConditionalStatement cur = cs; Statement st; Expression e; cs.condition = new VariableLValue(GetPragma(la), GetVariable("IT"));
     Expect(33);
     Expect(34);
     Expect(23);
     SetEndPragma(cs);
     while (la.kind == 5) {
     Get();
     }
     if (la.kind == 35) {
     Get();
     Expect(34);
     while (la.kind == 5) {
         Get();
     }
     }
     BeginScope();
     Statements(out cs.trueStatements);
     EndScope();
     while (la.kind == 36) {
     Get();
     cur.falseStatements = new ConditionalStatement(GetPragma(la));
     Expression(out e);
     (cur.falseStatements as ConditionalStatement).condition = e; SetEndPragma(cur.falseStatements); cur = (ConditionalStatement)cur.falseStatements; BeginScope();
     while (la.kind == 5) {
         Get();
     }
     Statements(out cur.trueStatements);
     EndScope();
     }
     if (la.kind == 37) {
     Get();
     Expect(38);
     while (la.kind == 5) {
         Get();
     }
     BeginScope();
     Statements(out cur.falseStatements);
     EndScope();
     }
     Expect(39);
 }
Пример #24
0
 private Statement ParseIf(TokenSet followers)       
   //^ requires this.currentToken == Token.If;
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   SourceLocationBuilder slb = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken);
   this.GetNextToken();
   Expression ifCondition = this.ParseParenthesizedExpression(false, followers|Parser.StatementStart);
   Statement ifTrue = this.ParseStatement(followers|Token.Else);
   if (ifTrue is EmptyStatement)
     this.HandleError(ifTrue.SourceLocation, Error.PossibleMistakenNullStatement);
   Statement ifFalse;
   if (this.currentToken == Token.Else) {
     this.GetNextToken();
     ifFalse = this.ParseStatement(followers);
     if (ifFalse is EmptyStatement)
       this.HandleError(ifFalse.SourceLocation, Error.PossibleMistakenNullStatement);
   } else {
     ifFalse = new EmptyStatement(false, ifTrue.SourceLocation);
   }
   slb.UpdateToSpan(ifFalse.SourceLocation);
   Statement result = new ConditionalStatement(ifCondition, ifTrue, ifFalse, slb);
   this.SkipTo(followers);
   return result;
 }
Пример #25
0
        /// <summary>
        /// Finds the following pattern:
        /// i   :  c ? A : B; // either A or B must be an empty statement and the other is "goto L1;"
        /// i+1 :  push x;
        /// i+2 :  goto L2;
        /// i+3 :  Block1
        ///        0  : L1;
        ///        1  : push y;
        ///        2  : goto L2;
        ///        3  : Block2
        ///             0 : whatever (but presumably it is the label L2)
        ///
        /// Transforms it into:
        /// i   : push d ? X : Y;
        /// i+1 : goto L1;
        /// i+2 : Block 2
        ///
        /// Where if A is the empty statement,
        ///   d == c, X == x, Y == y
        /// If B is the empty statement and y is zero
        ///   d == !c, X == x, Y == y
        /// If B is the empty statement and y is not zero
        ///   d == c, X == y, Y == x
        /// And Block1 is deleted from the list.
        /// </summary>
        private bool ReplaceShortCircuitPatternCreatedByCCI2(List <IStatement> statements, int i)
        {
            if (i > statements.Count - 4)
            {
                return(false);
            }
            ConditionalStatement /*?*/ conditionalStatement = statements[i] as ConditionalStatement;

            if (conditionalStatement == null)
            {
                return(false);
            }
            PushStatement /*?*/ push1 = statements[i + 1] as PushStatement;

            if (push1 == null)
            {
                return(false);
            }
            GotoStatement /*?*/ Goto = statements[i + 2] as GotoStatement;

            if (Goto == null)
            {
                return(false);
            }
            BasicBlock /*?*/ block1 = statements[i + 3] as BasicBlock;

            if (block1 == null)
            {
                return(false);
            }
            if (block1.Statements.Count < 4)
            {
                return(false);
            }
            LabeledStatement /*?*/ label = block1.Statements[0] as LabeledStatement;

            if (label == null)
            {
                return(false);
            }
            List <IGotoStatement> branchesToThisLabel;

            if (this.predecessors.TryGetValue(label, out branchesToThisLabel))
            {
                if (1 < branchesToThisLabel.Count)
                {
                    return(false);
                }
            }
            // TODO? Should we make sure that one of the branches in the conditionalStatement is
            // to label?
            PushStatement /*?*/ push2 = block1.Statements[1] as PushStatement;

            if (push2 == null)
            {
                return(false);
            }
            GotoStatement /*?*/ Goto2 = block1.Statements[2] as GotoStatement;

            if (Goto2 == null)
            {
                return(false);
            }
            if (Goto.TargetStatement != Goto2.TargetStatement)
            {
                return(false);
            }
            BasicBlock /*?*/ block2 = block1.Statements[3] as BasicBlock;

            if (block2 == null)
            {
                return(false);
            }
            if (conditionalStatement.TrueBranch is EmptyStatement)
            {
                Conditional conditional = new Conditional();
                conditional.Condition     = conditionalStatement.Condition;
                conditional.ResultIfTrue  = push1.ValueToPush;
                conditional.ResultIfFalse = push2.ValueToPush;
                conditional.Type          = TypeHelper.MergedType(TypeHelper.StackType(conditional.ResultIfTrue.Type), TypeHelper.StackType(conditional.ResultIfFalse.Type));
                push1.ValueToPush         = conditional;
                push1.Locations           = conditionalStatement.Locations;
                statements[i]             = push1;
                statements[i + 1]         = statements[i + 2]; // move the goto up
                statements[i + 2]         = block2;
                statements.RemoveRange(i + 3, 1);
                return(true);
            }
            if (conditionalStatement.FalseBranch is EmptyStatement)
            {
                Conditional conditional = new Conditional();
                if (ExpressionHelper.IsIntegralZero(push2.ValueToPush))
                {
                    conditional.Condition     = InvertCondition(conditionalStatement.Condition);
                    conditional.ResultIfTrue  = push1.ValueToPush;
                    conditional.ResultIfFalse = push2.ValueToPush;
                }
                else
                {
                    conditional.Condition     = conditionalStatement.Condition;
                    conditional.ResultIfTrue  = push2.ValueToPush;
                    conditional.ResultIfFalse = push1.ValueToPush;
                }
                conditional.Locations = conditionalStatement.Locations;
                conditional.Type      = TypeHelper.MergedType(TypeHelper.StackType(conditional.ResultIfTrue.Type), TypeHelper.StackType(conditional.ResultIfFalse.Type));
                push1.ValueToPush     = conditional;
                push1.Locations       = conditionalStatement.Locations;
                statements[i]         = push1;
                statements[i + 1]     = statements[i + 2]; // move the goto up
                statements[i + 2]     = block2;
                statements.RemoveRange(i + 3, 1);
                return(true);
            }
            return(false);
        }
Пример #26
0
        private void DecompileIfThenElseStatement(BasicBlock b, int i)
        {
            List <IStatement>          statements           = b.Statements;
            ConditionalStatement /*?*/ conditionalStatement = statements[i++] as ConditionalStatement;

            if (conditionalStatement == null)
            {
                return;
            }
            IExpression         condition;
            var                 trueBranch    = UnwrapSingletonBlock(conditionalStatement.TrueBranch);
            GotoStatement /*?*/ gotoAfterThen = trueBranch as GotoStatement;

            if (gotoAfterThen == null)
            {
                gotoAfterThen = UnwrapSingletonBlock(conditionalStatement.FalseBranch) as GotoStatement;
                if (gotoAfterThen == null || !(trueBranch is EmptyStatement))
                {
                    return;
                }
                condition = conditionalStatement.Condition;
            }
            else
            {
                if (!(conditionalStatement.FalseBranch is EmptyStatement))
                {
                    return;
                }
                LogicalNot not = new LogicalNot();
                not.Operand = conditionalStatement.Condition;
                condition   = not;
            }
            //At this point we have:
            //if (!condition) goto afterThen;
            var afterThen = this.FindLabeledStatement(statements, i, gotoAfterThen.TargetStatement.Label);

            if (afterThen == null)
            {
                return;
            }
            List <IGotoStatement> branchesToThisLabel;

            if (this.predecessors.TryGetValue(afterThen, out branchesToThisLabel))
            {
                branchesToThisLabel.Remove(gotoAfterThen);
            }
            BasicBlock          ifBlock   = this.ExtractBasicBlockUpto(b, i, afterThen);
            GotoStatement /*?*/ gotoEndif = this.RemoveAndReturnLastGotoStatement(ifBlock);

            this.Traverse(ifBlock);
            BasicBlock elseBlock = null;

            if (gotoEndif != null)
            {
                var endif = this.FindLabeledStatement(statements, i, gotoEndif.TargetStatement.Label);
                if (endif != null)
                {
                    if (this.predecessors.TryGetValue(gotoEndif.TargetStatement, out branchesToThisLabel))
                    {
                        branchesToThisLabel.Remove(gotoEndif);
                    }
                    elseBlock = this.ExtractBasicBlockUpto(b, i, gotoEndif.TargetStatement);
                    elseBlock.Statements.Add(gotoEndif.TargetStatement);
                    this.Traverse(elseBlock);
                    elseBlock.Statements.Remove(gotoEndif.TargetStatement);
                }
                else
                {
                    ifBlock.Statements.Add(gotoEndif);
                }
            }
            conditionalStatement.Condition  = condition;
            conditionalStatement.TrueBranch = ifBlock;
            if (elseBlock != null)
            {
                conditionalStatement.FalseBranch = elseBlock;
            }
            else
            {
                conditionalStatement.FalseBranch = new EmptyStatement();
            }
            return;
        }
        public void ConditionalStatementProducesErrorWithMissingCondition()
        {
            var c = new ConditionalStatement();

            Expect.Throw<InvalidOperationException>(() => c.ToString());
        }
Пример #28
0
        private bool ReplaceShortCircuitPattern3(List <IStatement> statements, int i)
        {
            if (i > statements.Count - 3)
            {
                return(false);
            }
            ConditionalStatement /*?*/ conditionalStatement = statements[i] as ConditionalStatement;

            if (conditionalStatement == null)
            {
                return(false);
            }
            ConditionalStatement /*?*/ conditionalStatement2 = statements[i + 1] as ConditionalStatement;

            if (conditionalStatement2 == null)
            {
                return(false);
            }
            if (statements[i + 2] is ConditionalStatement)
            {
                if (!this.ReplaceShortCircuitPattern2(statements, i + 1))
                {
                    return(false);
                }
                if (i > statements.Count - 3)
                {
                    return(false);
                }
                conditionalStatement2 = statements[i + 1] as ConditionalStatement;
                if (conditionalStatement2 == null)
                {
                    return(false);
                }
            }
            GotoStatement /*?*/ gotoStatement = conditionalStatement.FalseBranch as GotoStatement;

            if (gotoStatement == null)
            {
                return(false);
            }
            if (!(conditionalStatement.TrueBranch is EmptyStatement))
            {
                return(false);
            }
            GotoStatement /*?*/ gotoStatement2 = conditionalStatement2.FalseBranch as GotoStatement;

            if (gotoStatement2 == null)
            {
                gotoStatement2 = conditionalStatement2.TrueBranch as GotoStatement;
                if (gotoStatement2 == null)
                {
                    return(false);
                }
                if (!(conditionalStatement2.FalseBranch is EmptyStatement))
                {
                    return(false);
                }
                //brfalse, brtrue, ... could be A && B || C
                BasicBlock /*?*/ bb = statements[i + 2] as BasicBlock;
                if (bb == null)
                {
                    return(false);
                }
                if (bb.Statements.Count < 1 || !(bb.Statements[0] == gotoStatement.TargetStatement))
                {
                    return(false);
                }
                //we have:
                //i+0: if (cond1) {} else goto lab1;
                //i+1: if (cond2) goto lab2;
                //i+2: {....}
                Conditional conditional = new Conditional();
                conditional.Condition     = conditionalStatement.Condition;
                conditional.Locations     = conditionalStatement.Locations;
                conditional.ResultIfTrue  = conditionalStatement2.Condition;
                conditional.ResultIfFalse = new CompileTimeConstant()
                {
                    Value = 0, Type = this.sourceMethodBody.MethodDefinition.Type.PlatformType.SystemInt32
                };
                conditional.Type = TypeHelper.MergedType(TypeHelper.StackType(conditional.ResultIfTrue.Type), TypeHelper.StackType(conditional.ResultIfFalse.Type));
                conditionalStatement2.Condition = conditional;
                statements.RemoveAt(i);
                //we now have:
                //i+0: if (cond1 ? cond2 : 0) goto lab2;
                //i+1: {....}
                //which amounts to:
                // if (cond1 && cond2) goto lab2;
                // {...}
                return(this.ReplaceShortCircuitPattern2(statements, i));
            }
            if (!(conditionalStatement2.TrueBranch is EmptyStatement))
            {
                return(false);
            }
            if (gotoStatement.TargetStatement == gotoStatement2.TargetStatement)
            {
                Conditional conditional = new Conditional();
                conditional.Condition     = conditionalStatement.Condition;
                conditional.Locations     = conditionalStatement.Locations;
                conditional.ResultIfTrue  = conditionalStatement2.Condition;
                conditional.ResultIfFalse = new CompileTimeConstant()
                {
                    Value = 0, Type = this.sourceMethodBody.MethodDefinition.Type.PlatformType.SystemInt32
                };
                conditional.Type = TypeHelper.MergedType(TypeHelper.StackType(conditional.ResultIfTrue.Type), TypeHelper.StackType(conditional.ResultIfFalse.Type));
                conditionalStatement2.Condition = conditional;
                statements.RemoveAt(i);
                return(true);
            }
            return(false);
        }
Пример #29
0
        private bool ReplaceShortCircuitPattern2(List <IStatement> statements, int i)
        {
            if (i > statements.Count - 3)
            {
                return(false);
            }
            ConditionalStatement /*?*/ conditionalStatement = statements[i] as ConditionalStatement;

            if (conditionalStatement == null)
            {
                return(false);
            }
            ConditionalStatement /*?*/ conditionalStatement2 = statements[i + 1] as ConditionalStatement;

            if (conditionalStatement2 == null)
            {
                return(false);
            }
            if (statements[i + 2] is ConditionalStatement)
            {
                if (!ReplaceShortCircuitPattern2(statements, i + 1))
                {
                    return(false);
                }
                if (i > statements.Count - 3)
                {
                    return(false);
                }
                conditionalStatement2 = statements[i + 1] as ConditionalStatement;
                if (conditionalStatement2 == null)
                {
                    return(false);
                }
            }
            BasicBlock /*?*/ block = statements[i + 2] as BasicBlock;

            if (block == null)
            {
                return(this.ReplaceShortCircuitPattern3(statements, i));
            }
            if (block.Statements.Count < 1)
            {
                return(false);
            }
            GotoStatement /*?*/ gotoStatement = conditionalStatement.TrueBranch as GotoStatement;

            if (gotoStatement == null)
            {
                return(this.ReplaceShortCircuitPattern3(statements, i));
            }
            if (!(conditionalStatement.FalseBranch is EmptyStatement))
            {
                return(false);
            }
            if (gotoStatement.TargetStatement != block.Statements[0])
            {
                return(false);
            }
            if (!(conditionalStatement2.TrueBranch is EmptyStatement))
            {
                if (!(conditionalStatement2.TrueBranch is GotoStatement))
                {
                    return(false);
                }
                if (!(conditionalStatement2.FalseBranch is EmptyStatement))
                {
                    return(false);
                }
                //Now have:
                //if (cond1) goto lab1;
                //if (cond2) goto lab2;
                //lab1:...
                conditionalStatement2.Condition = InvertCondition(conditionalStatement2.Condition);
                IStatement temp = conditionalStatement2.TrueBranch;
                conditionalStatement2.TrueBranch  = conditionalStatement2.FalseBranch;
                conditionalStatement2.FalseBranch = temp;
                //Now have:
                //if (cond1) goto lab1;
                //if (!cond2) {} else goto lab2;
                //lab1:...
            }
            else
            {
                if (!(conditionalStatement2.FalseBranch is GotoStatement))
                {
                    return(false);
                }
            }

            //Now have:
            //if (cond1) goto lab1;
            //if (cond2a) {} else goto lab2;
            //lab1:...

            Conditional conditional = new Conditional();

            conditional.Condition    = conditionalStatement.Condition;
            conditional.Locations    = conditionalStatement.Locations;
            conditional.ResultIfTrue = new CompileTimeConstant()
            {
                Value = 1, Type = this.sourceMethodBody.MethodDefinition.Type.PlatformType.SystemInt32
            };
            conditional.ResultIfFalse       = conditionalStatement2.Condition;
            conditional.Type                = TypeHelper.MergedType(TypeHelper.StackType(conditional.ResultIfTrue.Type), TypeHelper.StackType(conditional.ResultIfFalse.Type));
            conditionalStatement2.Condition = conditional;
            statements.RemoveAt(i);

            //Now have:
            //if (cond1 ? true : cond2a) {} goto lab2;
            //lab1:....
            //
            //Which amounts to
            //if (!(cond1 || cond2a)) goto lab2;
            //lab1:...
            return(true);
        }
Пример #30
0
        /// <summary>
        /// Finds the following pattern:
        /// i   :  if (c) A else B; // either A or B must be an empty statement and the other is "goto L1;"
        /// i+1 :  push x;
        /// i+2 :  goto L2;
        /// i+3 :  Block1
        ///        0  : L1;
        ///        1  : push y;
        ///        2  : Block2
        ///             0 : L2;
        ///             1 : (rest of statements in Block2)
        ///
        /// Transforms it into:
        /// i   : push (d ? X : Y);
        /// i+1 : (rest of statements in Block2, preceded by L2 if there are more branches to L2 than just the one that was at i+2)
        ///
        /// Where if A is the empty statement, then
        ///   d == c, X == x, Y == y
        /// If B is the empty statement, then if y is zero,
        ///   d == !c, X == x, Y == y
        /// If B is the empty statement, then if y is not zero,
        ///   d == c, X == y, Y == x
        /// </summary>
        private bool ReplaceShortCircuitPattern(List <IStatement> statements, int i)
        {
            if (i > statements.Count - 4)
            {
                return(false);
            }
            ConditionalStatement /*?*/ conditionalStatement = statements[i] as ConditionalStatement;

            if (conditionalStatement == null)
            {
                return(false);
            }
            if (statements[i + 1] is ConditionalStatement)
            {
                return(this.ReplaceChainedShortCircuitBooleanPattern(statements, i));
            }
            GotoStatement /*?*/ gotoL1 = null;

            if (conditionalStatement.TrueBranch is EmptyStatement)
            {
                gotoL1 = conditionalStatement.FalseBranch as GotoStatement;
            }
            else if (conditionalStatement.FalseBranch is EmptyStatement)
            {
                gotoL1 = conditionalStatement.TrueBranch as GotoStatement;
            }
            if (gotoL1 == null)
            {
                return(false);
            }

            PushStatement /*?*/ push = statements[i + 1] as PushStatement;

            if (push == null)
            {
                return(false);
            }
            GotoStatement /*?*/ gotoL2 = statements[i + 2] as GotoStatement;

            if (gotoL2 == null)
            {
                return(false);
            }

            BasicBlock /*?*/ block = statements[i + 3] as BasicBlock;

            if (block == null)
            {
                return(false);
            }
            if (block.Statements.Count < 3)
            {
                return(false);
            }
            LabeledStatement /*?*/ l1 = block.Statements[0] as LabeledStatement;

            if (l1 == null)
            {
                return(false);
            }
            if (l1 != gotoL1.TargetStatement)
            {
                return(false);
            }
            List <IGotoStatement> branchesToThisLabel;

            if (this.predecessors.TryGetValue(l1, out branchesToThisLabel))
            {
                if (branchesToThisLabel.Count > 1)
                {
                    return(false);
                }
            }
            PushStatement /*?*/ push2 = block.Statements[1] as PushStatement;

            if (push2 == null)
            {
                return(false);
            }

            BasicBlock /*?*/ block2 = block.Statements[2] as BasicBlock;

            if (block2 == null || block2.Statements.Count < 1 || block2.Statements[0] != gotoL2.TargetStatement)
            {
                return(false);
            }

            Conditional conditional = new Conditional();

            if (conditionalStatement.TrueBranch is EmptyStatement)
            {
                conditional.Condition     = conditionalStatement.Condition;
                conditional.ResultIfTrue  = push.ValueToPush;
                conditional.ResultIfFalse = push2.ValueToPush;
            }
            else if (conditionalStatement.FalseBranch is EmptyStatement)
            {
                if (ExpressionHelper.IsIntegralZero(push2.ValueToPush))
                {
                    conditional.Condition     = InvertCondition(conditionalStatement.Condition);
                    conditional.ResultIfTrue  = push.ValueToPush;
                    conditional.ResultIfFalse = push2.ValueToPush;
                }
                else
                {
                    conditional.Condition     = conditionalStatement.Condition;
                    conditional.ResultIfTrue  = push2.ValueToPush;
                    conditional.ResultIfFalse = push.ValueToPush;
                }
            }
            conditional.Type      = TypeHelper.MergedType(TypeHelper.StackType(conditional.ResultIfTrue.Type), TypeHelper.StackType(conditional.ResultIfFalse.Type));
            conditional.Locations = conditionalStatement.Locations;

            push.ValueToPush = conditional;
            push.Locations   = conditional.Locations;
            statements[i]    = push;
            statements.RemoveRange(i + 1, 3);
            var l2 = gotoL2.TargetStatement;

            this.predecessors.TryGetValue(l2, out branchesToThisLabel);
            branchesToThisLabel.Remove(gotoL2);
            if (branchesToThisLabel.Count == 0)
            {
                block2.Statements.RemoveAt(0);
            }
            statements.InsertRange(i + 1, block2.Statements);

            return(true);
        }
Пример #31
0
 public ConditionalExpressionInterpreter(ExpressionInterpreterHandler expressionInterpreterHandler, ConditionalStatement conditionalStatement)
 {
     this.expressionInterpreterHandler = expressionInterpreterHandler;
     this.conditionalStatement         = conditionalStatement;
 }