static void AddWriteHelpers(CodeTypeDeclaration type)
        {
            var generationEnvironment = Expression.This.Property("GenerationEnvironment");
            var currentIndent         = Expression.This.Field("currentIndent");

            var textToAppendParamDef = Declare.Parameter <string> ("textToAppend").WithReference(out var textToAppend);
            var formatParamDef       = Declare.Parameter <string> ("format").WithReference(out var format);
            var argsParamDef         = Declare.Parameter <object[]> ("args").Params().WithReference(out var args);

            type.AddMethod("Write").WithParameter(textToAppendParamDef)
            .WithStatements(
                generationEnvironment.InvokeMethod("Append", textToAppend));

            type.AddMethod("Write").WithParameters(formatParamDef, argsParamDef)
            .WithStatements(
                generationEnvironment.InvokeMethod("AppendFormat", format, args));

            type.AddMethod("WriteLine").WithParameter(textToAppendParamDef)
            .WithStatements(
                generationEnvironment.InvokeMethod("Append", currentIndent).AsStatement(),
                generationEnvironment.InvokeMethod("AppendLine", textToAppend).AsStatement()
                );

            type.AddMethod("WriteLine").WithParameters(formatParamDef, argsParamDef)
            .WithStatements(
                generationEnvironment.InvokeMethod("Append", currentIndent).AsStatement(),
                generationEnvironment.InvokeMethod("AppendFormat", format, args).AsStatement(),
                generationEnvironment.InvokeMethod("AppendLine").AsStatement()
                );
        }
        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()
                );
        }
Пример #3
0
        private CodeMemberMethod Generate_InitMethod(CodeTypeDeclaration pContainerType, string strTypeName)
        {
            var pMethod = pContainerType.AddMethod($"DoInit", MemberAttributes.Public | MemberAttributes.Static);

            pMethod.Parameters.Add(new CodeParameterDeclarationExpression(pContainerType.Name, "pSingletonInstance"));
            pMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(bool), "bIsUpdateChildAsset"));

            pMethod.Statements.Add(new CodeSnippetStatement($"          {const_strFieldName_private_instance} = pSingletonInstance;"));

            pMethod.Statements.Add(new CodeSnippetStatement("#if UNITY_EDITOR"));
            pMethod.Statements.Add(new CodeSnippetStatement("           if(bIsUpdateChildAsset)"));
            pMethod.Statements.Add(new CodeSnippetStatement("           {"));
            pMethod.Statements.Add(new CodeSnippetStatement($"              {const_strFieldName_private_instance}.listData.Clear();"));
            pMethod.Statements.Add(new CodeSnippetStatement($"               Object[] arrObject = UnityEditor.AssetDatabase.LoadAllAssetRepresentationsAtPath(UnityEditor.AssetDatabase.GetAssetPath({const_strFieldName_private_instance}));"));
            pMethod.Statements.Add(new CodeSnippetStatement("               for (int i = 0; i < arrObject.Length; i++)"));
            pMethod.Statements.Add(new CodeSnippetStatement($"                  {const_strFieldName_private_instance}.listData.Add(({strTypeName})arrObject[i]);"));

            pMethod.Statements.Add(new CodeSnippetStatement("               if(Application.isPlaying == false)"));
            pMethod.Statements.Add(new CodeSnippetStatement("               {"));
            pMethod.Statements.Add(new CodeSnippetStatement($"                   UnityEditor.EditorUtility.SetDirty({const_strFieldName_private_instance});"));
            pMethod.Statements.Add(new CodeSnippetStatement("                   UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene());"));
            pMethod.Statements.Add(new CodeSnippetStatement("               }"));

            pMethod.Statements.Add(new CodeSnippetStatement("           }"));
            pMethod.Statements.Add(new CodeSnippetStatement("#endif"));

            return(pMethod);
        }
Пример #4
0
        private static CodeMemberMethod AddMethod(CodeTypeDeclaration marshal_type, string method_name, CodeTypeReference generic_type, CodeTypeReference return_type,
                                                  string name, CodeTypeReference[] pre_args, AdditionalArguments additional_args)
        {
            var method = marshal_type.AddMethod(method_name, MemberAttributes.Public | MemberAttributes.Final);

            method.ReturnType = return_type;
            int arg_count = 0;

            List <CodeExpression> arg_names = new List <CodeExpression>(pre_args.Select(a => AddParam(a, arg_count++, method)));

            arg_names.AddRange(additional_args.FixedArgs);
            arg_names.AddRange(additional_args.Params.Select(a => AddParam(a, arg_count++, method)));

            CodeMethodReferenceExpression generic_method = generic_type != null ? new CodeMethodReferenceExpression(null, name, generic_type) : new CodeMethodReferenceExpression(null, name);
            var invoke_method = new CodeMethodInvokeExpression(generic_method, arg_names.ToArray());

            if (return_type != null)
            {
                method.AddReturn(invoke_method);
            }
            else
            {
                method.Statements.Add(invoke_method);
            }

            return(method);
        }
Пример #5
0
        static CodeTypeDeclaration CreateNotImplementedAstVisitorClass(List <Type> nodeTypes)
        {
            CodeTypeDeclaration td = new CodeTypeDeclaration("NotImplementedAstVisitor");

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

            string comment = "<summary>\n " +
                             "IAstVisitor implementation that always throws NotImplementedExceptions.\n " +
                             "</summary>";

            td.Comments.Add(new CodeCommentStatement(comment, true));

            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(new CodeTypeReference(typeof(object)), "data");

                    m.Body.Throw(Easy.New(typeof(NotImplementedException), Easy.Prim(type.Name)));
                }
            }

            return(td);
        }
Пример #6
0
        public static CodeMemberMethod AddUnmarshalMethod(this CodeTypeDeclaration type, string unmarshal_name)
        {
            CodeMemberMethod method = type.AddMethod("Unmarshal", MemberAttributes.Final | MemberAttributes.Private);

            method.PrivateImplementationType = new CodeTypeReference(typeof(INdrStructure));
            method.AddParam(typeof(NdrUnmarshalBuffer), unmarshal_name);
            return(method);
        }
Пример #7
0
        public static void AddArrayConstructorMethod(this CodeTypeDeclaration type, string name, RpcTypeDescriptor complex_type)
        {
            CodeMemberMethod method = type.AddMethod(name, MemberAttributes.Public | MemberAttributes.Final);

            method.AddParam(new CodeTypeReference(typeof(int)), "size");
            method.ReturnType = complex_type.GetArrayType();
            method.AddReturn(new CodeArrayCreateExpression(complex_type.CodeType, GetVariable("size")));
        }
Пример #8
0
        public static CodeMemberMethod AddInequalityOperator(this CodeTypeDeclaration declaration)
        {
            var result = declaration.AddMethod("operator !=", typeof(bool));

            result.AddParameter("value1", declaration.Name);
            result.AddParameter("value2", declaration.Name);
            result.Attributes = MemberAttributes.Public | MemberAttributes.Static;
            return(result);
        }
Пример #9
0
        private void Generate_CacheMethod_Global(CodeTypeDeclaration pContainerType, CodeMemberMethod pInitMethod, string strListDataName, string strMapFieldName, string strTypeFieldName, string strTypeName, string strValueFieldName)
        {
            string strMethodName = $"Init_{strMapFieldName}";
            var    pMethod       = pContainerType.AddMethod(strMethodName);

            pMethod.Attributes = MemberAttributes.Private | MemberAttributes.Final;

            CodeFieldReferenceExpression pCasheMemberReference =
                new CodeFieldReferenceExpression(
                    new CodeThisReferenceExpression(), strMapFieldName);

            CodeTypeReferenceExpression pField_List = new CodeTypeReferenceExpression($"{strListDataName}");

            // 1. Where로 묶는다.
            CodeMethodInvokeExpression pMethod_CachingLocal = new CodeMethodInvokeExpression(
                pField_List, "Where", new CodeSnippetExpression($"x => x.{strTypeFieldName} == \"{strTypeName}\""));

            CodeVariableDeclarationStatement pGroupbyVariableDeclaration = new CodeVariableDeclarationStatement(
                "var", "arrLocal", pMethod_CachingLocal);

            pMethod.Statements.Add(pGroupbyVariableDeclaration);

            // 3. Gropby로 묶은걸 Dictionary로 변환하며 할당한다.
            // 여기서 기본 형식은 다 형변환해야함
            string strParseString = $"p.{strValueFieldName}";

            if (strTypeName == "float")
            {
                strParseString = $"float.Parse({strParseString})";
            }
            else if (strTypeName == "int")
            {
                strParseString = $"int.Parse({strParseString})";
            }
            else if (strTypeFieldName == "string")
            {
            }
            else
            {
                strParseString = $"({strTypeName})System.Enum.Parse(typeof({strTypeName}), {strParseString})";

                // SpreadSheetParser_MainForm.WriteConsole($"Error Parsing Not Define {strTypeName}");
            }


            CodeMethodInvokeExpression pMethod_Caching = new CodeMethodInvokeExpression(
                new CodeVariableReferenceExpression("arrLocal"), "ToDictionary", new CodeSnippetExpression($"p => p.{const_GlobalKey_FieldName}_{strTypeName}, p => {strParseString}"));

            CodeAssignStatement pCachAssign = new CodeAssignStatement(pCasheMemberReference, pMethod_Caching);

            pMethod.Statements.Add(pCachAssign);

            pInitMethod.Statements.Add(new CodeMethodInvokeExpression(
                                           new CodeMethodReferenceExpression(
                                               new CodeSnippetExpression(const_strFieldName_private_instance),
                                               strMethodName)));
        }
Пример #10
0
        public static CodeMemberMethod AddImplicitOperator(this CodeTypeDeclaration declaration, string toType)
        {
            var result = declaration.AddMethod("implicit operator " + toType, toType);

            result.AddParameter("value", declaration.Name);
            result.Attributes = MemberAttributes.Public | MemberAttributes.Static;

            result.ReturnType = new CodeTypeReference();
            return(result);
        }
        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()
                );
        }
Пример #12
0
        /// <summary>
        /// Adds an implementation of the INotifyPropertyChanged interface to the given type.
        /// </summary>
        /// <param name="type">The type declaration</param>
        /// <returns>Type with INotifyPropertyChanged implemented.</returns>
        protected CodeTypeDeclaration ImplementINotifyPropertyChanged(CodeTypeDeclaration type)
        {
            //// This method will implement the INotifyPropertyChanged interface
            //// Here's an example :
            //// public class Customer :INotifyPropertyChanged {
            ////      public PropertyChangedEventHandler PropertyChanged;
            ////      public void RaisePropertyChanged(string propertyName) {
            ////          if( this.PropertyChanged !=null ) {
            ////              this.PropertyChanged (this, new PropertyChangedEventArgs( propertyName ) );
            ////          }
            ////      }
            //// }
            CodeThisReferenceExpression thisReference         = new CodeThisReferenceExpression();
            CodeTypeReference           notifyPropertyChanged = Code.TypeRef(typeof(INotifyPropertyChanged));

            // Add the implements INotifyPropertyChanged statement
            // public class Customer :INotifyPropertyChanged {
            type.BaseTypes.Add(notifyPropertyChanged);

            // Add the PropertyChanged event as a field to the type
            // public PropertyChangedEventHandler PropertyChanged;
            CodeMemberEvent propertyChangedEvent = type.AddEvent(Code.TypeRef(typeof(PropertyChangedEventHandler)), "PropertyChanged");

            propertyChangedEvent.ImplementationTypes.Add(notifyPropertyChanged);

            // this.PropertyChanged
            CodeEventReferenceExpression eventFieldReference = new CodeEventReferenceExpression(thisReference, "PropertyChanged");

            // Add the RaisePropertyChanged Method which will invoke the PropertyChanged handler whenever a property value changes
            // if( this.PropertyChanged !=null )
            CodeConditionStatement invokeEventHandlersIfAny = new CodeConditionStatement(new CodeBinaryOperatorExpression(eventFieldReference, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)));

            // this.PropertyChanged (this, new PropertyChangedEventArgs( propertyName ) );
            invokeEventHandlersIfAny.TrueStatements.Add(
                new CodeDelegateInvokeExpression(eventFieldReference, new CodeExpression[] { thisReference, new CodeObjectCreateExpression("PropertyChangedEventArgs", new CodeArgumentReferenceExpression("propertyName")) }));

            // public void RaisePropertyChanged
            CodeMemberMethod method = type.AddMethod("RaisePropertyChanged", MemberAttributes.Public);

            method.Parameters.Add(new CodeParameterDeclarationExpression("System.String", "propertyName"));

            ////      public void RaisePropertyChanged(string propertyName) {
            ////          if( this.PropertyChanged !=null ) {
            ////              this.PropertyChanged (this, new PropertyChangedEventArgs( propertyName ) );
            ////          }
            ////      }
            method.Statements.Add(invokeEventHandlersIfAny);
            return(type);
        }
Пример #13
0
        public static void AddDefaultConstructorMethod(this CodeTypeDeclaration type, string name, MemberAttributes attributes, RpcTypeDescriptor complex_type, Dictionary <string, CodeExpression> initialize_expr)
        {
            CodeMemberMethod method = type.AddMethod(name, attributes);

            method.ReturnType = complex_type.CodeType;
            CodeExpression return_value = new CodeObjectCreateExpression(complex_type.CodeType);

            if (initialize_expr.Count > 0)
            {
                method.Statements.Add(new CodeVariableDeclarationStatement(complex_type.CodeType, "ret", return_value));
                return_value = GetVariable("ret");
                method.Statements.AddRange(initialize_expr.Select(p => new CodeAssignStatement(return_value.GetFieldReference(p.Key), p.Value)).ToArray());
            }
            method.AddReturn(return_value);
        }
Пример #14
0
        public static void AddConstructorMethod(this CodeTypeDeclaration type, string name, RpcTypeDescriptor complex_type, IEnumerable <Tuple <CodeTypeReference, string> > parameters)
        {
            if (!parameters.Any())
            {
                return;
            }

            CodeMemberMethod method = type.AddMethod(name, MemberAttributes.Public | MemberAttributes.Final);

            method.ReturnType = complex_type.CodeType;
            method.Statements.Add(new CodeVariableDeclarationStatement(complex_type.CodeType, "ret", new CodeObjectCreateExpression(complex_type.CodeType)));
            CodeExpression return_value = GetVariable("ret");

            method.AddAssignmentStatements(return_value, parameters);
            method.AddReturn(return_value);
        }
Пример #15
0
        static CodeTypeDeclaration CreateAstVisitorInterface(List <Type> nodeTypes)
        {
            CodeTypeDeclaration td = new CodeTypeDeclaration("IAstVisitor");

            td.IsInterface = true;

            foreach (Type t in nodeTypes)
            {
                if (!t.IsAbstract)
                {
                    EasyMethod m = td.AddMethod(typeof(object), VisitPrefix + t.Name);
                    m.AddParameter(ConvertType(t), GetFieldName(t.Name));
                    m.AddParameter(typeof(object), "data");
                }
            }
            return(td);
        }
Пример #16
0
        private void Generate_ExtensionMethod_ByEnumKey(CodeTypeDeclaration pEnumHelperClass, CodeTypeDeclaration pContainerType, string strMapFieldName, string strKeyTypeName, string strDataTypeName, bool bIsOverlapKey)
        {
            string strMethodName = $"Get{strDataTypeName}";

            if (bIsOverlapKey)
            {
                strMethodName += "_List";
            }

            var pMethod = pEnumHelperClass.AddMethod(strMethodName);

            pMethod.Attributes = MemberAttributes.Public | MemberAttributes.Static;

            if (bIsOverlapKey)
            {
                pMethod.ReturnType = new CodeTypeReference($"List<{strDataTypeName}>");
            }
            else
            {
                switch (strDataTypeName)
                {
                case "int": strDataTypeName = "System.Int32"; break;

                case "float": strDataTypeName = "System.Single"; break;
                }

                pMethod.ReturnType = new CodeTypeReference(strDataTypeName);
            }

            pMethod.Parameters.Add(new CodeParameterDeclarationExpression($"this {strKeyTypeName}", "eKey"));
            pMethod.Parameters.Add(new CodeParameterDeclarationExpression("System.Action<string>", "OnError = null"));

            pMethod.Statements.Add(new CodeSnippetStatement($"          {pMethod.ReturnType.BaseType} pData;"));
            pMethod.Statements.Add(new CodeSnippetStatement($"          if({pContainerType.Name}.{const_strFieldName_instance}.{strMapFieldName}.TryGetValue(eKey, out pData) == false)"));
            pMethod.Statements.Add(new CodeSnippetStatement("          {"));
            pMethod.Statements.Add(new CodeSnippetStatement($"              if(OnError != null)"));
            pMethod.Statements.Add(new CodeSnippetStatement($"                  OnError(nameof({pContainerType.Name}) + \"- Not Found Data // Key : \" + eKey);"));
            pMethod.Statements.Add(new CodeSnippetStatement("          }"));

            if (bIsOverlapKey)
            {
            }

            pMethod.Statements.Add(new CodeSnippetStatement("          return pData;"));
        }
Пример #17
0
        private void Generate_CacheMethod(CodeTypeDeclaration pContainerType, CodeMemberMethod pInitMethod, string strListDataName, string strMapFieldName, string strCacheFieldName, bool bIsOverlapKey)
        {
            string strMethodName = $"Init_{strMapFieldName}";
            var    pMethod       = pContainerType.AddMethod(strMethodName);

            pMethod.Attributes = MemberAttributes.Private | MemberAttributes.Final;

            CodeFieldReferenceExpression pCasheMemberReference =
                new CodeFieldReferenceExpression(
                    new CodeThisReferenceExpression(), strMapFieldName);

            CodeTypeReferenceExpression pField_List = new CodeTypeReferenceExpression($"{strListDataName}");

            if (bIsOverlapKey)
            {
                CodeMethodInvokeExpression pMethod_CachingLocal = new CodeMethodInvokeExpression(
                    pField_List, "GroupBy", new CodeSnippetExpression($"x => x.{strCacheFieldName}"));

                CodeVariableDeclarationStatement pGroupbyVariableDeclaration = new CodeVariableDeclarationStatement(
                    "var", "arrLocal", pMethod_CachingLocal);

                pMethod.Statements.Add(pGroupbyVariableDeclaration);

                CodeMethodInvokeExpression pMethod_Caching = new CodeMethodInvokeExpression(
                    new CodeVariableReferenceExpression("arrLocal"), "ToDictionary", new CodeSnippetExpression($"g => g.Key, g => g.ToList()"));

                CodeAssignStatement pCacheAssign = new CodeAssignStatement(pCasheMemberReference, pMethod_Caching);
                pMethod.Statements.Add(pCacheAssign);
            }
            else
            {
                CodeMethodInvokeExpression pMethod_Caching = new CodeMethodInvokeExpression(
                    pField_List, "ToDictionary", new CodeSnippetExpression($"x => x.{strCacheFieldName}"));

                CodeAssignStatement pCacheAssign = new CodeAssignStatement(pCasheMemberReference, pMethod_Caching);
                pMethod.Statements.Add(pCacheAssign);
            }

            pInitMethod.Statements.Add(new CodeMethodInvokeExpression(
                                           new CodeMethodReferenceExpression(
                                               new CodeSnippetExpression(const_strFieldName_private_instance),
                                               strMethodName)));
        }
Пример #18
0
        static CodeTypeDeclaration CreateNodeTrackingAstVisitorClass(List <Type> nodeTypes)
        {
            CodeTypeDeclaration td = new CodeTypeDeclaration("NodeTrackingAstVisitor");

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

            string comment = "<summary>\n " +
                             "The NodeTrackingAstVisitor will iterate through the whole AST,\n " +
                             "just like the AbstractAstVisitor, and calls the virtual methods\n " +
                             "BeginVisit and EndVisit for each node being visited.\n " +
                             "</summary>";

            td.Comments.Add(new CodeCommentStatement(comment, true));
            comment = "<remarks>\n " +
                      "base.Visit(node, data) calls this.TrackedVisit(node, data), so if\n " +
                      "you want to visit child nodes using the default visiting behaviour,\n " +
                      "use base.TrackedVisit(parentNode, data).\n " +
                      "</remarks>";
            td.Comments.Add(new CodeCommentStatement(comment, true));

            EasyMethod m = td.AddMethod("BeginVisit");

            m.Attributes = MemberAttributes.Family;
            m.AddParameter(Easy.TypeRef("INode"), "node");

            m            = td.AddMethod("EndVisit");
            m.Attributes = MemberAttributes.Family;
            m.AddParameter(Easy.TypeRef("INode"), "node");

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

                    CodeExpression var = Easy.Var(GetFieldName(type.Name));

                    m.Body.InvokeMethod(Easy.This, "BeginVisit", var);
                    m.Body.DeclareVariable(typeof(object), "result").InitExpression
                        = Easy.This.InvokeMethod("TrackedVisit" + type.Name, var, Easy.Var("data"));
                    m.Body.InvokeMethod(Easy.This, "EndVisit", var);
                    m.Body.Return(Easy.Var("result"));
                }
            }

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

                    m.Body.Return(Easy.Base.InvokeMethod(VisitPrefix + type.Name, Easy.Var(GetFieldName(type.Name)), Easy.Var("data")));
                }
            }

            return(td);
        }
Пример #19
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);
        }
Пример #20
0
        static CodeTypeDeclaration CreateAstComparisonVisitorClass(List <Type> nodeTypes)
        {
            CodeTypeDeclaration td = new CodeTypeDeclaration("AstComparisonVisitor");

            td.TypeAttributes = TypeAttributes.Public;
            td.IsPartial      = true;

            //td.BaseTypes.Add(new CodeTypeReference("IAstVisitor"));

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

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

                    if (varVariableName == "using")
                    {
                        varVariableName = "@using";
                    }

                    CodeExpression r_var = Easy.Var(right_hand_side_name);
                    assertions.Add(IfNullSetFailure(r_var));

                    // Confirm their types are the same.
                    m.Statements.Add(new CodeSnippetStatement("\t\t\tif(" + varVariableName + ".GetType() != " + right_hand_side_name + ".GetType()) {return SetFailure();}"));

                    // Cast the object parameter to whatever the other parameter is, and call the variable 'data'.
                    // Like so: AddHandlerStatement data = (AddHandlerStatement) d;
                    m.Statements.Add(new CodeSnippetStatement("\t\t\tvar data = (" + ConvertType(type).BaseType + ")d;"));

                    m.Statements.Add(new CodeConditionStatement(new CodeSnippetExpression("!IsMatch(" + varVariableName + ", data)"),
                                                                new CodeSnippetStatement("\t\t\t\treturn SetFailure();")));

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

                    if (type.GetCustomAttributes(typeof(HasChildrenAttribute), true).Length > 0)
                    {
                        m.Body.Return(var.InvokeMethod("AcceptChildren", Easy.This, Easy.Var(right_hand_side_name)));
                    }
                    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(new CodeSnippetExpression("true"));
                        }
                    }

                    for (int i = 0; i < assertions.Count; i++)
                    {
                        m.Statements.Insert(i, assertions[i]);
                    }
                }
            }
            return(td);
        }
Пример #21
0
        private void GenerateClient(string name, CodeNamespace ns, int complex_type_count)
        {
            CodeTypeDeclaration type = ns.AddType(name);

            type.IsClass        = true;
            type.TypeAttributes = TypeAttributes.Public | TypeAttributes.Sealed;
            type.BaseTypes.Add(typeof(RpcAlpcClientBase));

            CodeConstructor constructor = type.AddConstructor(MemberAttributes.Public | MemberAttributes.Final);

            constructor.BaseConstructorArgs.Add(CodeGenUtils.GetPrimitive(_server.InterfaceId.ToString()));
            constructor.BaseConstructorArgs.Add(CodeGenUtils.GetPrimitive(_server.InterfaceVersion.Major));
            constructor.BaseConstructorArgs.Add(CodeGenUtils.GetPrimitive(_server.InterfaceVersion.Minor));

            foreach (var proc in _server.Procedures)
            {
                string proc_name = proc.Name;
                if (!_proc_names.Add(proc_name))
                {
                    proc_name = $"{proc_name}_{proc.ProcNum}";
                    if (!_proc_names.Add(proc_name))
                    {
                        throw new ArgumentException($"Duplicate name {proc.Name}");
                    }
                }

                var method = type.AddMethod(proc_name, MemberAttributes.Public | MemberAttributes.Final);
                RpcTypeDescriptor return_type = GetTypeDescriptor(proc.ReturnValue.Type);
                if (return_type == null)
                {
                    method.ThrowNotImplemented("Return type unsupported.");
                    continue;
                }

                var offset_to_name =
                    proc.Params.Select(p => Tuple.Create(p.Offset, p.Name)).ToList();

                method.ReturnType = return_type.CodeType;
                method.CreateMarshalObject(MARSHAL_NAME);
                foreach (var p in proc.Params)
                {
                    if (p == proc.Handle)
                    {
                        continue;
                    }
                    RpcTypeDescriptor p_type = GetTypeDescriptor(p.Type);

                    List <RpcMarshalArgument> extra_marshal_args = new List <RpcMarshalArgument>();
                    if (p_type.VarianceDescriptor.IsValid)
                    {
                        extra_marshal_args.Add(p_type.VarianceDescriptor.CalculateCorrelationArgument(p.Offset, offset_to_name));
                    }

                    var p_obj = method.AddParam(p_type.GetParameterType(), p.Name);
                    p_obj.Direction = p.GetDirection();
                    if (!p.IsIn)
                    {
                        continue;
                    }
                    if (p_type.Pointer)
                    {
                        if (p_type.PointerType == RpcPointerType.Reference)
                        {
                            method.AddNullCheck(MARSHAL_NAME, p.Name);
                        }
                        else
                        {
                            method.AddWriteReferent(MARSHAL_NAME, p.Name);
                        }
                    }
                    else if (!p_type.ValueType)
                    {
                        method.AddNullCheck(MARSHAL_NAME, p.Name);
                    }
                    method.AddMarshalCall(p_type, MARSHAL_NAME, p.Name, extra_marshal_args.ToArray());
                    // If it's a constructed type then ensure any deferred writes are flushed.
                    if (p_type.Constructed)
                    {
                        method.AddFlushDeferredWrites(MARSHAL_NAME);
                    }
                }

                method.SendReceive(MARSHAL_NAME, UNMARSHAL_NAME, proc.ProcNum);

                foreach (var p in proc.Params.Where(x => x.IsOut))
                {
                    if (p == proc.Handle)
                    {
                        continue;
                    }

                    RpcTypeDescriptor p_type = GetTypeDescriptor(p.Type);
                    if (p_type.Pointer)
                    {
                        method.AddPointerUnmarshalCall(p_type, UNMARSHAL_NAME, p.Name);
                    }
                    else
                    {
                        method.AddUnmarshalCall(p_type, UNMARSHAL_NAME, p.Name);
                    }
                    if (p_type.Constructed)
                    {
                        method.AddPopluateDeferredPointers(UNMARSHAL_NAME);
                    }
                }

                method.AddUnmarshalReturn(return_type, UNMARSHAL_NAME);
            }

            if (complex_type_count > 0 && HasFlag(RpcClientBuilderFlags.GenerateConstructorProperties))
            {
                var constructor_type = new CodeTypeReference(CodeGenUtils.MakeIdentifier(CONSTRUCTOR_STRUCT_NAME));
                var prop             = type.AddProperty("New", constructor_type, MemberAttributes.Public | MemberAttributes.Final,
                                                        new CodeMethodReturnStatement(new CodeObjectCreateExpression(constructor_type)));
                constructor_type = new CodeTypeReference(CodeGenUtils.MakeIdentifier(ARRAY_CONSTRUCTOR_STRUCT_NAME));
                type.AddProperty("NewArray", constructor_type, MemberAttributes.Public | MemberAttributes.Final,
                                 new CodeMethodReturnStatement(new CodeObjectCreateExpression(constructor_type)));
            }
        }