Example #1
0
        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");
            }
        }
Example #2
0
        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");
            }
        }