Esempio n. 1
0
 private void SetVariablesExpressionStatements(ConditionStatement node)
 {
     V_0 = this.variables.get_Count() - 1;
     while (V_0 >= 0)
     {
         V_1 = this.variables.get_Item(V_0);
         if (V_1.get_VariableState() != 8)
         {
             V_2 = V_1.get_StatementExpressions().get_Count() - 1;
             while (V_2 >= 0)
             {
                 V_3 = V_1.get_StatementExpressions().get_Item(V_2);
                 if (V_3.get_Statement() == null)
                 {
                     if (node == V_3.get_ParentWhileStatement())
                     {
                         V_3.set_ParentWhileStatement(this.GetParentWhileStatementAtLevel(1));
                     }
                     V_3.set_Statement(node);
                 }
                 V_2 = V_2 - 1;
             }
         }
         V_0 = V_0 - 1;
     }
     return;
 }
        private void TryMergeExpressions(ConditionStatement node)
        {
            if (!(node.Condition is UnaryExpression))
            {
                return;
            }

            UnaryExpression unaryExpression = (UnaryExpression)node.Condition;

            if (unaryExpression.Operator != UnaryOperator.LogicalNot)
            {
                return;
            }

            if (unaryExpression.Operand is MethodInvocationExpression || unaryExpression.Operand is PropertyReferenceExpression)
            {
                return;
            }

            if (!IsConditionExpression(unaryExpression.Operand))
            {
                return;
            }

            node.Condition = Negator.Negate(unaryExpression.Operand, typeSystem);
        }
Esempio n. 3
0
 public LogicalStatement(WordTokens[] tokens, ConditionStatement left, ConditionStatement right, WordTokens op, Statement subStatement = null) : base(tokens, subStatement)
 {
     this.left  = left;
     this.right = right;
     this.op    = op;
     type       = StatementType.ConditionalStatement;
 }
Esempio n. 4
0
        private VariableReferenceExpression CreateBodyArgument(Method method, MethodDeclaration methodDeclaration)
        {
            var bodyArguments = method.Parameters.Where(p => GetParameterLocation(method, p) == ParameterLocation.Body).ToList();

            if (bodyArguments.Count == 0)
            {
                return(null);
            }

            var variable = new VariableDeclarationStatement(typeof(Dictionary <string, object>), "body");

            methodDeclaration.Statements.Add(variable);
            variable.InitExpression = new NewObjectExpression(typeof(Dictionary <string, object>));
            foreach (var arg in bodyArguments)
            {
                var argumentReference = methodDeclaration.Arguments.First(a => a.Data["Parameter"] == arg);
                var assign            = variable.CreateInvokeMethodExpression(nameof(Dictionary <string, object> .Add), arg.Name, argumentReference);
                if (arg.IsOptional)
                {
                    var condition = new ConditionStatement
                    {
                        Condition      = new BinaryExpression(BinaryOperator.NotEquals, argumentReference, new LiteralExpression(null)),
                        TrueStatements = assign
                    };
                    methodDeclaration.Statements.Add(condition);
                }
                else
                {
                    methodDeclaration.Statements.Add(assign);
                }
            }

            return(variable);
        }
Esempio n. 5
0
 public IfStatement(int startIndex, ConditionStatement condition, Statement elseStatement, Statement endIfStatement)
 {
     Start          = startIndex;
     Condition      = condition;
     ElseStatement  = elseStatement;
     EndIfStatement = endIfStatement;
 }
Esempio n. 6
0
        public LogicalStatementTest()
        {
            this.EqualStatement = new SingleValueCondition("name", "", this.Binder);
            this.EqualSql       = this.EqualStatement.GenerateQuery();

            this.GreaterStatement = new SingleValueCondition("age", 18, this.Binder)
            {
                Operator = SingleValueOperator.Greater
            };
            this.GreaterSql = this.GreaterStatement.GenerateQuery();

            this.LikeStatement = new SingleValueCondition("address", "Thailand", this.Binder)
            {
                Operator = SingleValueOperator.Like
            };
            this.LikeSql = this.LikeStatement.GenerateQuery();

            this.InStatement = new MultiValueCondition("id", new object[] { 1, 2, 3, 4, 5 }, this.Binder);
            this.InSql       = this.InStatement.GenerateQuery();

            this.BetweenStatement = new BetweenCondition("salaey", 0, 10, this.Binder);
            this.BetweenSql       = this.BetweenStatement.GenerateQuery();

            this.NullStatement = new NullCondition("super");
            this.NullSql       = this.NullStatement.GenerateQuery();
        }
Esempio n. 7
0
        /// <summary>
        /// Inline a condition statement.
        /// </summary>
        /// <param name="conditionStatement">The condition to inline.</param>
        /// <returns>A set of statements that represents a condition.</returns>
        private List <Statement> InlineCondition(ConditionStatement conditionStatement)
        {
            var newStatements = new List <Statement>();

            if (conditionStatement.FalseStatements.Count > 0)
            {
                var elseLabel  = CreateNewLabel();
                var endIfLabel = CreateNewLabel();
                newStatements.Add(new LabelConditionStatement(OptimizeExpression(conditionStatement.Condition), elseLabel.Name.Identifier));
                newStatements.AddRange(OptimizeStatementBlock(conditionStatement.TrueStatements));
                newStatements.Add(new GoToLabelStatement(endIfLabel.Name.Identifier));
                newStatements.Add(elseLabel);
                newStatements.AddRange(OptimizeStatementBlock(conditionStatement.FalseStatements));
                newStatements.Add(endIfLabel);
            }
            else
            {
                var endIfLabel = CreateNewLabel();
                newStatements.Add(new LabelConditionStatement(OptimizeExpression(conditionStatement.Condition), endIfLabel.Name.Identifier));
                newStatements.AddRange(OptimizeStatementBlock(conditionStatement.TrueStatements));
                newStatements.Add(endIfLabel);
            }

            return(newStatements);
        }
			public IfStatement (int startIndex, ConditionStatement condition, Statement elseStatement, Statement endIfStatement)
			{
				Start = startIndex;
				Condition = condition;
				ElseStatement = elseStatement;
					EndIfStatement = endIfStatement;
			}
        private void SetVariablesExpressionStatements(ConditionStatement node)
        {
            for (int i = variables.Count - 1; i >= 0; i--)
            {
                var keyValuePair = variables[i];

                if (keyValuePair.VariableState == VariableState.Other)
                {
                    continue;
                }

                for (int j = keyValuePair.StatementExpressions.Count - 1; j >= 0; j--)
                {
                    var statementExpression = keyValuePair.StatementExpressions[j];
                    if (statementExpression.Statement == null)
                    {
                        if (node == statementExpression.ParentWhileStatement)
                        {
                            statementExpression.ParentWhileStatement = GetParentWhileStatementAtLevel(1);
                        }
                        statementExpression.Statement = node;
                    }
                }
            }
        }
Esempio n. 10
0
 private void TryProcessConditionStatement(ConditionStatement node)
 {
     if (this.processStep == 1 && this.TryGetVariableExpression(node.get_Condition(), out V_0))
     {
         node.set_Condition(V_0);
     }
     if (this.processStep == RemoveConditionOnlyVariables.ProcessStep.Search && node as WhileStatement == null && node as DoWhileStatement == null)
     {
         this.SetVariablesExpressionStatements(node);
     }
     return;
 }
        public void CSharpCodeGenerator_If_Empty()
        {
            var statement = new ConditionStatement();

            statement.Condition = new LiteralExpression(true);

            var generator = new CSharpCodeGenerator();
            var result    = generator.Write(statement);

            Assert.That.StringEquals(@"if (true)
{
}
", result);
        }
        public override SqlStatement VisitIfStatement(PlSqlParser.IfStatementContext context)
        {
            var conditions = new List <ConditionPart> {
                new ConditionPart {
                    Condition  = Expression.Build(context.condition()),
                    Statements = context.seqOfStatements().statement().Select(Visit).ToArray()
                }
            };

            foreach (var partContext in context.elsifPart())
            {
                conditions.Add(new ConditionPart {
                    Condition  = Expression.Build(partContext.condition()),
                    Statements = partContext.seqOfStatements().statement().Select(Visit).ToArray()
                });
            }

            if (context.elsePart() != null)
            {
                var statements = context.elsePart().seqOfStatements().statement().Select(Visit).ToArray();
                conditions.Add(new ConditionPart {
                    Condition  = SqlExpression.Constant(true),
                    Statements = statements
                });
            }

            ConditionStatement conditional = null;

            for (int i = conditions.Count - 1; i >= 0; i--)
            {
                var current = conditions[i];

                var condition = new ConditionStatement(current.Condition, current.Statements);

                if (conditional != null)
                {
                    conditional = new ConditionStatement(current.Condition, current.Statements, new SqlStatement[] { conditional });
                }
                else
                {
                    conditional = condition;
                }
            }

            return(conditional);
        }
 private void TryProcessConditionStatement(ConditionStatement node)
 {
     if (processStep == ProcessStep.Replace)
     {
         Expression expression;
         if (TryGetVariableExpression(node.Condition, out expression))
         {
             node.Condition = expression;
         }
     }
     if (processStep == ProcessStep.Search)
     {
         if (!(node is WhileStatement) && !(node is DoWhileStatement))
         {
             SetVariablesExpressionStatements(node);
         }
     }
 }
        LogicalStatement CheckForConditional(WordTokens[] tokens)
        {
            var firstToken     = tokens.First();
            var validOperators = new TokenType[] { TokenType.AndLogicalOperator, TokenType.OrLogicalOperator };

            if (tokens.First().tokens.Any(t => t.type == TokenType.NotLogicalOperator))
            {
                var statement     = tokens.Skip(1).ToArray();
                var isConditional = CheckForConditional(statement);
                var isRelational  = CheckForRelational(statement);
                if (isConditional != null)
                {
                    return(new LogicalStatement(tokens, null, isConditional, tokens.First()));
                }
                if (isRelational != null)
                {
                    return(new LogicalStatement(tokens, null, isRelational, tokens.First()));
                }
            }
            else
            {
                var op = tokens.Select((value, index) => new { value, index }).FirstOrDefault(t => t.value.tokens.Any(to => validOperators.Any(vOp => vOp == to.type)));
                if (op != null)
                {
                    var index           = op.index;
                    var firstStatement  = tokens.Take(index).ToArray();
                    var secondStatement = tokens.Skip(index + 1).ToArray();

                    var firstConditional = CheckForConditional(firstStatement);
                    var firstRelational  = CheckForRelational(firstStatement);

                    var secondConditional = CheckForConditional(secondStatement);
                    var secondRelational  = CheckForRelational(secondStatement);

                    ConditionStatement first  = ((ConditionStatement)firstConditional) == null ? (ConditionStatement)firstRelational : (ConditionStatement)firstConditional;
                    ConditionStatement second = ((ConditionStatement)secondConditional) == null ? (ConditionStatement)secondRelational : (ConditionStatement)secondConditional;
                    if (first != null && second != null)
                    {
                        return(new LogicalStatement(tokens, first, second, op.value));
                    }
                }
            }
            return(null);
        }
Esempio n. 15
0
        /// <summary>
        ///		Create and insert a quick tab
        ///		along with all the other needed entities.
        ///		It will have the provided system name, display name, and HTML.
        ///		It will display ONLY for a single product whose ID is given.
        /// </summary>
        public async Task InsertQuickTabForSpecificProductAsync(
            string systemName, string displayName, string html, int productId)
        {
            Tab tab = new Tab();

            tab.SystemName      = systemName;
            tab.DisplayName     = displayName;
            tab.Description     = html;
            tab.LimitedToStores = false;
            tab.TabMode         = TabMode.Mappings;
            tab.DisplayOrder    = 0;
            await _tabService.InsertTabAsync(tab);

            Condition condition = await _conditionService.CreateConditionAsync();

            condition.Active = true;
            await _conditionService.UpdateConditionAsync(condition);

            EntityCondition entityCondition = new EntityCondition();

            entityCondition.ConditionId     = condition.Id;
            entityCondition.EntityType      = EntityType.Tab;
            entityCondition.EntityId        = tab.Id;
            entityCondition.LimitedToStores = false;
            await _entityConditionService.InsertEntityConditionAsync(entityCondition);

            ConditionGroup conditionGroup = new ConditionGroup();
            await _conditionService.CreateConditionGroupAsync(condition, conditionGroup);

            ConditionStatement conditionStatement = new ConditionStatement();
            await _conditionService.CreateConditionStatementAsync(conditionGroup, conditionStatement);

            conditionStatement.Value = "Fail";
            await _conditionService.UpdateConditionStatementAsync(conditionStatement);

            EntityMapping entityMapping = new EntityMapping();

            entityMapping.EntityType     = EntityType.Tab;
            entityMapping.EntityId       = tab.Id;
            entityMapping.MappedEntityId = productId;
            entityMapping.DisplayOrder   = 0;
            entityMapping.MappingType    = MappingType.Product;
            await _entityMappingService.InsertEntityMappingAsync(entityMapping);
        }
        public override SqlStatement VisitSimpleCaseStatement(PlSqlParser.SimpleCaseStatementContext context)
        {
            var exp = Expression.Build(context.atom());

            var switches = new List <CaseSwitch>();

            foreach (var partContext in context.simpleCaseWhenPart())
            {
                var otherExp = Expression.Build(partContext.expressionWrapper());
                switches.Add(new CaseSwitch {
                    Condition        = SqlExpression.Equal(exp, otherExp),
                    ReturnStatements = partContext.seqOfStatements().statement().Select(Visit).ToArray()
                });
            }

            if (context.caseElsePart() != null)
            {
                var returnstatements = context.caseElsePart().seqOfStatements().statement().Select(Visit).ToArray();
                switches.Add(new CaseSwitch {
                    Condition        = SqlExpression.Constant(true),
                    ReturnStatements = returnstatements
                });
            }

            ConditionStatement conditional = null;

            for (int i = switches.Count - 1; i >= 0; i--)
            {
                var current = switches[i];

                var condition = new ConditionStatement(current.Condition, current.ReturnStatements);

                if (conditional != null)
                {
                    conditional = new ConditionStatement(current.Condition, current.ReturnStatements, new SqlStatement[] { conditional });
                }
                else
                {
                    conditional = condition;
                }
            }

            return(conditional);
        }
Esempio n. 17
0
        /// <summary>
        /// Generates the code for a <see cref="ConditionStatement"/>.
        /// </summary>
        /// <param name="statement">The statement</param>
        /// <returns>A BaZic code</returns>
        private string GenerateConditionStatement(ConditionStatement statement)
        {
            Requires.NotNull(statement.Condition, nameof(statement.Condition));

            var condition = GenerateExpression(statement.Condition);

            var indent = IncreaseIndent();

            var trueStatements = new List <string>();

            foreach (var stmt in statement.TrueStatements)
            {
                trueStatements.Add($"{indent}{GenerateStatement(stmt)}");
            }

            var trueStatementsString = string.Join(Environment.NewLine, trueStatements);

            if (statement.FalseStatements.Count > 0)
            {
                var falseStatements = new List <string>();
                foreach (var stmt in statement.FalseStatements)
                {
                    falseStatements.Add($"{indent}{GenerateStatement(stmt)}");
                }

                var falseStatementsString = string.Join(Environment.NewLine, falseStatements);

                indent = DecreaseIndent();

                return($"IF {condition} THEN" + Environment.NewLine +
                       $"{trueStatementsString}" + Environment.NewLine +
                       $"{indent}ELSE" + Environment.NewLine +
                       $"{falseStatementsString}" + Environment.NewLine +
                       $"{indent}END IF");
            }

            indent = DecreaseIndent();

            return($"IF {condition} THEN" + Environment.NewLine +
                   $"{trueStatementsString}" + Environment.NewLine +
                   $"{indent}END IF");
        }
Esempio n. 18
0
        public PropertyDeclaration AddProperty(
            FieldDeclaration f,
            string name,
            bool hasGet,
            bool hasSet,
            bool checkNonNull
            )
        {
            PropertyDeclaration p = this.AddProperty(
                f.Type,
                name);

            if (hasGet)
            {
                p.Get.Return(Expr.This.Field(f));
            }
            if (hasSet)
            {
                if (checkNonNull)
                {
                    ConditionStatement ifnull = Stm.If(Expr.Value.Identity(Expr.Null));
                    p.Set.Add(ifnull);
                    ifnull.TrueStatements.Add(
                        Stm.Throw(typeof(ArgumentNullException))
                        );
                    p.SetExceptions.Add(new ThrowedExceptionDeclaration(
                                            typeof(ArgumentNullException),
                                            "value is a null reference"
                                            ));
                }
                p.Set.Add(
                    Stm.Assign(
                        Expr.This.Field(f),
                        Expr.Value
                        )
                    );
            }

            return(p);
        }
Esempio n. 19
0
        static IfStatement FindIfStatement(string input, int startIndex)
        {
            if (!IsMatch(input, IfStatementText, startIndex))
            {
                return(null);
            }

            ConditionStatement condition = FindCondition(input, startIndex + IfStatementText.Length);

            if (condition == null)
            {
                return(null);
            }

            Statement elseStatement  = null;
            Statement endIfStatement = FindElseOrEndIfStatement(input, condition.End + 1);

            if (endIfStatement == null)
            {
                return(null);
            }

            if (endIfStatement.StatementType == StatementType.EndIfStatement)
            {
                return(new IfStatement(startIndex, condition, endIfStatement));
            }
            else
            {
                elseStatement = endIfStatement;
            }

            endIfStatement = FindEndIfStatement(input, elseStatement.End + 1);
            if (endIfStatement == null)
            {
                return(null);
            }

            return(new IfStatement(startIndex, condition, elseStatement, endIfStatement));
        }
        public void CSharpCodeGenerator_If_Else()
        {
            var statement = new ConditionStatement
            {
                Condition       = new LiteralExpression(true),
                TrueStatements  = new SnippetStatement("TrueSnippet"),
                FalseStatements = new SnippetStatement("FalseSnippet")
            };

            var generator = new CSharpCodeGenerator();
            var result    = generator.Write(statement);

            Assert.That.StringEquals(@"if (true)
{
    TrueSnippet
}
else
{
    FalseSnippet
}
", result);
        }
 private void TryMergeExpressions(ConditionStatement node)
 {
     if (node.get_Condition() as UnaryExpression == null)
     {
         return;
     }
     V_0 = (UnaryExpression)node.get_Condition();
     if (V_0.get_Operator() != 1)
     {
         return;
     }
     if (V_0.get_Operand() as MethodInvocationExpression != null || V_0.get_Operand() as PropertyReferenceExpression != null)
     {
         return;
     }
     if (!this.IsConditionExpression(V_0.get_Operand()))
     {
         return;
     }
     node.set_Condition(Negator.Negate(V_0.get_Operand(), this.typeSystem));
     return;
 }
Esempio n. 22
0
        /// <summary>
        ///		Create and insert an HTML widget
        ///		along with all the other needed entities.
        ///		It will have the provided name and HTML.
        ///		It will display in the provided widget zone
        ///		with the given display order.
        /// </summary>
        /// <returns>
        ///		The ID of the inserted HTML widget.
        /// </returns>
        public async Task <int> InsertHtmlWidgetAsync(
            string name, string html, string widgetZone, int displayOrder)
        {
            HtmlWidget widget = new HtmlWidget();

            widget.Name            = name;
            widget.Visible         = true;
            widget.HtmlContent     = html;
            widget.LimitedToStores = false;
            await _htmlWidgetRepository.InsertAsync(widget);

            Schedule schedule = new Schedule();

            schedule.EntityType              = EntityType.HtmlWidget;
            schedule.EntityId                = widget.Id;
            schedule.EntityFromDate          = null;
            schedule.EntityToDate            = null;
            schedule.SchedulePatternType     = SchedulePatternType.Everyday;
            schedule.SchedulePatternFromTime = TimeSpan.Zero;
            schedule.SchedulePatternToTime   = TimeSpan.Zero;
            schedule.ExactDayValue           = 1;
            schedule.EveryMonthFromDayValue  = 1;
            schedule.EveryMonthToDayValue    = 1;
            await _scheduleRepository.InsertAsync(schedule);

            Condition condition = new Condition();

            condition.Name   = null;
            condition.Active = true;
            await _conditionRepository.InsertAsync(condition);

            EntityCondition entityCondition = new EntityCondition();

            entityCondition.ConditionId     = condition.Id;
            entityCondition.EntityType      = EntityType.HtmlWidget;
            entityCondition.EntityId        = widget.Id;
            entityCondition.LimitedToStores = false;
            await _entityConditionRepository.InsertAsync(entityCondition);

            ConditionGroup conditionGroup = new ConditionGroup();

            conditionGroup.ConditionId = condition.Id;
            await _conditionGroupRepository.InsertAsync(conditionGroup);

            ConditionStatement conditionStatement = new ConditionStatement();

            conditionStatement.ConditionType     = ConditionType.Default;
            conditionStatement.ConditionProperty = 0;
            conditionStatement.OperatorType      = OperatorType.EqualTo;
            conditionStatement.Value             = "Fail";
            conditionStatement.ConditionGroupId  = conditionGroup.Id;
            await _conditionStatementRepository.InsertAsync(conditionStatement);

            EntityWidgetMapping widgetMapping = new EntityWidgetMapping();

            widgetMapping.EntityType   = EntityType.HtmlWidget;
            widgetMapping.EntityId     = widget.Id;
            widgetMapping.WidgetZone   = widgetZone;
            widgetMapping.DisplayOrder = displayOrder;
            await _widgetMappingRepository.InsertAsync(widgetMapping);

            return(widget.Id);
        }
Esempio n. 23
0
        public override void Generate()
        {
            // generate data
            this.Data.NamespaceDeclaration = this.NamespaceDeclaration;
            this.Data.Generate();

            // generate the rest
            this.NamespaceDeclaration.Imports.Add("System.Data");

            // create class
            ClassDeclaration c = this.NamespaceDeclaration.AddClass(this.DataReaderName);

            // IDisposable
            c.Interfaces.Add(typeof(IDisposable));

            // add datareader field
            FieldDeclaration dr = c.AddField(typeof(IDataReader), "dr");

            // add data field
            FieldDeclaration data = c.AddField(
                this.Data.DataName
                , "data");

            data.InitExpression =
                Expr.New(data.Type);
            PropertyDeclaration datap = c.AddProperty(data, true, false, false);

            // foreach field values, add get property
            foreach (DictionaryEntry de in this.Data.Properties)
            {
                DictionaryEntry     dde = (DictionaryEntry)de.Key;
                PropertyDeclaration pd  = (PropertyDeclaration)de.Value;

                PropertyDeclaration pcd = c.AddProperty(pd.Type, pd.Name);
                pcd.Get.Return(
                    Expr.This.Field(data).Prop(pd)
                    );
            }


            // add constructor
            ConstructorDeclaration cs  = c.AddConstructor();
            ParameterDeclaration   drp = cs.Signature.Parameters.Add(dr.Type, "dr", false);

            cs.Body.Add(Stm.ThrowIfNull(drp));
            cs.Body.Add(
                Stm.Assign(
                    Expr.This.Field(dr),
                    Expr.Arg(drp)
                    )
                );

            // add close method
            MethodDeclaration close = c.AddMethod("Close");

            // if dr ==null return;
            close.Body.Add(
                Stm.IfNull(Expr.This.Field(dr), Stm.Return())
                );
            // dr.Close();
            close.Body.Add(
                Expr.This.Field(dr).Method("Close").Invoke()
                );
            // dr = null;
            close.Body.AddAssign(Expr.This.Field(dr), Expr.Null);
            // data = null
            close.Body.AddAssign(Expr.This.Field(data), Expr.Null);

            // add read method
            MethodDeclaration read = c.AddMethod("Read");

            read.Signature.ReturnType = new TypeTypeDeclaration(typeof(bool));

            // if (!dr.Read()){close and return)
            ConditionStatement ifnotread = Stm.IfIdentity(
                Expr.This.Field(dr).Method("Read").Invoke(),
                Expr.False,
                Stm.ToStm(Expr.This.Method(close).Invoke()),
                Stm.Return(Expr.False)
                );

            read.Body.Add(ifnotread);


            // foreach field values
            foreach (DictionaryEntry de in this.Data.Properties)
            {
                DictionaryEntry     dde = (DictionaryEntry)de.Key;
                PropertyDeclaration pd  = (PropertyDeclaration)de.Value;
                read.Body.AddAssign(
                    Expr.This.Field(data).Prop(pd),
                    (
                        Expr.This.Field(dr).Item(Expr.Prim(dde.Key.ToString()))
                    ).Cast(dde.Value.ToString())
                    );
            }
            // return true
            read.Body.Return(Expr.True);

            // add dispose method
            MethodDeclaration dispose = c.AddMethod("Dispose");

            dispose.ImplementationTypes.Add(typeof(IDisposable));

            // Close();
            dispose.Body.Add(
                Expr.This.Method(close).Invoke()
                );

            if (this.Enumerator)
            {
                AddEnumerator(c, data, close);
            }
        }
        private static MethodDeclaration GenerateMethod(ClassDeclaration clientClass, Method method, TypeReference requestType)
        {
            var m = clientClass.AddMember(new MethodDeclaration(method.MethodGroup.Name + '_' + GetMethodName(method)));

            m.SetData("Method", method);
            var buildUrlMethod = GenerateBuildUrlMethod(clientClass, method, requestType);

            GenerateMethodSignature(method, m, requestType, out var requestArgument, out var requestOptionsArgument, out var cancellationTokenArgument);
            m.Modifiers = Modifiers.Private;
            if (method.MethodType != MethodType.GetPaged)
            {
                m.Modifiers |= Modifiers.Async;
            }

            // Method body
            m.Statements = new StatementCollection();

            // 1. Create url from parameters
            var buildUrlExpression = new MethodInvokeExpression(new MemberReferenceExpression(new TypeReference(clientClass), buildUrlMethod));

            if (buildUrlMethod.Arguments.Count > 0)
            {
                buildUrlExpression.Arguments.Add(requestArgument);
            }

            var urlVariable = new VariableDeclarationStatement(typeof(string), "url", buildUrlExpression);

            m.Statements.Add(urlVariable);

            if (method.MethodType == MethodType.GetPaged)
            {
                // return new Meziantou.GitLab.PagedResponse<MergeRequest>(this, url, requestOptions);
                m.Statements.Add(new ReturnStatement(new NewObjectExpression(m.ReturnType !.Clone(), new ThisExpression(), urlVariable, requestOptionsArgument)));
            }
            else
            {
                // 2. Create HttpRequestMessage object
                var requestVariable = new VariableDeclarationStatement(typeof(HttpRequestMessage), "requestMessage", new NewObjectExpression(typeof(HttpRequestMessage)));
                var usingStatement  = new UsingStatement()
                {
                    Statement = requestVariable, Body = new StatementCollection()
                };
                m.Statements.Add(usingStatement);
                var statements = usingStatement.Body;

                statements.Add(new AssignStatement(new MemberReferenceExpression(requestVariable, nameof(HttpRequestMessage.Method)), GetHttpMethod(method.MethodType)));
                statements.Add(new AssignStatement(new MemberReferenceExpression(requestVariable, nameof(HttpRequestMessage.RequestUri)), new NewObjectExpression(typeof(Uri), urlVariable, new MemberReferenceExpression(typeof(UriKind), nameof(UriKind.RelativeOrAbsolute)))));

                CreateBodyArgument(method, statements, requestArgument, requestVariable);

                // 3. Send request
                // var response = await SendAsync(request, options, cancellationToken).ConfigureAwait(false);
                var responseVariable = new VariableDeclarationStatement(WellKnownTypes.HttpResponseTypeReference.MakeNullable(), "response", LiteralExpression.Null());
                statements.Add(responseVariable);
                var responseTry = new TryCatchFinallyStatement()
                {
                    Try = new StatementCollection()
                };
                statements.Add(responseTry);
                responseTry.Try.Add(new AssignStatement(responseVariable, new AwaitExpression(new MethodInvokeExpression(new MemberReferenceExpression(new ThisExpression(), "SendAsync"), requestVariable, requestOptionsArgument, cancellationTokenArgument)).ConfigureAwait(false)));

                // Dispose reponse in catch if Stream or in finally if not stream
                var disposeReponseStatements = new ConditionStatement()
                {
                    Condition      = new BinaryExpression(BinaryOperator.NotEquals, responseVariable, LiteralExpression.Null()),
                    TrueStatements = responseVariable.CreateInvokeMethodExpression("Dispose"),
                };

                if (method.ReturnType == ModelRef.File)
                {
                    responseTry.Catch = new CatchClauseCollection
                    {
                        new CatchClause()
                        {
                            Body = disposeReponseStatements,
                        },
                    };

                    responseTry.Catch[0].Body.Add(new ThrowStatement());
                }
                else
                {
                    responseTry.Finally = disposeReponseStatements;
                }

                // 4. Convert and return response object
                //    if (response.StatusCode == HttpStatusCode.NotFound) return default;
                if (method.MethodType == MethodType.Get)
                {
                    responseTry.Try.Add(new ConditionStatement()
                    {
                        Condition      = new BinaryExpression(BinaryOperator.Equals, responseVariable.CreateMemberReferenceExpression("StatusCode"), new MemberReferenceExpression(typeof(HttpStatusCode), "NotFound")),
                        TrueStatements = new ReturnStatement(new DefaultValueExpression()),
                    });
                }

                // await response.EnsureStatusCodeAsync(cancellationToken).ConfigureAwait(false);
                responseTry.Try.Add(new AwaitExpression(new MethodInvokeExpression(new MemberReferenceExpression(responseVariable, "EnsureStatusCodeAsync"), cancellationTokenArgument)).ConfigureAwait(false));

                if (method.ReturnType != null)
                {
                    // var result = await response.ToObjectAsync<T>(cancellationToken).ConfigureAwait(false);
                    var resultVariable = new VariableDeclarationStatement(m.ReturnType.Parameters[0].MakeNullable(), "result");
                    responseTry.Try.Add(resultVariable);
                    if (method.MethodType == MethodType.Get && method.ReturnType == ModelRef.File)
                    {
                        resultVariable.InitExpression = new AwaitExpression(responseVariable.CreateInvokeMethodExpression("ToStreamAsync", cancellationTokenArgument)).ConfigureAwait(false);
                    }
                    else if (method.MethodType == MethodType.GetCollection)
                    {
                        resultVariable.InitExpression = new AwaitExpression(responseVariable.CreateInvokeMethodExpression("ToCollectionAsync", new TypeReference[] { method.ReturnType.ToPropertyTypeReference() }, cancellationTokenArgument)).ConfigureAwait(false);
                    }
                    else
                    {
                        resultVariable.InitExpression = new AwaitExpression(responseVariable.CreateInvokeMethodExpression("ToObjectAsync", new TypeReference[] { method.ReturnType.ToPropertyTypeReference() }, cancellationTokenArgument)).ConfigureAwait(false);
                    }

                    // if (result is null)
                    //   throw new GitLabException(response.RequestMethod, response.RequestUri, response.StatusCode, $"The response cannot be converted to '{typeof(T)}' because the body is null or empty");
                    if (method.MethodType != MethodType.Get)
                    {
                        responseTry.Try.Add(new ConditionStatement()
                        {
                            Condition      = new BinaryExpression(BinaryOperator.Equals, resultVariable, LiteralExpression.Null()),
                            TrueStatements = new ThrowStatement(new NewObjectExpression(WellKnownTypes.GitLabExceptionTypeReference,
                                                                                        responseVariable.CreateMemberReferenceExpression("RequestMethod"),
                                                                                        responseVariable.CreateMemberReferenceExpression("RequestUri"),
                                                                                        responseVariable.CreateMemberReferenceExpression("StatusCode"),
                                                                                        new LiteralExpression($"The response cannot be converted to '{method.ReturnType.ToPropertyTypeReference().ClrFullTypeName}' because the body is null or empty"))),
                        });
                    }

                    responseTry.Try.Add(new ReturnStatement(resultVariable));
                }
            }

            return(m);
Esempio n. 25
0
 public IfStatement(int startIndex, ConditionStatement condition, Statement endIfStatement)
     : this(startIndex, condition, null, endIfStatement)
 {
 }
Esempio n. 26
0
        public static void OptimizeBlock(ref Block block)
        {
            var gotoTable = new Hashtable();

            for (int i = 0; i < block.Statements.Count; i++)
            {
                var statement = block.Statements[i];
                if (statement is Annotation || statement is Assignment || statement is Label)
                {
                    continue;
                }
                else if (statement is While)
                {
                    Block body = ((While)statement).Body;
                    OptimizeBlock(ref body);
                    ((While)statement).Body = body;
                }
                else if (statement is ReturnMove)
                {
                    var retMove = statement as ReturnMove;
                    if (retMove.RValue == block.FindDeclaration("__hl"))
                    {
                        block.Statements.Remove(statement);
                    }
                }
                else if (statement is Move)
                {
                    var move = statement as Move;
                    if (((Declaration)move.RValue).ConstStatement != null)
                    {
                        var newStatement = (Statement)((Declaration)move.RValue).ConstStatement.Clone();
                        newStatement.ReplaceDeclaration((Declaration)move.RValue, move.LValue);
                        block.Statements[i] = newStatement;
                        i--;    //rerun current statement to correctly populate LValue const statement
                    }
                    else
                    {
                        move.LValue.ConstStatement = move;
                    }
                }
                else if (statement is ConditionStatement)
                {
                    var cond = statement as ConditionStatement;
                    cond.LValue.ConstStatement = cond;
                }
                else if (statement is MathStatement)
                {
                    var math  = statement as MathStatement;
                    var refed = math.RValue as Declaration;
                    if (refed != null)
                    {
                        var newStatement = refed.ConstStatement;
                        if (newStatement != null && newStatement is Move)
                        {
                            math.ReplaceDeclaration(refed, newStatement.GetReferencedDeclarations().First());
                            block.Statements[i] = math;
                            //block.Statements.Remove(newStatement);
                        }
                        math.LValue.ConstStatement = null;
                    }
                    else
                    {
                        if (math.LValue.ConstStatement != null)
                        {
                            var newStatement = math.LValue.ConstStatement;
                            if (statement is Not)
                            {
                                if (newStatement is ConditionStatement)
                                {
                                    var newBlock = new Block(block);
                                    var cond     = newStatement as ConditionStatement;
                                    var decl     = ConditionStatement.BuildStatements(newBlock, new Expression(cond.GetInverseOperator()),
                                                                                      Tokenizer.ToToken(cond.CondDecl.ToString()), Tokenizer.ToToken(cond.CondValue.ToString()));
                                    newBlock.Statements[0].ReplaceDeclaration(decl, cond.LValue);
                                    block.Statements.Remove(newStatement);
                                    block.Statements.Remove(math);
                                    block.Statements.InsertRange(i - 1, newBlock.Statements);
                                }
                            }
                            else
                            {
                                /*var decl = math.LValue.ConstStatement.GetReferencedDeclarations()[0];
                                 * if (decl.ConstStatement == null)
                                 * {
                                 *  math.LValue.ConstStatement = null;
                                 * }
                                 * /*else
                                 * {
                                 *  math.ReplaceDeclaration(math.LValue, decl);
                                 *  //block.Statements.Remove(newStatement);
                                 *  //i--;
                                 * }*/
                                math.LValue.ConstStatement = null;
                            }
                        }
                        else
                        {
                            math.LValue.ConstStatement = null;
                        }
                    }
                }
                else if (statement is FunctionCall)
                {
                    var funcCall = statement as FunctionCall;
                    for (int j = 0; j < funcCall.Params.Count; j++)
                    {
                        var param = funcCall.Params[j];
                        if (param.ConstStatement != null)
                        {
                            if (param.ConstStatement is Move)
                            {
                                param = (Declaration)(param.ConstStatement as Move).RValue;
                            }
                        }
                        funcCall.Params[j] = param;
                    }
                    if (funcCall.LValue != null)
                    {
                        funcCall.LValue.ConstStatement = funcCall;
                    }
                }
                else if (statement is Goto)
                {
                    var gotoType = statement as Goto;
                    int j;
                    if (gotoType.CondDecl != null)
                    {
                        if (!gotoTable.Contains(i))
                        {
                            gotoTable.Add(i, true);
                            j = i - 1;
                            //we really only care if were going backwards
                            while (j > 0 && statement != gotoType.TargetLabel)
                            {
                                statement = block.Statements[--j];
                            }
                            if (j != 0)
                            {
                                i = j;
                            }
                        }
                    }
                    for (int k = 0; k < block.Declarations.Count; k++)
                    {
                        block.Declarations[k].ConstStatement = null;
                    }

                    /*else
                     * {
                     *  j = i + 1;
                     *  while (j + 1 < block.Statements.Count && statement != gotoType.TargetLabel)
                     *      statement = block.Statements[++j];
                     *  if (j + 1 != block.Statements.Count)
                     *      i = j;
                     * }*/
                }
                else if (statement is Return)
                {
                    var returnStatement = statement as Return;
                    var returnVal       = returnStatement.ReturnReg as Declaration;
                    if (returnVal.ConstStatement != null && returnVal.ConstStatement is Move)
                    {
                        var newStatement = returnVal.ConstStatement;
                        var lValue       = newStatement.GetModifiedDeclarations().First();
                        returnStatement.ReplaceDeclaration(lValue, newStatement.GetReferencedDeclarations().First());
                        //block.Statements.Remove(newStatement);
                    }
                }
            }
        }
Esempio n. 27
0
 public IfStatement(WordTokens[] tokens, ConditionStatement condition, ExpressionStatement expression, Statement subStatement = null) : base(tokens, subStatement)
 {
     this.condition  = condition;
     this.expression = expression;
     type            = StatementType.IfStatement;
 }
Esempio n. 28
0
 private void ExtractConditionIntoVariable(VariableReferenceExpression conditionVar, ConditionStatement statement, BlockStatement containingBlock)
 {
     V_0 = new ExpressionStatement(new BinaryExpression(26, conditionVar, statement.get_Condition(), this.typeSystem, null, false));
     containingBlock.AddStatementAt(containingBlock.get_Statements().IndexOf(statement), V_0);
     statement.set_Condition(conditionVar.CloneExpressionOnly());
     return;
 }
Esempio n. 29
0
        private MethodDeclaration GenerateMethod(ClassDeclaration clientClass, Method method)
        {
            var m = clientClass.AddMember(new MethodDeclaration(method.Name + "Async"));

            m.SetData("Method", method);
            GenerateMethodSignature(method, m, out var arguments, out var pageArgument, out var requestOptionsArgument, out var cancellationTokenArgument);
            m.Modifiers = Modifiers.Public;

            // Method body
            m.Statements = new StatementCollection();

            var urlBuilder = new VariableDeclarationStatement(
                typeof(UrlBuilder), "urlBuilder",
                new TypeReference(typeof(UrlBuilder))
                .CreateInvokeMethodExpression("Get", method.UrlTemplate));

            m.Statements.Add(urlBuilder);

            foreach (var param in method.Parameters.Where(p => GetParameterLocation(method, p) == ParameterLocation.Url))
            {
                if (param.Type.IsParameterEntity)
                {
                    if (param.Type.IsNullable)
                    {
                        var hasValueCondition = new ConditionStatement
                        {
                            Condition      = arguments[param].CreateMemberReferenceExpression(nameof(Nullable <int> .HasValue)),
                            TrueStatements = urlBuilder.CreateInvokeMethodExpression(nameof(UrlBuilder.WithValue), param.Name, arguments[param].CreateMemberReferenceExpression(nameof(Nullable <int> .Value), "Value"))
                        };
                        m.Statements.Add(hasValueCondition);
                    }
                    else
                    {
                        m.Statements.Add(urlBuilder.CreateInvokeMethodExpression(nameof(UrlBuilder.WithValue), param.Name, arguments[param].CreateMemberReferenceExpression("Value")));
                    }
                }
                else
                {
                    m.Statements.Add(urlBuilder.CreateInvokeMethodExpression(nameof(UrlBuilder.WithValue), param.Name, arguments[param]));
                }
            }

            if (pageArgument != null)
            {
                var pageCondition = new ConditionStatement()
                {
                    Condition      = new BinaryExpression(BinaryOperator.NotEquals, pageArgument, new LiteralExpression(null)),
                    TrueStatements = new StatementCollection
                    {
                        new ConditionStatement()
                        {
                            Condition      = new BinaryExpression(BinaryOperator.GreaterThan, pageArgument.CreateMemberReferenceExpression(nameof(PageOptions.PageIndex)), new LiteralExpression(0)),
                            TrueStatements = new StatementCollection
                            {
                                urlBuilder.CreateInvokeMethodExpression(nameof(UrlBuilder.WithValue), "page", pageArgument.CreateMemberReferenceExpression(nameof(PageOptions.PageIndex)))
                            }
                        },
                        new ConditionStatement()
                        {
                            Condition      = new BinaryExpression(BinaryOperator.GreaterThan, pageArgument.CreateMemberReferenceExpression(nameof(PageOptions.PageSize)), new LiteralExpression(0)),
                            TrueStatements = new StatementCollection
                            {
                                urlBuilder.CreateInvokeMethodExpression(nameof(UrlBuilder.WithValue), "per_page", pageArgument.CreateMemberReferenceExpression(nameof(PageOptions.PageSize)))
                            }
                        },
                        new ConditionStatement()
                        {
                            Condition      = new BinaryExpression(BinaryOperator.Equals, pageArgument.CreateMemberReferenceExpression(nameof(PageOptions.OrderBy), nameof(OrderBy.Name)).CreateIsNullOrEmptyExpression(), new LiteralExpression(false)),
                            TrueStatements = new StatementCollection
                            {
                                urlBuilder.CreateInvokeMethodExpression(nameof(UrlBuilder.WithValue), "order_by", pageArgument.CreateMemberReferenceExpression(nameof(PageOptions.OrderBy), nameof(OrderBy.Name))),
                                urlBuilder.CreateInvokeMethodExpression(nameof(UrlBuilder.WithValue), "sort", pageArgument.CreateMemberReferenceExpression(nameof(PageOptions.OrderBy), nameof(OrderBy.Direction)))
                            }
                        }
                    }
                };

                m.Statements.Add(pageCondition);
            }

            var url = new VariableDeclarationStatement(typeof(string), "url", urlBuilder.CreateInvokeMethodExpression(nameof(UrlBuilder.Build)));

            m.Statements.Add(url);

            var bodyArgument = CreateBodyArgument(method, m);

            switch (method.MethodType)
            {
            case MethodType.Get:
                if (method.ReturnType.IsCollection)
                {
                    m.Statements.Add(new ReturnStatement(new ThisExpression().CreateInvokeMethodExpression("GetCollectionAsync", new TypeReference[] { method.ReturnType }, url, requestOptionsArgument, cancellationTokenArgument)));
                }
                else
                {
                    m.Statements.Add(new ReturnStatement(new ThisExpression().CreateInvokeMethodExpression("GetAsync", new TypeReference[] { method.ReturnType }, url, requestOptionsArgument, cancellationTokenArgument)));
                }

                break;

            case MethodType.GetPaged:
                m.Statements.Add(new ReturnStatement(new ThisExpression().CreateInvokeMethodExpression("GetPagedAsync", new TypeReference[] { method.ReturnType }, url, requestOptionsArgument, cancellationTokenArgument)));
                break;

            case MethodType.Put:
                var putArgs = new List <Expression>();
                putArgs.Add(url);
                putArgs.Add((Expression)bodyArgument ?? new LiteralExpression(null));
                putArgs.Add(requestOptionsArgument);
                putArgs.Add(cancellationTokenArgument);
                m.Statements.Add(new ReturnStatement(new ThisExpression().CreateInvokeMethodExpression("PutJsonAsync", new TypeReference[] { method.ReturnType }, putArgs.ToArray())));
                break;

            case MethodType.Post:
                var postArgs = new List <Expression>();
                postArgs.Add(url);
                postArgs.Add((Expression)bodyArgument ?? new LiteralExpression(null));
                postArgs.Add(requestOptionsArgument);
                postArgs.Add(cancellationTokenArgument);
                if (method.ReturnType != null)
                {
                    m.Statements.Add(new ReturnStatement(new ThisExpression().CreateInvokeMethodExpression("PostJsonAsync", new TypeReference[] { method.ReturnType }, postArgs.ToArray())));
                }
                else
                {
                    m.Statements.Add(new ReturnStatement(new ThisExpression().CreateInvokeMethodExpression("PostJsonAsync", postArgs.ToArray())));
                }
                break;

            case MethodType.Delete:
                m.Statements.Add(new ReturnStatement(new ThisExpression().CreateInvokeMethodExpression("DeleteAsync", url, requestOptionsArgument, cancellationTokenArgument)));
                break;

            default:
                throw new NotSupportedException($"Method {method.MethodType} is not supported");
            }

            return(m);
        }
			public IfStatement (int startIndex, ConditionStatement condition, Statement endIfStatement)
				: this (startIndex, condition, null, endIfStatement)
			{
			}
        private static MethodDeclaration GenerateBuildUrlMethod(ClassDeclaration clientClass, Method method, TypeReference requestType)
        {
            var m = clientClass.AddMember(new MethodDeclaration(method.MethodGroup.Name + '_' + GetMethodName(method) + "_BuildUrl"));

            m.Modifiers  = Modifiers.Private | Modifiers.Static;
            m.ReturnType = typeof(string);

            // Method body
            m.Statements = new StatementCollection();

            var urlVariable = new VariableDeclarationStatement(typeof(string), "url");

            m.Statements.Add(urlVariable);

            // 1. Create url from parameters
            var parameters = method.Parameters.Where(p => GetParameterLocation(method, p) == ParameterLocation.Url).ToList();

            if (parameters.Any())
            {
                var requestArgument = m.AddArgument("request", requestType);

                // [System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "<Pending>")]
                m.CustomAttributes.Add(new CustomAttribute(typeof(SuppressMessageAttribute))
                {
                    Arguments =
                    {
                        new CustomAttributeArgument(new LiteralExpression("Reliability")),
                        new CustomAttributeArgument(new LiteralExpression("CA2000:Dispose objects before losing scope")),
                        new CustomAttributeArgument("Justification",                                                     new LiteralExpression("The rule doesn't understand ref struct")),
                    },
                });

                var segments   = GetSegments(method.UrlTemplate);
                var urlBuilder = new VariableDeclarationStatement(
                    WellKnownTypes.UrlBuilderTypeReference, "urlBuilder",
                    new NewObjectExpression(WellKnownTypes.UrlBuilderTypeReference));
                var urlUsingStatement = new UsingStatement()
                {
                    Statement = urlBuilder,
                    Body      = new StatementCollection(),
                };
                var usingStatements = urlUsingStatement.Body;
                m.Statements.Add(urlUsingStatement);

                foreach (var segment in segments)
                {
                    if (segment[0] == ':')
                    {
                        var param = parameters.SingleOrDefault(p => p.Name == segment[1..]);
                        if (param == null)
                        {
                            throw new InvalidOperationException($"Parameter '{segment}' is not mapped for method '{method.UrlTemplate}'");
                        }

                        AddParameter(param, parameterDelimiterVariable: null, encoded: true);
                        parameters.Remove(param);
                    }
                    else if (segment[0] == '*')
                    {
                        var param = parameters.SingleOrDefault(p => p.Name == segment[1..]);
                        if (param == null)
                        {
                            throw new InvalidOperationException($"Parameter '{segment}' is not mapped for method '{method.UrlTemplate}'");
                        }

                        AddParameter(param, parameterDelimiterVariable: null, encoded: false);
                        parameters.Remove(param);
                    }
                    else if (segment.StartsWith("[.", StringComparison.Ordinal))
                    {
                        var param = parameters.SingleOrDefault(p => p.Name == segment[2..^ 1]);
                        if (param == null)
                        {
                            throw new InvalidOperationException($"Parameter '{segment}' is not mapped for method '{method.UrlTemplate}'");
                        }

                        AddParameter(param, parameterDelimiterVariable: null, encoded: false, prefix: ".");
                        parameters.Remove(param);
                    }
                    else
                    {
                        usingStatements.Add(urlBuilder.CreateInvokeMethodExpression("Append", new LiteralExpression(segment)));
                    }
                }

                if (parameters.Any())
                {
                    var separator = new VariableDeclarationStatement(typeof(char), "separator", new LiteralExpression('?'));
                    usingStatements.Add(separator);

                    foreach (var param in parameters)
                    {
                        AddParameter(param, separator, encoded: true);
                    }
                }

                usingStatements.Add(new AssignStatement(urlVariable, urlBuilder.CreateInvokeMethodExpression("ToString")));

                void AddParameter(MethodParameter param, VariableDeclarationStatement parameterDelimiterVariable, bool encoded, string prefix = null)
                {
                    var appendParameterMethodName = encoded ? "AppendParameter" : "AppendRawParameter";

                    void AddSeparator(StatementCollection statements)
                    {
                        if (parameterDelimiterVariable != null)
                        {
                            statements.Add(urlBuilder.CreateInvokeMethodExpression("Append", parameterDelimiterVariable));
                            statements.Add(new AssignStatement(parameterDelimiterVariable, new LiteralExpression('&')));

                            if (!param.Options.HasFlag(MethodParameterOptions.CustomMapping))
                            {
                                statements.Add(urlBuilder.CreateInvokeMethodExpression("Append", new LiteralExpression(param.Name + '=')));
                            }
                        }
                    }

                    void AppendPrefix(StatementCollection statements)
                    {
                        if (!string.IsNullOrEmpty(prefix))
                        {
                            statements.Add(urlBuilder.CreateInvokeMethodExpression("Append", prefix));
                        }
                    }

                    if (param.Type.IsParameterEntity)
                    {
                        var propertyName      = param.Type.ParameterEntity.FinalType == ModelRef.Object ? "ValueAsString" : "Value";
                        var hasValueCondition = new ConditionStatement
                        {
                            Condition      = CreatePropertyReference().CreateMemberReferenceExpression(nameof(Nullable <int> .HasValue)),
                            TrueStatements = new StatementCollection(),
                        };

                        AddSeparator(hasValueCondition.TrueStatements);
                        AppendPrefix(hasValueCondition.TrueStatements);
                        var parameterValue = FormatValue(param.Type, CreatePropertyReference().CreateInvokeMethodExpression("GetValueOrDefault").CreateMemberReferenceExpression(propertyName));

                        if (param.Options.HasFlag(MethodParameterOptions.CustomMapping))
                        {
                            hasValueCondition.TrueStatements.Add(urlBuilder
                                                                 .CreateInvokeMethodExpression(
                                                                     "AppendParameter",
                                                                     param.Name,
                                                                     parameterValue));
                        }
                        else
                        {
                            hasValueCondition.TrueStatements.Add(urlBuilder
                                                                 .CreateInvokeMethodExpression(
                                                                     appendParameterMethodName,
                                                                     parameterValue));
                        }

                        urlUsingStatement.Body.Add(hasValueCondition);
                    }
                    else
                    {
                        var isValueType = param.Type.IsValueType && !param.Type.IsCollection;

                        var hasValueCondition = new ConditionStatement
                        {
                            Condition = isValueType ? CreatePropertyReference().CreateMemberReferenceExpression("HasValue") :
                                        new UnaryExpression(UnaryOperator.Not,
                                                            new MethodInvokeExpression(
                                                                new MemberReferenceExpression(new TypeReference(typeof(object)), "ReferenceEquals"),
                                                                CreatePropertyReference(), LiteralExpression.Null())),
                            TrueStatements = new StatementCollection(),
                        };

                        AddSeparator(hasValueCondition.TrueStatements);
                        AppendPrefix(hasValueCondition.TrueStatements);

                        Expression parameterValue = isValueType ? CreatePropertyReference().CreateInvokeMethodExpression("GetValueOrDefault") : CreatePropertyReference();

                        if (param.Options.HasFlag(MethodParameterOptions.CustomMapping))
                        {
                            hasValueCondition.TrueStatements.Add(urlBuilder
                                                                 .CreateInvokeMethodExpression(
                                                                     "AppendParameter",
                                                                     param.Name,
                                                                     parameterValue));
                        }
                        else
                        {
                            var appendMethod = new MethodInvokeExpression(
                                new MemberReferenceExpression(urlBuilder, appendParameterMethodName),
                                FormatValue(param.Type, parameterValue));

                            hasValueCondition.TrueStatements.Add(appendMethod);
                        }

                        urlUsingStatement.Body.Add(hasValueCondition);
                    }

                    MemberReferenceExpression CreatePropertyReference()
                    {
                        return(requestArgument.CreateMemberReferenceExpression(ToPropertyName(param.Name)));
                    }
                }
            }
            else
            {
                m.Statements.Add(new AssignStatement(urlVariable, new LiteralExpression(method.UrlTemplate)));
            }

            m.Statements.Add(new ReturnStatement(urlVariable));
            return(m);
        }