private void GenerateType(IndentedStringBuilder writer, INamedTypeSymbol ownerType) { if (_typeMap.ContainsKey(ownerType)) { return; } var ownerTypeName = GetGlobalQualifier(ownerType) + ownerType.ToString(); var flattenedProperties = from property in ownerType.GetAllProperties() where !property.IsStatic && !IsIgnoredType(property.ContainingSymbol as INamedTypeSymbol) && !IsNonBindable(property) && !IsOverride(property.GetMethod) select property; var properties = from property in ownerType.GetProperties() where !property.IsStatic && !IsNonBindable(property) && HasPublicGetter(property) && !IsOverride(property.GetMethod) select property; var propertyDependencyProperties = from property in ownerType.GetProperties() where property.IsStatic && Equals(property.Type, _dependencyPropertySymbol) select property.Name; var fieldDependencyProperties = from field in ownerType.GetFields() where field.IsStatic && Equals(field.Type, _dependencyPropertySymbol) select field.Name; var dependencyProperties = fieldDependencyProperties .Concat(propertyDependencyProperties) .ToArray(); properties = from prop in properties.Distinct(new PropertyNameEqualityComparer()) where !dependencyProperties.Contains(prop.Name + "Property") select prop; properties = properties .ToArray(); var typeInfo = new GeneratedTypeInfo( index: _typeMap.Count, hasProperties: properties.Any() || dependencyProperties.Any() ); _typeMap.Add(ownerType, typeInfo); var baseType = GetBaseType(ownerType); // Call the builders for the base types if (baseType != null) { GenerateType(writer, baseType); } writer.AppendLineInvariant("/// <summary>"); writer.AppendLineInvariant("/// Builder for {0}", ownerType.GetFullName()); writer.AppendLineInvariant("/// </summary>"); writer.AppendLineInvariant("[System.Runtime.CompilerServices.CompilerGeneratedAttribute]"); writer.AppendLineInvariant("[System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Maintainability\", \"CA1502:AvoidExcessiveComplexity\", Justification=\"Must be ignored even if generated code is checked.\")]"); writer.AppendLineInvariant("[System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Maintainability\", \"CA1506:AvoidExcessiveClassCoupling\", Justification = \"Must be ignored even if generated code is checked.\")]"); AnalyzerSuppressionsGenerator.Generate(writer, AnalyzerSuppressions); using (writer.BlockInvariant("static class MetadataBuilder_{0:000}", typeInfo.Index)) { var postWriter = new IndentedStringBuilder(); postWriter.Indent(writer.CurrentLevel); // Generate a parameter-less build to avoid generating a lambda during registration (avoids creating a caching backing field) writer.AppendLineInvariant("[System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Maintainability\", \"CA1502:AvoidExcessiveComplexity\", Justification=\"Must be ignored even if generated code is checked.\")]"); writer.AppendLineInvariant("[System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Maintainability\", \"CA1506:AvoidExcessiveClassCoupling\", Justification = \"Must be ignored even if generated code is checked.\")]"); writer.AppendLineInvariant("[System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Maintainability\", \"CA1505:AvoidUnmaintainableCode\", Justification = \"Must be ignored even if generated code is checked.\")]"); using (writer.BlockInvariant("internal static global::Uno.UI.DataBinding.IBindableType Build()")) { writer.AppendLineInvariant("return Build(null);"); } writer.AppendLineInvariant("[System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Maintainability\", \"CA1502:AvoidExcessiveComplexity\", Justification=\"Must be ignored even if generated code is checked.\")]"); writer.AppendLineInvariant("[System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Maintainability\", \"CA1506:AvoidExcessiveClassCoupling\", Justification = \"Must be ignored even if generated code is checked.\")]"); writer.AppendLineInvariant("[System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Maintainability\", \"CA1505:AvoidUnmaintainableCode\", Justification = \"Must be ignored even if generated code is checked.\")]"); using (writer.BlockInvariant("internal static global::Uno.UI.DataBinding.IBindableType Build(global::Uno.UI.DataBinding.BindableType parent)")) { writer.AppendLineInvariant( @"var bindableType = parent ?? new global::Uno.UI.DataBinding.BindableType({0}, typeof({1}));", flattenedProperties .Where(p => !IsStringIndexer(p) && HasPublicGetter(p)) .Count() , ExpandType(ownerType) ); // Call the builders for the base types if (baseType != null) { var baseTypeMapped = _typeMap.UnoGetValueOrDefault(baseType); writer.AppendLineInvariant(@"MetadataBuilder_{0:000}.Build(bindableType); // {1}", baseTypeMapped.Index, ExpandType(baseType)); } var ctor = ownerType.GetMethods().FirstOrDefault(m => m.MethodKind == MethodKind.Constructor && !m.Parameters.Any() && m.IsLocallyPublic(_currentModule)); if (ctor != null && IsCreateable(ownerType)) { using (writer.BlockInvariant("if(parent == null)")) { writer.AppendLineInvariant(@"bindableType.AddActivator(CreateInstance);"); postWriter.AppendLineInvariant($@"private static object CreateInstance() => new {ownerTypeName}();"); } } foreach (var property in properties) { var propertyTypeName = property.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); var propertyName = property.Name; if (IsStringIndexer(property)) { writer.AppendLineInvariant("bindableType.AddIndexer(GetIndexer, SetIndexer);"); postWriter.AppendLineInvariant($@"private static object GetIndexer(object instance, string name) => (({ownerTypeName})instance)[name];"); if (property.SetMethod != null) { postWriter.AppendLineInvariant($@"private static void SetIndexer(object instance, string name, object value) => (({ownerTypeName})instance)[name] = ({propertyTypeName})value;"); } else { postWriter.AppendLineInvariant("private static void SetIndexer(object instance, string name, object value) {{}}"); } continue; } if (property.IsIndexer) { // Other types of indexers are currently not supported. continue; } if ( property.SetMethod != null && property.SetMethod != null && property.SetMethod.IsLocallyPublic(_currentModule) ) { if (property.Type.IsValueType) { writer.AppendLineInvariant($@"bindableType.AddProperty(""{propertyName}"", typeof({propertyTypeName}), Get{propertyName}, Set{propertyName});"); postWriter.AppendLineInvariant($@"private static object Get{propertyName}(object instance, Windows.UI.Xaml.DependencyPropertyValuePrecedences? precedence) => (({ownerTypeName})instance).{propertyName};"); using (postWriter.BlockInvariant($@"private static void Set{propertyName}(object instance, object value, Windows.UI.Xaml.DependencyPropertyValuePrecedences? precedence)")) { using (postWriter.BlockInvariant($"if(value != null)")) { postWriter.AppendLineInvariant($"(({ownerTypeName})instance).{propertyName} = ({propertyTypeName})value;"); } } } else { writer.AppendLineInvariant($@"bindableType.AddProperty(""{propertyName}"", typeof({propertyTypeName}), Get{propertyName}, Set{propertyName});"); postWriter.AppendLineInvariant($@"private static object Get{propertyName}(object instance, Windows.UI.Xaml.DependencyPropertyValuePrecedences? precedence) => (({ownerTypeName})instance).{propertyName};"); postWriter.AppendLineInvariant($@"private static void Set{propertyName}(object instance, object value, Windows.UI.Xaml.DependencyPropertyValuePrecedences? precedence) => (({ownerTypeName})instance).{propertyName} = ({propertyTypeName})value;"); } } else if (HasPublicGetter(property)) { writer.AppendLineInvariant($@"bindableType.AddProperty(""{propertyName}"", typeof({propertyTypeName}), Get{propertyName});"); postWriter.AppendLineInvariant($@"private static object Get{propertyName}(object instance, Windows.UI.Xaml.DependencyPropertyValuePrecedences? precedence) => (({ownerTypeName})instance).{propertyName};"); } } foreach (var dependencyProperty in dependencyProperties) { var propertyName = dependencyProperty.TrimEnd("Property"); var getMethod = ownerType.GetMethods().FirstOrDefault(m => m.Name == "Get" + propertyName && m.Parameters.Length == 1 && m.IsLocallyPublic(_currentModule)); var setMethod = ownerType.GetMethods().FirstOrDefault(m => m.Name == "Set" + propertyName && m.Parameters.Length == 2 && m.IsLocallyPublic(_currentModule)); if (getMethod == null) { getMethod = ownerType .GetProperties() .FirstOrDefault(p => p.Name == propertyName && (p.GetMethod?.IsLocallyPublic(_currentModule) ?? false)) ?.GetMethod; } if (getMethod != null) { var getter = $"{XamlConstants.Types.DependencyObjectExtensions}.GetValue(instance, {ownerTypeName}.{propertyName}Property, precedence)"; var setter = $"{XamlConstants.Types.DependencyObjectExtensions}.SetValue(instance, {ownerTypeName}.{propertyName}Property, value, precedence)"; var propertyType = GetGlobalQualifier(getMethod.ReturnType) + SanitizeTypeName(getMethod.ReturnType.ToString()); writer.AppendLineInvariant($@"bindableType.AddProperty(""{propertyName}"", typeof({propertyType}), Get{propertyName}, Set{propertyName});"); postWriter.AppendLineInvariant($@"private static object Get{propertyName}(object instance, Windows.UI.Xaml.DependencyPropertyValuePrecedences? precedence) => {getter};"); postWriter.AppendLineInvariant($@"private static void Set{propertyName}(object instance, object value, Windows.UI.Xaml.DependencyPropertyValuePrecedences? precedence) => {setter};"); } } writer.AppendLineInvariant(@"return bindableType;"); } writer.Append(postWriter.ToString()); } writer.AppendLine(); }
private void GenerateProviderTable(IEnumerable <INamedTypeSymbol> q, IndentedStringBuilder writer) { writer.AppendLineInvariant("[System.Runtime.CompilerServices.CompilerGeneratedAttribute]"); writer.AppendLineInvariant("[System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Maintainability\", \"CA1502:AvoidExcessiveComplexity\", Justification=\"Must be ignored even if generated code is checked.\")]"); writer.AppendLineInvariant("[System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Maintainability\", \"CA1506:AvoidExcessiveClassCoupling\", Justification = \"Must be ignored even if generated code is checked.\")]"); AnalyzerSuppressionsGenerator.Generate(writer, AnalyzerSuppressions); using (writer.BlockInvariant("public class BindableMetadataProvider : global::Uno.UI.DataBinding.IBindableMetadataProvider")) { writer.AppendLineInvariant(@"static global::System.Collections.Hashtable _bindableTypeCacheByFullName = new global::System.Collections.Hashtable({0});", q.Count()); writer.AppendLineInvariant("[System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Maintainability\", \"CA1502:AvoidExcessiveComplexity\", Justification=\"Must be ignored even if generated code is checked.\")]"); writer.AppendLineInvariant("[System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Maintainability\", \"CA1506:AvoidExcessiveClassCoupling\", Justification = \"Must be ignored even if generated code is checked.\")]"); writer.AppendLineInvariant("[System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Maintainability\", \"CA1505:AvoidUnmaintainableCode\", Justification = \"Must be ignored even if generated code is checked.\")]"); writer.AppendLineInvariant("private delegate global::Uno.UI.DataBinding.IBindableType TypeBuilderDelegate();"); using (writer.BlockInvariant("private static TypeBuilderDelegate CreateMemoized(TypeBuilderDelegate builder)")) { writer.AppendLineInvariant(@"global::Uno.UI.DataBinding.IBindableType value = null; return () => {{ if (value == null) {{ value = builder(); }} return value; }};" ); } using (writer.BlockInvariant("static BindableMetadataProvider()")) { GenerateTypeTable(writer, q); } writer.AppendLineInvariant(@"#if DEBUG"); writer.AppendLineInvariant(@"private global::System.Collections.Generic.List<global::System.Type> _knownMissingTypes = new global::System.Collections.Generic.List<global::System.Type>();"); writer.AppendLineInvariant(@"#endif"); using (writer.BlockInvariant("public void ForceInitialize()")) { using (writer.BlockInvariant(@"foreach(TypeBuilderDelegate item in _bindableTypeCacheByFullName.Values)")) { writer.AppendLineInvariant(@"item();"); } } using (writer.BlockInvariant("public global::Uno.UI.DataBinding.IBindableType GetBindableTypeByFullName(string fullName)")) { writer.AppendLineInvariant(@"var selector = _bindableTypeCacheByFullName[fullName] as TypeBuilderDelegate;"); using (writer.BlockInvariant(@"if(selector != null)")) { writer.AppendLineInvariant(@"return selector();"); } using (writer.BlockInvariant(@"else")) { writer.AppendLineInvariant(@"return null;"); } } using (writer.BlockInvariant("public global::Uno.UI.DataBinding.IBindableType GetBindableTypeByType(Type type)")) { writer.AppendLineInvariant(@"var selector = _bindableTypeCacheByFullName[type.FullName] as TypeBuilderDelegate;"); using (writer.BlockInvariant(@"if(selector != null)")) { writer.AppendLineInvariant(@"return selector();"); } writer.AppendLineInvariant(@"#if DEBUG"); using (writer.BlockInvariant(@"else")) { using (writer.BlockInvariant(@"lock(_knownMissingTypes)")) { using (writer.BlockInvariant(@"if(!_knownMissingTypes.Contains(type) || !type.IsGenericType)")) { writer.AppendLineInvariant(@"_knownMissingTypes.Add(type);"); writer.AppendLineInvariant(@"Debug.WriteLine($""The Bindable attribute is missing and the type [{{type.FullName}}] is not known by the MetadataProvider. Reflection was used instead of the binding engine and generated static metadata. Add the Bindable attribute to prevent this message and performance issues."");"); } } } writer.AppendLineInvariant(@"#endif"); writer.AppendLineInvariant(@"return null;"); } } }
private string GenerateGlobalResources(IEnumerable <XamlFileDefinition> files) { var outputFile = Path.Combine(_targetPath, "GlobalStaticResources.g.cs"); var writer = new IndentedStringBuilder(); writer.AppendLineInvariant("// <autogenerated />"); writer.AppendLineInvariant("#pragma warning disable 618 // Ignore obsolete members warnings"); writer.AppendLineInvariant("#pragma warning disable 105 // Ignore duplicate namespaces"); writer.AppendLineInvariant("using System;"); writer.AppendLineInvariant("using System.Linq;"); writer.AppendLineInvariant("using System.Collections.Generic;"); writer.AppendLineInvariant("using Uno.Extensions;"); writer.AppendLineInvariant("using Uno;"); writer.AppendLineInvariant("using System.Diagnostics;"); //TODO Determine the list of namespaces to use writer.AppendLineInvariant($"using {XamlConstants.BaseXamlNamespace};"); writer.AppendLineInvariant($"using {XamlConstants.Namespaces.Controls};"); writer.AppendLineInvariant($"using {XamlConstants.Namespaces.Data};"); writer.AppendLineInvariant($"using {XamlConstants.Namespaces.Documents};"); writer.AppendLineInvariant($"using {XamlConstants.Namespaces.Media};"); writer.AppendLineInvariant($"using {XamlConstants.Namespaces.MediaAnimation};"); writer.AppendLineInvariant("using {0};", _defaultNamespace); writer.AppendLineInvariant(""); using (writer.BlockInvariant("namespace {0}", _defaultNamespace)) { writer.AppendLineInvariant("/// <summary>"); writer.AppendLineInvariant("/// Contains all the static resources defined for the application"); writer.AppendLineInvariant("/// </summary>"); AnalyzerSuppressionsGenerator.Generate(writer, _analyzerSuppressions); using (writer.BlockInvariant("public sealed partial class GlobalStaticResources")) { writer.AppendLineInvariant("static bool _initialized;"); using (writer.BlockInvariant("static GlobalStaticResources()")) { writer.AppendLineInvariant("Initialize();"); } using (writer.BlockInvariant("public static void Initialize()")) { using (writer.BlockInvariant("if(!_initialized)")) { writer.AppendLineInvariant("_initialized = true;"); foreach (var ambientResource in _ambientGlobalResources) { if (ambientResource.GetMethods().Any(m => m.Name == "Initialize")) { writer.AppendLineInvariant("global::{0}.Initialize();", ambientResource.GetFullName()); } writer.AppendLineInvariant("AddResolver(global::{0}.FindResource);", ambientResource.GetFullName()); } foreach (var file in files) { writer.AppendLineInvariant("RegisterResources_{0}();", file.UniqueID); writer.AppendLineInvariant("RegisterImplicitStylesResources_{0}();", file.UniqueID); } } } // Generate all the partial methods, even if they don't exist. That avoids // having to sync the generation of the files with this global table. foreach (var file in files) { writer.AppendLineInvariant("static partial void RegisterResources_{0}();", file.UniqueID); writer.AppendLineInvariant("static partial void RegisterImplicitStylesResources_{0}();", file.UniqueID); } writer.AppendLineInvariant(""); writer.AppendLineInvariant("/// <summary>"); writer.AppendLineInvariant("/// Finds a resource instance in the Global Static Resources"); writer.AppendLineInvariant("/// </summary>"); writer.AppendLineInvariant("/// <param name=\"name\">The name of the resource</param>"); writer.AppendLineInvariant("/// <returns>The instance of the resources, otherwise null.</returns>"); using (writer.BlockInvariant("public static object FindResource(string name)")) { using (writer.BlockInvariant("foreach(var resolver in _resolvers)")) { writer.AppendLineInvariant("var resource = resolver(name);"); writer.AppendLineInvariant("if(resource != null){{ return resource; }}"); } writer.AppendLineInvariant("return null;"); } writer.AppendLineInvariant(""); writer.AppendLineInvariant("private static List<Func<string, object>> _resolvers = new List<Func<string, object>>();"); using (writer.BlockInvariant("private static void AddResolver(Func<string, object> resolver)")) { writer.AppendLineInvariant("_resolvers.Add(resolver);"); } } } return(writer.ToString()); }
private string GenerateGlobalResources(IEnumerable <XamlFileDefinition> files, XamlGlobalStaticResourcesMap map) { var outputFile = Path.Combine(_targetPath, "GlobalStaticResources.g.cs"); var writer = new IndentedStringBuilder(); writer.AppendLineInvariant("// <autogenerated />"); writer.AppendLineInvariant("#pragma warning disable 618 // Ignore obsolete members warnings"); writer.AppendLineInvariant("#pragma warning disable 105 // Ignore duplicate namespaces"); writer.AppendLineInvariant("#pragma warning disable 1591 // Ignore missing XML comment warnings"); writer.AppendLineInvariant("using System;"); writer.AppendLineInvariant("using System.Linq;"); writer.AppendLineInvariant("using System.Collections.Generic;"); writer.AppendLineInvariant("using Uno.Extensions;"); writer.AppendLineInvariant("using Uno;"); writer.AppendLineInvariant("using System.Diagnostics;"); //TODO Determine the list of namespaces to use writer.AppendLineInvariant($"using {XamlConstants.BaseXamlNamespace};"); writer.AppendLineInvariant($"using {XamlConstants.Namespaces.Controls};"); writer.AppendLineInvariant($"using {XamlConstants.Namespaces.Data};"); writer.AppendLineInvariant($"using {XamlConstants.Namespaces.Documents};"); writer.AppendLineInvariant($"using {XamlConstants.Namespaces.Media};"); writer.AppendLineInvariant($"using {XamlConstants.Namespaces.MediaAnimation};"); writer.AppendLineInvariant("using {0};", _defaultNamespace); writer.AppendLineInvariant(""); using (writer.BlockInvariant("namespace {0}", _defaultNamespace)) { writer.AppendLineInvariant("/// <summary>"); writer.AppendLineInvariant("/// Contains all the static resources defined for the application"); writer.AppendLineInvariant("/// </summary>"); AnalyzerSuppressionsGenerator.Generate(writer, _analyzerSuppressions); using (writer.BlockInvariant("public sealed partial class GlobalStaticResources")) { writer.AppendLineInvariant("static bool _initialized;"); writer.AppendLineInvariant("private static bool _stylesRegistered;"); writer.AppendLineInvariant("private static bool _dictionariesRegistered;"); using (writer.BlockInvariant("internal static {0} {1} {{get; }} = new {0}()", ParseContextPropertyType, ParseContextPropertyName)) { writer.AppendLineInvariant("AssemblyName = \"{0}\",", _projectInstance.GetPropertyValue("AssemblyName")); } writer.AppendLineInvariant(";"); writer.AppendLine(); using (writer.BlockInvariant("static GlobalStaticResources()")) { writer.AppendLineInvariant("Initialize();"); } using (writer.BlockInvariant("public static void Initialize()")) { using (writer.BlockInvariant("if (!_initialized)")) { using (IsUnoAssembly ? writer.BlockInvariant("using (ResourceResolver.WriteInitiateGlobalStaticResourcesEventActivity())") : null) { writer.AppendLineInvariant("_initialized = true;"); foreach (var ambientResource in _ambientGlobalResources) { if (ambientResource.GetMethods().Any(m => m.Name == "Initialize")) { writer.AppendLineInvariant("global::{0}.Initialize();", ambientResource.GetFullName()); } } foreach (var ambientResource in _ambientGlobalResources) { // Note: we do *not* call RegisterDefaultStyles for the current assembly, because those styles are treated as implicit styles, not default styles if (ambientResource.GetMethods().Any(m => m.Name == "RegisterDefaultStyles")) { writer.AppendLineInvariant("global::{0}.RegisterDefaultStyles();", ambientResource.GetFullName()); } } foreach (var ambientResource in _ambientGlobalResources) { if (ambientResource.GetMethods().Any(m => m.Name == "RegisterResourceDictionariesBySource")) { writer.AppendLineInvariant("global::{0}.RegisterResourceDictionariesBySource();", ambientResource.GetFullName()); } } if (IsUnoAssembly && _xamlSourceFiles.Any()) { // Build master dictionary foreach (var dictProperty in map.GetAllDictionaryProperties(_baseResourceDependencies, _nonSystemResources)) { writer.AppendLineInvariant("MasterDictionary.MergedDictionaries.Add({0});", dictProperty); } } } } } using (writer.BlockInvariant("public static void RegisterDefaultStyles()")) { using (writer.BlockInvariant("if(!_stylesRegistered)")) { writer.AppendLineInvariant("_stylesRegistered = true;"); foreach (var file in files.Where(f => IsIncludedResource(f, map)).Select(f => f.UniqueID).Distinct()) { writer.AppendLineInvariant("RegisterDefaultStyles_{0}();", file); } } } writer.AppendLineInvariant("// Register ResourceDictionaries using ms-appx:/// syntax, this is called for external resources"); using (writer.BlockInvariant("public static void RegisterResourceDictionariesBySource()")) { using (writer.BlockInvariant("if(!_dictionariesRegistered)")) { writer.AppendLineInvariant("_dictionariesRegistered = true;"); if (!IsUnoAssembly && !IsUnoFluentAssembly) { // For third-party libraries, expose all files using standard uri foreach (var file in files.Where(IsResourceDictionary)) { var url = "{0}/{1}".InvariantCultureFormat(_metadataHelper.AssemblyName, map.GetSourceLink(file)); RegisterForFile(file, url); } } else if (files.Any()) // The NETSTD reference assembly contains no Xaml files { // For Uno assembly, we expose WinUI resources using same uri as on Windows RegisterForFile(files.FirstOrDefault(f => map.GetSourceLink(f).EndsWith(WinUIThemeResourcePathSuffix)), XamlFilePathHelper.WinUIThemeResourceURL); RegisterForFile(files.FirstOrDefault(f => map.GetSourceLink(f).EndsWith(WinUICompactPathSuffix)), XamlFilePathHelper.WinUICompactURL); } void RegisterForFile(XamlFileDefinition file, string url) { if (file != null) { writer.AppendLineInvariant("global::Uno.UI.ResourceResolver.RegisterResourceDictionaryBySource(uri: \"ms-appx:///{0}\", context: {1}, dictionary: () => {2}_ResourceDictionary);", url, ParseContextPropertyName, file.UniqueID ); } } } } writer.AppendLineInvariant("// Register ResourceDictionaries using ms-resource:/// syntax, this is called for local resources"); using (writer.BlockInvariant("internal static void RegisterResourceDictionariesBySourceLocal()")) { foreach (var file in files.Where(IsResourceDictionary)) { // We leave context null because local resources should be found through Application.Resources writer.AppendLineInvariant("global::Uno.UI.ResourceResolver.RegisterResourceDictionaryBySource(uri: \"{0}{1}\", context: null, dictionary: () => {2}_ResourceDictionary);", XamlFilePathHelper.LocalResourcePrefix, map.GetSourceLink(file), file.UniqueID ); // Local resources can also be found through the ms-appx:/// prefix writer.AppendLineInvariant("global::Uno.UI.ResourceResolver.RegisterResourceDictionaryBySource(uri: \"{0}{1}\", context: null, dictionary: () => {2}_ResourceDictionary);", XamlFilePathHelper.AppXIdentifier, map.GetSourceLink(file), file.UniqueID ); } } if (IsUnoAssembly) { // Declare master dictionary writer.AppendLine(); writer.AppendLineInvariant("internal static ResourceDictionary MasterDictionary {{get; }} = new ResourceDictionary();"); } // Generate all the partial methods, even if they don't exist. That avoids // having to sync the generation of the files with this global table. foreach (var file in files.Select(f => f.UniqueID).Distinct()) { writer.AppendLineInvariant("static partial void RegisterDefaultStyles_{0}();", file); } writer.AppendLineInvariant("[global::System.Obsolete(\"This method is provided for binary backward compatibility. It will always return null.\")]"); writer.AppendLineInvariant("[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]"); writer.AppendLineInvariant("public static object FindResource(string name) => null;"); writer.AppendLineInvariant(""); } } return(writer.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()); } }