public void GenerateExtensionsClass() { var usings = new Usings(Context, NamespaceName); var properties = new List <Property>(); var methods = new Source(Context, usings); var staticFields = new Source(Context, usings); // Add interface extension methods, allowing fluent style setters foreach (IPropertySymbol propertySymbol in Type.GetMembers().Where(member => member.Kind == SymbolKind.Property)) { var property = new Property(Context, this, propertySymbol); properties.Add(property); property.GenerateExtensionClassMethods(methods); } // If there are any attached properties, add target extension methods for those too if (AttachedType != null) { string attachedClassName = FrameworkClassName + "Attached"; usings.AddNamespace("System"); staticFields.AddLines( $"private static readonly Lazy<{AttachedType.Name}> s_{attachedClassName} = new Lazy<{AttachedType.Name}>(() => StandardUIEnvironment.Instance.Factory.{attachedClassName}Instance);", $"public static {AttachedType.Name} {attachedClassName}Instance => s_{attachedClassName}.Value;"); methods.AddBlankLineIfNonempty(); methods.AddLine("// Attached properties"); foreach (ISymbol member in AttachedType.GetMembers()) { if (!(member is IMethodSymbol getterMethod)) { continue; } // We just process the Get string methodName = getterMethod.Name; if (!methodName.StartsWith("Get")) { if (!methodName.StartsWith("Set")) { throw new UserViewableException( $"Attached type method {AttachedType.Name}.{methodName} doesn't start with Get or Set"); } else { continue; } } string propertyName = methodName.Substring("Get".Length); string setterMethodName = "Set" + propertyName; IMethodSymbol?setterMethod = (IMethodSymbol?)AttachedType.GetMembers(setterMethodName).FirstOrDefault(); var attachedProperty = new AttachedProperty(Context, this, AttachedType, getterMethod, setterMethod); attachedProperty.GenerateExtensionClassMethods(methods); } } if (!(methods.IsEmpty && staticFields.IsEmpty)) { string extensionsClassName = FrameworkClassName + "Extensions"; Source extensionsClassSource = GenerateStaticClassFile(usings, NamespaceName, extensionsClassName, methods, staticFields); extensionsClassSource.WriteToFile(Context.GetSharedOutputDirectory(ChildNamespaceName), extensionsClassName + ".cs"); } }
public void Generate(UIFramework uiFramework) { string frameworkNamespaceName = uiFramework.ToFrameworkNamespaceName(Namespace); var usings = new Usings(Context, frameworkNamespaceName); var properties = new List <Property>(); var stubSourceForUsings = new Source(Context, usings); var mainClassStaticFields = new Source(Context, usings); var mainClassStaticMethods = new Source(Context, usings); var mainClassNonstaticFields = new Source(Context, usings); var mainClassNonstaticMethods = new Source(Context, usings); var attachedClassStaticFields = new Source(Context, usings); var attachedClassMethods = new Source(Context, usings); // Add the property descriptors and accessors foreach (IPropertySymbol propertySymbol in Type.GetMembers().Where(member => member.Kind == SymbolKind.Property)) { var property = new Property(Context, this, propertySymbol); properties.Add(property); uiFramework.GeneratePropertyDescriptor(property, mainClassStaticFields); uiFramework.GeneratePropertyField(property, mainClassNonstaticFields); uiFramework.GeneratePropertyMethods(property, mainClassNonstaticMethods); } // If there are any attached properties, add the property descriptors and accessors for them if (AttachedType != null) { foreach (ISymbol member in AttachedType.GetMembers()) { if (!(member is IMethodSymbol getterMethod)) { continue; } // We just process the Get string methodName = getterMethod.Name; if (!methodName.StartsWith("Get")) { if (!methodName.StartsWith("Set")) { throw new UserViewableException( $"Attached type method {AttachedType.Name}.{methodName} doesn't start with Get or Set"); } else { continue; } } string propertyName = methodName.Substring("Get".Length); string setterMethodName = "Set" + propertyName; IMethodSymbol?setterMethod = (IMethodSymbol?)AttachedType.GetMembers(setterMethodName).FirstOrDefault(); var attachedProperty = new AttachedProperty(Context, this, AttachedType, getterMethod, setterMethod); uiFramework.GenerateAttachedPropertyDescriptor(attachedProperty, mainClassStaticFields); uiFramework.GenerateAttachedPropertyMethods(attachedProperty, mainClassStaticMethods); uiFramework.GenerateAttachedPropertyAttachedClassMethods(attachedProperty, attachedClassMethods); } } // Add any other methods needed for particular special types if (IsDrawableObject) { uiFramework.GenerateDrawableObjectMethods(this, mainClassNonstaticMethods); } if (IsThisType(KnownTypes.IPanel)) { uiFramework.GeneratePanelMethods(mainClassNonstaticMethods); } if (Purpose == InterfacePurpose.StandardPanel) { uiFramework.GenerateStandardPanelLayoutMethods(LayoutManagerType !.Name, mainClassNonstaticMethods); } usings.AddTypeNamespace(Type); usings.AddNamespace(frameworkNamespaceName); Source usingDeclarations = GenerateUsingDeclarations(uiFramework, usings); string?destinationBaseClass = GetOutputBaseClass(uiFramework); Source?constructor = GenerateConstructor(uiFramework, properties); string frameworkOutputDirectory = uiFramework.GetOutputDirectory(ChildNamespaceName); string mainClassDerviedFrom; if (destinationBaseClass == null) { mainClassDerviedFrom = Name; } else { mainClassDerviedFrom = $"{destinationBaseClass}, {Name}"; } Source mainClassSource = GenerateClassFile(usings, frameworkNamespaceName, FrameworkClassName, mainClassDerviedFrom, constructor: constructor, staticFields: mainClassStaticFields, staticMethods: mainClassStaticMethods, nonstaticFields: mainClassNonstaticFields, nonstaticMethods: mainClassNonstaticMethods); mainClassSource.WriteToFile(frameworkOutputDirectory, FrameworkClassName + ".cs"); if (AttachedType != null) { string attachedClassName = FrameworkClassName + "Attached"; string attachedClassDerivedFrom = AttachedType.Name; attachedClassStaticFields.AddLine($"public static {attachedClassName} Instance = new {attachedClassName}();"); Source attachedClassSource = GenerateClassFile(usings, frameworkNamespaceName, attachedClassName, attachedClassDerivedFrom, staticFields: attachedClassStaticFields, nonstaticMethods: attachedClassMethods); attachedClassSource.WriteToFile(frameworkOutputDirectory, attachedClassName + ".cs"); } }