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(); }
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); } } }
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); }
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); } }