Beispiel #1
0
        public override StatementList ReadInstanceField(InstanceFieldAccess instanceFieldAccess, IVariable result)
        {
            StatementList stmts      = new StatementList();
            var           boogieType = Helpers.GetBoogieType(result);

            var readFieldExpr = dispatcher.ReadInstanceField(instanceFieldAccess);

            if (!Settings.SplitFieldsEnabled())
            {
                if (!Helpers.IsBoogieRefType(Helpers.GetBoogieType(result))) // int, bool, real
                {
                    var expr = Expression.Union2PrimitiveType(boogieType, readFieldExpr);
                    stmts.Add(bg.VariableAssignment(result, expr));
                }
                else
                {
                    stmts.Add(bg.VariableAssignment(result, readFieldExpr));
                }
            }
            else
            {
                //p_int:= F$ConsoleApplication3.Holds`1.x[$tmp2];
                if (Helpers.IsGenericField(instanceFieldAccess.Field) &&
                    !boogieType.Equals(Helpers.BoogieType.Ref))
                {
                    stmts.Add(bg.VariableAssignment(result, Expression.Union2PrimitiveType(boogieType, readFieldExpr)));
                }
                else
                {
                    stmts.Add(bg.VariableAssignment(result, readFieldExpr));
                }
            }

            return(stmts);
        }
        public override Expression VisitReturnValue(ReturnValue returnValue)
        {
            // return a default value of the same type as the return value
            TypeNode returnType = returnValue.Type;
            ITypeParameter itp = returnType as ITypeParameter;
            if (itp != null)
            {
                Local loc = new Local(returnType);

                UnaryExpression loca = new UnaryExpression(loc, NodeType.AddressOf, loc.Type.GetReferenceType());
                StatementList statements = new StatementList(2);

                statements.Add(new AssignmentStatement(new AddressDereference(loca, returnType, false, 0),
                    new Literal(null, SystemTypes.Object)));

                statements.Add(new ExpressionStatement(loc));

                return new BlockExpression(new Block(statements), returnType);
            }

            if (returnType.IsValueType)
                return new Literal(0, returnType);
            
            return new Literal(null, returnType);
        }
        public override Expression VisitReturnValue(ReturnValue returnValue)
        {
            // return a default value of the same type as the return value
            TypeNode       returnType = returnValue.Type;
            ITypeParameter itp        = returnType as ITypeParameter;

            if (itp != null)
            {
                Local loc = new Local(returnType);

                UnaryExpression loca       = new UnaryExpression(loc, NodeType.AddressOf, loc.Type.GetReferenceType());
                StatementList   statements = new StatementList(2);

                statements.Add(new AssignmentStatement(new AddressDereference(loca, returnType, false, 0),
                                                       new Literal(null, SystemTypes.Object)));

                statements.Add(new ExpressionStatement(loc));

                return(new BlockExpression(new Block(statements), returnType));
            }

            if (returnType.IsValueType)
            {
                return(new Literal(0, returnType));
            }

            return(new Literal(null, returnType));
        }
        public override Expression VisitUnaryExpression(UnaryExpression unaryExpression)
        {
            var temp = base.VisitUnaryExpression(unaryExpression);

            if (temp.NodeType == NodeType.AddressOf)
            {
                var unary = temp as UnaryExpression;
                if (unary != null)
                {
                    if (!IsAddressoffable(unary.Operand.NodeType))
                    {
                        var newVar = new Local(unary.Operand.Type);
                        var sl     = new StatementList();
                        sl.Add(new AssignmentStatement(newVar, unary.Operand));

                        unary.Operand = newVar;
                        sl.Add(new ExpressionStatement(unary));

                        return(new BlockExpression(new Block(sl)));
                    }
                }
            }

            return(temp);
        }
Beispiel #5
0
        public override StatementList AllocLocalVariables(IList <IVariable> variables)
        {
            StatementList stmts = new StatementList();

            // we allocate an address for all local variables
            // except they are a pointer, we are assuming that you can't take the address of a pointer
            foreach (var v in variables)
            {
                if (!(v.Type is IManagedPointerType))
                {
                    stmts.Add(dispatcher.AllocAddr(v));
                }
            }

            // load values into stack space
            foreach (var paramVariable in variables.Where(v => v.IsParameter))
            {
                // paramValue are variables in the three address code
                // however in boogie they are treated as values
                // those values are loaded into the stack memory space

                /*
                 * void foo(int x){
                 * }
                 *
                 * procedure foo(x : int){
                 *  var _x : Addr; // stack space (done in previous loop)
                 *  x_ := AllocAddr();
                 *
                 *  data(_x) := x; // we are doing this conceptually
                 * }
                 */
                var boogieParamVariable = BoogieParameter.FromDotNetVariable(paramVariable);

                if (paramVariable.Type is IManagedPointerType)
                {
                    stmts.Add(BoogieStatement.VariableAssignment(BoogieVariable.AddressVar(paramVariable), boogieParamVariable));
                    continue;
                }

                Addressable paramAddress = dispatcher.AddressOf(paramVariable);

                // boogie generator knows that must fetch paramVariable's address (_x and not x)
                stmts.Add(dispatcher.WriteAddr(paramAddress, boogieParamVariable));

                if (Helpers.GetBoogieType(paramVariable).Equals(Helpers.BoogieType.Object))
                {
                    stmts.Add(BoogieStatement.AllocObjectAxiom(paramVariable));
                }
                else if (Helpers.GetBoogieType(paramVariable).Equals(Helpers.BoogieType.Addr))
                {
                    stmts.Add(BoogieStatement.AllocAddrAxiom(paramVariable));
                }
            }

            return(stmts);
        }
Beispiel #6
0
        public override StatementList AllocObject(IVariable var, InstructionTranslator instTranslator)
        {
            var freshVariable = instTranslator.GetFreshVariable(Helpers.GetBoogieType(var));
            var stmts         = new StatementList();

            stmts.Add(dispatcher.AllocObject(freshVariable));
            stmts.Add(bg.VariableAssignment(var, freshVariable));
            return(stmts);
        }
        private Expression ExtractOldExpression(MethodCall call)
        {
            var cand = call.Operands[0];

            if (this.currentSL != null)
            {
                var locs = FindLocals.Get(cand);
                if (locs.Count > 0)
                {
                    // find the instructions that set these locals
                    var assignments = new List <Statement>();
                    for (int i = this.currentSLindex - 1; i >= 0; i--)
                    {
                        var a = this.currentSL[i] as AssignmentStatement;
                        if (a == null)
                        {
                            continue;
                        }

                        var loc = a.Target as Local;
                        if (loc == null)
                        {
                            continue;
                        }

                        if (locs.Contains(loc))
                        {
                            assignments.Add(a);
                            this.currentSL[i] = null;
                            locs.Remove(loc);
                        }

                        if (locs.Count == 0)
                        {
                            break;
                        }
                    }
                    assignments.Reverse();

                    var be = new StatementList();
                    assignments.ForEach(astmt => be.Add(astmt));

                    be.Add(new ExpressionStatement(cand));
                    var sc = cand.SourceContext;

                    cand = new BlockExpression(new Block(be));
                    cand.SourceContext = sc;

                    if (locs.Count > 0)
                    {
                        // warn that we couldn't extract the local
                    }
                }
            }

            return(cand);
        }
Beispiel #8
0
        /// <summary>
        /// Construeix la funcio de transicio.
        /// </summary>
        /// <param name="state">El estat.</param>
        /// <param name="transitionName">El nom de la transicio.</param>
        /// <returns>La funcio.</returns>
        ///
        private FunctionDeclaration MakeOnTransitionFunction(State state, string transitionName, string contextClassName, string ownerClassName)
        {
            StatementList bodyStatements = new StatementList();

            // Intruccio per recuperar el context.
            //
            bodyStatements.Add(
                new InlineStatement(
                    String.Format("{0}* ctx = static_cast<{0}*>(getContext())", contextClassName)));
            bodyStatements.Add(
                new InlineStatement(
                    String.Format("{0}* owner = ctx->getOwner()", ownerClassName)));

            foreach (Transition transition in state.Transitions)
            {
                if (transition.TransitionEvent.Name == transitionName)
                {
                    StatementList trueBodyStatements = new StatementList();

                    trueBodyStatements.Add(new InvokeStatement(
                                               new InvokeExpression(
                                                   new IdentifierExpression("ctx->beginTransition"))));

                    // Accio de transicio.
                    //
                    if (transition.Action != null)
                    {
                        trueBodyStatements.AddRange(MakeActionStatements(transition.Action));
                    }

                    trueBodyStatements.Add(new InvokeStatement(
                                               new InvokeExpression(
                                                   new IdentifierExpression("ctx->endTransition"),
                                                   new InvokeExpression(
                                                       new IdentifierExpression("ctx->getStateInstance"),
                                                       new IdentifierExpression(
                                                           String.Format("Context::StateID::{0}", transition.NextState.Name))))));

                    Expression conditionExpr = new InlineExpression(transition.Guard == null ? "true" : transition.Guard.Expression);
                    bodyStatements.Add(new IfThenElseStatement(
                                           conditionExpr,
                                           new BlockStatement {
                        Statements = trueBodyStatements
                    },
                                           null));
                }
            }

            return(new FunctionDeclaration {
                Access = AccessSpecifier.Public,
                Implementation = ImplementationSpecifier.Override,
                ReturnType = TypeIdentifier.FromName("void"),
                Name = String.Format("transition_{0}", transitionName),
                Body = new BlockStatement(bodyStatements),
            });
        }
Beispiel #9
0
        private Node EvaluateLoopStatements()
        {
            var stmts = new StatementList();

            while (firstOfStatement.Contains(CurrentToken) &&
                   CurrentToken != TokenCategory.CONTINUE)
            {
                stmts.Add(Statement());
            }
            stmts.Add(Continue());
            return(stmts);
        }
        public Node StmtList()
        {
            var statementList = new StatementList();

            while (System.Array.Exists(stmtCategories, category => category == Current))
            {
                switch (Current)
                {
                case TokenCategory.IDENTIFIER:
                    var id = Expect(TokenCategory.IDENTIFIER);
                    switch (Current)
                    {
                    case TokenCategory.ASSIGN:
                        statementList.Add(StmtAssign(id));
                        break;

                    case TokenCategory.INCREMENT:
                        statementList.Add(StmtIncr(id));
                        break;

                    case TokenCategory.DECREMENT:
                        statementList.Add(StmtDecr(id));
                        break;

                    case TokenCategory.OPEN_PARENTHESIS:
                        statementList.Add(StmtFunCall(id));
                        break;

                    default:
                        throw new SyntaxError(String.Format("Syntax Error: Expected operator or open parenthesis, given '{0}' at ({1}, {2})", stream.Current.Value, previous.Row, previous.LastIndex()));
                    }
                    break;

                case TokenCategory.IF:
                    statementList.Add(StmtIf());
                    break;

                case TokenCategory.LOOP:
                    statementList.Add(StmtLoop());
                    break;

                case TokenCategory.BREAK:
                    statementList.Add(StmtBreak());
                    break;

                case TokenCategory.RETURN:
                    statementList.Add(StmtReturn());
                    break;

                case TokenCategory.SEMICOLON:
                    statementList.Add(StmtEmpty());
                    break;
                }
            }
            return(statementList);
        }
Beispiel #11
0
        StatementList TranslateLocalVariables(Dictionary <string, BoogieVariable> temporalVariables)
        {
            StatementList localVariablesStmts = new StatementList();
            var           bg = BoogieGenerator.Instance();

            var allVariables = methodBody.Variables.Union(methodBody.Parameters).ToList();

            localVariablesStmts.Add(bg.DeclareLocalVariables(allVariables, temporalVariables));

            localVariablesStmts.Add(bg.AllocLocalVariables(allVariables));

            // replace for class generated by compiler
            return(localVariablesStmts);
        }
Beispiel #12
0
        StatementList ParseStatements()
        {
            StatementList statements = new StatementList();
            int           Scope      = 1;

            while (Scope > 0)
            {
                if (tokenReader.Expect(LexKind.BraceOpen))
                {
                    Scope++;
                }
                else if (tokenReader.Expect(LexKind.BraceClose))
                {
                    Scope--;
                }

                bool statementParsed = ParseStatement(out Statement statement);
                if (statementParsed)
                {
                    statements.Add(statement);
                }
                else
                {
                    tokenReader.Skip(1);
                }

                if (tokenReader.Expect(LexKind.EOF))
                {
                    Scope = 0;
                }
            }

            return(statements);
        }
Beispiel #13
0
        public GeneratedCode Parse(List<Token> _tokens)
        {
            Dictionary<string, Function> Functions = new Dictionary<string, Function>();
            StatementList TopLevelStatements = new StatementList();
            Tokens = _tokens;
            Position = 0;

            GetNextToken(); //Initialize first token
            while (true)
            {
                if (CurToken.Type == TokenType.EOF)
                    break;
                if (CurToken.IsCharacter(";"))
                    GetNextToken(); //eat ;
                else if (CurToken.IsIdentifier("function"))
                {
                    Function func = ParseFunction();
                    Functions[func.Name] = func;
                }
                else
                    TopLevelStatements.Add(ParseStatement());
            }
            Function TopLevel = new Function(TopLevelStatements);
            return new GeneratedCode()
            {
                TopLevelStatements = TopLevel,
                Functions = Functions
            };
        }
        public Node Program()
        {
            var declList = new DeclarationList();
            var stmtList = new StatementList();

            while (firstOfDeclaration.Contains(CurrentToken))
            {
                declList.Add(Declaration());
            }

            while (firstOfStatement.Contains(CurrentToken))
            {
                stmtList.Add(Statement());
            }

            Expect(TokenCategory.EOF);

            // This refers to the class that refers to the 'Program' token,
            // not this method's name.
            return(new Program()
            {
                declList,
                stmtList
            });
        }
Beispiel #15
0
        public Node For()
        {
            var idToken    = Expect(TokenCategory.FOR);
            var identifier = new Identifier()
            {
                AnchorToken = Expect(TokenCategory.IDENTIFIER)
            };

            Expect(TokenCategory.IN);
            var expr = Expression();

            Expect(TokenCategory.DO);
            var stmtList = new StatementList();

            while (firstOfStatement.Contains(CurrentToken))
            {
                stmtList.Add(Statement());
            }
            Expect(TokenCategory.END);
            Expect(TokenCategory.ENDLINE);
            var result = new For()
            {
                identifier, expr, stmtList
            };

            result.AnchorToken = idToken;
            return(result);
            //Si nos estamos refiriendo a FormatException?
        }
Beispiel #16
0
        public static string CreateDefaultValuesStaticVariablesProcedure()
        {
            #region Create body of the procedure
            StatementList body = new StatementList();

            foreach (IFieldReference field in FieldTranslator.GetFieldReferences())
            {
                if (field.IsStatic)
                {
                    BoogieGenerator   bg = BoogieGenerator.Instance();
                    StaticFieldAccess staticFieldAccess = new StaticFieldAccess(field);

                    body.Add(bg.WriteStaticField(staticFieldAccess, GetDefaultConstant(Helpers.GetBoogieType(field.Type))));
                }
            }
            #endregion

            string        procedureName       = "$default_values_static_fields";
            string        attributes          = String.Empty;
            StatementList localVariables      = new StatementList();
            String        parametersWithTypes = String.Empty;
            String        returnTypeIfAny     = String.Empty;

            BoogieProcedureTemplate temp = new BoogieProcedureTemplate(procedureName, attributes, localVariables, body, parametersWithTypes, returnTypeIfAny, false);
            return(temp.TransformText());
        }
Beispiel #17
0
        public override StatementList DeclareLocalVariables(IList <IVariable> variables, Dictionary <string, BoogieVariable> temporalVariables)
        {
            StatementList stmts = new StatementList();

            foreach (var v in variables.Where(v => !v.IsParameter))
            {
                stmts.Add(BoogieStatement.VariableDeclaration(v));
            }

            foreach (var kv in temporalVariables)
            {
                stmts.Add(BoogieStatement.VariableDeclaration(kv.Value));
            }

            return(stmts);
        }
Beispiel #18
0
        // hides implementation in super class
        //public new string VariableAssignment(string variableA, string expr)
        //{
        //    return string.Format("{0} := {1};", variableA, expr);
        //}

        public override StatementList DeclareLocalVariables(IList <IVariable> variables, Dictionary <string, BoogieVariable> temporalVariables)
        {
            var stmts = new StatementList();

            foreach (var v in variables)
            {
                stmts.Add(BoogieStatement.VariableDeclaration(BoogieVariable.AddressVar(v)));
            }

            foreach (var kv in temporalVariables)
            {
                stmts.Add(BoogieStatement.VariableDeclaration(kv.Value));
            }

            return(stmts);
        }
Beispiel #19
0
        public Node For()
        {
            var result = new For()
            {
                AnchorToken = Expect(TokenCategory.FOR)
            };

            result.Add(new Identifier()
            {
                AnchorToken = Expect(TokenCategory.IDENTIFIER)
            });

            Expect(TokenCategory.IN);
            result.Add(Expression());
            Expect(TokenCategory.DO);

            var statementList = new StatementList();

            if (firstOfStatement.Contains(CurrentToken))
            {
                while (firstOfStatement.Contains(CurrentToken))
                {
                    statementList.Add(Statement());
                }
            }
            result.Add(statementList);

            Expect(TokenCategory.END);
            Expect(TokenCategory.SEMICOLON);
            return(result);
        }
Beispiel #20
0
        private StatementList ParseChild(Stream stream)
        {
            var child = new StatementList(_host);

            var open = stream.Next();

            while (stream.Peek() != null)
            {
                var token = stream.Peek();
                if (token == null)
                {
                    break;
                }

                switch (token.Type)
                {
                default:
                    var statements = ParseStatement(stream);
                    foreach (var statement in statements)
                    {
                        child.Add(statement);
                    }
                    goto doneWithChildren;
                }
            }

doneWithChildren:
            return(child);
        }
Beispiel #21
0
        public static void CreateAsyncStartMethod(StreamWriter sw)
        {
            StatementList stmts = new StatementList();

            var boogieGetTypeRes = BoogieVariable.GetTempVar(Helpers.ObjectType(), null /* need dict with used var names*/, prefix: "asyncType");
            var stateMachineVar  = BoogieVariable.GetTempVar(Helpers.ObjectType(), null /* need dict with used var names*/, prefix: "stateMachineCopy");

            stmts.Add(BoogieStatement.VariableDeclaration(stateMachineVar));
            stmts.Add(BoogieStatement.VariableDeclaration(boogieGetTypeRes));
            stmts.Add(BoogieStatement.FromString($"{stateMachineVar.Expr} := stateMachine;"));
            foreach (var asyncMethod in Helpers.asyncMoveNexts)
            {
                var asyncType = asyncMethod.ContainingTypeDefinition;
                var bg        = BoogieGenerator.Instance();
                stmts.Add(bg.ProcedureCall(BoogieMethod.GetTypeMethod, new List <Expression> {
                    stateMachineVar
                }, boogieGetTypeRes));
                StatementList ifStmts = new StatementList();
                ifStmts.Add(BoogieGenerator.Instance().ProcedureCall(BoogieMethod.From(asyncMethod), new List <Expression> {
                    stateMachineVar
                }));

                stmts.Add(BoogieStatement.If(Expression.Subtype(boogieGetTypeRes, asyncType), ifStmts));
            }
            stmts.Add(BoogieStatement.FromString($"v0$out := {stateMachineVar.Expr};"));

            sw.WriteLine(@"procedure {:extern} System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.Start``1$``0$(this : Ref,stateMachine : Ref) returns (v0$out : Ref) {");
            foreach (var stmt in stmts)
            {
                sw.WriteLine(stmt.Stmt);
            }
            sw.WriteLine("}");
        }
Beispiel #22
0
        public Node Program()
        {
            var decList  = new DeclarationList();
            var stmtList = new StatementList();

            while (firstOfDeclaration.Contains(CurrentToken))
            {
                decList.Add(Declaration());
            }

            var result = new Program()
            {
                AnchorToken = Expect(TokenCategory.PROG)
            };

            while (firstOfStatement.Contains(CurrentToken))
            {
                stmtList.Add(Statement());
            }

            Expect(TokenCategory.END);
            Expect(TokenCategory.SEMICOL);
            Expect(TokenCategory.EOF);

            result.Add(decList);
            result.Add(stmtList);

            return(result);
        }
        /// <summary>
        /// Method generates core part of the CheckMethod
        /// </summary>
        private void EmitCheckPostMethodCore(TypeNode taskType)
        {
            Contract.Requires(taskType != null);

            this.checkMethodTaskParameter = new Parameter(Identifier.For("task"), taskType);

            // TODO ST: can I switch to new Local(taskType.Type)?!? In this case this initialization
            // could be moved outside this method
            this.originalResultLocal = new Local(new Identifier("taskLocal"), checkMethodTaskParameter.Type);

            // Generate: public Task<T> CheckPost(Task<T> task) where T is taskType or
            // public Task CheckPost(Task task) for non-generic task.
            checkPostMethod = new Method(
                declaringType: this.closureClass,
                attributes: null,
                name: CheckMethodId,
                parameters: new ParameterList(checkMethodTaskParameter),
                // was: taskType.TemplateArguments[0] when hasResult was true and SystemTypes.Void otherwise
                returnType: taskType,
                body: null);

            checkPostMethod.CallingConvention = CallingConventionFlags.HasThis;
            checkPostMethod.Flags            |= MethodFlags.Public;

            this.checkPostBody = new StatementList();
            this.closureClass.Members.Add(this.checkPostMethod);

            if (taskType.IsGeneric)
            {
                // Assign taskParameter to originalResultLocal because
                // this field is used in a postcondition
                checkPostBody.Add(new AssignmentStatement(this.originalResultLocal, checkMethodTaskParameter));
            }
        }
Beispiel #24
0
        /// <summary>
        /// Crea la declaracio del metode 'start'
        /// </summary>
        /// <param name="machine">La maquina.</param>
        /// <returns>La declaracio del metode.</returns>
        ///
        private FunctionDeclaration MakeStartFunction(Machine machine)
        {
            StatementList bodyStatements = new StatementList();

            if (machine.InitializeAction != null)
            {
                var statements = MakeActionStatements(machine.InitializeAction);
                if (statements != null)
                {
                    bodyStatements.AddRange(statements);
                }
            }
            bodyStatements.Add(
                new InvokeStatement(
                    new InvokeExpression(
                        new IdentifierExpression("initialize"),
                        new InvokeExpression(
                            new IdentifierExpression("getStateInstance"),
                            new IdentifierExpression(
                                String.Format("StateID::{0}", machine.Start.FullName))))));

            return(new FunctionDeclaration(
                       "start",
                       AccessSpecifier.Public,
                       TypeIdentifier.FromName("void"),
                       null,
                       bodyStatements));
        }
Beispiel #25
0
        public override Statement VisitBranch(Branch branch)
        {
            if (branch == null)
            {
                return(null);
            }
            if (branch.Target == null)
            {
                return(null);
            }
            branch.Condition = this.VisitExpression(branch.Condition);
            int         n           = this.localsStack.top + 1;
            LocalsStack targetStack = (LocalsStack)this.StackLocalsAtEntry[branch.Target.UniqueKey];

            if (targetStack == null)
            {
                this.StackLocalsAtEntry[branch.Target.UniqueKey] = this.localsStack.Clone();
                return(branch);
            }
            //Target block has an entry stack that is different from the current stack. Need to copy stack before branching.
            if (n <= 0)
            {
                return(branch);  //Empty stack, no need to copy
            }
            StatementList statements = new StatementList(n + 1);

            this.localsStack.Transfer(targetStack, statements);
            statements.Add(branch);
            return(new Block(statements));
        }
Beispiel #26
0
        public override StatementList CallReadArrayElement(IVariable resultVariable, Expression array, Expression index, InstructionTranslator instructionTranslator)
        {
            StatementList stmts = new StatementList();

            BoogieVariable boogieResVar = null;

            if (resultVariable != null)
            {
                boogieResVar = instructionTranslator.GetFreshVariable(Helpers.GetBoogieType(resultVariable));
            }
            stmts.Add(dispatcher.CallReadArrayElement(boogieResVar, array, index));
            if (resultVariable != null)
            {
                stmts.Add(dispatcher.WriteAddr(dispatcher.AddressOf(resultVariable), boogieResVar));
            }
            return(stmts);
        }
Beispiel #27
0
        public override StatementList AllocLocalVariables(IList <IVariable> variables)
        {
            StatementList stmts = new StatementList();

            // only allocate an address for variables that are referenced
            foreach (var v in variables)
            {
                if (RequiresAllocation(v))
                {
                    stmts.Add(AllocAddr(v));
                }
            }

            foreach (var paramVariable in variables.Where(v => v.IsParameter && (RequiresAllocation(v) || (v.Type is IManagedPointerType))))
            {
                var boogieParamVariable = BoogieParameter.FromDotNetVariable(paramVariable);

                //if (!RequiresAllocation(paramVariable))
                if (paramVariable.Type is IManagedPointerType)
                {
                    //BoogieVariable target = RequiresAllocation(paramVariable) || (paramVariable.Type is IManagedPointerType) ?
                    //    BoogieVariable.AddressVar(paramVariable) : BoogieVariable.FromDotNetVariable(paramVariable);

                    BoogieVariable target = BoogieVariable.AddressVar(paramVariable);
                    stmts.Add(BoogieStatement.VariableAssignment(target, boogieParamVariable));
                    continue;
                }

                Addressable paramAddress = AddressOf(paramVariable);

                // boogie generator knows that must fetch paramVariable's address (_x and not x)
                stmts.Add(WriteAddr(paramAddress, boogieParamVariable));

                if (Helpers.GetBoogieType(paramVariable).Equals(Helpers.BoogieType.Object))
                {
                    stmts.Add(BoogieStatement.AllocObjectAxiom(paramVariable));
                }
                else if (Helpers.GetBoogieType(paramVariable).Equals(Helpers.BoogieType.Addr))
                {
                    stmts.Add(BoogieStatement.AllocAddrAxiom(paramVariable));
                }
            }

            return(stmts);
        }
Beispiel #28
0
        public override StatementList WriteInstanceField(InstanceFieldAccess instanceFieldAccess, Expression expr, InstructionTranslator instTranslator)
        {
            StatementList stmts = new StatementList();

            var boogieType = expr.Type;

            if (Helpers.IsGenericField(instanceFieldAccess.Field) && !boogieType.Equals(Helpers.BoogieType.Object))
            {
                stmts.Add(Expression.AssumeInverseRelationUnionAndPrimitiveType(expr));
                stmts.Add(dispatcher.WriteAddr(dispatcher.AddressOf(instanceFieldAccess), Expression.PrimitiveType2Union(expr, instTranslator.Boogie())));
            }
            else
            {
                stmts.Add(dispatcher.WriteAddr(dispatcher.AddressOf(instanceFieldAccess), expr));
            }

            return(stmts);
        }
Beispiel #29
0
        public string AsyncStubsScheduleTask(bool genericVersion = false)
        {
            StatementList localVars = new StatementList();

            localVars.Add(BoogieStatement.FromString("var state : bool;"));

            StatementList instructions = new StatementList();
            var           param0       = new BoogieVariable(Helpers.BoogieType.Object, "sm");


            var procIsCompleted = genericVersion ? BoogieMethod.AsyncStubsTaskAwaiterIsCompletedGeneric : BoogieMethod.AsyncStubsTaskAwaiterIsCompleted;
            var awaiterVar      = new BoogieVariable(Helpers.BoogieType.Object, "awaiter");
            var stateVar        = new BoogieVariable(Helpers.BoogieType.Bool, "state");
            var argsList        = new List <Expression>();

            argsList.Add(awaiterVar);
            var resList = new List <BoogieVariable>();

            resList.Add(stateVar);
            var callIsCompleted = BoogieStatement.ProcedureCall(procIsCompleted, argsList, resList, stateVar);

            var assume = BoogieStatement.Assume(Expression.BinaryOperationExpression(stateVar, new Expression(Helpers.BoogieType.Bool, "true"), Backend.ThreeAddressCode.Instructions.BinaryOperation.Eq));

            var yield = BoogieStatement.FromString("yield;");

            // it is crucial to yield before anything else
            instructions.Add(yield);
            instructions.Add(callIsCompleted);
            instructions.Add(assume);

            var moveNextMethods = stateMachinesTypes.Select(t => t.Members.Where(m => m.Name.Value.Contains("MoveNext")).First()).Cast <IMethodDefinition>();
            var ifCases         = moveNextMethods.Select(m => Invoke(m, param0));

            foreach (var ifCase in ifCases)
            {
                instructions.Add(ifCase);
            }

            string procedureName = genericVersion ? "$AsyncStubs`1$ScheduleTask" : "$AsyncStubs$ScheduleTask";

            var procedureTemplate = new BoogieProcedureTemplate(procedureName, "", localVars, instructions, "awaiter : Object, sm : Object", String.Empty, false);

            return(procedureTemplate.TransformText());
        }
Beispiel #30
0
        public Node StmtList()
        {
            var node = new StatementList();

            while (firstOfStmt.Contains(CurrentToken))
            {
                node.Add(Stmt());
            }
            return(node);
        }
Beispiel #31
0
        /****************************************************************
         *                    Statements List Node
         ***************************************************************/

        private Node EvaluateStatements()
        {
            var stmts = new StatementList();

            while (firstOfStatement.Contains(CurrentToken))
            {
                stmts.Add(Statement());
            }
            return(stmts);
        }
Beispiel #32
0
        public Node StmtList()
        {
            var statementList = new StatementList();

            while (firstOfStatement.Contains(CurrentToken))
            {
                statementList.Add(Stmt());
            }
            return(statementList);
        }
 public override Statement VisitBranch(Branch branch){
   if (branch == null) return null;
   if (branch.Target == null) return null;
   branch.Condition = this.VisitExpression(branch.Condition);
   int n = this.localsStack.top+1;
   LocalsStack targetStack = (LocalsStack)this.StackLocalsAtEntry[branch.Target.UniqueKey];
   if (targetStack == null){
     this.StackLocalsAtEntry[branch.Target.UniqueKey] = this.localsStack.Clone();
     return branch;
   }
   //Target block has an entry stack that is different from the current stack. Need to copy stack before branching.
   if (n <= 0) return branch; //Empty stack, no need to copy
   StatementList statements = new StatementList(n+1);
   this.localsStack.Transfer(targetStack, statements);
   statements.Add(branch);
   return new Block(statements);
 }
        //public override Block VisitBlock(Block block) {
        //  if(block.Statements != null && block.Statements.Count == 1) {
        //    Return r = block.Statements[0] as Return;
        //    if(r != null) {
        //      Statement s = this.VisitReturn(r);
        //      Block retBlock = s as Block;
        //      if(retBlock != null) {
        //        block.Statements = retBlock.Statements;
        //        return block;
        //      } else {
        //        return base.VisitBlock(block);
        //      }
        //    } else {
        //      return base.VisitBlock(block);
        //    }
        //  } else {
        //    return base.VisitBlock(block);
        //  }
        //}

        public override Statement VisitReturn(Return Return)
        {
            if (Return == null)
            {
                return null;
            }

            returnCount++;
            this.lastReturnSourceContext = Return.SourceContext;

            StatementList stmts = new StatementList();

            Return.Expression = this.VisitExpression(Return.Expression);

            if (Return.Expression != null)
            {
                MethodCall mc = Return.Expression as MethodCall;
                if (mc != null && mc.IsTailCall)
                {
                    mc.IsTailCall = false;
                }

                var assgnmt = new AssignmentStatement(result, Return.Expression);

                assgnmt.SourceContext = Return.SourceContext;
                stmts.Add(assgnmt);
            }

            // the branch is a "leave" out of the try block that the body will be
            // in.
            var branch = new Branch(null, newExit, false, false, this.leaveExceptionBody);
            branch.SourceContext = Return.SourceContext;

            stmts.Add(branch);

            return new Block(stmts);
        }
Beispiel #35
0
 StatementList AddCheckForNull(StatementList statements, Expression src, TypeNode type) {
   if (type.Template == SystemTypes.GenericBoxed) {
     If checknull = new If(new BinaryExpression(
       new MethodCall(new MemberBinding(src, type.GetMethod(Identifier.For("IsNull"),null)), new ExpressionList()),
       Literal.True, NodeType.Ne), 
       new Block(new StatementList()), null);
     statements.Add(checknull);
     return checknull.TrueBlock.Statements;        
   }
   else if (type is TypeAlias) {
     // cast to underlying type and check that for null.
     TypeNode atype = ((TypeAlias)type).AliasedType;
     return AddCheckForNull(statements, CastTo(src, atype), atype); 
   }
   else if (type is ConstrainedType) {
     // cast to underlying type and check that for null.
     TypeNode atype = ((ConstrainedType)type).UnderlyingType;
     return AddCheckForNull(statements, CastTo(src, atype), atype); 
   }
   else if (!IsStream(type) && !type.IsValueType) { //stream types are doing weird things to the null check?
     if (type == SystemTypes.String || IsStream(type))
       src = CastTo(src, SystemTypes.Object);
     If checknull = new If(new BinaryExpression(src, Literal.Null, NodeType.Ne), 
       new Block(new StatementList()), null);
     statements.Add(checknull);
     return checknull.TrueBlock.Statements;        
   }
   return statements;
 }
Beispiel #36
0
    bool AddWriteSimpleAttribute(TypeNode type, Identifier name, StatementList statements, TypeNode referringType, Identifier writer, Expression src) {
      ExpressionList args = new ExpressionList();
      args.Add(GetXmlNameFromId(name));
      args.Add(GetXmlNamespaceFromId(name));
      args.Add(src);

      if (type == SystemTypes.String) {
        statements = AddCheckForNull(statements, Duplicate(src, referringType), type);
        statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(writer, Identifier.For("WriteAttributeString")), args)));
      } else if( type == SystemTypes.Boolean) {
        statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(writer, Identifier.For("WriteAttributeBoolean")), args)));
      } else if( type == SystemTypes.Int8) {
        statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(writer, Identifier.For("WriteAttributeSByte")), args)));
      } else if( type == SystemTypes.Char) {
        statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(writer, Identifier.For("WriteAttributeChar")), args)));
      } else if( type == SystemTypes.DateTime) {
        statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(writer, Identifier.For("WriteAttributeDateTime")), args)));
      } else if( type == SystemTypes.Decimal) {
        statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(writer, Identifier.For("WriteAttributeDecimal")), args)));
      } else if( type == SystemTypes.Double) {
        statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(writer, Identifier.For("WriteAttributeDouble")), args)));
      } else if( type == SystemTypes.Guid) {
        statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(writer, Identifier.For("WriteAttributeGuid")), args)));
      } else if( type == SystemTypes.Int16) {
        statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(writer, Identifier.For("WriteAttributeInt16")), args)));
      } else if( type == SystemTypes.Int32) {
        statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(writer, Identifier.For("WriteAttributeInt32")), args)));
      } else if( type == SystemTypes.Int64) {
        statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(writer, Identifier.For("WriteAttributeInt64")), args)));
      } else if( type == SystemTypes.UInt8) {
        statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(writer, Identifier.For("WriteAttributeByte")), args)));
      } else if( type == SystemTypes.Single) {
        statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(writer, Identifier.For("WriteAttributeSingle")), args)));
      } else if( type == SystemTypes.TimeSpan) {
        statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(writer, Identifier.For("WriteAttributeTimeSpan")), args)));
      } else if( type == SystemTypes.UInt16 ) {
        statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(writer, Identifier.For("WriteAttributeUInt16")), args)));
      } else if( type == SystemTypes.UInt32) {
        statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(writer, Identifier.For("WriteAttributeUInt32")), args)));
      } else if( type == SystemTypes.UInt64) {
        statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(writer, Identifier.For("WriteAttributeUInt64")), args)));
      } else {
        Expression conversion = GetConvertToString(type, src, true);
        if (conversion != null) {         
          statements = AddCheckForNull(statements, Duplicate(src, referringType), type);
          ExpressionList args2 = new ExpressionList();
          args2.Add(args[0]);
          args2.Add(args[1]);
          args2.Add(conversion);          
          statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(writer, Identifier.For("WriteAttributeString")), args2)));
        } else {
          return false;
        } 
      }
      return true;
    }
Beispiel #37
0
    bool AddReadSimpleType(TypeNode simpleType, StatementList statements, Identifier reader, Expression mb, Expression result, bool always) {
      TypeNode type = Unwrap(simpleType);

      string method = null;
      Expression conversion = null;

      if (type == SystemTypes.String) {
        method = "ReadStringElement";
      } else if (type == SystemTypes.Boolean) {
        method = "ReadBool";
      } else if (type == SystemTypes.Int8) {
        method = "ReadSByte";
      } else if (type == SystemTypes.Char) {
        method = "ReadChar";
      } else if (type == SystemTypes.DateTime) {
        method = "ReadDateTime";
      } else if (type == SystemTypes.Decimal) {
        method = "ReadDecimal";
      } else if (type == SystemTypes.Double) {
        method = "ReadDouble";
      } else if (type == SystemTypes.Guid) {
        method = "ReadGuid";
      } else if (type == SystemTypes.Int16) {
        method = "ReadInt16";
      } else if (type == SystemTypes.Int32) {
        method = "ReadInt32";
      } else if (type == SystemTypes.Int64) {
        method = "ReadInt64";
      } else if (type == SystemTypes.UInt8) {
        method = "ReadInt8";
      } else if (type == SystemTypes.Single) {
        method = "ReadSingle";
      } else if (type == SystemTypes.TimeSpan) {
        method = "ReadTimeSpan";
      } else if (type == SystemTypes.UInt16) {
        method = "ReadUInt16";
      } else if (type == SystemTypes.UInt32) {
        method = "ReadUInt32";
      } else if (type == SystemTypes.UInt64) {
        method = "ReadUInt64";
      } else {
        // see if there's a type converter for it.
        conversion = GetConvertFromString(type, new MethodCall(new QualifiedIdentifier(reader, Identifier.For("ReadStringElement")), null), always);         
      }
      if (method != null) {
        conversion = new MethodCall(new QualifiedIdentifier(reader, Identifier.For(method)), null, NodeType.Callvirt, type);
      }
      if (conversion == null)
        return false; // there is no simple conversion!
      
      statements.Add(new AssignmentStatement(mb, CastTo(conversion, simpleType)));      
      if (result != null)
        statements.Add(new AssignmentStatement(result, Literal.True));
      return true;
    }
Beispiel #38
0
    void AddCallDeserializer(TypeNode type, StatementList statements, Identifier reader, 
      Expression target, Expression required, Expression result) {

      Class memberSerializer = this.CreateSerializerFor(type);      
      // call the Deserialize method on it, and assign result to target object.
      ExpressionList args = new ExpressionList();
      args.Add(reader);
      args.Add(required);
      if (result is Local) 
        result = new UnaryExpression(result, NodeType.AddressOf);
      args.Add(result);
      MethodCall call = new MethodCall();
      Method deserialize = memberSerializer.GetMethod(Identifier.For("Deserialize"), new TypeNode[3] { Runtime.XmlSerializationReader, SystemTypes.Boolean, SystemTypes.Boolean.GetReferenceType() } );
      call.Callee = new MemberBinding(new MemberBinding(null, memberSerializer), deserialize);
      call.Operands = args;
      statements.Add(new AssignmentStatement(target, call));
    }
Beispiel #39
0
    bool AddWriteSimpleType(TypeNode simpleType, StatementList statements, TypeNode referringType, Identifier writer, Expression src, Expression name, Expression ns) {

      Identifier method = null;
      TypeNode type = Unwrap(simpleType);

      ExpressionList args = new ExpressionList(src);

      if (type == SystemTypes.String) {
        method = Identifier.For("WriteString");
      } else if( type == SystemTypes.Boolean) {
        method = Identifier.For("WriteBoolean");
      } else if( type == SystemTypes.Int8) {
        method = Identifier.For("WriteSByte");
      } else if( type == SystemTypes.Char) {
        method = Identifier.For("WriteChar");
      } else if( type == SystemTypes.DateTime) {
        method = Identifier.For("WriteDateTime");
      } else if( type == SystemTypes.Decimal) {
        method = Identifier.For("WriteDecimal");
      } else if( type == SystemTypes.Double) {
        method = Identifier.For("WriteDouble");
      } else if( type == SystemTypes.Guid) {
        method = Identifier.For("WriteGuid");
      } else if( type == SystemTypes.Int16) {
        method = Identifier.For("WriteInt16");
      } else if( type == SystemTypes.Int32) {
        method = Identifier.For("WriteInt32");
      } else if( type == SystemTypes.Int64) {
        method = Identifier.For("WriteInt64");
      } else if( type == SystemTypes.UInt8) {
        method = Identifier.For("WriteByte");
      } else if( type == SystemTypes.Single) {
        method = Identifier.For("WriteSingle");
      } else if( type == SystemTypes.TimeSpan) {
        method = Identifier.For("WriteTimeSpan");
      } else if( type == SystemTypes.UInt16 ) {
        method = Identifier.For("WriteUInt16");
      } else if( type == SystemTypes.UInt32) {
        method = Identifier.For("WriteUInt32");
      } else if( type == SystemTypes.UInt64) {
        method = Identifier.For("WriteUInt64");
      } else {
        Expression conversion = GetConvertToString(type, src, false);
        if (conversion != null) {
          statements = AddCheckForNull(statements, Duplicate(src, referringType), type);
          method = Identifier.For("WriteString");
          args = new ExpressionList(conversion);
        } else {
          return false;
        } 
      }
    
      if (name != null) {        
        Identifier id = Checker.GetDefaultElementName(type);
        string defaultName = id.Name;
        string defaultNamespace = (id.Prefix != null) ? id.Prefix.Name : null;
        Expression localName = new Local(SystemTypes.String);
        Expression localNamespace = new Local(SystemTypes.String);
        Expression safeName = name;
        if (name is Literal) {
          if (name == Literal.Null) {
            localName =  new Literal(defaultName, SystemTypes.String);
            localNamespace = new Literal(defaultNamespace, SystemTypes.String);
          } else {
            localName = name;
            localNamespace = ns;
          }
        } else {
          If nameNull = new If(new BinaryExpression(name, Literal.Null, NodeType.Eq), new Block(new StatementList()), new Block(new StatementList()));
          nameNull.TrueBlock.Statements.Add(new AssignmentStatement(localName, new Literal(defaultName, SystemTypes.String)));
          nameNull.TrueBlock.Statements.Add(new AssignmentStatement(localNamespace, new Literal(defaultNamespace, SystemTypes.String)));
          nameNull.FalseBlock.Statements.Add(new AssignmentStatement(localName, name));
          nameNull.FalseBlock.Statements.Add(new AssignmentStatement(localNamespace, ns));
          statements.Add(nameNull);
        }

        MethodCall call = new MethodCall();
        call.Callee = new QualifiedIdentifier(writer,Identifier.For("WriteStartElement"));
        call.Operands = new ExpressionList();
        call.Operands.Add(localName);
        call.Operands.Add(localNamespace);
        statements.Add( new ExpressionStatement( call ) );
      }
      StatementList notNull = statements;
      if (!type.IsValueType) {
        notNull = AddCheckForNull(statements, Duplicate(src, referringType), type);
      }        
      notNull.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(writer, method), args)));

      if (name != null) {
        MethodCall call = new MethodCall();
        call.Callee = new QualifiedIdentifier(writer,Identifier.For("WriteEndElement"));
        call.Operands = new ExpressionList();
        statements.Add( new ExpressionStatement( call ) );      
      }
      return true;
    }
Beispiel #40
0
 void InvalidContent(StatementList statements, Identifier reader, string expecting) {
   statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(reader, Identifier.For("InvalidContent")),
     new ExpressionList(new Expression[1]{ new Literal(expecting, SystemTypes.String)}))));
 }
Beispiel #41
0
    If AddReadChild(Block scope, StatementList statements, Identifier name, TypeNode type, Expression target, Identifier reader, Expression result, bool unwrapChild, bool ignoreNamespace) {
      ExpressionList args = new ExpressionList();
      args.Add(new Literal(name.Name, SystemTypes.String));
      if (name.Prefix != null) args.Add(new Literal(name.Prefix.Name, SystemTypes.String));
      
      // see if we're on a text node...
      Local nodeType = new Local(Identifier.For("nodeType"), Runtime.XmlNodeType, scope);
      statements.Add(new AssignmentStatement(nodeType, new QualifiedIdentifier(reader, Identifier.For("NodeType"))));
      StatementList ifTextStatements = new StatementList();      
      If ifIsText = new If(
        new BinaryExpression(IsTextNode(nodeType),
          new BinaryExpression(nodeType,
            new QualifiedIdentifier(Identifier.For("XmlNodeType"), Identifier.For("EndElement")), NodeType.Eq),
        NodeType.Or), new Block(ifTextStatements), new Block(new StatementList()));            
      statements.Add(ifIsText);
      
      // then see if we can force the text into the desired type.
      TypeNode unwrapped = UnwrapSingletonTuple(Unwrap(type), false);
      if (unwrapped == null) unwrapped = type;
      Expression readString = new MethodCall(new QualifiedIdentifier(reader, Identifier.For("ReadString")), null, NodeType.Callvirt, SystemTypes.String);
      Expression coercion = GetConvertFromString(unwrapped, readString, false);
      if (coercion != null) {
        ifTextStatements = ifIsText.TrueBlock.Statements;
        ifTextStatements.Add(new AssignmentStatement(target, CastTo(CastTo(coercion, unwrapped),type)));
        ifTextStatements.Add(new AssignmentStatement(result, Literal.True));        
      }
      statements = ifIsText.FalseBlock.Statements;

      If ifFound = null;
      string method = ignoreNamespace ? "IsStartElementIgnoreNamespace" : "IsStartElement";
      MethodCall isStartEle = new MethodCall(new QualifiedIdentifier(reader, Identifier.For(method)), args);
      ifFound = new If(isStartEle, new Block(new StatementList()), new Block(new StatementList()));
      statements.Add(ifFound);
      statements = ifFound.TrueBlock.Statements;       
      
      statements.Add(new AssignmentStatement(result, Literal.True));

      // body of if test, parse the child element as the specified type.
      MethodCall read = new MethodCall(new QualifiedIdentifier(reader, Identifier.For("Read")), new ExpressionList());
      bool isStructuralType = this.IsStructuralType(type);
      if (isStructuralType && unwrapChild) {
        // consume member element wrapper.
        statements.Add(new ExpressionStatement(read));
      }
      if (type.Template == SystemTypes.GenericBoxed){
        type = Checker.GetCollectionElementType(type);
      }

      if (!AddReadSimpleType(type, statements, reader, target, result, false)) {
        AddCallDeserializer(type, statements, reader, target, result, result);
      }
      if (isStructuralType && unwrapChild) {
        // consume member element end tag wrapper.
        statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(reader, Identifier.For("ReadEndTag")), new ExpressionList(new Literal(name.Name, SystemTypes.String)))));
      }
      return ifFound;
    }
Beispiel #42
0
        private static int ExtractVB_ENCCallToPreamble(Block firstBlock, int currentIndex, StatementList preamble)
        {
            if (firstBlock == null) return currentIndex;

            while (currentIndex < firstBlock.Statements.Count)
            {
                Statement s = firstBlock.Statements[currentIndex];
                if (s != null && s.NodeType != NodeType.Nop)
                {
                    // check for VB literal assignments
                    if (!s.SourceContext.Hidden) break;

                    var es = s as ExpressionStatement;
                    
                    if (es != null)
                    {
                        MethodCall call = es.Expression as MethodCall;
                        if (call != null)
                        {
                            var mb = call.Callee as MemberBinding;
                            if (mb == null) break;

                            var encMethod = mb.BoundMember as Method;
                            if (encMethod == null) break;
                            
                            if (encMethod.Name.Name != "__ENCAddToList") break;
                            
                            // okay, we are calling the VB memory leak, put it into the preamble
                            goto addToPreamble;
                        }
                    }

                    break; // don't skip other stuff
                }

                if (s == null) continue;
                
            addToPreamble:
                preamble.Add(s);
                
                var oldCount = firstBlock.Statements.Count;
                var oldStats = firstBlock.Statements;
                
                firstBlock.Statements[currentIndex] = null;
                
                Contract.Assert(oldStats == firstBlock.Statements);
                Contract.Assert(oldCount == firstBlock.Statements.Count);
                
                currentIndex++;
                
                Contract.Assert(currentIndex <= firstBlock.Statements.Count);
            }

            return currentIndex;
        }
Beispiel #43
0
 void AddError(StatementList statements, Identifier reader, RuntimeError code, params Expression[] args) {
   ExpressionList list = new ExpressionList();
   list.Add(new Literal(code, Runtime.RuntimeError));
   foreach (Expression e in args) list.Add(e);
   statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(reader, Identifier.For("Error")), list)));
 }
Beispiel #44
0
        internal static StatementList ExtractClump(StatementList blocks, int firstBlockIndex, int firstStmtIndex,
            int lastBlockIndex, int lastStmtIndex, AssumeBlock assumeBlock = null)
        {
            Contract.Requires(blocks != null);
            Contract.Requires(firstBlockIndex >= 0);
            Contract.Requires(firstStmtIndex >= 0);

            Contract.Ensures(Contract.Result<StatementList>().Count == lastBlockIndex - firstBlockIndex + 1);
            Contract.Ensures(blocks[firstBlockIndex] == Contract.OldValue(blocks[firstBlockIndex]));

            StatementList clump = new StatementList();

            // first extract the tail of the first block into a new block.
            Block oldFirstBlock = (Block) blocks[firstBlockIndex];
            Block newFirstBlock = new Block(new StatementList());
            
            if (oldFirstBlock != null)
            {
                var count = firstBlockIndex == lastBlockIndex ? lastStmtIndex + 1 : oldFirstBlock.Statements.Count;
                for (int stmtIndex = firstStmtIndex; stmtIndex < count; stmtIndex++)
                {
                    var stmt = oldFirstBlock.Statements[stmtIndex];
                    newFirstBlock.Statements.Add(stmt);
                    
                    if (stmt == null) continue;

                    oldFirstBlock.Statements[stmtIndex] = assumeBlock;
                    assumeBlock = null;
                }
            }

            clump.Add(newFirstBlock);
            
            var currentBlockIndex = firstBlockIndex + 1;
            
            if (currentBlockIndex > lastBlockIndex) return clump;

            // setup info about forwarding branches to new last full block
            Block newLastBlock = null;

            var lastFullBlock = lastBlockIndex - 1;
            var oldLastBlock = (Block) blocks[lastBlockIndex];
            
            if (oldLastBlock != null && lastStmtIndex == oldLastBlock.Statements.Count - 1)
            {
                // last block is also fully used.
                lastFullBlock = lastBlockIndex;
            }
            else
            {
                newLastBlock = new Block(new StatementList());

                // check if first block had a branch
                if (newFirstBlock != null && newFirstBlock.Statements != null && newFirstBlock.Statements.Count > 0)
                {
                    // check if we need to adjust branch to last block
                    var branch = newFirstBlock.Statements[newFirstBlock.Statements.Count - 1] as Branch;
                    if (branch != null && branch.Target != null && branch.Target.UniqueKey == oldLastBlock.UniqueKey)
                    {
                        branch.Target = newLastBlock;
                    }
                }
            }

            // Next extract full blocks between currentBlockIndex and including lastFullBlock
            for (; currentBlockIndex <= lastFullBlock; currentBlockIndex++)
            {
                var block = (Block) blocks[currentBlockIndex];

                // don't skip null blocks since context relies on number
                clump.Add(block);

                if (block == null) continue;
                
                blocks[currentBlockIndex] = assumeBlock;
                assumeBlock = null;
                
                if (newLastBlock != null && block.Statements != null && block.Statements.Count > 0)
                {
                    // check if we need to adjust branch to last block
                    var branch = block.Statements[block.Statements.Count - 1] as Branch;
                    if (branch != null && branch.Target != null && branch.Target.UniqueKey == oldLastBlock.UniqueKey)
                    {
                        branch.Target = newLastBlock;
                    }
                }
            }

            // next, if last block wasn't full, we have a new last block, extract the prefix
            if (newLastBlock != null)
            {
                for (int i = 0; i < lastStmtIndex + 1; i++)
                {
                    newLastBlock.Statements.Add(oldLastBlock.Statements[i]);
                    oldLastBlock.Statements[i] = assumeBlock;
                    assumeBlock = null;
                }

                clump.Add(newLastBlock);
            }

            return clump;
        }
Beispiel #45
0
 void AddWriteString(StatementList statements, TypeNode referringType, Identifier writer, Expression src) {
   statements = AddCheckForNull(statements, Duplicate(src, referringType), SystemTypes.String);
   statements.Add( new ExpressionStatement(
     new MethodCall(new QualifiedIdentifier(writer,Identifier.For("WriteString")),
     new ExpressionList(src))));
 }
Beispiel #46
0
    If AddEmptyElementCheck(StatementList statements, Identifier reader) {
      // make sure the element is not empty.
      If isEmpty = new If(new BinaryExpression(new QualifiedIdentifier(reader, Identifier.For("IsEmptyElement")), Literal.True, NodeType.Eq),
        new Block(new StatementList()), new Block(new StatementList()));

      statements.Add(isEmpty);

      statements = isEmpty.TrueBlock.Statements;
      // consume empty start tag and just return.
      statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(reader, Identifier.For("Read")), new ExpressionList())));
  
      return isEmpty;
    }
Beispiel #47
0
    //================= reader methods ==========================================    
    void AddReadAttributes(TypeNode type, StatementList statements, Identifier reader, Expression target, SchemaValidator validator) {

      if (validator.Attributes != null) {
        Block whileBody = new Block(new StatementList());
        Literal trueLit = Literal.True;
        MethodCall movenext = new MethodCall(new QualifiedIdentifier(reader, Identifier.For("MoveToNextAttribute")), new ExpressionList());
        BinaryExpression condition = new BinaryExpression(movenext, trueLit, NodeType.Eq);
        While w = new While(condition, whileBody);
        statements.Add(w);
        Block lastElseBlock = null;

        Local nameLocal = new Local(SystemTypes.String);
        whileBody.Statements.Add(new AssignmentStatement(nameLocal, new QualifiedIdentifier(reader, Identifier.For("LocalName"))));
        Local nsLocal = new Local(SystemTypes.String);
        whileBody.Statements.Add(new AssignmentStatement(nsLocal, new QualifiedIdentifier(reader, Identifier.For("NamespaceURI"))));

        foreach (SchemaAttDef ad in validator.Attributes) {
          // todo: any way to do tokenized compares?
          BinaryExpression nameEqual = new BinaryExpression(nameLocal,
            new Literal(ad.Name.Name, SystemTypes.String), NodeType.Eq);
          BinaryExpression nsEqual = new BinaryExpression(nsLocal,
            new Literal(ad.Name.Prefix != null ? ad.Name.Prefix.Name : "", SystemTypes.String), NodeType.Eq);
          Block elseBlock = new Block(new StatementList());
          If ifExpr = new If(new BinaryExpression(nameEqual, nsEqual, NodeType.And), new Block(new StatementList()), elseBlock);
          if (lastElseBlock != null) {
            lastElseBlock.Statements.Add(ifExpr);
          } else {
            whileBody.Statements.Add(ifExpr);
          }
          lastElseBlock = elseBlock;

          // body of if test, parse the attribute value as the specified type.
          Debug.Assert(ad.Member is Field || ad.Member is Property);
          AddReadSimpleType(Checker.GetMemberType(ad.Member), ifExpr.TrueBlock.Statements, reader, GetMemberBinding(target, ad.Member), null, true);
        }
        //todo: report unknown attributes?
      }
    }
Beispiel #48
0
    void AddWriteChoice(TypeUnion tu, StatementList statements, TypeNode referringType, Expression src, Identifier writer) {
      // generate the following code:
      //    Type srcType = src.GetType();
      //    if (choiceType.IsAssignableFrom(srcType)){ 
      //      XxxxSerializer s = new XxxxSerializer();
      //      s.Serialize((runtimeType)src, writer);
      //    } else if (...) {
      //      // and so on.
      //    }
      // What we cannot do here is by creating nested XmlSerializers
      // based on runtime type because this could cause infinite recurrsion.
      // So we cannot serialize a type union where one of the choices is "object".

      TypeNodeList choices = tu.Types;

      MethodCall call = new MethodCall();
      call.Callee = new QualifiedIdentifier(src, Identifier.For("GetType"));
      call.Operands = new ExpressionList();

      Local local = new Local(SystemTypes.Type);
      statements.Add(new AssignmentStatement(local, call));

      for (int i = 0, n = choices.Length; i < n; i++) {
        TypeNode choiceType = choices[i];
        if (choiceType == null) continue; // type resolution error.

        // if (choiceType.IsAssignableFrom(srcType)){ 
        BinaryExpression condition = new BinaryExpression(
          new MethodCall(
            new QualifiedIdentifier(new UnaryExpression(new MemberBinding(null, choiceType), NodeType.Typeof), Identifier.For("IsAssignableFrom")),
            new ExpressionList(new Expression[] { local })),
          Literal.True,
          NodeType.Eq);

        Block block = new Block();
        block.Statements = new StatementList();
        BinaryExpression cast = CastTo(src, choiceType);

        Expression name = null, ns = null;
        GetNameAndNamespace(choiceType, out name, out ns);
        Expression simplename = name, simplens = ns;

        // Check for choice of type: [string] and match this with XmlTextNode.
        TypeNode unwrapped = UnwrapSingletonTuple(choiceType, true);
        if (unwrapped == null) unwrapped = choiceType;
        if (unwrapped != null && unwrapped.IsPrimitive) {
          simplename = simplens = null;
          choiceType = unwrapped;
        }

        if (!AddWriteSimpleType(choiceType, block.Statements, referringType, writer, cast, simplename, simplens)) {
          AddCallSerializer(choiceType, block.Statements, cast, writer, name, ns);
        }
        If ifStatement = new If(condition, block, null);
        statements.Add(ifStatement);
      } 
    }
Beispiel #49
0
 public override InstanceInitializer InjectDefaultConstructor(TypeNode typeNode) {
   if (this.DontInjectDefaultConstructors || typeNode.IsNormalized) return null;
   Class Class = typeNode as Class;
   if (Class != null && Class.Name != null && !(Class is ClassParameter) && ClassHasNoExplicitConstructors(typeNode)) {
     if (Class.IsAbstractSealedContainerForStatics) return null;
     if (Class.PartiallyDefines != null){
       this.InjectDefaultConstructor(Class.PartiallyDefines);
       InstanceInitializer defCons = Class.PartiallyDefines.GetConstructor();
       if (defCons != null && !defCons.HasCompilerGeneratedSignature) 
         defCons = null; //Not an orphan
       if (defCons != null){
         //This is an injected default constructor that is an orphan, adopt it
         defCons.HasCompilerGeneratedSignature = false; //abuse this flag to stop other partial types from adopting it
         Class.Members.Add(defCons);
         Class.BaseClass = ((Class)Class.PartiallyDefines).BaseClass;
       }
       return defCons; //Ok if defCons null, this type should not show up in inheritance chains
     }else{
       //Inject a default constructor
       This thisParameter = new This(Class);
       Class baseClass = Class.BaseClass;
       StatementList statements = new StatementList(2);
       statements.Add(new FieldInitializerBlock(typeNode, false));
       if (baseClass != null) {
         MethodCall mcall = new MethodCall(new QualifiedIdentifier(new Base(), StandardIds.Ctor, typeNode.Name.SourceContext), null);
         mcall.SourceContext = typeNode.Name.SourceContext;
         ExpressionStatement callSupCons = new ExpressionStatement(mcall);
         callSupCons.SourceContext = typeNode.Name.SourceContext;
         statements.Add(callSupCons);
       }
       InstanceInitializer defCons = new InstanceInitializer(typeNode, null, null, new Block(statements));
       defCons.Name = new Identifier(".ctor", typeNode.Name.SourceContext);
       defCons.SourceContext = typeNode.Name.SourceContext;
       defCons.ThisParameter = thisParameter;
       if (typeNode.IsAbstract)
         defCons.Flags |= MethodFlags.Family|MethodFlags.HideBySig;
       else
         defCons.Flags |= MethodFlags.Public|MethodFlags.HideBySig;
       defCons.CallingConvention = CallingConventionFlags.HasThis;
       defCons.IsCompilerGenerated = true;
       typeNode.Members.Add(defCons);
       return defCons;
     }
   }
   return null;
 }
 public virtual Differences VisitStatementList(StatementList list1, StatementList list2,
   out StatementList changes, out StatementList deletions, out StatementList insertions){
   changes = list1 == null ? null : list1.Clone();
   deletions = list1 == null ? null : list1.Clone();
   insertions = list1 == null ? new StatementList() : list1.Clone();
   //^ assert insertions != null;
   Differences differences = new Differences();
   for (int j = 0, n = list2 == null ? 0 : list2.Count; j < n; j++){
     //^ assert list2 != null;
     Statement nd2 = list2[j];
     if (nd2 == null) continue;
     insertions.Add(null);
   }
   TrivialHashtable savedDifferencesMapFor = this.differencesMapFor;
   this.differencesMapFor = null;
   TrivialHashtable matchedNodes = new TrivialHashtable();
   for (int i = 0, k = 0, n = list1 == null ? 0 : list1.Count; i < n; i++){
     //^ assert list1 != null && changes != null && deletions != null;
     Statement nd1 = list1[i]; 
     if (nd1 == null) continue;
     Differences diff;
     int j;
     Statement nd2 = this.GetClosestMatch(nd1, list1, list2, i, ref k, matchedNodes, out diff, out j);
     if (nd2 == null || diff == null){Debug.Assert(nd2 == null && diff == null); continue;}
     matchedNodes[nd1.UniqueKey] = nd1;
     matchedNodes[nd2.UniqueKey] = nd2;
     changes[i] = diff.Changes as Statement;
     deletions[i] = diff.Deletions as Statement;
     insertions[i] = diff.Insertions as Statement;
     insertions[n+j] = nd1; //Records the position of nd2 in list2 in case the change involved a permutation
     Debug.Assert(diff.Changes == changes[i] && diff.Deletions == deletions[i] && diff.Insertions == insertions[i]);
     differences.NumberOfDifferences += diff.NumberOfDifferences;
     differences.NumberOfSimilarities += diff.NumberOfSimilarities;
   }
   //Find deletions
   for (int i = 0, n = list1 == null ? 0 : list1.Count; i < n; i++){
     //^ assert list1 != null && changes != null && deletions != null;
     Statement nd1 = list1[i]; 
     if (nd1 == null) continue;
     if (matchedNodes[nd1.UniqueKey] != null) continue;
     changes[i] = null;
     deletions[i] = nd1;
     insertions[i] = null;
     differences.NumberOfDifferences += 1;
   }
   //Find insertions
   for (int j = 0, n = list1 == null ? 0 : list1.Count, m = list2 == null ? 0 : list2.Count; j < m; j++){
     //^ assert list2 != null;
     Statement nd2 = list2[j]; 
     if (nd2 == null) continue;
     if (matchedNodes[nd2.UniqueKey] != null) continue;
     insertions[n+j] = nd2;  //Records nd2 as an insertion into list1, along with its position in list2
     differences.NumberOfDifferences += 1; //REVIEW: put the size of the tree here?
   }
   if (differences.NumberOfDifferences == 0){
     changes = null;
     deletions = null;
     insertions = null;
   }
   this.differencesMapFor = savedDifferencesMapFor;
   return differences;
 }
Beispiel #51
0
    void AddCallSerializer(TypeNode srcType, StatementList statements, Expression src, Identifier writer, Expression rootName, Expression rootNamespace ) {

      TypeNode type = Unwrap(srcType);

      Class memberSerializer = this.CreateSerializerFor(type);
      // call the Serialize method on it, passing the member we're serializing.
      ExpressionList args = new ExpressionList();
      args.Add(src);
      args.Add(writer);
      args.Add(rootName);
      args.Add(rootNamespace);
      MethodCall call = new MethodCall();
      Method serialize = memberSerializer.GetMethod(Identifier.For("Serialize"), new TypeNode[4] { type, Runtime.XmlSerializationWriter, SystemTypes.String, SystemTypes.String} );
      call.Callee = new MemberBinding(new MemberBinding(null, memberSerializer), serialize);
      call.Operands = args;
      statements.Add( new ExpressionStatement( call ) );    
    }
Beispiel #52
0
    void AddReadAlias( Block block, TypeAlias alias, StatementList statements, Identifier reader, 
      Expression target, Expression required, Expression result) {

      Local local = new Local(Identifier.Empty, alias.AliasedType, block);
      AddReadRequiredChild(block, statements, alias.Name, alias.AliasedType, local, reader, result, required, true, true);
      statements.Add(new AssignmentStatement(target, this.tempChecker.typeSystem.ImplicitCoercion(local, target.Type)));

    }
Beispiel #53
0
    void AddWriteStream(TypeNode type, StatementList statements, TypeNode referringType, Expression src, Identifier writer) {
      // Generate the following code:
      // XxxxSerializer s = new XxxxSerializer();
      // foreach (Xxxx x in src) {
      //    s.Serialize(x,writer);
      // }
      // Where Xxxx is the element type for the given stream type.

      if (type.Template == SystemTypes.GenericNonEmptyIEnumerable) {
        type = Checker.GetIEnumerableTypeFromNonEmptyIEnumerableStruct(this.module, type);
      } else {
        statements = AddCheckForNull(statements, Duplicate(src, referringType), type);
      }
      TypeNode ceType = Checker.GetCollectionElementType(type);  
      //todo: should check that type has an IEnumerator.

      Identifier loopVariable = Identifier.For("e");
      loopVariable.Type = ceType;
      Block body = new Block();
      body.Statements = new StatementList();

      Expression name, ns;
      GetNameAndNamespace(ceType, out name, out ns);

      // call the Serialize method on it, passing the member we're serializing.  
      if (!AddWriteSimpleType(ceType, body.Statements, referringType, writer, loopVariable, name, ns)) {
        AddCallSerializer(ceType, body.Statements, loopVariable, writer, name, ns);
      }

      ForEach fe = new ForEach(ceType, loopVariable, src, body);      
      statements.Add(fe);
    }
Beispiel #54
0
 void AddReadOptional(Block block, StatementList statements, Member mem, Expression target, Identifier reader, Expression result) {
   TypeNode boxed = Checker.GetMemberType(mem);
   TypeNode type = Checker.GetCollectionElementType(boxed);
   statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(reader, Identifier.For("MoveToContent")), new ExpressionList())));
   Local nameLocal = new Local(Identifier.For("name"),SystemTypes.String, block);
   Local nsLocal = new Local(Identifier.For("ns"),SystemTypes.String, block);
   statements.Add(new AssignmentStatement(nameLocal, new QualifiedIdentifier(reader, Identifier.For("LocalName"))));
   statements.Add(new AssignmentStatement(nsLocal, new QualifiedIdentifier(reader, Identifier.For("NamespaceURI"))));
   StringBuilder expecting = new StringBuilder();
   Expression isFound = null;
   if (mem.IsAnonymous) {
     isFound = IsStartOf(block, type, statements, nameLocal, nsLocal, expecting);    
   } else {
     ExpressionList args = new ExpressionList();
     args.Add(new Literal(mem.Name.Name, SystemTypes.String));
     isFound = new MethodCall(new QualifiedIdentifier(reader, Identifier.For("IsStartElement")), args);
   }
   StatementList trueStatements = new StatementList();
   If ifIsFound = new If(isFound, new Block(trueStatements), null);
   statements.Add(ifIsFound);
   
   if (!AddReadSimpleType(type, trueStatements, reader, target, result, false)) {
     Local localRequired = new Local(Identifier.Empty,SystemTypes.Boolean,block);
     statements.Add(new AssignmentStatement(localRequired, Literal.True));
     AddCallDeserializer(type, trueStatements, reader, target, localRequired, result);            
   } 
 }
Beispiel #55
0
    void AddReadContent(Class serializer, Block block, TypeNode type, StatementList statements, Identifier reader, 
      Expression target, Expression required, Expression result, SchemaValidator validator) {
    
      // position us in the content.
      statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(reader, Identifier.For("MoveToContent")), new ExpressionList())));
      Local elementName = new Local(Identifier.Empty,SystemTypes.String);
      statements.Add(new AssignmentStatement(elementName, new QualifiedIdentifier(reader, Identifier.For("LocalName"))));
      
      // make sure the element is not empty.
      If isEmpty = AddEmptyElementCheck(statements, reader);

      // Read the contents.
      statements = isEmpty.FalseBlock.Statements;
      statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(reader, Identifier.For("Read")), new ExpressionList())));
      statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(reader, Identifier.For("MoveToContent")), new ExpressionList())));

      ValidationState context = new ValidationState();
      context.ErrorHandler = this.errorHandler;
      validator.validator.InitValidation(context);
      ArrayList members = null;
      if (validator.validator is AllElementsContentValidator) {
        members = validator.validator.ExpectedElements(context, false, false);
        AddReadAllGroup(serializer, block, type, statements, reader, target, required, result, members, validator.validator.MixedMember);
      } else {

        // There should be one root level anonymous Item0 member.
        SequenceNode seq = (SequenceNode)validator.RootNode; // this is a wrapper node.
        if (seq == null) {
          // perhaps it is ContentType.Empty or Mixed.
          if (validator.validator.ContentType == XmlSchemaContentType.Mixed ||
            validator.validator.ContentType == XmlSchemaContentType.TextOnly){
            Debug.Assert(validator.validator.MixedMember != null);
            statements.Add(new AssignmentStatement(GetMemberBinding(target, validator.validator.MixedMember), 
              new MethodCall(new QualifiedIdentifier(reader, Identifier.For("ReadStringElement")), new ExpressionList())));         
          }
          return;
        } else {
          ContentNode n = seq.LeftChild;
          AddReadContentNode(n, block, statements, reader, target, required, result, validator);
        }
      }    

      // consume final end tag
      statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(reader, Identifier.For("ReadEndTag")), new ExpressionList(elementName))));
    }
Beispiel #56
0
 void AddConsoleWriteLine(StatementList statements, Expression e) {
   statements.Add(new ExpressionStatement(
     new MethodCall(new QualifiedIdentifier(Identifier.For("Console"), Identifier.For("WriteLine")),
     new ExpressionList(new Expression[1] { e }
     ))));
 }
Beispiel #57
0
    void AddReadAllGroup(Class serializer, Block block, TypeNode type, StatementList statements, Identifier reader, 
      Expression target, Expression required, Expression result, ArrayList members, Member mixedMember) {

      // todo: keep track of which members have been read and report error on duplicates
      MethodCall read = new MethodCall(new QualifiedIdentifier(reader, Identifier.For("Read")), new ExpressionList());

      Local sb = new Local(SystemTypes.StringBuilder);
      bool isMixed = mixedMember != null;
      if (isMixed) {
        statements.Add(new AssignmentStatement(sb,
          new Construct(new MemberBinding(null, SystemTypes.StringBuilder), new ExpressionList(), SystemTypes.StringBuilder)));
      }

      Block whileBody = new Block(new StatementList());
      BinaryExpression notEndTag = new BinaryExpression(
        new QualifiedIdentifier(reader, Identifier.For("NodeType")) ,
        new QualifiedIdentifier(Identifier.For("XmlNodeType"), Identifier.For("EndElement")), NodeType.Ne);
      BinaryExpression notEOF = new BinaryExpression(
        new QualifiedIdentifier(reader, Identifier.For("EOF")), Literal.True, NodeType.Ne);
      While w = new While(new BinaryExpression(notEndTag, notEOF, NodeType.And), whileBody);
      statements.Add(w);

      Local nameLocal = new Local(Identifier.For("name"),SystemTypes.String,block);
      Local nsLocal = new Local(Identifier.For("ns"),SystemTypes.String,block);
      Local nodeType = new Local(Identifier.For("nodeType"),Runtime.XmlNodeType,block);

      whileBody.Statements.Add(new AssignmentStatement(nameLocal, new QualifiedIdentifier(reader, Identifier.For("LocalName"))));
      whileBody.Statements.Add(new AssignmentStatement(nsLocal, new QualifiedIdentifier(reader, Identifier.For("NamespaceURI"))));
      whileBody.Statements.Add(new AssignmentStatement(nodeType, new QualifiedIdentifier(reader, Identifier.For("NodeType"))));
      
      Block childBlock = whileBody;

      if (isMixed) {
        // Append the text node to the current StringBuilder contents.
        childBlock = new Block(new StatementList());
        If ifText = new If(IsTextNode(nodeType), new Block(new StatementList()), childBlock);

        whileBody.Statements.Add(ifText);
        ExpressionList args = new ExpressionList();
        args.Add(new QualifiedIdentifier(reader, Identifier.For("Value")));
        ifText.TrueBlock.Statements.Add(new ExpressionStatement(new MethodCall(
          new QualifiedIdentifier(sb, Identifier.For("Append")), args)));
        ifText.TrueBlock.Statements.Add(new ExpressionStatement(read)); // advance to next node
      }      

      If ifElement = new If(new BinaryExpression(nodeType,
        new QualifiedIdentifier(Identifier.For("XmlNodeType"), Identifier.For("Element")), NodeType.Eq),
        new Block(new StatementList()), new Block(new StatementList()));
      childBlock.Statements.Add(ifElement);
      childBlock = ifElement.TrueBlock;

      //AddConsoleWrite(statements, new Literal("name=",SystemTypes.String));
      //AddConsoleWriteLine(statements, nameLocal);
      //AddConsoleWrite(statements, new Literal("nodeType=",SystemTypes.String));
      //AddConsoleWriteLine(statements, nodeType);

      foreach (NamedNode childNode in members) {
        if (!(childNode.Member is Field || childNode.Member is Property)) {
          AddError(statements, reader, RuntimeError.SerializationOfTypeNotSupported, 
            new Literal(childNode.Member.GetType().FullName, SystemTypes.String));
        } else {
          Expression mb = GetMemberBinding(target, childNode.Member);
          childBlock = AddReadChild(block, childBlock.Statements, childNode.Name, childNode.TypeNode, mb, reader, result, true, false).FalseBlock;
          // todo: throw error if child is required. (e.g. NonEmptyIEnumerable...)
        }
      }
      // if it isn't any of the expected elements then throw an error.
      AddError(childBlock.Statements, reader, RuntimeError.NoSuchMember,
        new Expression[2]{new Literal(tempChecker.GetTypeName(type),SystemTypes.String), nameLocal});

      // If it's not an element then consume it anyway to keep the reader advancing.
      // Probably a comment or PI or something.
      ifElement.FalseBlock.Statements.Add(new ExpressionStatement(new MethodCall(
        new QualifiedIdentifier(reader, Identifier.For("Skip")), new ExpressionList())));

      if (isMixed) {
        statements.Add(new AssignmentStatement(GetMemberBinding(target, mixedMember), 
          new MethodCall(new QualifiedIdentifier(sb, Identifier.For("ToString")), new ExpressionList())));         
      }
      statements.Add(new AssignmentStatement(result, Literal.True));

    }
Beispiel #58
0
    void AddReadChoice(Block block, TypeUnion tu, StatementList statements, Identifier reader, 
      Expression target, Expression required, Expression result){
      // Read next element and figure out which of the choices in the type union it is then read the matching Type.
      
      Local nameLocal = new Local(Identifier.For("name"),SystemTypes.String,block);
      Local nsLocal = new Local(Identifier.For("ns"),SystemTypes.String,block);
      Local nodeType = new Local(Identifier.For("nodeType"),Runtime.XmlNodeType,block);
      statements.Add(new AssignmentStatement(nameLocal, new QualifiedIdentifier(reader, Identifier.For("LocalName"))));
      statements.Add(new AssignmentStatement(nsLocal, new QualifiedIdentifier(reader, Identifier.For("NamespaceURI"))));
      statements.Add(new AssignmentStatement(nodeType, new QualifiedIdentifier(reader, Identifier.For("NodeType"))));

      Local localRequired = new Local(Identifier.Empty,SystemTypes.Boolean,block);
      statements.Add(new AssignmentStatement(localRequired, Literal.True));

      Expression readString = new MethodCall(new QualifiedIdentifier(reader, Identifier.For("ReadString")), null, NodeType.Callvirt, SystemTypes.String);
      
      If ifIsElement = new If(new BinaryExpression(nodeType, 
                              new QualifiedIdentifier(Identifier.For("XmlNodeType"), Identifier.For("Element")), NodeType.Eq),
                              new Block(new StatementList()), new Block(new StatementList()));
      statements.Add(ifIsElement);
        
      StatementList elseList = ifIsElement.TrueBlock.Statements;
      StringBuilder expecting = new StringBuilder();
      Expression bestCoercion = null;
      TypeNode bestChoice = null;
      TypeNode bestUnwrappedChoice = null;
      bool stringCoercionAmbiguous = false;

      for (int i = 0, n = tu.Types.Length; i < n; i++) {
        TypeNode choice = tu.Types[i];
        if (choice == null) continue; // type resolution error.

        TypeNode unwrapped = UnwrapSingletonTuple(Unwrap(choice), false);
        if (unwrapped == null) unwrapped = choice;
        Expression coercion = GetConvertFromString(unwrapped, readString, false);
        if (coercion != null) {
          // Keep track of the best coercion to string and use this to handle text nodes below.
          if (bestChoice == null){
            bestChoice = choice;
            bestUnwrappedChoice = unwrapped;
            bestCoercion = coercion;
          } else if (tempTypeSystem.IsBetterMatch(unwrapped, bestUnwrappedChoice, SystemTypes.String)) {
            bestChoice = choice;
            bestUnwrappedChoice = unwrapped;
            bestCoercion = coercion;
          } else {
            stringCoercionAmbiguous = true;
          }
        }

        BinaryExpression be = IsStartOf(block, choice, statements, nameLocal, nsLocal, expecting);    
        StatementList trueStatements = new StatementList();
        If ifIsStartOf = new If(be, new Block(trueStatements), new Block(new StatementList()));
        elseList.Add(ifIsStartOf);
        Local choiceTarget = new Local(Identifier.Empty, choice, block);
        if (choice.Template == SystemTypes.GenericBoxed){
          choice = Checker.GetCollectionElementType(choice);
        }
        if (!AddReadSimpleType(choice, trueStatements, reader, choiceTarget, result, false)) {
          AddCallDeserializer(choice, trueStatements, reader, choiceTarget, localRequired, result);            
        } 
        trueStatements.Add(new AssignmentStatement(target, 
          CastTo(choiceTarget, target.Type)));

        elseList = ifIsStartOf.FalseBlock.Statements;
      }
      if (bestCoercion != null && !stringCoercionAmbiguous) {      
        // Then we can also accept text nodes
        StatementList ifTextStatements = new StatementList();
        If ifIsText = new If(IsTextNode(nodeType), new Block(ifTextStatements), null);            
        ifIsElement.FalseBlock.Statements.Add(ifIsText);
        // then we can also handle text nodes in this choice.
        ifTextStatements.Add(new AssignmentStatement(target, CastTo(CastTo(bestCoercion, bestChoice), tu)));
        ifTextStatements.Add(new AssignmentStatement(result, Literal.True));        
      }

      // If this was a required element, then throw an error.
      If isRequired = new If(new BinaryExpression(required, Literal.True, NodeType.Eq), 
        new Block(new StatementList()), new Block(new StatementList()));
      elseList.Add(isRequired);
      InvalidContent(isRequired.TrueBlock.Statements, reader, expecting.ToString());
      isRequired.FalseBlock.Statements.Add(new AssignmentStatement(result, Literal.False));

    }
        /// <summary>
        /// Visits the ForEachStatement Node and collects information from it.
        /// </summary>
        /// <param name="forEachStatement">The ForEachStatement</param>
        public override Node Visit(ForEachStatement forEachStatement)
        {
            if (expandForEachStatements)
            {
                // run analysis on collection
                VisitDynamic(forEachStatement.Collection);

                var inference = forEachStatement.Collection.TypeInference.Declaration as Variable;
                if (!(inference != null && inference.Type is ArrayType))
                    return forEachStatement;

                if ((inference.Type as ArrayType).Dimensions.Count > 1)
                {
                    Error(XenkoMessageCode.ErrorMultiDimArray, forEachStatement.Span, inference, forEachStatement, analyzedModuleMixin.MixinName);
                    return forEachStatement;
                }

                var dim = (int)((inference.Type as ArrayType).Dimensions.FirstOrDefault() as LiteralExpression).Value;

                var result = new StatementList();
                for (int i = 0; i < dim; ++i)
                {
                    var cloned = forEachStatement.DeepClone();
                    var replace = new XenkoReplaceExtern(cloned.Variable, new IndexerExpression(cloned.Collection, new LiteralExpression(i)));
                    replace.Run(cloned.Body);
                    result.Add(cloned.Body);
                }

                VisitDynamic(result);
                return result;
            }
            else
            {
                base.Visit(forEachStatement);
                parsingInfo.ForEachStatements.Add(new StatementNodeCouple(forEachStatement, ParentNode));
                return forEachStatement;
            }
        }
Beispiel #60
0
    void AddReadStream(Block block, TypeNode type, StatementList statements, Identifier reader, 
      Expression target, Expression result){
      // Read next element and figure out if it matches the stream element type, if so read it and add it to the list
      // If not, then return (throw an error if there are no items and the list is the non-empty type).

      // flexArray = new flexarray();
      // while (reader.Read() && read.NodeType != XmlNodeType.EndElement) {
      //    if (reader.NodeType == XmlNodeType.Element) {
      //      readchild(flexarray);
      //    }
      // }
      // target = flexArray; 

      Local nameLocal = new Local(Identifier.For("name"),SystemTypes.String, block);
      Local nsLocal = new Local(Identifier.For("ns"),SystemTypes.String, block);
      Local nodeType = new Local(Identifier.For("nodeType"),Runtime.XmlNodeType, block);
      Local optional = new Local(Identifier.Empty, SystemTypes.Boolean, block);
      Local foundChild = new Local(Identifier.Empty, SystemTypes.Boolean, block);
      statements.Add(new AssignmentStatement(optional, Literal.False));

      TypeNode eType = Checker.GetCollectionElementType(type);
      Local local = new Local(Identifier.Empty, eType, block);
      Method addMethod = null;
      Local localArray = null;

      if (type.Template == SystemTypes.GenericBoxed) {

        addMethod = null; // only needs one!

      } else if (Checker.IsGenericList(type)) {
        //TODO: this call is invalid if the eType is not public
        TypeNode flexArrayType = SystemTypes.GenericList.GetTemplateInstance(this.module, eType);
        localArray = new Local(Identifier.For("stream"+streamCount++), flexArrayType, block);

        statements.Add(new AssignmentStatement(localArray,
          new Construct(new MemberBinding(null, flexArrayType), new ExpressionList(), flexArrayType)));

        addMethod = flexArrayType.GetMethod(Identifier.For("Add"), eType);
      } else  {        
        TypeNode arrayType = SystemTypes.ArrayList;
        localArray = new Local(Identifier.Empty, arrayType, block);
        statements.Add(new AssignmentStatement(localArray,
          new Construct(new MemberBinding(null, arrayType), new ExpressionList(), arrayType)));

        addMethod = arrayType.GetMethod(Identifier.For("Add"), SystemTypes.Object);
      }

      Block whileBody = new Block(new StatementList());
      MethodCall moveToContent = new MethodCall(new QualifiedIdentifier(reader, Identifier.For("MoveToContent")), new ExpressionList());
      BinaryExpression notAtEnd = new BinaryExpression(moveToContent, 
        new QualifiedIdentifier(Identifier.For("XmlNodeType"), Identifier.For("EndElement")), NodeType.Ne);
      BinaryExpression notEOF = new BinaryExpression(
        new QualifiedIdentifier(reader, Identifier.For("EOF")), Literal.True, NodeType.Ne);

      While w = new While(new BinaryExpression(notAtEnd, notEOF, NodeType.And), whileBody);
      statements.Add(w);

      whileBody.Statements.Add(new AssignmentStatement(nameLocal, new QualifiedIdentifier(reader, Identifier.For("LocalName"))));
      whileBody.Statements.Add(new AssignmentStatement(nsLocal, new QualifiedIdentifier(reader, Identifier.For("NamespaceURI"))));
      whileBody.Statements.Add(new AssignmentStatement(nodeType, new QualifiedIdentifier(reader, Identifier.For("NodeType"))));

      StatementList trueStatements = whileBody.Statements;
      if (type.Template == SystemTypes.GenericBoxed){
        type = Checker.GetCollectionElementType(type);
      }

      trueStatements.Add(new AssignmentStatement(foundChild, Literal.False));

      if (eType is TupleType || eType is TypeUnion || IsStream(eType)) {
        AddCallDeserializer(eType, trueStatements, reader, local, optional, foundChild);        
      } else  {
        AddReadChild(whileBody, trueStatements, Checker.GetDefaultElementName(eType), eType, local, reader, foundChild, true, false);
      }

      If ifFound = new If(new BinaryExpression(foundChild, Literal.True, NodeType.Eq),
        new Block(new StatementList()), new Block(new StatementList()));
      ifFound.TrueBlock.Statements.Add(new AssignmentStatement(result, Literal.True)); // set our result to true then.
      ifFound.FalseBlock.Statements.Add(new Exit()); // break out of loop then.

      trueStatements.Add(ifFound);

      if (addMethod == null) {        
        trueStatements.Add(new AssignmentStatement(target, 
          CastTo(local, type))); // box the result.
        trueStatements.Add(new Exit()); // break out of loop we have it!
      } else {
        MemberBinding addCall = new MemberBinding(localArray, addMethod);
        trueStatements.Add(new ExpressionStatement(new MethodCall(addCall, 
          new ExpressionList(new Expression[1] {local}))));
      }

      // clear out the local, it is a struct of some sort.
      if (local.Type.IsValueType && ! local.Type.IsPrimitive) {
        trueStatements.Add(new AssignmentStatement(local, 
          new Construct(new MemberBinding(null,local.Type), new ExpressionList(), local.Type)));
      }

      // end while
      // assign resulting array to the target object (if we have anything to assign).
      If ifResult = new If(new BinaryExpression(result, Literal.True, NodeType.Eq),
        new Block(new StatementList()), null);
      statements.Add(ifResult);
      statements = ifResult.TrueBlock.Statements;

      if (addMethod != null) {
        if (type is ArrayType) {
          // target = (type)localArray.ToArray(etype);
          Method toArray = SystemTypes.ArrayList.GetMethod(Identifier.For("ToArray"), SystemTypes.Type);
          ExpressionList args = new ExpressionList();
          args.Add(new UnaryExpression(new Literal(eType, SystemTypes.Type), NodeType.Typeof, SystemTypes.Type));
          statements.Add(new AssignmentStatement(target, 
            CastTo(new MethodCall(new MemberBinding(localArray, toArray), 
                     args, NodeType.Callvirt, SystemTypes.Array), type)));

        } else if (type.Template == SystemTypes.GenericNonEmptyIEnumerable) {
          // Explicit coercion of IEnumerable to NonEmptyIEnumerable requires constructing 
          // the NonEmptyIEnumerable object passing in the IEnumerable as an argument.
          TypeNode ienumtype = Checker.GetIEnumerableTypeFromNonEmptyIEnumerableStruct(this.module, type);
          Debug.Assert(ienumtype!=null);
          //TODO: this call is invalid if the eType is not public
          TypeNode nonEmptyIEnum = SystemTypes.GenericNonEmptyIEnumerable.GetTemplateInstance(this.module, eType);

          InstanceInitializer ii = nonEmptyIEnum.GetConstructor(ienumtype);
          Construct c = new Construct(new MemberBinding(null, ii), new ExpressionList(localArray), nonEmptyIEnum);
          statements.Add(new AssignmentStatement(target, c));
        } else {
          statements.Add(new AssignmentStatement(target, localArray));
        }
      }
    }