Example #1
0
        /// <summary>
        /// Adds a property to the given type which raises PropertyChange Notifications when the property is set.
        /// </summary>
        /// <param name="type">The type to add property to.</param>
        /// <param name="propertyType">Type of the property.</param>
        /// <param name="propertyName">Name of the property.</param>
        /// <returns>Added property.</returns>
        protected CodeMemberProperty AddPropertyWithChangeNotification(CodeTypeDeclaration type, CodeTypeReference propertyType, string propertyName)
        {
            // Declare a private property to be the backing field
            string backingFieldName = string.Format(CultureInfo.InvariantCulture, "backing{0}", propertyName);

            type.AddField(propertyType, backingFieldName);
            CodeMemberProperty propertyWithChangeNotifications = new CodeMemberProperty()
            {
                Name       = propertyName,
                Type       = propertyType,
                Attributes = MemberAttributes.Public
            };
            CodeThisReferenceExpression thisReference = new CodeThisReferenceExpression();

            // this will hold the reference to the backing field
            CodeFieldReferenceExpression backingFieldReference = new CodeFieldReferenceExpression(thisReference, backingFieldName);

            // add a getter which returns the backing field
            propertyWithChangeNotifications.GetStatements.Add(new CodeMethodReturnStatement(backingFieldReference));

            // add a statement which sets the value of the backing field
            CodeAssignStatement setStatement = new CodeAssignStatement(backingFieldReference, new CodeArgumentReferenceExpression("value"));

            // This will call the RaisePropertyChanged method passing in the propertyName
            CodeMethodInvokeExpression invokePropertyChangeNotifier = new CodeMethodInvokeExpression(thisReference, "RaisePropertyChanged", new CodeExpression[] { new CodePrimitiveExpression(propertyName) });

            propertyWithChangeNotifications.SetStatements.Add(setStatement);
            propertyWithChangeNotifications.SetStatements.Add(invokePropertyChangeNotifier);
            type.Members.Add(propertyWithChangeNotifications);
            return(propertyWithChangeNotifications);
        }
        static void AddErrorHelpers(CodeTypeDeclaration type)
        {
            var minusOne = Expression.Primitive(-1);

            var errors = type.AddProperty <CompilerErrorCollection> ("Errors").AsProtected()
                         .WithGetLazyInitialize(
                type.AddField <CompilerErrorCollection> ("errors"),
                init: Expression.New <CompilerErrorCollection> ())
                         .OnThis();

            type.AddMethod("Error")
            .WithParameter <string> ("message", out var paramErrorMessage)
            .WithStatements(
                errors.InvokeMethod(
                    "Add",
                    Expression.New <CompilerError> (Expression.Null, minusOne, minusOne, Expression.Null, paramErrorMessage)
                    ));

            type.AddMethod("Warning")
            .WithParameter("message", TypeReference.String, out var paramWarningMessage)
            .WithStatements(
                Statement.DeclareVariable <CompilerError> ("val",
                                                           Expression.New <CompilerError> (Expression.Null, minusOne, minusOne, Expression.Null, paramWarningMessage),
                                                           out var val),
                val.SetProperty("IsWarning", Expression.True),
                errors.InvokeMethod("Add", val).AsStatement()
                );
        }
        static void AddIndentHelpers(CodeTypeDeclaration type)
        {
            var zero = Expression.Primitive(0);

            type.AddPropertyGetOnly("CurrentIndent",
                                    type.AddField("currentIndent", TypeReference.String, init: Expression.StringEmpty)
                                    .WithReference(out var currentIndent));

            type.AddProperty <Stack <int> > ("Indents").AsPrivate()
            .WithGetLazyInitialize(
                type.AddField <Stack <int> > ("indents"),
                Expression.New <Stack <int> > ())
            .WithReference(out var indents);

            type.AddMethod("PopIndent").Returns <string> ()
            .WithStatements(
                Statement.If(indents.Property("Count").IsEqualValue(zero),
                             Then: Expression.StringEmpty.Return()),
                Statement.DeclareVariable <int> ("lastPos",
                                                 currentIndent.Property("Length").Subtract(indents.InvokeMethod("Pop")),
                                                 out var lastPosRef),
                Statement.DeclareVariable(TypeReference.String, "last",
                                          currentIndent.InvokeMethod("Substring", lastPosRef),
                                          out var lastRef),
                currentIndent.Assign(currentIndent.InvokeMethod("Substring", zero, lastPosRef)),
                lastRef.Return()
                );

            type.AddMethod("PushIndent")
            .WithParameter("indent", TypeReference.String, out var paramIndent)
            .WithStatements(
                indents.InvokeMethod("Push", paramIndent.Property("Length")).AsStatement(),
                currentIndent.Assign(currentIndent.Add(paramIndent))
                );

            type.AddMethod("ClearIndent")
            .WithStatements(
                currentIndent.Assign(Expression.StringEmpty),
                indents.InvokeMethod("Clear").AsStatement()
                );
        }
Example #4
0
        private void Create_SOContainer(CodeNamespace pNameSpace, CodeNamespaceImport[] arrDefaultUsing, CodeTypeDeclaration pType, CodeTypeDeclaration[] arrEnumType, out CodeTypeDeclaration pContainerType, out CodeMemberMethod pInitMethod)
        {
            string strContainerTypeName = pType.Name + "_Container";

            pContainerType = new CodeTypeDeclaration(strContainerTypeName);
            pContainerType.AddBaseClass("UnityEngine.ScriptableObject");

            pNameSpace.Imports.Clear();
            pNameSpace.Imports.AddRange(arrDefaultUsing);
            pNameSpace.Imports.Add(new CodeNamespaceImport("System.Linq"));
            pNameSpace.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
            pNameSpace.Types.Clear();
            pNameSpace.Types.Add(pContainerType);
            pNameSpace.Types.AddRange(arrEnumType);

            pContainerType.AddField(new FieldTypeData(const_strFieldName_private_instance, strContainerTypeName), MemberAttributes.Private | MemberAttributes.Static);
            var pPublicInstanceProperty = pContainerType.AddProperty(new FieldTypeData(const_strFieldName_instance, strContainerTypeName), MemberAttributes.Public | MemberAttributes.Static);

            pPublicInstanceProperty.GetStatements.Add(new CodeSnippetStatement($"               return {const_strFieldName_private_instance};"));

            pContainerType.AddField(new FieldTypeData(const_strFieldName_ListData, $"List<{pType.Name}>"));
            pInitMethod = Generate_InitMethod(pContainerType, pType.Name);
        }
Example #5
0
        private void Create_SO(CodeFileBuilder pCodeFileBuilder, CodeNamespace pNameSpace, CodeTypeDeclaration pType, TypeData pSaveData)
        {
            pType.AddBaseClass("UnityEngine.ScriptableObject");
            pNameSpace.Types.Clear();
            pNameSpace.Types.Add(pType);

            var listVirtualFieldOption = pSaveData.listFieldData.Where(pExportOption => pExportOption.bDeleteThisField_InCode == false && pExportOption.bIsVirtualField);

            foreach (var pVirtualField in listVirtualFieldOption)
            {
                pType.AddField(pVirtualField);
            }

            pCodeFileBuilder.Generate_CSharpCode(pNameSpace, $"{GetRelative_To_AbsolutePath(strExportPath)}/{pType.Name}");
        }
        static void GenerateProcessingHelpers(CodeTypeDeclaration type)
        {
            var builderFieldDef = type.AddField <StringBuilder> ("builder").WithReference(out var builder);
            var sessionFieldDef = type.AddField <IDictionary <string, object> > ("session");

            type.AddPropertyGetSet("Session", sessionFieldDef).AsVirtual();

            type.AddProperty <StringBuilder> ("GenerationEnvironment")
            .WithSet(builder)
            .WithGetLazyInitialize(builder, builderFieldDef.Type.New());

            AddErrorHelpers(type);
            AddIndentHelpers(type);
            AddWriteHelpers(type);
        }
        private void Create_SOContainer(CodeNamespace pNameSpace, CodeNamespaceImport[] arrDefaultUsing, CodeTypeDeclaration pType, CodeTypeDeclaration[] arrEnumType, out CodeTypeDeclaration pContainerType, out CodeMemberMethod pInitMethod)
        {
            pContainerType = new CodeTypeDeclaration(pType.Name + "_Container");
            pContainerType.AddBaseClass("UnityEngine.ScriptableObject");

            pNameSpace.Imports.Clear();
            pNameSpace.Imports.AddRange(arrDefaultUsing);
            pNameSpace.Imports.Add(new CodeNamespaceImport("System.Linq"));
            pNameSpace.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
            pNameSpace.Types.Clear();
            pNameSpace.Types.Add(pContainerType);
            pNameSpace.Types.AddRange(arrEnumType);

            pContainerType.AddField(new FieldTypeData(const_strListData, $"List<{pType.Name}>"));
            pInitMethod = Generate_InitMethod(pContainerType, pType.Name);
        }
        static void AddToStringHelper(CodeTypeDeclaration type, CodeDomProvider provider)
        {
            var helperClass = Declare.Class("ToStringInstanceHelper")
                              .AsNestedPublic()
                              .WithReference(out var helperClassType);

            helperClass.AddField <IFormatProvider> ("formatProvider",
                                                    TypeReference <System.Globalization.CultureInfo> .Global.Property("InvariantCulture"))
            .WithReference(out var formatProvider);

            helperClass.AddProperty <IFormatProvider> ("FormatProvider")
            .WithGet(formatProvider)
            .WithSetIgnoresNull(formatProvider);

            helperClass.AddMethod("ToStringWithCulture")
            .Returns <string> ()
            .WithParameter <object> ("objectToConvert", out var objectToConvert)
            .WithStatements(
                objectToConvert.ThrowIfNull(),
                Declare.Variable <Type> ("type", objectToConvert.InvokeMethod("GetType"), out var objType),
                Declare.Variable <Type> ("iConvertibleType", Expression.TypeOf <IConvertible> (), out var iConvertibleType),
                Statement.If(iConvertibleType.InvokeMethod("IsAssignableFrom", objType),
                             Then: Statement.Return(objectToConvert.Cast <IConvertible> ().InvokeMethod("ToString", formatProvider))),
                Declare.Variable <System.Reflection.MethodInfo> ("methInfo",
                                                                 objType.InvokeMethod("GetMethod", Expression.Primitive("ToString"), Expression.Array <Type> (iConvertibleType)),
                                                                 out var methInfoLocalRef),
                Statement.If(methInfoLocalRef.IsNotNull(),
                             Then: Statement.Return(Expression.Cast <string> (
                                                        methInfoLocalRef.InvokeMethod("Invoke", objectToConvert, Expression.Array <object> (formatProvider))))),
                Statement.Return(objectToConvert.InvokeMethod("ToString"))
                );

            var helperFieldName = provider.CreateValidIdentifier("_toStringHelper");

            type.AddPropertyGetOnly("ToStringHelper",
                                    type.AddField(helperFieldName, helperClassType, Expression.New(helperClassType)));

            type.AddMember(helperClass);
        }
Example #9
0
 static void ProcessType(Type type, CodeTypeDeclaration ctd)
 {
     foreach (FieldInfo field in type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic))
     {
         ctd.AddField(ConvertType(field.FieldType), field.Name).Attributes = 0;
     }
     foreach (FieldInfo field in type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic))
     {
         EasyProperty p = ctd.AddProperty(ConvertType(field.FieldType), GetPropertyName(field.Name));
         p.Getter.Return(Easy.Var(field.Name));
         CodeExpression ex;
         if (field.FieldType.IsValueType)
         {
             ex = new CodePropertySetValueReferenceExpression();
         }
         else
         {
             ex = GetDefaultValue("value", field);
         }
         p.Setter.Assign(Easy.Var(field.Name), ex);
         if (typeof(INode).IsAssignableFrom(field.FieldType))
         {
             if (typeof(INullable).IsAssignableFrom(field.FieldType))
             {
                 p.SetStatements.Add(new CodeSnippetStatement("\t\t\t\tif (!" + field.Name + ".IsNull) " + field.Name + ".Parent = this;"));
             }
             else
             {
                 p.SetStatements.Add(new CodeSnippetStatement("\t\t\t\t" + field.Name + ".Parent = this;"));
             }
         }
     }
     foreach (ConstructorInfo ctor in type.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
     {
         CodeConstructor c = new CodeConstructor();
         if (type.IsAbstract)
         {
             c.Attributes = MemberAttributes.Family;
         }
         else
         {
             c.Attributes = MemberAttributes.Public;
         }
         ctd.Members.Add(c);
         ConstructorInfo baseCtor = GetBaseCtor(type);
         foreach (ParameterInfo param in ctor.GetParameters())
         {
             c.Parameters.Add(new CodeParameterDeclarationExpression(ConvertType(param.ParameterType),
                                                                     param.Name));
             if (baseCtor != null && Array.Exists(baseCtor.GetParameters(), delegate(ParameterInfo p) { return(param.Name == p.Name); }))
             {
                 continue;
             }
             c.Statements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression(GetPropertyName(param.Name)),
                                                      new CodeVariableReferenceExpression(param.Name)));
         }
         if (baseCtor != null)
         {
             foreach (ParameterInfo param in baseCtor.GetParameters())
             {
                 c.BaseConstructorArgs.Add(new CodeVariableReferenceExpression(param.Name));
             }
         }
         // initialize fields that were not initialized by parameter
         foreach (FieldInfo field in type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic))
         {
             if (field.FieldType.IsValueType && field.FieldType != typeof(Location))
             {
                 continue;
             }
             if (Array.Exists(ctor.GetParameters(), delegate(ParameterInfo p) { return(field.Name == p.Name); }))
             {
                 continue;
             }
             c.Statements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression(field.Name),
                                                      GetDefaultValue(null, field)));
         }
     }
 }
Example #10
0
        static CodeTypeDeclaration CreateAstVisitorClass(List <Type> nodeTypes, bool transformer)
        {
            CodeTypeDeclaration td = new CodeTypeDeclaration(transformer ? "AbstractAstTransformer" : "AbstractAstVisitor");

            td.TypeAttributes = TypeAttributes.Public | TypeAttributes.Abstract;
            td.BaseTypes.Add(new CodeTypeReference("IAstVisitor"));

            if (transformer)
            {
                string comment =
                    "The AbstractAstTransformer will iterate through the whole AST,\n " +
                    "just like the AbstractAstVisitor. However, the AbstractAstTransformer allows\n " +
                    "you to modify the AST at the same time: It does not use 'foreach' internally,\n " +
                    "so you can add members to collections of parents of the current node (but\n " +
                    "you cannot insert or delete items as that will make the index used invalid).\n " +
                    "You can use the methods ReplaceCurrentNode and RemoveCurrentNode to replace\n " +
                    "or remove the current node, totally independent from the type of the parent node.";
                Easy.AddSummary(td, comment);

                CodeMemberField field = td.AddField(Easy.TypeRef("Stack", "INode"), "nodeStack");
                field.InitExpression = Easy.New(field.Type);

                /*
                 * CodeExpression nodeStack = Easy.Var("nodeStack");
                 * CodeMemberProperty p = new CodeMemberProperty();
                 * p.Name = "CurrentNode";
                 * p.Type = new CodeTypeReference("INode");
                 * p.Attributes = MemberAttributes.Public | MemberAttributes.Final;
                 * p.GetStatements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("currentNode")));
                 * p.SetStatements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression("currentNode"),
                 *                                          new CodePropertySetValueReferenceExpression()));
                 * td.Members.Add(p);
                 */

                EasyMethod m = td.AddMethod("ReplaceCurrentNode");
                m.AddParameter(Easy.TypeRef("INode"), "newNode");
                m.Statements.Add(Easy.Var("nodeStack").InvokeMethod("Pop"));
                m.Statements.Add(Easy.Var("nodeStack").InvokeMethod("Push", Easy.Var("newNode")));

                m = td.AddMethod("RemoveCurrentNode");
                m.Statements.Add(Easy.Var("nodeStack").InvokeMethod("Pop"));
                m.Statements.Add(Easy.Var("nodeStack").InvokeMethod("Push", Easy.Null));
            }

            foreach (Type type in nodeTypes)
            {
                if (!type.IsAbstract)
                {
                    EasyMethod m = td.AddMethod(typeof(object), VisitPrefix + type.Name);
                    m.Attributes = MemberAttributes.Public;
                    m.AddParameter(ConvertType(type), GetFieldName(type.Name));
                    m.AddParameter(typeof(object), "data");

                    List <CodeStatement> assertions = new List <CodeStatement>();
                    string         varVariableName  = GetFieldName(type.Name);
                    CodeExpression var = Easy.Var(varVariableName);
                    assertions.Add(AssertIsNotNull(var));

                    AddFieldVisitCode(m, type, var, assertions, transformer);

                    if (type.GetCustomAttributes(typeof(HasChildrenAttribute), true).Length > 0)
                    {
                        if (transformer)
                        {
                            m.Statements.Add(new CodeSnippetStatement(CreateTransformerLoop(varVariableName + ".Children", "INode")));
                            m.Body.Return(Easy.Null);
                        }
                        else
                        {
                            m.Body.Return(var.InvokeMethod("AcceptChildren", Easy.This, Easy.Var("data")));
                        }
                    }
                    else
                    {
                        CodeExpressionStatement lastStatement = null;
                        if (m.Statements.Count > 0)
                        {
                            lastStatement = m.Statements[m.Statements.Count - 1] as CodeExpressionStatement;
                        }
                        if (lastStatement != null)
                        {
                            m.Statements.RemoveAt(m.Statements.Count - 1);
                            m.Body.Return(lastStatement.Expression);
                        }
                        else
                        {
                            m.Body.Return(Easy.Null);
                        }
                    }

                    for (int i = 0; i < assertions.Count; i++)
                    {
                        m.Statements.Insert(i, assertions[i]);
                    }
                }
            }
            return(td);
        }
 public static CodeMemberField AddField(this CodeTypeDeclaration typeDecl, Type type, string name)
 {
     return(typeDecl.AddField(Easy.TypeRef(type), name));
 }
Example #12
0
        public virtual CodeTypeDeclaration CreateClass(SettingsDocument setDoc)
        {
            CodeTypeDeclaration c = new CodeTypeDeclaration(setDoc.GeneratedClassName);

            c.AddAttribute(typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute));
            c.AddAttribute(typeof(System.CodeDom.Compiler.GeneratedCodeAttribute),
                           Easy.Prim(typeof(SettingsCodeGeneratorTool).FullName),
                           Easy.Prim(typeof(SettingsCodeGeneratorTool).Assembly.GetName().Version.ToString()));
            c.TypeAttributes = TypeAttributes.NotPublic | TypeAttributes.Sealed;
            c.IsPartial      = true;
            c.BaseTypes.Add(Easy.TypeRef(typeof(ApplicationSettingsBase)));

            CodeMemberField f = c.AddField(Easy.TypeRef(c), "defaultInstance");

            f.Attributes     = MemberAttributes.Private | MemberAttributes.Static;
            f.InitExpression = Easy.Type(typeof(ApplicationSettingsBase))
                               .InvokeMethod("Synchronized", Easy.New(Easy.TypeRef(c)))
                               .CastTo(Easy.TypeRef(c));

            var defaultProperty = c.AddProperty(f, "Default");

            if (setDoc.UseMySettingsClassName)
            {
                c.AddAttribute(typeof(EditorBrowsableAttribute), Easy.Prim(EditorBrowsableState.Advanced));
                AddAutoSaveLogic(c, defaultProperty);
            }

            foreach (SettingsEntry entry in setDoc.Entries)
            {
                Type           entryType      = entry.Type ?? typeof(string);
                SpecialSetting?specialSetting = null;
                foreach (SpecialTypeDescriptor desc in SpecialTypeDescriptor.Descriptors)
                {
                    if (desc.type == entryType)
                    {
                        entryType      = typeof(string);
                        specialSetting = desc.specialSetting;
                        break;
                    }
                }
                EasyProperty p = c.AddProperty(entryType, entry.Name);
                if (entry.Scope == SettingScope.User)
                {
                    p.AddAttribute(typeof(UserScopedSettingAttribute));
                }
                else
                {
                    p.AddAttribute(typeof(ApplicationScopedSettingAttribute));
                }
                if (!string.IsNullOrEmpty(entry.Provider))
                {
                    p.AddAttribute(typeof(SettingsProviderAttribute),
                                   Easy.TypeOf(new CodeTypeReference(entry.Provider)));
                }
                if (!string.IsNullOrEmpty(entry.Description))
                {
                    p.AddAttribute(typeof(SettingsDescriptionAttribute), Easy.Prim(entry.Description));
                    Easy.AddSummary(p, entry.Description);
                }
                p.AddAttribute(typeof(DebuggerNonUserCodeAttribute));
                if (specialSetting != null)
                {
                    p.AddAttribute(typeof(SpecialSettingAttribute),
                                   Easy.Prim(specialSetting.Value));
                }
                if (entry.GenerateDefaultValueInCode)
                {
                    p.AddAttribute(typeof(DefaultSettingValueAttribute), Easy.Prim(entry.SerializedValue));
                }
                if (entry.Scope == SettingScope.User && entry.Roaming)
                {
                    p.AddAttribute(typeof(SettingsManageabilityAttribute),
                                   Easy.Prim(SettingsManageability.Roaming));
                }
                p.Getter.Return(Easy.This.Index(Easy.Prim(entry.Name)).CastTo(entryType));
//				p.GetStatements.Add(new CodeMethodReturnStatement(
//					new CodeCastExpression(new CodeTypeReference(entryType),
//					                       new CodeIndexerExpression(new CodeThisReferenceExpression(),
//					                                                 new CodePrimitiveExpression(entry.Name))
//					                      )
//				));
                if (entry.Scope == SettingScope.User)
                {
                    p.Setter.Assign(Easy.This.Index(Easy.Prim(entry.Name)), Easy.Value);
                }
            }

            return(c);
        }
        static void GenerateHostProperty(CodeTypeDeclaration type, Type hostType)
        {
            hostType ??= typeof(ITextTemplatingEngineHost);

            type.AddPropertyGetSet("Host", type.AddField("hostValue", TypeReference.Global(hostType)));
        }