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()); } }
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 ) ); } }
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()); } }