Exemple #1
0
            private void ProcessType(INamedTypeSymbol typeSymbol)
            {
                var isiOSView       = typeSymbol.Is(_iosViewSymbol);
                var ismacOSView     = typeSymbol.Is(_macosViewSymbol);
                var isAndroidView   = typeSymbol.Is(_androidViewSymbol);
                var smallSymbolName = typeSymbol.ToString() !.Replace(typeSymbol.ContainingNamespace + ".", "");

                if (isiOSView || ismacOSView)
                {
                    var nativeCtor = typeSymbol
                                     .GetMethods()
                                     .Where(m => m.MethodKind == MethodKind.Constructor && SymbolEqualityComparer.Default.Equals(m.Parameters.FirstOrDefault()?.Type, _intPtrSymbol))
                                     .FirstOrDefault();

                    if (nativeCtor == null)
                    {
                        _context.AddSource(
                            HashBuilder.BuildIDFromSymbol(typeSymbol),
                            string.Format(
                                BaseClassFormat,
                                typeSymbol.ContainingNamespace,
                                smallSymbolName,
                                NeedsExplicitDefaultCtor(typeSymbol),
                                typeSymbol.Name
                                )
                            );
                    }
                }

                if (isAndroidView)
                {
                    var nativeCtor = typeSymbol
                                     .GetMethods()
                                     .Where(m =>
                                            m.MethodKind == MethodKind.Constructor &&
                                            m.Parameters.Select(p => p.Type).SequenceEqual(_javaCtorParams ?? Array.Empty <ITypeSymbol?>()))
                                     .FirstOrDefault();

                    if (nativeCtor == null)
                    {
                        _context.AddSource(
                            HashBuilder.BuildIDFromSymbol(typeSymbol),
                            string.Format(
                                BaseClassFormat,
                                typeSymbol.ContainingNamespace,
                                smallSymbolName,
                                NeedsExplicitDefaultCtor(typeSymbol),
                                typeSymbol.Name
                                )
                            );
                    }
                }
            }
            private void ProcessType(INamedTypeSymbol typeSymbol)
            {
                var isDependencyObject = typeSymbol.Interfaces.Any(t => t == _dependencyObjectSymbol) &&
                                         (typeSymbol.BaseType?.GetAllInterfaces().None(t => t == _dependencyObjectSymbol) ?? true);

                if (isDependencyObject && typeSymbol.TypeKind == TypeKind.Class)
                {
                    var builder = new IndentedStringBuilder();
                    builder.AppendLineInvariant("// <auto-generated>");
                    builder.AppendLineInvariant("// ******************************************************************");
                    builder.AppendLineInvariant("// This file has been generated by Uno.UI (DependencyObjectGenerator)");
                    builder.AppendLineInvariant("// ******************************************************************");
                    builder.AppendLineInvariant("// </auto-generated>");
                    builder.AppendLine();
                    builder.AppendLineInvariant("#pragma warning disable 1591 // Ignore missing XML comment warnings");
                    builder.AppendLineInvariant($"using System;");
                    builder.AppendLineInvariant($"using System.Linq;");
                    builder.AppendLineInvariant($"using System.Collections.Generic;");
                    builder.AppendLineInvariant($"using System.Collections;");
                    builder.AppendLineInvariant($"using System.Diagnostics.CodeAnalysis;");
                    builder.AppendLineInvariant($"using Uno.Disposables;");
                    builder.AppendLineInvariant($"using System.Runtime.CompilerServices;");
                    builder.AppendLineInvariant($"using Uno.Extensions;");
                    builder.AppendLineInvariant($"using Uno.Logging;");
                    builder.AppendLineInvariant($"using Uno.UI;");
                    builder.AppendLineInvariant($"using Uno.UI.DataBinding;");
                    builder.AppendLineInvariant($"using Windows.UI.Xaml;");
                    builder.AppendLineInvariant($"using Windows.UI.Xaml.Data;");
                    builder.AppendLineInvariant($"using Uno.Diagnostics.Eventing;");

                    using (builder.BlockInvariant($"namespace {typeSymbol.ContainingNamespace}"))
                    {
                        if (typeSymbol.FindAttribute(_bindableAttributeSymbol) == null)
                        {
                            builder.AppendLineInvariant(@"[global::Windows.UI.Xaml.Data.Bindable]");
                        }

                        using (GenerateNestingContainers(builder, typeSymbol))
                        {
                            using (builder.BlockInvariant($"{typeSymbol.GetAccessibilityAsCodeString()} partial class {typeSymbol.Name} : IDependencyObjectStoreProvider, IWeakReferenceProvider"))
                            {
                                GenerateDependencyObjectImplementation(builder);
                                GenerateIBinderImplementation(typeSymbol, builder);
                            }
                        }
                    }

                    _context.AddCompilationUnit(HashBuilder.BuildIDFromSymbol(typeSymbol), builder.ToString());
                }
            }
Exemple #3
0
            private void ProcessType(INamedTypeSymbol typeSymbol)
            {
                var isiOSView       = typeSymbol.Is(_iosViewSymbol);
                var ismacOSView     = typeSymbol.Is(_macosViewSymbol);
                var isAndroidView   = typeSymbol.Is(_androidViewSymbol);
                var smallSymbolName = typeSymbol.ToString() !.Replace(typeSymbol.ContainingNamespace + ".", "");

                if (isiOSView || ismacOSView)
                {
                    Func <IMethodSymbol, bool> predicate = m => !m.Parameters.IsDefaultOrEmpty && SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, _intPtrSymbol);
                    var nativeCtor = GetNativeCtor(typeSymbol, predicate, considerAllBaseTypes: false);

                    if (nativeCtor == null && GetNativeCtor(typeSymbol.BaseType, predicate, considerAllBaseTypes: true) != null)
                    {
                        _context.AddSource(
                            HashBuilder.BuildIDFromSymbol(typeSymbol),
                            string.Format(
                                BaseClassFormat,
                                typeSymbol.ContainingNamespace,
                                smallSymbolName,
                                NeedsExplicitDefaultCtor(typeSymbol),
                                SyntaxFacts.GetKeywordKind(typeSymbol.Name) == SyntaxKind.None ? typeSymbol.Name : "@" + typeSymbol.Name
                                )
                            );
                    }
                }

                if (isAndroidView)
                {
                    Func <IMethodSymbol, bool> predicate = m => m.Parameters.Select(p => p.Type).SequenceEqual(_javaCtorParams ?? Array.Empty <ITypeSymbol?>());
                    var nativeCtor = GetNativeCtor(typeSymbol, predicate, considerAllBaseTypes: false);

                    if (nativeCtor == null && GetNativeCtor(typeSymbol.BaseType, predicate, considerAllBaseTypes: true) != null)
                    {
                        _context.AddSource(
                            HashBuilder.BuildIDFromSymbol(typeSymbol),
                            string.Format(
                                BaseClassFormat,
                                typeSymbol.ContainingNamespace,
                                smallSymbolName,
                                NeedsExplicitDefaultCtor(typeSymbol),
                                SyntaxFacts.GetKeywordKind(typeSymbol.Name) == SyntaxKind.None ? typeSymbol.Name : "@" + typeSymbol.Name
                                )
                            );
                    }
                }
Exemple #4
0
            private void ProcessType(INamedTypeSymbol typeSymbol)
            {
                var isDependencyObject = typeSymbol.GetAllInterfaces().Any(t => SymbolEqualityComparer.Default.Equals(t, _dependencyObjectSymbol));

                if ((isDependencyObject || typeSymbol.IsStatic) && typeSymbol.TypeKind == TypeKind.Class)
                {
                    var hasGeneratedProperties =
                        typeSymbol.GetProperties().Any(p => p.FindAttribute(_generatedDependencyPropertyAttributeSymbol) != null) ||
                        typeSymbol.GetFields().Any(p => p.FindAttribute(_generatedDependencyPropertyAttributeSymbol) != null);

                    if (hasGeneratedProperties)
                    {
                        var builder = new IndentedStringBuilder();
                        builder.AppendLineInvariant("// <auto-generated>");
                        builder.AppendLineInvariant("// ******************************************************************");
                        builder.AppendLineInvariant("// This file has been generated by Uno.UI (DependencyPropertyGenerator)");
                        builder.AppendLineInvariant("// ******************************************************************");
                        builder.AppendLineInvariant("// </auto-generated>");
                        builder.AppendLine();
                        builder.AppendLineInvariant("#pragma warning disable 1591 // Ignore missing XML comment warnings");
                        builder.AppendLineInvariant($"using System;");
                        builder.AppendLineInvariant($"using System.Linq;");
                        builder.AppendLineInvariant($"using System.Collections.Generic;");
                        builder.AppendLineInvariant($"using System.Collections;");
                        builder.AppendLineInvariant($"using System.Diagnostics.CodeAnalysis;");
                        builder.AppendLineInvariant($"using Uno.Disposables;");
                        builder.AppendLineInvariant($"using System.Runtime.CompilerServices;");
                        builder.AppendLineInvariant($"using Uno.UI;");
                        builder.AppendLineInvariant($"using Uno.UI.DataBinding;");
                        builder.AppendLineInvariant($"using Windows.UI.Xaml;");
                        builder.AppendLineInvariant($"using Windows.UI.Xaml.Controls;");
                        builder.AppendLineInvariant($"using Windows.UI.Xaml.Data;");
                        builder.AppendLineInvariant($"using Uno.Diagnostics.Eventing;");

                        var attachedPropertiesBackingFieldStatements = new Dictionary <INamedTypeSymbol, List <string> >();

                        using (builder.BlockInvariant($"namespace {typeSymbol.ContainingNamespace}"))
                        {
                            using (GenerateNestingContainers(builder, typeSymbol))
                            {
                                using (builder.BlockInvariant($"partial class {typeSymbol.Name}"))
                                {
                                    foreach (var memberSymbol in typeSymbol.GetMembers())
                                    {
                                        if (memberSymbol.FindAttribute(_generatedDependencyPropertyAttributeSymbol) is AttributeData attribute)
                                        {
                                            var isAttached = GetBooleanAttributeValue(attribute, "Attached", false);

                                            if (isAttached)
                                            {
                                                GenerateAttachedProperty(builder, typeSymbol, memberSymbol, attribute, attachedPropertiesBackingFieldStatements);
                                            }
                                            else
                                            {
                                                GenerateProperty(builder, typeSymbol, memberSymbol, attribute);
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        foreach (var backingFieldType in attachedPropertiesBackingFieldStatements)
                        {
                            using (builder.BlockInvariant($"namespace {backingFieldType.Key.ContainingNamespace}"))
                            {
                                using (GenerateNestingContainers(builder, backingFieldType.Key))
                                {
                                    using (builder.BlockInvariant($"partial class {backingFieldType.Key.Name}"))
                                    {
                                        foreach (var statement in backingFieldType.Value)
                                        {
                                            builder.AppendLineInvariant(statement);
                                        }
                                    }
                                }
                            }
                        }

                        _context.AddSource(HashBuilder.BuildIDFromSymbol(typeSymbol), builder.ToString());
                    }
                }
            }
            private void ProcessType(INamedTypeSymbol typeSymbol)
            {
                var isiOSView     = typeSymbol.Is(_iosViewSymbol);
                var ismacOSView   = typeSymbol.Is(_macosViewSymbol);
                var isAndroidView = typeSymbol.Is(_androidViewSymbol);

                if (isiOSView || ismacOSView)
                {
                    Func <IMethodSymbol, bool> predicate = m =>
                                                           !m.Parameters.IsDefaultOrEmpty &&
                                                           (
                        SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, _intPtrSymbol) ||
                        SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, _objcNativeHandleSymbol));

                    var nativeCtor = GetNativeCtor(typeSymbol, predicate, considerAllBaseTypes: false);

                    if (nativeCtor == null && GetNativeCtor(typeSymbol.BaseType, predicate, considerAllBaseTypes: true) != null)
                    {
                        _context.AddSource(
                            HashBuilder.BuildIDFromSymbol(typeSymbol),
                            GetGeneratedCode(typeSymbol));
                    }
                }

                if (isAndroidView)
                {
                    Func <IMethodSymbol, bool> predicate = m => m.Parameters.Select(p => p.Type).SequenceEqual(_javaCtorParams ?? Array.Empty <ITypeSymbol?>());
                    var nativeCtor = GetNativeCtor(typeSymbol, predicate, considerAllBaseTypes: false);

                    if (nativeCtor == null && GetNativeCtor(typeSymbol.BaseType, predicate, considerAllBaseTypes: true) != null)
                    {
                        _context.AddSource(
                            HashBuilder.BuildIDFromSymbol(typeSymbol),
                            GetGeneratedCode(typeSymbol));
                    }
                }

                string GetGeneratedCode(INamedTypeSymbol typeSymbol)
                {
                    var builder = new IndentedStringBuilder();

                    builder.AppendLineInvariant("// <auto-generated>");
                    builder.AppendLineInvariant("// *************************************************************");
                    builder.AppendLineInvariant("// This file has been generated by Uno.UI (NativeCtorsGenerator)");
                    builder.AppendLineInvariant("// *************************************************************");
                    builder.AppendLineInvariant("// </auto-generated>");
                    builder.AppendLine();
                    builder.AppendLineInvariant("using System;");
                    builder.AppendLine();
                    var disposables = typeSymbol.AddToIndentedStringBuilder(builder, beforeClassHeaderAction: builder =>
                    {
                        // These will be generated just before `partial class ClassName {`
                        builder.Append("#if __IOS__ || __MACOS__");
                        builder.AppendLine();
                        builder.AppendLineInvariant("[global::Foundation.Register]");
                        builder.Append("#endif");
                        builder.AppendLine();
                    });

                    var syntacticValidSymbolName = SyntaxFacts.GetKeywordKind(typeSymbol.Name) == SyntaxKind.None ? typeSymbol.Name : "@" + typeSymbol.Name;

                    if (NeedsExplicitDefaultCtor(typeSymbol))
                    {
                        builder.AppendLineInvariant("/// <summary>");
                        builder.AppendLineInvariant("/// Initializes a new instance of the class.");
                        builder.AppendLineInvariant("/// </summary>");
                        builder.AppendLineInvariant($"public {syntacticValidSymbolName}() {{{{ }}}}");
                        builder.AppendLine();
                    }

                    builder.Append("#if __ANDROID__");
                    builder.AppendLine();
                    builder.AppendLineInvariant("/// <summary>");
                    builder.AppendLineInvariant("/// Native constructor, do not use explicitly.");
                    builder.AppendLineInvariant("/// </summary>");
                    builder.AppendLineInvariant("/// <remarks>");
                    builder.AppendLineInvariant("/// Used by the Xamarin Runtime to materialize native ");
                    builder.AppendLineInvariant("/// objects that may have been collected in the managed world.");
                    builder.AppendLineInvariant("/// </remarks>");
                    builder.AppendLineInvariant($"public {syntacticValidSymbolName}(IntPtr javaReference, global::Android.Runtime.JniHandleOwnership transfer) : base (javaReference, transfer) {{{{ }}}}");
                    builder.Append("#endif");
                    builder.AppendLine();

                    builder.Append("#if __IOS__ || __MACOS__ || __MACCATALYST__");
                    builder.AppendLine();
                    builder.AppendLineInvariant("/// <summary>");
                    builder.AppendLineInvariant("/// Native constructor, do not use explicitly.");
                    builder.AppendLineInvariant("/// </summary>");
                    builder.AppendLineInvariant("/// <remarks>");
                    builder.AppendLineInvariant("/// Used by the Xamarin Runtime to materialize native ");
                    builder.AppendLineInvariant("/// objects that may have been collected in the managed world.");
                    builder.AppendLineInvariant("/// </remarks>");
                    builder.AppendLineInvariant($"public {syntacticValidSymbolName}(IntPtr handle) : base (handle) {{{{ }}}}");

                    if (_objcNativeHandleSymbol != null)
                    {
                        builder.AppendLineInvariant("/// <summary>");
                        builder.AppendLineInvariant("/// Native constructor, do not use explicitly.");
                        builder.AppendLineInvariant("/// </summary>");
                        builder.AppendLineInvariant("/// <remarks>");
                        builder.AppendLineInvariant("/// Used by the .NET Runtime to materialize native ");
                        builder.AppendLineInvariant("/// objects that may have been collected in the managed world.");
                        builder.AppendLineInvariant("/// </remarks>");
                        builder.AppendLineInvariant($"public {syntacticValidSymbolName}(global::ObjCRuntime.NativeHandle handle) : base (handle) {{{{ }}}}");
                    }

                    builder.Append("#endif");
                    builder.AppendLine();

                    while (disposables.Count > 0)
                    {
                        disposables.Pop().Dispose();
                    }

                    return(builder.ToString());
                }
            private void ProcessType(INamedTypeSymbol typeSymbol)
            {
                _context.CancellationToken.ThrowIfCancellationRequested();

                if (typeSymbol.TypeKind != TypeKind.Class)
                {
                    return;
                }

                var isDependencyObject = typeSymbol.Interfaces.Any(t => SymbolEqualityComparer.Default.Equals(t, _dependencyObjectSymbol)) &&
                                         (typeSymbol.BaseType?.GetAllInterfaces().None(t => SymbolEqualityComparer.Default.Equals(t, _dependencyObjectSymbol)) ?? true);

                if (isDependencyObject)
                {
                    if (!_isUnoSolution)
                    {
                        if (typeSymbol.Is(_iosViewSymbol))
                        {
                            throw new InvalidOperationException("A 'UIKit.UIView' shouldn't implement 'DependencyObject'. Inherit 'FrameworkElement' instead.");
                        }
                        else if (typeSymbol.Is(_androidViewSymbol))
                        {
                            throw new InvalidOperationException("An 'Android.Views.View' shouldn't implement 'DependencyObject'. Inherit 'FrameworkElement' instead.");
                        }
                        else if (typeSymbol.Is(_macosViewSymbol))
                        {
                            throw new InvalidOperationException("An 'AppKit.NSView' shouldn't implement 'DependencyObject'. Inherit 'FrameworkElement' instead.");
                        }
                    }

                    var builder = new IndentedStringBuilder();
                    builder.AppendLineInvariant("// <auto-generated>");
                    builder.AppendLineInvariant("// ******************************************************************");
                    builder.AppendLineInvariant("// This file has been generated by Uno.UI (DependencyObjectGenerator)");
                    builder.AppendLineInvariant("// ******************************************************************");
                    builder.AppendLineInvariant("// </auto-generated>");
                    builder.AppendLine();
                    builder.AppendLineInvariant("#pragma warning disable 1591 // Ignore missing XML comment warnings");
                    builder.AppendLineInvariant($"using System;");
                    builder.AppendLineInvariant($"using System.Linq;");
                    builder.AppendLineInvariant($"using System.Collections.Generic;");
                    builder.AppendLineInvariant($"using System.Collections;");
                    builder.AppendLineInvariant($"using System.Diagnostics.CodeAnalysis;");
                    builder.AppendLineInvariant($"using Uno.Disposables;");
                    builder.AppendLineInvariant($"using System.Runtime.CompilerServices;");
                    builder.AppendLineInvariant($"using Uno.UI;");
                    builder.AppendLineInvariant($"using Uno.UI.Controls;");
                    builder.AppendLineInvariant($"using Uno.UI.DataBinding;");
                    builder.AppendLineInvariant($"using Windows.UI.Xaml;");
                    builder.AppendLineInvariant($"using Windows.UI.Xaml.Data;");
                    builder.AppendLineInvariant($"using Uno.Diagnostics.Eventing;");
                    builder.AppendLineInvariant("#if __MACOS__");
                    builder.AppendLineInvariant("using AppKit;");
                    builder.AppendLineInvariant("#endif");

                    using (builder.BlockInvariant($"namespace {typeSymbol.ContainingNamespace}"))
                    {
                        using (GenerateNestingContainers(builder, typeSymbol))
                        {
                            if (_bindableAttributeSymbol != null && typeSymbol.FindAttribute(_bindableAttributeSymbol) == null)
                            {
                                builder.AppendLineInvariant(@"[global::Windows.UI.Xaml.Data.Bindable]");
                            }

                            AnalyzerSuppressionsGenerator.Generate(builder, _analyzerSuppressions);

                            var internalDependencyObject = _isUnoSolution && !typeSymbol.IsSealed ? ", IDependencyObjectInternal" : "";

                            using (builder.BlockInvariant($"partial class {typeSymbol.Name} : IDependencyObjectStoreProvider, IWeakReferenceProvider{internalDependencyObject}"))
                            {
                                GenerateDependencyObjectImplementation(typeSymbol, builder);
                                GenerateIBinderImplementation(typeSymbol, builder);
                            }
                        }
                    }

                    _context.AddSource(HashBuilder.BuildIDFromSymbol(typeSymbol), builder.ToString());
                }
            }