예제 #1
0
    public static AttachedMemberList Create(INamedTypeSymbol typeSymbol, TypeDataStore store, INamedTypeSymbol attachedMemberAttr)
    {
        var comparer = SymbolEqualityComparer.Default;
        Dictionary <string, AttachedMemberData>?dic = null;

        foreach (var attr in typeSymbol.GetAttributes())
        {
            if (comparer.Equals(attachedMemberAttr, attr.AttributeClass) == false)
            {
                continue;
            }
            var args = attr.ConstructorArguments;
            if (args.Length != 3)
            {
                continue;
            }
            var memberName     = args[0].Value?.ToString();
            var code           = args[1].Value?.ToString();
            var memberTypeName = args[2].Value?.ToString();
            var memberType     = memberTypeName != null?store.Compilation.GetTypeByMetadataNameOrSpecialType(memberTypeName) : null;

            if (memberName == null || code == null || memberType == null)
            {
                continue;
            }
            dic ??= new();
            dic[memberName] = new AttachedMemberData(typeSymbol, memberName, code, memberType);
        }
        if (dic == null)
        {
            return(Empty);
        }
        return(new AttachedMemberList(dic, typeSymbol, store));
    }
예제 #2
0
 public MarkupTranslatorContext(XmlObject xml, SourceStringBuilder sourceStringBuilder, TypeDataStore typeStore, MarkupTranslationResult resultHolder, CancellationToken ct)
 {
     _sourceBuilder = sourceStringBuilder;
     _xml           = xml;
     _typeStore     = typeStore;
     _result        = resultHolder;
     _ct            = ct;
 }
예제 #3
0
    public static MemberSetterList Create(INamedTypeSymbol typeSymbol, TypeDataStore store, INamedTypeSymbol?memberSetterAttr)
    {
        if (memberSetterAttr == null)
        {
            return(Empty);
        }

        var comparer = SymbolEqualityComparer.Default;
        Dictionary <string, MemberSetterData>?dic = null;

        foreach (var attr in typeSymbol.GetAttributes())
        {
            if (comparer.Equals(memberSetterAttr, attr.AttributeClass) == false)
            {
                continue;
            }
            var args = attr.ConstructorArguments;

            if (args.Length != 4)
            {
                continue;
            }
            if (TryGetString(args[0], out var memberName) == false)
            {
                continue;
            }
            if (TryGetRegex(args[1], out var pattern) == false)
            {
                continue;
            }
            if (TryGetRegexPatterns(args[2].Values, out var replacePatterns) == false)
            {
                continue;
            }
            if (TryGetStrings(args[3].Values, out var replaces) == false)
            {
                continue;
            }
            if (replacePatterns.Length != replaces.Length)
            {
                continue;
            }

            var data = new MemberSetterData(memberName, pattern, replacePatterns, replaces);
            dic ??= new();
            if (dic.ContainsKey(memberName) == false)
            {
                dic.Add(memberName, data);
            }
        }
        if (dic == null)
        {
            return(Empty);
        }
        return(new MemberSetterList(store, typeSymbol, dic));
    }
예제 #4
0
 public static bool IsAttachedMemberAttr(this XmlAttribute attr, TypeDataStore store, out RawString memberName, [MaybeNullWhen(false)] out TypeData ownerType)
 {
     if (attr.TryGetTypeFullNameAndMember(out var typeFullName, out memberName))
     {
         if (store.TryGetTypeData(typeFullName.ToString(), out ownerType))
         {
             return(true);
         }
     }
     ownerType = null;
     return(false);
 }
예제 #5
0
    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);
    }
예제 #6
0
 private AttachedMemberList(Dictionary <string, AttachedMemberData> dic, INamedTypeSymbol ownerType, TypeDataStore store)
 {
     _dic       = dic;
     _ownerType = ownerType;
     _store     = store;
 }
예제 #7
0
 private MemberSetterList(TypeDataStore store, INamedTypeSymbol ownerType, Dictionary <string, MemberSetterData> dic)
 {
     _ownerType = ownerType;
     _dic       = dic;
     _store     = store;
 }