コード例 #1
0
 public MarkupTranslatorContext(XmlObject xml, SourceStringBuilder sourceStringBuilder, TypeDataStore typeStore, MarkupTranslationResult resultHolder, CancellationToken ct)
 {
     _sourceBuilder = sourceStringBuilder;
     _xml           = xml;
     _typeStore     = typeStore;
     _result        = resultHolder;
     _ct            = ct;
 }
コード例 #2
0
ファイル: MarkupTranslator.cs プロジェクト: ikorin24/Elffy
    public static void Translate(
        XmlObject xml,
        TypeDataStore typeStore,
        MarkupTranslationResult resultHolder,
        CancellationToken ct)
    {
        ct.ThrowIfCancellationRequested();

        if (TryGetBuilderName(xml, out var builder, out var diagnostic) == false)
        {
            if (diagnostic != null)
            {
                resultHolder.AddDiagnostic(diagnostic);
            }
            return;
        }
        if (diagnostic != null)
        {
            resultHolder.AddDiagnostic(diagnostic);
        }
        var sourceBuilder = new SourceStringBuilder(builder.NamespaceName.ToString(), builder.Name.ToString());
        var context       = new MarkupTranslatorContext(xml, sourceBuilder, typeStore, resultHolder, ct);

        sourceBuilder.Header.AppendLine(@"// <auto-generated>
// Auto generated by a source generator.
// Generator: Elffy.Generator.MarkupTranslationGenerator
// </auto-generated>

#nullable enable");

        var rootNode   = xml.Root;
        var rootMethod = sourceBuilder.CreateMethodBuilder(2, out _);

        if (typeStore.TryGetTypeData("Elffy.UI.Control", out var rootCallerType) == false)
        {
            throw new NotSupportedException("not found: Elffy.UI.Control");
        }

        var(id, returnedType) = GenerateFactoryMethodCode(rootNode, rootCallerType, context);

        if (id == SkippedMethodID || returnedType == null)
        {
            rootMethod.AppendLine("[global::System.Obsolete(\"The markup file was not translated to code successfully.\", true)]");
            if (returnedType == null)
            {
                rootMethod.AppendLine($"public static async global::Cysharp.Threading.Tasks.UniTask Create()");
            }
            else
            {
                rootMethod.AppendLine($"public static async global::Cysharp.Threading.Tasks.UniTask<global::{returnedType.Name}> Create()");
            }
            rootMethod.AppendLine("{ throw new global::System.InvalidOperationException(\"The markup file was not translated to code successfully.\"); }");
            return;
        }

        var unitaskT = $"global::Cysharp.Threading.Tasks.UniTask<global::{returnedType.Name}>";

        rootMethod.AppendLine($@"public static async {unitaskT} CreateUI(global::Elffy.UI.Control parent)");
        rootMethod.AppendLine("{");
        rootMethod.IncrementIndent();
        rootMethod.AppendLine("global::System.ArgumentNullException.ThrowIfNull(parent);");
        rootMethod.AppendLine("var context = new Context();");
        rootMethod.AppendLine("try {");
        rootMethod.AppendLine($"    var obj = __F{id}(ref context, parent);");
        rootMethod.AppendLine("    await context.WhenAllTask();");
        rootMethod.AppendLine("    return obj;");
        rootMethod.AppendLine("} finally { context.Dispose(); }");
        rootMethod.DecrementIndent();
        rootMethod.AppendLine("}");

        var source = sourceBuilder.ToString();
        var result = SourceText.From(source, Encoding.UTF8);

        resultHolder.SetResult(result);
    }