Пример #1
0
        public override void WriteTo(CCodeWriterBase c)
        {
            c.Separate();

            c.TextSpan(string.Format("// adapter: {0}", Method));
            c.NewLine();

            foreach (var statement in this.typeDefs)
            {
                statement.WriteTo(c);
            }

            var namedTypeSymbol = (INamedTypeSymbol)this.type;

            if (namedTypeSymbol.IsGenericType)
            {
                c.WriteTemplateDeclaration(namedTypeSymbol);
                c.NewLine();
            }

            c.WriteMethodReturn(Method, true);
            c.WriteMethodNamespace(namedTypeSymbol);
            c.WriteMethodName(Method, false, interfaceWrapperMethodSpecialCase: true);
            c.WriteMethodParameters(Method, true, MethodBodyOpt != null);

            if (MethodBodyOpt == null)
            {
                c.EndStatement();
            }
            else
            {
                MethodBodyOpt.WriteTo(c);
            }
        }
Пример #2
0
        internal override void WriteTo(CCodeWriterBase c)
        {
            c.DecrementIndent();

            foreach (var label in this.Labels)
            {
                if (label.Value != null)
                {
                    var skipCaseForNullableWhenNull = this.SwitchType.IsValueType && label.Value.IsNull;
                    if (!skipCaseForNullableWhenNull)
                    {
                        c.TextSpan("case");
                        c.WhiteSpace();
                        if (label.Value != null)
                        {
                            new Literal {
                                Value = label.Value, Type = label.Type
                            }.WriteTo(c);
                        }
                        else
                        {
                            label.WriteTo(c);
                        }

                        c.TextSpan(":");
                    }
                    else
                    {
                        label.GenerateLabel = this.IsNullableType;
                    }
                }
                else
                {
                    c.TextSpan("default:");
                    if (this.IsNullableType)
                    {
                        label.GenerateLabel = true;
                    }
                }

                c.NewLine();

                if (label.GenerateLabel)
                {
                    label.WriteTo(c);
                    c.TextSpan(":");
                    c.NewLine();
                }
            }

            c.IncrementIndent();

            NoParenthesis = true;
            base.WriteTo(c);
        }
Пример #3
0
        internal override void WriteTo(CCodeWriterBase c)
        {
            c.DecrementIndent();

            foreach (var label in this.Labels)
            {
                if (label.Value != null)
                {
                    var skipCaseForNullableWhenNull = this.SwitchType.IsValueType && label.Value.IsNull;
                    if (!skipCaseForNullableWhenNull)
                    {
                        c.TextSpan("case");
                        c.WhiteSpace();

                        if (this.SwitchType.TypeKind == TypeKind.Enum)
                        {
                            c.TextSpan("(");
                            c.WriteType(this.SwitchType, containingNamespace: MethodOwner?.ContainingNamespace);
                            c.TextSpan(")");
                        }

                        c.TextSpan(label.ToString());
                        c.TextSpan(":");
                    }
                    else
                    {
                        label.GenerateLabel = this.IsNullableType;
                    }
                }
                else
                {
                    c.TextSpan("default:");
                    if (this.IsNullableType)
                    {
                        label.GenerateLabel = true;
                    }
                }

                c.NewLine();

                if (label.GenerateLabel)
                {
                    label.WriteTo(c);
                    c.TextSpan(":");
                    c.NewLine();
                }
            }

            c.IncrementIndent();

            NoParenthesis = true;
            base.WriteTo(c);
        }
Пример #4
0
        internal override void WriteTo(CCodeWriterBase c)
        {
            c.TextSpan("if");
            c.WhiteSpace();
            c.TextSpan("(");

            if (!this.JumpIfTrue)
            {
                c.TextSpan("!");
                c.WriteWrappedExpressionIfNeeded(this.Condition);
            }
            else
            {
                this.Condition.WriteTo(c);
            }

            c.TextSpan(")");

            c.NewLine();
            c.OpenBlock();

            new GotoStatement {
                Label = this.Label
            }.WriteTo(c);

            c.EndBlock();

            c.Separate();
        }
Пример #5
0
        public override void WriteTo(CCodeWriterBase c)
        {
            c.TextSpan("class");
            c.WhiteSpace();
            this.Name(c);

            c.WhiteSpace();
            c.TextSpan(":");
            c.WhiteSpace();
            c.TextSpan("public");
            c.WhiteSpace();
            c.TextSpan("__methods_table");
            c.NewLine();
            c.OpenBlock();

            c.DecrementIndent();
            c.TextSpanNewLine("public:");
            c.IncrementIndent();

            foreach (var declaration in Declarations)
            {
                declaration.WriteTo(c);
            }

            c.EndBlockWithoutNewLine();
        }
Пример #6
0
        internal override void WriteTo(CCodeWriterBase c)
        {
            c.TextSpan("[&]()");

            c.NewLine();
            c.OpenBlock();
            foreach (var statement in this.Locals)
            {
                statement.WriteTo(c);
            }

            foreach (var expression in this.SideEffects)
            {
                expression.WriteTo(c);
                c.EndStatement();
            }

            c.TextSpan("return");
            c.WhiteSpace();
            this.Value.WriteTo(c);
            c.EndStatement();

            c.EndBlockWithoutNewLine();
            c.TextSpan("()");
        }
Пример #7
0
        internal override void WriteTo(CCodeWriterBase c)
        {
            c.TextSpan("for");
            c.WhiteSpace();
            c.TextSpan("(");

            PrintStatementAsExpression(c, this.InitializationOpt);

            c.TextSpan(";");
            c.WhiteSpace();

            if (this.ConditionOpt != null)
            {
                this.ConditionOpt.WriteTo(c);
            }

            c.TextSpan(";");
            c.WhiteSpace();

            PrintStatementAsExpression(c, this.IncrementingOpt);

            c.TextSpan(")");

            c.NewLine();
            base.WriteTo(c);
        }
Пример #8
0
        internal override void WriteTo(CCodeWriterBase c)
        {
            if (this.locals.Count > 0)
            {
                c.OpenBlock();

                foreach (var statement in this.locals)

                {
                    statement.WriteTo(c);
                }
            }

            c.TextSpan("for");
            c.WhiteSpace();
            c.TextSpan("(");

            var block = this.Initialization as Block;

            if (block != null)
            {
                var any = false;
                foreach (var initializationItem in block.Statements)
                {
                    if (any)
                    {
                        c.TextSpan(",");
                        c.WhiteSpace();
                    }

                    PrintStatementAsExpression(c, initializationItem);
                    any = true;
                }
            }
            else
            {
                PrintStatementAsExpression(c, this.Initialization);
            }

            c.TextSpan(";");
            c.WhiteSpace();

            this.Condition.WriteTo(c);

            c.TextSpan(";");
            c.WhiteSpace();

            PrintStatementAsExpression(c, this.Incrementing);

            c.TextSpan(")");

            c.NewLine();
            base.WriteTo(c);

            if (this.locals.Count > 0)
            {
                c.EndBlock();
            }
        }
Пример #9
0
        internal override void WriteTo(CCodeWriterBase c)
        {
            CCodeWriterBase.SetLocalObjectIDGenerator();

            // get actual statements
            var statements = Statements;

            if (statements.Count == 1 && statements.First().Kind == Kinds.BlockStatement)
            {
                var blockStatement = statements.First() as BlockStatement;
                if (blockStatement != null)
                {
                    var block = blockStatement.Statements as Block;
                    if (block != null)
                    {
                        statements = block.Statements;
                    }
                }
            }

            var extraLocalDecls = this.SanitizeCode(statements);

            var skip = 0;

            ////if (this.MethodSymbol.MethodKind == MethodKind.Constructor)
            ////{
            ////    skip = ConstructorInitializer(c, statements);
            ////}

            c.NewLine();
            c.OpenBlock();

            foreach (var localDecl in extraLocalDecls)
            {
                var loadState = localDecl.Suppressed;
                localDecl.Suppressed = false;
                localDecl.WriteTo(c);
                localDecl.Suppressed = loadState;
            }

            if (MethodSymbol.MethodKind == MethodKind.StaticConstructor)
            {
                c.TextSpanNewLine("_cctor_being_called = true;");
            }

            foreach (var statement in statements.Skip(skip))
            {
                if (MethodSymbol.MethodKind == MethodKind.StaticConstructor && statement.Kind == Kinds.ReturnStatement)
                {
                    c.TextSpanNewLine("_cctor_called = true;");
                    c.TextSpanNewLine("_cctor_being_called = false;");
                }

                statement.WriteTo(c);
            }

            c.EndBlock();
        }
Пример #10
0
        internal override void WriteTo(CCodeWriterBase c)
        {
            if (this.FinallyBlockOpt != null)
            {
                var block = this.FinallyBlockOpt as Block;
                if (block != null)
                {
                    block.SuppressNewLineAtEnd = true;
                }

                c.OpenBlock();
                c.TextSpan("Finally");
                c.WhiteSpace();
                c.TextSpan("__finally_block");
                c.TextSpan("(");
                new LambdaExpression()
                {
                    Statements = block
                }.WriteTo(c);
                c.TextSpan(");");
                c.NewLine();
            }

            if (this.catchBlocks.Any())
            {
                c.TextSpan("try");
            }

            c.NewLine();

            c.WriteBlockOrStatementsAsBlock(this.TryBlock);

            foreach (var catchBlock in this.catchBlocks)
            {
                catchBlock.WriteTo(c);
            }

            if (this.FinallyBlockOpt != null)
            {
                c.EndBlock();
            }

            c.Separate();
        }
Пример #11
0
        internal override void WriteTo(CCodeWriterBase c)
        {
            c.SaveAndSet0Indent();
            this.Label.WriteTo(c);
            c.TextSpan(":");
            c.RestoreIndent();
            c.NewLine();

            c.RequireEmptyStatement();
        }
Пример #12
0
        /// <summary>
        /// </summary>
        /// <param name="c">
        /// </param>
        /// <param name="newNonStaticMethod">
        /// </param>
        /// <param name="nonStaticType">
        /// </param>
        private static void WriteNewMethod(CCodeWriterBase c, IMethodSymbol newNonStaticMethod, NamedTypeImpl nonStaticType)
        {
            c.WriteMethodDeclaration(newNonStaticMethod, true, true);
            c.NewLine();
            c.OpenBlock();

            var objectCreationExpression = new ObjectCreationExpression {
                Type = nonStaticType, NewOperator = true
            };

            foreach (var parameter in newNonStaticMethod.Parameters)
            {
                Expression parameterExpression = new Parameter {
                    ParameterSymbol = parameter
                };
                if (parameter.Name == "m")
                {
                    parameterExpression = new Cast
                    {
                        Operand        = parameterExpression,
                        MapPointerCast = true,
                        MapPointerCastTypeParameter1 =
                            new Access
                        {
                            AccessType  = Access.AccessTypes.DoubleColon,
                            ReceiverOpt = new TypeExpression {
                                Type = nonStaticType, TypeNameRequred = true
                            },
                            Expression = new Parameter {
                                ParameterSymbol = new ParameterImpl {
                                    Name = "_Memptr"
                                }
                            }
                        },
                        MapPointerCastTypeParameter2 = new TypeExpression {
                            Type = new TypeImpl {
                                TypeKind = TypeKind.TypeParameter, Name = "_Memptr"
                            }
                        },
                    };
                }

                objectCreationExpression.Arguments.Add(parameterExpression);
            }

            new ReturnStatement {
                ExpressionOpt = objectCreationExpression
            }.WriteTo(c);

            c.EndBlockWithoutNewLine();
            c.EndStatement();
        }
Пример #13
0
        internal override void WriteTo(CCodeWriterBase c)
        {
            c.TextSpan("while");
            c.WhiteSpace();
            c.TextSpan("(");

            this.Condition.WriteTo(c);

            c.TextSpan(")");

            c.NewLine();
            base.WriteTo(c);
        }
Пример #14
0
        internal override void WriteTo(CCodeWriterBase c)
        {
            c.TextSpan("if");
            c.WhiteSpace();
            c.TextSpan("(");
            this.Condition.WriteTo(c);
            c.TextSpan(")");

            c.NewLine();
            c.WriteBlockOrStatementsAsBlock(this.IfStatements);

            if (this.ElseStatementsOpt != null)
            {
                c.TextSpan("else");

                c.NewLine();
                c.WriteBlockOrStatementsAsBlock(this.ElseStatementsOpt);
            }

            c.Separate();

            // No normal ending of Statement as we do not need extra ;
        }
Пример #15
0
        public override void WriteTo(CCodeWriterBase c)
        {
            c.TextSpan("class");
            c.WhiteSpace();
            this.Name(c);

            c.WhiteSpace();
            c.TextSpan(":");
            c.WhiteSpace();
            c.TextSpan("public");
            c.WhiteSpace();
            c.WriteTypeFullName(this.@interface);
            c.NewLine();
            c.OpenBlock();

            c.DecrementIndent();
            c.TextSpanNewLine("public:");
            c.IncrementIndent();

            // write default constructor
            this.Name(c);
            c.TextSpan("(");
            c.WriteType(Type, false, true, true);
            c.WhiteSpace();
            c.TextSpan("class_");
            c.TextSpan(")");
            c.WhiteSpace();
            c.TextSpan(":");
            c.WhiteSpace();
            c.TextSpan("_class{class_}");
            c.WhiteSpace();
            c.TextSpanNewLine("{}");

            // add new method
            var namedTypeSymbol = (INamedTypeSymbol)Type;

            // not needed as we use global normal allocator
            ////new CCodeNewOperatorDeclaration(@interface).WriteTo(c);
            new CCodeObjectCastOperatorDefinition(namedTypeSymbol).WriteTo(c);

            foreach (var declaration in Declarations)
            {
                declaration.WriteTo(c);
            }

            c.EndBlockWithoutNewLine();
        }
Пример #16
0
        internal override void WriteTo(CCodeWriterBase c)
        {
            c.TextSpan("do");
            c.NewLine();
            NoSeparation = true;
            base.WriteTo(c);

            c.TextSpan("while");
            c.WhiteSpace();
            c.TextSpan("(");

            this.Condition.WriteTo(c);

            c.TextSpan(")");

            c.EndStatement();
        }
Пример #17
0
        internal override void WriteTo(CCodeWriterBase c)
        {
            CCodeWriterBase.SetLocalObjectIDGenerator();

            // get actual statements
            var statements = Statements;

            if (statements.Count == 1 && statements.First().Kind == Kinds.BlockStatement)
            {
                var blockStatement = statements.First() as BlockStatement;
                if (blockStatement != null)
                {
                    var block = blockStatement.Statements as Block;
                    if (block != null)
                    {
                        statements = block.Statements;
                    }
                }
            }

            this.SanitizeCaseLabelsAndSetReturnTypes(statements);

            var skip = 0;

            ////if (this.MethodSymbol.MethodKind == MethodKind.Constructor)
            ////{
            ////    skip = ConstructorInitializer(c, statements);
            ////}

            c.NewLine();
            c.OpenBlock();

            if (this.MethodSymbol.MethodKind == MethodKind.StaticConstructor)
            {
                c.TextSpanNewLine("_cctor_called = true;");
            }

            foreach (var statement in statements.Skip(skip))
            {
                statement.WriteTo(c);
            }

            c.EndBlock();
        }
Пример #18
0
        internal override void WriteTo(CCodeWriterBase c)
        {
            if (this.locals.Count > 0)
            {
                c.OpenBlock();

                foreach (var statement in this.locals)
                {
                    statement.WriteTo(c);
                }
            }

            c.TextSpan("for");
            c.WhiteSpace();
            c.TextSpan("(");

            PrintStatementAsExpression(c, this.InitializationOpt);

            c.TextSpan(";");
            c.WhiteSpace();

            if (this.ConditionOpt != null)
            {
                this.ConditionOpt.WriteTo(c);
            }

            c.TextSpan(";");
            c.WhiteSpace();

            PrintStatementAsExpression(c, this.IncrementingOpt);

            c.TextSpan(")");

            c.NewLine();
            base.WriteTo(c);

            if (this.locals.Count > 0)
            {
                c.EndBlock();
            }
        }
Пример #19
0
        public override void WriteTo(CCodeWriterBase c)
        {
            c.TextSpan("class");
            c.WhiteSpace();
            this.Name(c);

            c.WhiteSpace();
            c.TextSpan(":");
            c.WhiteSpace();
            c.TextSpan("public");
            c.WhiteSpace();
            c.WriteTypeFullName(this.@interface);
            c.NewLine();
            c.OpenBlock();

            c.DecrementIndent();
            c.TextSpanNewLine("public:");
            c.IncrementIndent();

            // write default constructor
            this.Name(c);
            c.TextSpan("(");
            c.WriteType(Type, false, true, true);
            c.WhiteSpace();
            c.TextSpan("class_");
            c.TextSpan(")");
            c.WhiteSpace();
            c.TextSpan(":");
            c.WhiteSpace();
            c.TextSpan("_class{class_}");
            c.WhiteSpace();
            c.TextSpanNewLine("{}");

            foreach (var declaration in Declarations)
            {
                declaration.WriteTo(c);
            }

            c.EndBlockWithoutNewLine();
        }
        public override void WriteTo(CCodeWriterBase c)
        {
            c.TextSpan(string.Format("// adapter: {0}", Method));
            c.NewLine();

            foreach (var statement in this.typeDefs)
            {
                statement.WriteTo(c);
            }

            c.WriteMethodReturn(Method, true);
            c.WriteMethodName(Method, allowKeywords: false, interfaceWrapperMethodSpecialCase: true);
            c.WriteMethodParameters(Method, true, MethodBodyOpt != null);

            if (MethodBodyOpt == null)
            {
                c.EndStatement();
            }
            else
            {
                MethodBodyOpt.WriteTo(c);
            }
        }
Пример #21
0
        internal override void WriteTo(CCodeWriterBase c)
        {
            c.TextSpan("catch");
            c.WhiteSpace();
            c.TextSpan("(");
            if (this.ExceptionTypeOpt != null)
            {
                c.WriteType(this.ExceptionTypeOpt);
                if (this.ExceptionSourceOpt != null)
                {
                    c.WhiteSpace();
                    this.ExceptionSourceOpt.WriteTo(c);
                }
            }
            else
            {
                c.TextSpan("...");
            }

            c.TextSpan(")");

            c.NewLine();
            c.WriteBlockOrStatementsAsBlock(Statements);
        }
Пример #22
0
        internal override void WriteTo(CCodeWriterBase c)
        {
            Local localCase = null;

            if (this.stringEquality != null)
            {
                c.OpenBlock();

                var localImpl = new LocalImpl {
                    Name = "__SwitchExpression", Type = this.expression.Type
                };
                var local = new Local {
                    LocalSymbol = localImpl
                };

                var localImplCase = new LocalImpl {
                    Name = "__SwitchCase", Type = new TypeImpl {
                        SpecialType = SpecialType.System_Int32
                    }
                };
                localCase = new Local {
                    LocalSymbol = localImplCase
                };

                new VariableDeclaration {
                    Local = localCase
                }.WriteTo(c);
                new VariableDeclaration {
                    Local = local
                }.WriteTo(c);

                // first if
                IfStatement first     = null;
                IfStatement last      = null;
                var         caseIndex = 0;

                foreach (var switchSection in this.switchCases)
                {
                    foreach (var label in switchSection.Labels)
                    {
                        if (label.Value == null)
                        {
                            // default case;
                            continue;
                        }

                        caseIndex++;

                        // compare
                        var callEqual = new Call()
                        {
                            Method = this.stringEquality
                        };
                        callEqual.Arguments.Add(local);
                        callEqual.Arguments.Add(new Literal {
                            Value = label.Value
                        });

                        // set value
                        var setExpr = new ExpressionStatement
                        {
                            Expression =
                                new AssignmentOperator
                            {
                                Left  = localCase,
                                Right = new Literal {
                                    Value = ConstantValue.Create(caseIndex)
                                }
                            }
                        };

                        var ifStatement = new IfStatement
                        {
                            Condition =
                                new BinaryOperator
                            {
                                OperatorKind = BinaryOperatorKind.Equal,
                                Left         = new Literal {
                                    Value = ConstantValue.Create(0)
                                },
                                Right = callEqual
                            },
                            IfStatements = setExpr
                        };

                        first = first ?? ifStatement;
                        if (last != null)
                        {
                            last.ElseStatementsOpt = ifStatement;
                        }

                        last = ifStatement;

                        // remap case value
                        label.Value = ConstantValue.Create(caseIndex);
                    }
                }

                if (first != null)
                {
                    first.WriteTo(c);
                }

                c.Separate();
            }

            foreach (var statement in this.statements)
            {
                statement.WriteTo(c);
            }

            c.TextSpan("switch");
            c.WhiteSpace();
            c.TextSpan("(");
            if (this.stringEquality != null)
            {
                localCase.WriteTo(c);
            }
            else
            {
                this.expression.WriteTo(c);
            }

            c.TextSpan(")");
            c.NewLine();
            c.OpenBlock();
            foreach (var switchSection in this.switchCases)
            {
                switchSection.WriteTo(c);
            }

            c.EndBlock();

            if (this.stringEquality != null)
            {
                c.EndBlock();
            }

            c.Separate();
        }
Пример #23
0
        internal override void WriteTo(CCodeWriterBase c)
        {
            CCodeWriterBase.SetLocalObjectIDGenerator();

            // get actual statements
            var statements = Statements;

            if (statements.Count == 1 && statements.First().Kind == Kinds.BlockStatement)
            {
                var blockStatement = statements.First() as BlockStatement;
                if (blockStatement != null)
                {
                    var block = blockStatement.Statements as Block;
                    if (block != null)
                    {
                        statements = block.Statements;
                    }
                }
            }

            var extraLocalDecls = this.SanitizeCode(statements);

            var skip = 0;

            ////if (this.MethodSymbol.MethodKind == MethodKind.Constructor)
            ////{
            ////    skip = ConstructorInitializer(c, statements);
            ////}

            c.NewLine();
            c.OpenBlock();

            foreach (var localDecl in extraLocalDecls)
            {
                var loadState = localDecl.Suppressed;
                localDecl.Suppressed = false;
                localDecl.WriteTo(c);
                localDecl.Suppressed = loadState;
            }

            if (MethodSymbol.MethodKind == MethodKind.StaticConstructor)
            {
                c.TextSpanNewLine("_cctor_being_called = true;");
            }

            #region Virtual Generic methods support
            if (MethodSymbol.MethodKind == MethodKind.Constructor)
            {
                foreach (var typeParameter in MethodSymbol.ContainingType.GetTemplateParameters().Where(t => t.HasConstructorConstraint))
                {
                    c.TextSpanNewLine(string.Format("this->construct_{0} = construct_{0};", typeParameter.Name));
                }
            }
            #endregion

            foreach (var statement in statements.Skip(skip))
            {
                if (MethodSymbol.MethodKind == MethodKind.StaticConstructor && statement.Kind == Kinds.ReturnStatement)
                {
                    c.TextSpanNewLine("_cctor_called = true;");
                    c.TextSpanNewLine("_cctor_being_called = false;");
                }

                statement.WriteTo(c);
            }

            c.EndBlock();
        }
Пример #24
0
        /// <summary>
        /// </summary>
        /// <param name="c">
        /// </param>
        public override void WriteTo(CCodeWriterBase c)
        {
            // non-static
            var nonStaticType = this.GetDelegateType();

            if (nonStaticType.IsGenericType)
            {
                c.WriteTemplateDeclaration(nonStaticType);
            }

            c.TextSpan("class");
            c.WhiteSpace();
            c.WriteTypeName(nonStaticType);

            c.WhiteSpace();
            c.TextSpan(":");
            c.WhiteSpace();
            c.TextSpan("public");
            c.WhiteSpace();
            c.WriteTypeFullName(Type);
            c.NewLine();
            c.OpenBlock();

            c.DecrementIndent();
            c.TextSpanNewLine("public:");
            c.IncrementIndent();

            // typedef
            c.TextSpanNewLine("typedef typename std::remove_pointer<_T>::type _Ty;");
            c.TextSpan("typedef ");
            c.WriteType(this.invoke.ReturnType);
            c.WhiteSpace();
            c.TextSpan("(_Ty::* _Memptr)");
            c.WriteMethodParameters(this.invoke, true, false);
            c.TextSpanNewLine(";");

            // fields
            c.TextSpanNewLine("_Ty* _t;");
            c.TextSpanNewLine("_Memptr _memptr;");

            // write default constructor
            c.WriteTypeName(nonStaticType);
            c.TextSpanNewLine("(_Ty* t, _Memptr memptr) : _t(t), _memptr(memptr) { CoreLib::System::Delegate::_target = object_cast(t); CoreLib::System::Delegate::_methodPtr = __init<CoreLib::System::IntPtr>(map_pointer_cast<void*, _Memptr>(memptr)); }");

            // write invoke
            this.CreateInvokeMethod().WriteTo(c);

            // write clonse
            this.CreateCloneMethod().WriteTo(c);

            foreach (var declaration in Declarations)
            {
                declaration.WriteTo(c);
            }

            c.EndBlockWithoutNewLine();
            c.EndStatement();

            var newNonStaticMethod = this.GetNewMethod();

            WriteNewMethod(c, newNonStaticMethod, nonStaticType);

            // static
            var staticType = this.GetDelegateType(true);

            if (staticType.IsGenericType)
            {
                c.WriteTemplateDeclaration(staticType);
            }

            c.TextSpan("class");
            c.WhiteSpace();
            c.WriteTypeName(staticType);

            c.WhiteSpace();
            c.TextSpan(":");
            c.WhiteSpace();
            c.TextSpan("public");
            c.WhiteSpace();
            c.WriteTypeFullName(Type);
            c.NewLine();
            c.OpenBlock();

            c.DecrementIndent();
            c.TextSpanNewLine("public:");
            c.IncrementIndent();

            // typedef
            c.TextSpan("typedef ");
            c.WriteType(this.invoke.ReturnType);
            c.WhiteSpace();
            c.TextSpan("(* _Memptr)");
            c.WriteMethodParameters(this.invoke, true, false);
            c.TextSpanNewLine(";");

            // fields
            c.TextSpanNewLine("_Memptr _memptr;");

            // write default constructor
            c.WriteTypeName(staticType);
            c.TextSpanNewLine("(_Memptr memptr) : _memptr(memptr) {  CoreLib::System::Delegate::_methodPtr = __init<CoreLib::System::IntPtr>(map_pointer_cast<void*, _Memptr>(memptr)); }");

            // write invoke
            this.CreateInvokeMethod(true).WriteTo(c);

            // write clonse
            this.CreateCloneMethod(true).WriteTo(c);

            foreach (var declaration in Declarations)
            {
                declaration.WriteTo(c);
            }

            c.EndBlockWithoutNewLine();
            c.EndStatement();

            var newStaticMethod = this.GetNewMethod(true);

            WriteNewMethod(c, newStaticMethod, staticType);
        }
Пример #25
0
        internal override void WriteTo(CCodeWriterBase c)
        {
            Local localCase = null;

            if (this.stringEquality != null)
            {
                c.OpenBlock();

                var localImpl = new LocalImpl {
                    Name = "__SwitchExpression", Type = this.expression.Type
                };
                var local = new Local {
                    LocalSymbol = localImpl
                };

                var localImplCase = new LocalImpl {
                    Name = "__SwitchCase", Type = new TypeImpl {
                        SpecialType = SpecialType.System_Int32
                    }
                };
                localCase = new Local {
                    LocalSymbol = localImplCase
                };

                new VariableDeclaration
                {
                    Statements =
                    {
                        new ExpressionStatement
                        {
                            Expression =
                                new AssignmentOperator
                            {
                                TypeDeclaration = true,
                                Type            = new TypeImpl {
                                    SpecialType = SpecialType.System_Int32
                                },
                                Left  = localCase,
                                Right = new Literal{
                                    Value = ConstantValue.Create(0)
                                }
                            }
                        }
                    }
                }.WriteTo(c);
                new VariableDeclaration
                {
                    Statements =
                    {
                        new ExpressionStatement
                        {
                            Expression =
                                new AssignmentOperator
                            {
                                TypeDeclaration = true,
                                Type            = new TypeImpl {
                                    SpecialType = SpecialType.System_String
                                },
                                Left  = local,
                                Right = this.expression
                            }
                        }
                    }
                }.WriteTo(c);

                // first if
                IfStatement first     = null;
                IfStatement last      = null;
                var         caseIndex = 0;

                foreach (var switchSection in this.switchCases)
                {
                    foreach (var label in switchSection.Labels)
                    {
                        if (label.Value == null)
                        {
                            // default case;
                            continue;
                        }

                        caseIndex++;

                        // compare
                        var callEqual = new Call()
                        {
                            Method = this.stringEquality
                        };
                        callEqual.Arguments.Add(local);
                        callEqual.Arguments.Add(new Literal {
                            Value = label.Value
                        });

                        // set value
                        var setExpr = new ExpressionStatement
                        {
                            Expression =
                                new AssignmentOperator
                            {
                                Left  = localCase,
                                Right = new Literal {
                                    Value = ConstantValue.Create(caseIndex)
                                }
                            }
                        };

                        var ifStatement = new IfStatement
                        {
                            Condition    = callEqual,
                            IfStatements = setExpr
                        };

                        first = first ?? ifStatement;
                        if (last != null)
                        {
                            last.ElseStatementsOpt = ifStatement;
                        }

                        last = ifStatement;

                        // remap case value
                        label.Value = ConstantValue.Create(caseIndex);
                    }
                }

                if (first != null)
                {
                    first.WriteTo(c);
                }

                c.Separate();
            }

            foreach (var statement in this.statements)
            {
                statement.WriteTo(c);
            }

            var generateDefaultLabel = this.isNullableType;

            if (this.isNullableType)
            {
                var nullCase = this.switchCases.FirstOrDefault(sc => sc.Labels.Any(l => l.Value != null && l.Value.IsNull));
                if (nullCase != null)
                {
                    generateDefaultLabel = false;
                }

                var nullCaseOrDefault = nullCase ?? this.switchCases.FirstOrDefault(sc => sc.Labels.Any(l => l.Value == null));
                if (nullCaseOrDefault != null)
                {
                    var effectiveExpression = this.expression;

                    var callExpression = this.expression as Call;
                    if (callExpression != null)
                    {
                        effectiveExpression = new UnaryOperator
                        {
                            OperatorKind = UnaryOperatorKind.LogicalNegation,
                            Operand      = new Call {
                                ReceiverOpt = callExpression.ReceiverOpt, Method = new MethodImpl {
                                    Name = "get_HasValue", Parameters = ImmutableArray <IParameterSymbol> .Empty
                                }
                            }
                        };
                    }

                    // we need to insert nullable goto;
                    var ifStatement = new IfStatement
                    {
                        Condition    = effectiveExpression,
                        IfStatements = new GotoStatement {
                            Label = nullCaseOrDefault.Labels.First(l => l.Value == null || l.Value.IsNull)
                        }
                    };

                    ifStatement.WriteTo(c);
                }
            }

            c.TextSpan("switch");
            c.WhiteSpace();
            c.TextSpan("(");
            if (this.stringEquality != null)
            {
                localCase.WriteTo(c);
            }
            else
            {
                this.expression.WriteTo(c);
            }

            c.TextSpan(")");
            c.NewLine();
            c.OpenBlock();
            foreach (var switchSection in this.switchCases)
            {
                if (!generateDefaultLabel && switchSection.Labels.Any(l => l.Value == null))
                {
                    switchSection.IsNullableType = false;
                }

                switchSection.WriteTo(c);
            }

            c.EndBlock();

            if (this.stringEquality != null)
            {
                c.EndBlock();
            }

            c.Separate();
        }