Beispiel #1
0
        private static void WriteNamespaceClose(INamedTypeSymbol namedTypeSymbol, CCodeWriterText c)
        {
            foreach (var namespaceNode in namedTypeSymbol.ContainingNamespace.EnumNamespaces())
            {
                c.DecrementIndent();
                c.TextSpan("}");
            }

            c.NewLine();
        }
Beispiel #2
0
        private static bool WriteInterfaceWrapperImplementation(CCodeWriterText c, INamedTypeSymbol iface, INamedTypeSymbol namedTypeSymbol, bool genericHeaderFile = false)
        {
            var anyRecord = false;

            foreach (var interfaceMethodWrapper in new CCodeInterfaceWrapperClass(namedTypeSymbol, iface).GetMembersImplementation())
            {
                var allowedMethod = !genericHeaderFile || (namedTypeSymbol.IsGenericType || interfaceMethodWrapper.IsGeneric);
                if (!allowedMethod)
                {
                    continue;
                }

                interfaceMethodWrapper.WriteTo(c);
                anyRecord = true;
            }

            return(anyRecord);
        }
Beispiel #3
0
        private static void WriteNamespaceOpen(INamedTypeSymbol namedTypeSymbol, CCodeWriterText c)
        {
            bool any = false;

            foreach (var namespaceNode in namedTypeSymbol.ContainingNamespace.EnumNamespaces())
            {
                c.TextSpan("namespace ");
                c.WriteNamespaceName(namespaceNode);
                c.TextSpan(" { ");
                any = true;
            }

            if (any)
            {
                c.IncrementIndent();
                c.NewLine();
            }
        }
Beispiel #4
0
        private static void WriteTemplateTraits(CCodeWriterText c, INamedTypeSymbol namedTypeSymbol)
        {
            if (namedTypeSymbol.IsPrimitiveValueType() || namedTypeSymbol.TypeKind == TypeKind.Enum || namedTypeSymbol.SpecialType == SpecialType.System_Void)
            {
                // value to class
                c.TextSpanNewLine("template<>");
                c.TextSpan("struct");
                c.WhiteSpace();
                c.TextSpan("valuetype_to_class<");
                c.WriteType(namedTypeSymbol);
                c.TextSpan(">");
                c.WhiteSpace();
                c.TextSpan("{ typedef");
                c.WhiteSpace();
                c.WriteType(namedTypeSymbol, true, false, true);
                c.WhiteSpace();
                c.TextSpanNewLine("type; };");

                // class to value
                c.TextSpanNewLine("template<>");
                c.TextSpan("struct");
                c.WhiteSpace();
                c.TextSpan("class_to_valuetype<");
                c.WriteType(namedTypeSymbol, true, false, true);
                c.TextSpan(">");
                c.WhiteSpace();
                c.TextSpan("{ typedef");
                c.WhiteSpace();
                c.WriteType(namedTypeSymbol);
                c.WhiteSpace();
                c.TextSpanNewLine("type; };");

                // map class to valuetype
                if (namedTypeSymbol.IsAtomicType())
                {
                    c.TextSpanNewLine("template<>");
                    c.TextSpan("struct gc_traits<");
                    c.WriteType(namedTypeSymbol, true, false, true);
                    c.TextSpanNewLine("> { constexpr static const GCAtomic value = GCAtomic::Default; };");
                }
            }
        }
Beispiel #5
0
        private static void WriteNamespaceOpen(INamedTypeSymbol namedTypeSymbol, CCodeWriterText c)
        {
            bool any = false;

            foreach (var namespaceNode in namedTypeSymbol.ContainingNamespace.EnumNamespaces())
            {
                c.TextSpan("namespace ");
                c.WriteNamespaceName(namespaceNode);
                c.TextSpan(" { ");
                any = true;
            }

            if (any)
            {
                c.IncrementIndent();
                c.NewLine();
            }

            /*
             * // include using of namespace
             * c.TextSpan("using");
             * c.WhiteSpace();
             * c.TextSpan("namespace");
             * c.WhiteSpace();
             * c.WriteNamespace(namedTypeSymbol.ContainingNamespace);
             * c.EndStatement();
             * c.Separate();
             */

            // write alias for _
            c.TextSpan("namespace");
            c.WhiteSpace();
            c.TextSpan("_");
            c.WhiteSpace();
            c.TextSpan("=");
            c.WhiteSpace();
            c.WriteNamespace(namedTypeSymbol.ContainingNamespace);
            c.EndStatement();
            c.Separate();
            c.NewLine();
        }
Beispiel #6
0
        private static void WriteEnum(IndentedTextWriter itw, CCodeWriterText c, INamedTypeSymbol namedTypeSymbol)
        {
            itw.WriteLine();
            itw.Write("enum class ");
            c.WriteTypeName(namedTypeSymbol, false, true);
            itw.Write(" : ");
            c.WriteType(namedTypeSymbol.EnumUnderlyingType);

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

            var constantValueTypeDiscriminator = namedTypeSymbol.EnumUnderlyingType.SpecialType.GetDiscriminator();

            var any = false;

            foreach (var constValue in namedTypeSymbol.GetMembers().OfType <IFieldSymbol>().Where(f => f.IsConst))
            {
                if (any)
                {
                    c.TextSpan(",");
                    c.WhiteSpace();
                }

                c.TextSpan("c_");
                c.WriteName(constValue);
                if (constValue.ConstantValue != null)
                {
                    c.TextSpan(" = ");
                    new Literal {
                        Value = ConstantValue.Create(constValue.ConstantValue, constantValueTypeDiscriminator)
                    }
                    .WriteTo(c);
                }

                any = true;
            }

            c.EndBlockWithoutNewLine();
            c.EndStatement();
        }
Beispiel #7
0
 private static void WriteInterfaceWrapper(CCodeWriterText c, INamedTypeSymbol iface, INamedTypeSymbol namedTypeSymbol)
 {
     new CCodeInterfaceWrapperClass(namedTypeSymbol, iface).WriteTo(c);
     c.EndStatement();
     new CCodeInterfaceCastOperatorDeclaration(namedTypeSymbol, iface).WriteTo(c);
 }
Beispiel #8
0
        private static void WriteTemplateTraits(CCodeWriterText c, INamedTypeSymbol namedTypeSymbol)
        {
            if (namedTypeSymbol.IsPrimitiveValueType() || namedTypeSymbol.TypeKind == TypeKind.Enum || namedTypeSymbol.SpecialType == SpecialType.System_Void)
            {
                // value to class
                c.TextSpanNewLine("template<>");
                c.TextSpan("struct");
                c.WhiteSpace();
                c.TextSpan("valuetype_to_class<");
                c.WriteType(namedTypeSymbol);
                c.TextSpan(">");
                c.WhiteSpace();
                c.TextSpan("{ typedef");
                c.WhiteSpace();
                c.WriteType(namedTypeSymbol, true, false, true);
                c.WhiteSpace();
                c.TextSpanNewLine("type; };");

                // class to value
                c.TextSpanNewLine("template<>");
                c.TextSpan("struct");
                c.WhiteSpace();
                c.TextSpan("class_to_valuetype<");
                c.WriteType(namedTypeSymbol, true, false, true);
                c.TextSpan(">");
                c.WhiteSpace();
                c.TextSpan("{ typedef");
                c.WhiteSpace();
                c.WriteType(namedTypeSymbol);
                c.WhiteSpace();
                c.TextSpanNewLine("type; };");

                // map class to valuetype
                if (namedTypeSymbol.IsAtomicType())
                {
                    c.TextSpanNewLine("template<>");
                    c.TextSpan("struct gc_traits<");
                    c.WriteType(namedTypeSymbol, true, false, true);
                    c.TextSpanNewLine("> { constexpr static const GCAtomic value = GCAtomic::Default; };");
                }
            }

            // type holder
            var isTypeHolder = namedTypeSymbol.SpecialType == SpecialType.None && namedTypeSymbol.TypeKind == TypeKind.Struct && namedTypeSymbol.Name.EndsWith("__type");
            var isNotModule  = namedTypeSymbol.Name != "<Module>";

            if (!isTypeHolder && isNotModule)
            {
                c.TextSpan("template<");
                if (namedTypeSymbol.IsGenericType || namedTypeSymbol.IsAnonymousType)
                {
                    c.WriteTemplateDefinitionParameters(namedTypeSymbol);
                }

                c.TextSpanNewLine(">");
                c.TextSpan("struct");
                c.WhiteSpace();
                c.TextSpan("type_holder<");
                c.WriteType(namedTypeSymbol, true, false, true);
                c.TextSpan(">");
                c.WhiteSpace();
                c.TextSpan("{ typedef");
                c.WhiteSpace();
                c.WriteType(namedTypeSymbol, true, false, true, typeOfName: true);
                c.WhiteSpace();
                c.TextSpanNewLine("type; };");
            }
        }
Beispiel #9
0
        private static void WriteFullDeclarationForUnit(CCodeUnit unit, IndentedTextWriter itw, CCodeWriterText c)
        {
            var namedTypeSymbol = (INamedTypeSymbol)unit.Type;

            WriteTemplateTraits(c, namedTypeSymbol);

            WriteNamespaceOpen(namedTypeSymbol, c);

            // write extern declaration
            var externDeclarations = unit.Declarations.Select(
                declaration => new { declaration, codeMethodDeclaration = declaration as CCodeMethodDeclaration })
                                     .Where(@t => @t.codeMethodDeclaration != null && @t.codeMethodDeclaration.IsExternDeclaration)
                                     .Select(@t => @t.declaration).ToList();

            if (externDeclarations.Any())
            {
                itw.Write("extern \"C\"");
                c.WhiteSpace();
                c.OpenBlock();

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

                c.EndBlock();
            }

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

            itw.Write(namedTypeSymbol.IsValueType ? "struct" : "class");
            itw.Write(" ");
            c.WriteTypeName(namedTypeSymbol, false);
            if (namedTypeSymbol.BaseType != null)
            {
                itw.Write(" : public ");
                c.WriteTypeFullName(namedTypeSymbol.BaseType);
            }

            itw.WriteLine();
            itw.WriteLine("{");
            itw.WriteLine("public:");
            itw.Indent++;

            // base declaration
            if (namedTypeSymbol.BaseType != null)
            {
                itw.Write("typedef ");
                c.WriteTypeFullName(namedTypeSymbol.BaseType, false);
                itw.WriteLine(" base;");
            }

            foreach (var method in namedTypeSymbol.IterateAllMethodsWithTheSameNamesTakeOnlyOne())
            {
                c.TextSpan("using");
                c.WhiteSpace();
                c.WriteType(namedTypeSymbol.BaseType ?? method.ReceiverType, suppressReference: true, allowKeywords: true);
                c.TextSpan("::");
                c.WriteMethodName(method);
                c.TextSpan(";");
                c.NewLine();
            }

            if (namedTypeSymbol.TypeKind == TypeKind.Enum)
            {
                // value holder for enum
                c.WriteType(namedTypeSymbol);
                itw.WriteLine(" m_value;");
            }

            if (namedTypeSymbol.IsRuntimeType())
            {
                c.WriteTypeName(namedTypeSymbol, false);
                itw.WriteLine("() = default;");
            }

            /*
             * if (namedTypeSymbol.IsIntPtrType())
             * {
             *  c.WriteTypeName(namedTypeSymbol, false);
             *  itw.WriteLine("() = default;");
             * }
             */

            foreach (var declaration in unit.Declarations)
            {
                var codeMethodDeclaration = declaration as CCodeMethodDeclaration;
                if (codeMethodDeclaration == null || !codeMethodDeclaration.IsExternDeclaration)
                {
                    declaration.WriteTo(c);
                    if (codeMethodDeclaration != null && codeMethodDeclaration.MethodBodyOpt != null)
                    {
                        c.Separate();
                    }
                }
            }

            // write interface wrappers
            foreach (var iface in namedTypeSymbol.Interfaces)
            {
                WriteInterfaceWrapper(c, iface, namedTypeSymbol);
            }

            itw.Indent--;
            itw.WriteLine("};");

            WriteNamespaceClose(namedTypeSymbol, c);
        }
Beispiel #10
0
        private static void WriteForwardDeclarationForUnit(CCodeUnit unit, IndentedTextWriter itw, CCodeWriterText c)
        {
            var namedTypeSymbol = (INamedTypeSymbol)unit.Type;

            foreach (var namespaceNode in namedTypeSymbol.ContainingNamespace.EnumNamespaces())
            {
                itw.Write("namespace ");
                c.WriteNamespaceName(namespaceNode);
                itw.Write(" { ");
            }

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

            itw.Write(namedTypeSymbol.IsValueType ? "struct" : "class");
            itw.Write(" ");
            c.WriteTypeName(namedTypeSymbol, false);
            itw.Write("; ");

            if (namedTypeSymbol.TypeKind == TypeKind.Enum)
            {
                WriteEnum(itw, c, namedTypeSymbol);
            }

            foreach (var namespaceNode in namedTypeSymbol.ContainingNamespace.EnumNamespaces())
            {
                itw.Write("}");
            }

            itw.WriteLine();

            if (namedTypeSymbol.SpecialType == SpecialType.System_Object || namedTypeSymbol.SpecialType == SpecialType.System_String)
            {
                itw.Write("typedef ");
                c.WriteType(namedTypeSymbol, suppressReference: true, allowKeywords: false);
                itw.Write(" ");
                c.WriteTypeName(namedTypeSymbol);
                itw.WriteLine(";");
            }
        }
        public IList <string> WriteTemplateSources(IEnumerable <CCodeUnit> units, bool stubs = false)
        {
            var headersToInclude = new List <string>();

            // write all sources
            foreach (var unit in units)
            {
                int nestedLevel;
                var root = !stubs ? "src" : "impl";

                if (stubs)
                {
                    var path = this.GetPath(unit, out nestedLevel, ".h", root, doNotCreateFolder: true);
                    if (File.Exists(path))
                    {
                        headersToInclude.Add(path.Substring(string.Concat(root, "\\").Length + this.currentFolder.Length + 1));

                        // do not overwrite an existing file
                        continue;
                    }
                }

                var anyRecord = false;
                var text      = new StringBuilder();
                using (var itw = new IndentedTextWriter(new StringWriter(text)))
                {
                    var c = new CCodeWriterText(itw);
                    foreach (var definition in unit.Definitions.Where(d => d.IsGeneric && d.IsStub == stubs))
                    {
                        anyRecord = true;
                        definition.WriteTo(c);
                    }

                    if (!stubs)
                    {
                        var namedTypeSymbol = (INamedTypeSymbol)unit.Type;
                        // write interface wrappers
                        foreach (var iface in unit.Type.Interfaces)
                        {
                            anyRecord |= WriteInterfaceWrapperImplementation(c, iface, namedTypeSymbol, true);
                        }
                    }

                    itw.Close();
                }

                if (anyRecord && text.Length > 0)
                {
                    var path = this.GetPath(unit, out nestedLevel, ".h", root);
                    Debug.Assert(!path.Contains("Decimal.h"));

                    var newText = text.ToString();

                    headersToInclude.Add(path.Substring(string.Concat(root, "\\").Length + this.currentFolder.Length + 1));

                    if (IsNothingChanged(path, newText))
                    {
                        continue;
                    }

                    using (var textFile = new StreamWriter(path))
                    {
                        textFile.Write(newText);
                    }
                }
            }

            return(headersToInclude);
        }
Beispiel #12
0
        public IList <string> WriteTemplateSources(IEnumerable <IEnumerable <CCodeUnit> > units, bool stubs = false)
        {
            var headersToInclude = new List <string>();

            // write all sources
            foreach (var unitGroup in units)
            {
                var firstUnit = unitGroup.First();

                int nestedLevel;
                var root = !stubs ? "src" : "impl";
                var ext  = stubs ? ".hpp" : ".h";
                if (stubs)
                {
                    var path = this.GetPath(firstUnit, out nestedLevel, ext, root, doNotCreateFolder: true);
                    if (File.Exists(path))
                    {
                        headersToInclude.Add(path.Substring(string.Concat(root, "\\").Length + this.currentFolder.Length + 1));

                        // do not overwrite an existing file
                        continue;
                    }
                }

                var anyRecord = false;
                var text      = new StringBuilder();
                using (var itw = new IndentedTextWriter(new StringWriter(text)))
                {
                    var c = new CCodeWriterText(itw);
                    if (!stubs)
                    {
                        var typeFullNameClean = firstUnit.Type.GetTypeFullName().CleanUpName();
                        var varName           = string.Concat("HEADER_", typeFullNameClean, stubs ? "_STUBS" : string.Empty);
                        itw.WriteLine("#ifndef {0}", varName);
                        itw.WriteLine("#define {0}", varName);
                    }

                    foreach (var unit in unitGroup)
                    {
                        WriteNamespaceOpen((INamedTypeSymbol)unit.Type, c);

                        foreach (var definition in unit.Definitions.Where(d => d.IsGeneric && d.IsStub == stubs))
                        {
                            anyRecord = true;
                            definition.WriteTo(c);
                        }

                        if (!stubs)
                        {
                            var namedTypeSymbol = (INamedTypeSymbol)unit.Type;
                            // write interface wrappers
                            foreach (var iface in unit.Type.Interfaces)
                            {
                                anyRecord |= WriteInterfaceWrapperImplementation(c, iface, namedTypeSymbol, true);
                            }
                        }

                        WriteNamespaceClose((INamedTypeSymbol)unit.Type, c);
                    }

                    if (!stubs)
                    {
                        itw.WriteLine("#endif");
                    }

                    itw.Close();
                }

                if (anyRecord && text.Length > 0)
                {
                    var path    = this.GetPath(firstUnit, out nestedLevel, ext, root);
                    var newText = text.ToString();

                    headersToInclude.Add(path.Substring(string.Concat(root, "\\").Length + this.currentFolder.Length + 1));

                    if (IsNothingChanged(path, newText))
                    {
                        continue;
                    }

                    using (var textFile = new StreamWriter(path))
                    {
                        textFile.Write(newText);
                    }
                }
            }

            return(headersToInclude);
        }
Beispiel #13
0
        public void WriteHeader(AssemblyIdentity identity, ISet <AssemblyIdentity> references, bool isCoreLib, IEnumerable <CCodeUnit> units, IEnumerable <string> includeHeaders)
        {
            // write header
            var text = new StringBuilder();

            using (var itw = new IndentedTextWriter(new StringWriter(text)))
            {
                itw.WriteLine("#ifndef HEADER_{0}", identity.Name.CleanUpName());
                itw.WriteLine("#define HEADER_{0}", identity.Name.CleanUpName());

                var c = new CCodeWriterText(itw);

                if (isCoreLib)
                {
                    itw.WriteLine(Resources.c_include);
                    itw.WriteLine(Resources.intrin_template);
                }
                else
                {
                    foreach (var reference in references)
                    {
                        itw.WriteLine("#include \"{0}.h\"", reference.Name);
                    }

                    c.Separate();
                }

                // write forward declaration
                foreach (var unit in units)
                {
                    WriteForwardDeclarationForUnit(unit, itw, c);
                }

                itw.WriteLine();

                if (isCoreLib)
                {
                    itw.WriteLine(Resources.c_forward_declarations);
                }

                itw.WriteLine();

                // write full declaration
                foreach (var unit in units)
                {
                    WriteFullDeclarationForUnit(unit, itw, c);
                }

                if (isCoreLib)
                {
                    itw.WriteLine();
                    itw.WriteLine(Resources.c_declarations);
                    itw.WriteLine(Resources.c_template_definitions);
                    itw.WriteLine(Resources.overflow);
                }

                foreach (var unit in units)
                {
                    var namedTypeSymbol = (INamedTypeSymbol)unit.Type;
                    if (namedTypeSymbol.TypeKind == TypeKind.Delegate)
                    {
                        itw.WriteLine();
                        WriteNamespaceOpen(namedTypeSymbol, c);
                        new CCodeDelegateWrapperClass(namedTypeSymbol).WriteTo(c);
                        WriteNamespaceClose(namedTypeSymbol, c);
                    }
                }

                foreach (var includeHeader in includeHeaders)
                {
                    itw.WriteLine("#include \"{0}\"", includeHeader);
                }

                itw.WriteLine("#endif");

                itw.Close();
            }

            var path    = this.GetPath(identity.Name, subFolder: "src");
            var newText = text.ToString();

            if (IsNothingChanged(path, newText))
            {
                return;
            }

            using (var textFile = new StreamWriter(path))
            {
                textFile.Write(newText);
            }
        }
Beispiel #14
0
        private static void WriteNamespaceOpen(INamedTypeSymbol namedTypeSymbol, IndentedTextWriter itw, CCodeWriterText c)
        {
            bool any = false;

            foreach (var namespaceNode in namedTypeSymbol.ContainingNamespace.EnumNamespaces())
            {
                itw.Write("namespace ");
                c.WriteNamespaceName(namespaceNode);
                itw.Write(" { ");
                any = true;
            }

            if (any)
            {
                itw.Indent++;
                itw.WriteLine();
            }
        }
        private static void WriteFullDeclarationForUnit(CCodeUnit unit, IndentedTextWriter itw, CCodeWriterText c)
        {
            var any             = false;
            var namedTypeSymbol = (INamedTypeSymbol)unit.Type;

            foreach (var namespaceNode in namedTypeSymbol.ContainingNamespace.EnumNamespaces())
            {
                itw.Write("namespace ");
                c.WriteNamespaceName(namespaceNode);
                itw.Write(" { ");
                any = true;
            }

            if (any)
            {
                itw.Indent++;
                itw.WriteLine();
            }

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

            itw.Write(namedTypeSymbol.IsValueType ? "struct" : "class");
            itw.Write(" ");
            c.WriteTypeName(namedTypeSymbol, false);
            if (namedTypeSymbol.BaseType != null)
            {
                itw.Write(" : public ");
                c.WriteTypeFullName(namedTypeSymbol.BaseType);
            }

            itw.WriteLine();
            itw.WriteLine("{");
            itw.WriteLine("public:");
            itw.Indent++;

            // base declaration
            if (namedTypeSymbol.BaseType != null)
            {
                itw.Write("typedef ");
                c.WriteTypeFullName(namedTypeSymbol.BaseType, false);
                itw.WriteLine(" base;");
            }

            foreach (var method in namedTypeSymbol.IterateAllMethodsWithTheSameNamesTakeOnlyOne())
            {
                c.TextSpan("using");
                c.WhiteSpace();
                c.WriteType(namedTypeSymbol.BaseType ?? method.ReceiverType, suppressReference: true, allowKeywords: true);
                c.TextSpan("::");
                c.WriteMethodName(method);
                c.TextSpan(";");
                c.NewLine();
            }

            if (namedTypeSymbol.TypeKind == TypeKind.Enum)
            {
                // value holder for enum
                c.WriteType(namedTypeSymbol);
                itw.WriteLine(" m_value;");
            }

            /*
             * if (!unit.HasDefaultConstructor)
             * {
             *  c.WriteTypeName(namedTypeSymbol, false);
             *  itw.WriteLine("() = default;");
             * }
             */

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

            // write interface wrappers
            foreach (var iface in namedTypeSymbol.Interfaces)
            {
                WriteInterfaceWrapper(c, iface, namedTypeSymbol);
            }

            itw.Indent--;
            itw.WriteLine("};");

            if (namedTypeSymbol.TypeKind == TypeKind.Delegate)
            {
                itw.WriteLine();
                new CCodeDelegateWrapperClass(namedTypeSymbol).WriteTo(c);
                itw.WriteLine();
            }

            foreach (var namespaceNode in namedTypeSymbol.ContainingNamespace.EnumNamespaces())
            {
                itw.Indent--;
                itw.Write("}");
            }

            itw.WriteLine();

            if (namedTypeSymbol.IsPrimitiveValueType() || namedTypeSymbol.TypeKind == TypeKind.Enum || namedTypeSymbol.SpecialType == SpecialType.System_Void)
            {
                // value to class
                c.TextSpanNewLine("template<>");
                c.TextSpan("struct");
                c.WhiteSpace();
                c.TextSpan("valuetype_to_class<");
                c.WriteType(namedTypeSymbol);
                c.TextSpan(">");
                c.WhiteSpace();
                c.TextSpan("{ typedef");
                c.WhiteSpace();
                c.WriteType(namedTypeSymbol, true, false, true);
                c.WhiteSpace();
                c.TextSpan("type; };");

                // class to value
                c.TextSpanNewLine("template<>");
                c.TextSpan("struct");
                c.WhiteSpace();
                c.TextSpan("class_to_valuetype<");
                c.WriteType(namedTypeSymbol, true, false, true);
                c.TextSpan(">");
                c.WhiteSpace();
                c.TextSpan("{ typedef");
                c.WhiteSpace();
                c.WriteType(namedTypeSymbol);
                c.WhiteSpace();
                c.TextSpan("type; };");

                itw.WriteLine();
                if (namedTypeSymbol.SpecialType != SpecialType.System_Void)
                {
                    new CCodeBoxForPrimitiveValuesOrEnumsDeclaration(namedTypeSymbol).WriteTo(c);
                    itw.WriteLine();
                }
            }
        }
Beispiel #16
0
        private void WriteSource(AssemblyIdentity identity, IEnumerable <CCodeUnit> unitGroup, bool stubs = false)
        {
            int nestedLevel;

            var firstUnit = unitGroup.First();

            if (stubs)
            {
                var path = this.GetPath(firstUnit, out nestedLevel, folder: !stubs ? "src" : "impl", doNotCreateFolder: true);
                if (File.Exists(path))
                {
                    // do not overwrite an existing file
                    return;
                }
            }

            var anyRecord = false;
            var text      = new StringBuilder();

            using (var itw = new IndentedTextWriter(new StringWriter(text)))
            {
                var c = new CCodeWriterText(itw);
                WriteSourceInclude(itw, identity);
                foreach (var unit in unitGroup)
                {
                    c.Separate();

                    var namedTypeSymbol = (INamedTypeSymbol)unit.Type;
                    WriteNamespaceOpen(namedTypeSymbol, c);

                    foreach (var definition in unit.Definitions.Where(d => !d.IsGeneric && d.IsStub == stubs))
                    {
                        anyRecord = true;
                        definition.WriteTo(c);
                    }

                    if (!stubs)
                    {
                        // write interface wrappers
                        foreach (var iface in unit.Type.Interfaces)
                        {
                            anyRecord |= WriteInterfaceWrapperImplementation(c, iface, namedTypeSymbol);
                        }
                    }

                    WriteNamespaceClose(namedTypeSymbol, c);

                    if (!stubs && unit.MainMethod != null)
                    {
                        WriteSourceMainEntry(c, unit.MainMethod);
                    }
                }

                itw.Close();
            }

            if (anyRecord && text.Length > 0)
            {
                var path    = this.GetPath(firstUnit, out nestedLevel, folder: !stubs ? "src" : "impl");
                var newText = text.ToString();

                if (IsNothingChanged(path, newText))
                {
                    return;
                }

                using (var textFile = new StreamWriter(path))
                {
                    textFile.Write(newText);
                }
            }
        }
        public void WriteHeader(AssemblyIdentity identity, ISet <AssemblyIdentity> references, bool isCoreLib, IEnumerable <CCodeUnit> units, IEnumerable <string> includeHeaders)
        {
            // write header
            var text = new StringBuilder();

            using (var itw = new IndentedTextWriter(new StringWriter(text)))
            {
                var c = new CCodeWriterText(itw);

                if (isCoreLib)
                {
                    itw.WriteLine(Resources.c_include);
                }
                else
                {
                    foreach (var reference in references)
                    {
                        itw.WriteLine("#include \"{0}.h\"", reference.Name);
                    }
                }

                // write forward declaration
                foreach (var unit in units)
                {
                    WriteForwardDeclarationForUnit(unit, itw, c);
                }

                itw.WriteLine();

                if (isCoreLib)
                {
                    itw.WriteLine(Resources.c_forward_declarations);
                }

                itw.WriteLine();

                // write full declaration
                foreach (var unit in units)
                {
                    WriteFullDeclarationForUnit(unit, itw, c);
                }

                if (isCoreLib)
                {
                    itw.WriteLine();
                    itw.WriteLine(Resources.c_declarations);
                }

                itw.WriteLine();

                if (isCoreLib)
                {
                    itw.WriteLine(Resources.c_template_definitions);
                }

                foreach (var includeHeader in includeHeaders)
                {
                    itw.WriteLine("#include \"{0}\"", includeHeader);
                }

                itw.Close();
            }

            var path    = this.GetPath(identity.Name, subFolder: "src");
            var newText = text.ToString();

            if (IsNothingChanged(path, newText))
            {
                return;
            }

            using (var textFile = new StreamWriter(path))
            {
                textFile.Write(newText);
            }
        }