Browse Source

Rework Generator interface and add GenerationOutputMode option.

pull/1511/head
Joao Matos 5 years ago committed by João Matos
parent
commit
11d9f3ba50
  1. 98
      src/Generator/Generator.cs
  2. 7
      src/Generator/Generators/C/CCodeGenerator.cs
  3. 3
      src/Generator/Generators/CodeGenerator.cs
  4. 21
      src/Generator/Options.cs

98
src/Generator/Generator.cs

@ -22,7 +22,7 @@ namespace CppSharp.Generators
/// <summary> /// <summary>
/// Output generated by each backend generator. /// Output generated by each backend generator.
/// </summary> /// </summary>
public struct GeneratorOutput public class GeneratorOutput
{ {
/// <summary> /// <summary>
/// Translation unit associated with output. /// Translation unit associated with output.
@ -66,81 +66,103 @@ namespace CppSharp.Generators
} }
/// <summary>
/// Generates the outputs for the given translation units.
/// </summary>
/// <param name="units">The units to generate outputs for.</param>
public abstract List<CodeGenerator> Generate(IEnumerable<TranslationUnit> units);
/// <summary> /// <summary>
/// Generates the outputs. /// Generates the outputs.
/// </summary> /// </summary>
public virtual List<GeneratorOutput> Generate() public virtual List<GeneratorOutput> Generate()
{ {
var outputs = new List<GeneratorOutput>(); var outputMode = Context.Options.GenerationOutputMode;
var units = Context.ASTContext.TranslationUnits.GetGenerated().ToList(); // TODO: Remove this once file per module works for C++ backend
if (!Context.Options.IsCSharpGenerator)
outputMode = GenerationOutputMode.FilePerUnit;
var outputs = new List<GeneratorOutput>();
if (Context.Options.IsCSharpGenerator && if (outputMode == GenerationOutputMode.FilePerModule)
Context.Options.GenerateSingleCSharpFile)
{ {
foreach (var module in Context.Options.Modules) foreach (var module in Context.Options.Modules)
outputs.Add(GenerateModuleTemplate(module)); {
var output = GenerateModule(module);
if (output != null)
{
OnUnitGenerated(output);
outputs.Add(output);
}
}
} }
else else
{ {
GenerateTemplates(outputs, units.Where(u => !u.IsSystemHeader)); var units = Context.ASTContext.TranslationUnits.GetGenerated()
.Where(u => !u.IsSystemHeader).ToList();
if (Context.Options.IsCSharpGenerator && Context.Options.SystemModule != null) foreach (var unit in units)
outputs.Add(GenerateModuleTemplate(Context.Options.SystemModule)); {
var output = GenerateUnit(unit);
if (output != null)
{
outputs.Add(output);
OnUnitGenerated(output);
}
}
if (Context.Options.SystemModule != null)
{
var output = GenerateModule(Context.Options.SystemModule);
if (output != null)
{
OnUnitGenerated(output);
outputs.Add(output);
}
}
} }
return outputs; return outputs;
} }
private void GenerateTemplates(List<GeneratorOutput> outputs, IEnumerable<TranslationUnit> units) public virtual GeneratorOutput GenerateUnit(TranslationUnit unit)
{ {
foreach (var unit in units) var codeGenerators = Generate(new[] { unit });
{ if (codeGenerators.Count == 0)
var templates = Generate(new[] { unit }); return null;
if (templates.Count == 0)
return;
foreach (var template in templates) foreach (var codeGen in codeGenerators)
{ {
template.Process(); codeGen.Process();
} }
var output = new GeneratorOutput
{
TranslationUnit = unit,
Outputs = templates
};
outputs.Add(output); var output = new GeneratorOutput
{
TranslationUnit = unit,
Outputs = codeGenerators
};
OnUnitGenerated(output); return output;
}
} }
private GeneratorOutput GenerateModuleTemplate(Module module) public virtual GeneratorOutput GenerateModule(Module module)
{ {
var output = new GeneratorOutput var output = new GeneratorOutput
{ {
TranslationUnit = new TranslationUnit TranslationUnit = new TranslationUnit
{ {
FilePath = $"{module.LibraryName}.cs", FilePath = $"{module.LibraryName}",
Module = module Module = module
}, },
Outputs = Generate(module.Units.GetGenerated()) Outputs = Generate(module.Units.GetGenerated())
}; };
output.Outputs[0].Process();
OnUnitGenerated(output); output.Outputs[0].Process();
return output; return output;
} }
/// <summary>
/// Generates the outputs for the given translation units.
/// </summary>
/// <param name="units">The units to generate outputs for.</param>
public abstract List<CodeGenerator> Generate(IEnumerable<TranslationUnit> units);
protected abstract string TypePrinterDelegate(CppSharp.AST.Type type); protected abstract string TypePrinterDelegate(CppSharp.AST.Type type);
public static string GeneratedIdentifier(string id) => public static string GeneratedIdentifier(string id) =>

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

@ -35,9 +35,12 @@ namespace CppSharp.Generators.C
typePrinter = new CppTypePrinter(context); typePrinter = new CppTypePrinter(context);
} }
public abstract override string FileExtension { get; } public override string FileExtension { get; } = "h";
public abstract override void Process(); public override void Process()
{
}
public ISet<CInclude> Includes = new HashSet<CInclude>(); public ISet<CInclude> Includes = new HashSet<CInclude>();

3
src/Generator/Generators/CodeGenerator.cs

@ -61,7 +61,8 @@ namespace CppSharp.Generators
protected CodeGenerator(BindingContext context, IEnumerable<TranslationUnit> units) protected CodeGenerator(BindingContext context, IEnumerable<TranslationUnit> units)
{ {
Context = context; Context = context;
TranslationUnits = new List<TranslationUnit>(units); if (units != null)
TranslationUnits = new List<TranslationUnit>(units);
} }
public abstract void Process(); public abstract void Process();

21
src/Generator/Options.cs

@ -8,6 +8,12 @@ using CppSharp.Generators;
namespace CppSharp namespace CppSharp
{ {
public enum GenerationOutputMode
{
FilePerModule,
FilePerUnit
}
public class DriverOptions public class DriverOptions
{ {
public DriverOptions() public DriverOptions()
@ -137,7 +143,20 @@ namespace CppSharp
/// <summary> /// <summary>
/// Generates a single C# file. /// Generates a single C# file.
/// </summary> /// </summary>
public bool GenerateSingleCSharpFile { get; set; } = true; [Obsolete("Use the more general GenerationOutputMode property instead.")]
public bool GenerateSingleCSharpFile
{
get { return GenerationOutputMode == GenerationOutputMode.FilePerModule; }
set
{
GenerationOutputMode = value ? GenerationOutputMode.FilePerModule
: GenerationOutputMode.FilePerUnit;
}
}
public GenerationOutputMode GenerationOutputMode { get; set; } =
GenerationOutputMode.FilePerModule;
/// <summary> /// <summary>
/// Generates default values of arguments in the C# code. /// Generates default values of arguments in the C# code.

Loading…
Cancel
Save