65 lines
2.0 KiB
C#
65 lines
2.0 KiB
C#
using NubLang.Diagnostics;
|
|
using NubLang.Syntax.Parsing.Node;
|
|
|
|
namespace NubLang.Syntax.Templating;
|
|
|
|
public class TemplateGenerator
|
|
{
|
|
private readonly SyntaxTree _syntaxTree;
|
|
private readonly TemplateTable _templateTable;
|
|
|
|
public TemplateGenerator(SyntaxTree syntaxTree, TemplateTable templateTable)
|
|
{
|
|
_syntaxTree = syntaxTree;
|
|
_templateTable = templateTable;
|
|
}
|
|
|
|
public IReadOnlyList<DefinitionSyntax> Generate()
|
|
{
|
|
var definitions = new List<DefinitionSyntax>();
|
|
|
|
foreach (var type in _syntaxTree.ReferencedTemplatedCustomTypes)
|
|
{
|
|
definitions.Add(CreateDefinition(type));
|
|
}
|
|
|
|
return definitions;
|
|
}
|
|
|
|
private DefinitionSyntax CreateDefinition(TemplatedCustomTypeSyntax type)
|
|
{
|
|
var structTemplates = _templateTable.LookupStructTemplate(type.Namespace, type.Name).ToArray();
|
|
if (structTemplates.Length > 0)
|
|
{
|
|
if (structTemplates.Length > 1)
|
|
{
|
|
throw new TemplateGeneratorException(Diagnostic.Error($"Struct template {type.Namespace}::{type.Name} has multiple definitions").Build());
|
|
}
|
|
|
|
var structTemplate = structTemplates[0];
|
|
|
|
var transformations = new Dictionary<string, TypeSyntax>();
|
|
|
|
for (var i = 0; i < structTemplate.TemplateParameters.Count; i++)
|
|
{
|
|
transformations[structTemplate.TemplateParameters[i]] = type.Arguments[i];
|
|
}
|
|
|
|
var transformer = new TypeTransformer(transformations);
|
|
var transformed = transformer.TransformStruct(structTemplate.Struct);
|
|
return transformed with { Name = type.MangledName() };
|
|
}
|
|
|
|
throw new TemplateGeneratorException(Diagnostic.Error($"Template {type.Namespace}::{type.Name} is not defined").Build());
|
|
}
|
|
}
|
|
|
|
public class TemplateGeneratorException : Exception
|
|
{
|
|
public Diagnostic Diagnostic { get; }
|
|
|
|
public TemplateGeneratorException(Diagnostic diagnostic) : base(diagnostic.Message)
|
|
{
|
|
Diagnostic = diagnostic;
|
|
}
|
|
} |