Browse Source

Added a `CCodeGenerator` class and move `Include` class as `CInclude`.

pull/1170/head
Joao Matos 6 years ago committed by Dimitar Dobrev
parent
commit
a0c5dc8349
  1. 248
      src/Generator/Generators/C/CCodeGenerator.cs
  2. 26
      src/Generator/Generators/CLI/CLITemplate.cs
  3. 9
      src/Generator/Generators/CLI/CLITypeReferences.cs
  4. 7
      src/Generator/Generators/CodeGenerator.cs
  5. 5
      src/Generator/Types/Std/Stdlib.cs

248
src/Generator/Generators/C/CCodeGenerator.cs

@ -0,0 +1,248 @@ @@ -0,0 +1,248 @@
using CppSharp.AST;
using System.Collections.Generic;
using System.Linq;
namespace CppSharp.Generators.C
{
public struct CInclude
{
public enum IncludeKind
{
Angled,
Quoted
}
public string File;
public TranslationUnit TranslationUnit;
public IncludeKind Kind;
public bool InHeader;
public override string ToString()
{
return string.Format(Kind == IncludeKind.Angled ?
"#include <{0}>" : "#include \"{0}\"", File);
}
}
public abstract class CCodeGenerator : CodeGenerator
{
public CCodeGenerator(BindingContext context)
: base(context)
{
VisitOptions.VisitPropertyAccessors = true;
}
public virtual string QualifiedName(Declaration decl)
{
if (Options.GeneratorKind == GeneratorKind.CPlusPlus)
return decl.Name;
return decl.QualifiedName;
}
public override string GeneratedIdentifier(string id)
{
return "__" + id.Replace('-', '_');
}
private CppTypePrinter typePrinter = new CppTypePrinter();
public virtual CppTypePrinter CTypePrinter => typePrinter;
public virtual void WriteHeaders() { }
public virtual void WriteInclude(CInclude include)
{
WriteLine(include.ToString());
}
public override bool VisitDeclaration(Declaration decl)
{
return decl.IsGenerated && !AlreadyVisited(decl);
}
public virtual string GetMethodIdentifier(Method method) => method.Name;
public override void GenerateMethodSpecifier(Method method, Class @class)
{
var retType = method.ReturnType.Visit(CTypePrinter);
Write($"{retType} {GetMethodIdentifier(method)}(");
Write(CTypePrinter.VisitParameters(method.Parameters));
Write(")");
}
public override bool VisitTypedefDecl(TypedefDecl typedef)
{
if (!VisitDeclaration(typedef))
return false;
PushBlock();
var typeName = typedef.Type.Visit(CTypePrinter);
WriteLine($"typedef {typeName} {typedef};");
var newlineKind = NewLineKind.BeforeNextBlock;
var declarations = typedef.Namespace.Declarations.ToList();
var newIndex = declarations.FindIndex(d => d == typedef) + 1;
if (newIndex < declarations.Count)
{
if (declarations[newIndex] is TypedefDecl)
newlineKind = NewLineKind.Never;
}
PopBlock(newlineKind);
return true;
}
public override bool VisitEnumDecl(Enumeration @enum)
{
if (!VisitDeclaration(@enum))
return false;
PushBlock();
var useTypedefEnum = Options.GeneratorKind == GeneratorKind.C;
var enumName = Options.GeneratorKind != GeneratorKind.CPlusPlus ?
QualifiedName(@enum) : @enum.Name;
var enumKind = @enum.IsScoped ? "enum class" : "enum";
if (useTypedefEnum)
Write($"typedef {enumKind} {enumName}");
else
Write($"{enumKind} {enumName}");
if (Options.GeneratorKind == GeneratorKind.CPlusPlus)
{
var typeName = CTypePrinter.VisitPrimitiveType(
@enum.BuiltinType.Type, new TypeQualifiers());
if (@enum.BuiltinType.Type != PrimitiveType.Int)
Write($" : {typeName}");
}
NewLine();
WriteOpenBraceAndIndent();
foreach (var item in @enum.Items)
{
var enumItemName = Options.GeneratorKind != GeneratorKind.CPlusPlus ?
$"{@enum.QualifiedName}_{item.Name}" : item.Name;
Write(enumItemName);
if (item.ExplicitValue)
Write($" = {@enum.GetItemValueAsString(item)}");
if (item != @enum.Items.Last())
WriteLine(",");
}
NewLine();
Unindent();
if (!string.IsNullOrWhiteSpace(enumName) && useTypedefEnum)
WriteLine($"}} {enumName};");
else
WriteLine($"}};");
PopBlock(NewLineKind.BeforeNextBlock);
return true;
}
public static string GetAccess(AccessSpecifier accessSpecifier)
{
switch (accessSpecifier)
{
case AccessSpecifier.Private:
return "private";
case AccessSpecifier.Internal:
return string.Empty;
case AccessSpecifier.Protected:
return "protected";
default:
return "public";
}
}
public override void GenerateClassSpecifier(Class @class)
{
var keywords = new List<string>();
if (Options.GeneratorKind == GeneratorKind.CLI)
{
keywords.Add(AccessIdentifier(@class.Access));
if (@class.IsAbstract)
keywords.Add("abstract");
}
if (@class.IsFinal)
keywords.Add("final");
if (@class.IsStatic)
keywords.Add("static");
if (Options.GeneratorKind == GeneratorKind.CLI)
keywords.Add(@class.IsInterface ? "interface" : "class");
else
keywords.Add("class");
keywords.Add(@class.Name);
keywords = keywords.Where(s => !string.IsNullOrWhiteSpace(s)).ToList();
if (keywords.Count != 0)
Write("{0}", string.Join(" ", keywords));
var bases = @class.Bases.Where(@base => @base.IsGenerated &&
@base.IsClass && @base.Class.IsGenerated).ToList();
if (bases.Count > 0 && !@class.IsStatic)
{
var classes = bases.Select(@base =>
$"{GetAccess(@base.Access)} {@base.Class.Visit(CTypePrinter)}");
if (classes.Count() > 0)
Write(" : {0}", string.Join(", ", classes));
}
}
public override bool VisitClassDecl(Class @class)
{
if (!VisitDeclaration(@class))
return false;
PushBlock();
GenerateClassSpecifier(@class);
NewLine();
WriteOpenBraceAndIndent();
VisitDeclContext(@class);
Unindent();
WriteLine("};");
PopBlock(NewLineKind.BeforeNextBlock);
return true;
}
public override bool VisitTypedefNameDecl(TypedefNameDecl typedef)
{
return true;
}
public override bool VisitVariableDecl(Variable variable)
{
return true;
}
public override bool VisitFieldDecl(Field field)
{
return true;
}
}
}

26
src/Generator/Generators/CLI/CLITemplate.cs

@ -1,30 +1,10 @@ @@ -1,30 +1,10 @@
using System;
using System.Collections.Generic;
using CppSharp.AST;
using CppSharp.Generators.C;
namespace CppSharp.Generators.CLI
{
public struct Include
{
public enum IncludeKind
{
Angled,
Quoted
}
public string File;
public TranslationUnit TranslationUnit;
public IncludeKind Kind;
public bool InHeader;
public override string ToString()
{
return string.Format(Kind == IncludeKind.Angled ?
"#include <{0}>" : "#include \"{0}\"", File);
}
}
/// <summary>
/// There are two implementation
/// for source (CLISources) and header (CLIHeaders)
@ -34,13 +14,13 @@ namespace CppSharp.Generators.CLI @@ -34,13 +14,13 @@ namespace CppSharp.Generators.CLI
{
public CLITypePrinter TypePrinter { get; set; }
public ISet<Include> Includes;
public ISet<CInclude> Includes;
protected CLITemplate(BindingContext context, IEnumerable<TranslationUnit> units)
: base(context, units)
{
TypePrinter = new CLITypePrinter(context);
Includes = new HashSet<Include>();
Includes = new HashSet<CInclude>();
}
public abstract override string FileExtension { get; }

9
src/Generator/Generators/CLI/CLITypeReferences.cs

@ -3,13 +3,14 @@ using System.IO; @@ -3,13 +3,14 @@ using System.IO;
using CppSharp.AST;
using CppSharp.AST.Extensions;
using CppSharp.Generators.AST;
using CppSharp.Generators.C;
using CppSharp.Types;
namespace CppSharp.Generators.CLI
{
public class CLITypeReference : TypeReference
{
public Include Include;
public CInclude Include;
public override string ToString()
{
@ -125,13 +126,13 @@ namespace CppSharp.Generators.CLI @@ -125,13 +126,13 @@ namespace CppSharp.Generators.CLI
var typeRef = GetTypeReference(decl);
if (typeRef.Include.TranslationUnit == null)
{
typeRef.Include = new Include
typeRef.Include = new CInclude
{
File = GetIncludePath(translationUnit),
TranslationUnit = translationUnit,
Kind = translationUnit.IsGenerated
? Include.IncludeKind.Quoted
: Include.IncludeKind.Angled,
? CInclude.IncludeKind.Quoted
: CInclude.IncludeKind.Angled,
};
}

7
src/Generator/Generators/CodeGenerator.cs

@ -48,6 +48,11 @@ namespace CppSharp.Generators @@ -48,6 +48,11 @@ namespace CppSharp.Generators
public AstVisitorOptions VisitOptions { get; } = new AstVisitorOptions();
protected CodeGenerator(BindingContext context)
{
Context = context;
}
protected CodeGenerator(BindingContext context, TranslationUnit unit)
: this(context, new List<TranslationUnit> { unit })
{
@ -345,7 +350,7 @@ namespace CppSharp.Generators @@ -345,7 +350,7 @@ namespace CppSharp.Generators
public virtual bool VisitFriend(Friend friend)
{
throw new NotImplementedException();
return true;
}
public virtual bool VisitClassTemplateDecl(ClassTemplate template)

5
src/Generator/Types/Std/Stdlib.cs

@ -5,6 +5,7 @@ using CppSharp.AST; @@ -5,6 +5,7 @@ using CppSharp.AST;
using CppSharp.AST.Extensions;
using CppSharp.Generators;
using CppSharp.Generators.AST;
using CppSharp.Generators.C;
using CppSharp.Generators.CLI;
using CppSharp.Generators.CSharp;
@ -619,10 +620,10 @@ namespace CppSharp.Types.Std @@ -619,10 +620,10 @@ namespace CppSharp.Types.Std
{
var typeRef = collector.GetTypeReference(loc.Value);
var include = new Include
var include = new CInclude
{
File = "cstddef",
Kind = Include.IncludeKind.Angled,
Kind = CInclude.IncludeKind.Angled,
};
typeRef.Include = include;

Loading…
Cancel
Save