Exemple #1
0
        public EasyTypeDeclaration AddType(string name)
        {
            EasyTypeDeclaration n = new EasyTypeDeclaration(name);

            this.Types.Add(n);
            return(n);
        }
Exemple #2
0
 public EasyTypeDeclaration AddType(string name)
 {
     EasyTypeDeclaration n = new EasyTypeDeclaration(name);
     this.Types.Add(n);
     return n;
 }
Exemple #3
0
 static void ProcessType(Type type, EasyTypeDeclaration 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) && typeof(INullable).IsAssignableFrom(field.FieldType)) {
             p.SetStatements.Add(new CodeSnippetStatement("\t\t\t\tif (!" +field.Name+".IsNull) "+field.Name+".Parent = this;"));
         }
     }
     foreach (ConstructorInfo ctor in type.GetConstructors()) {
         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)));
         }
     }
 }
Exemple #4
0
        static CodeTypeDeclaration CreateNodeTrackingAstVisitorClass(List<Type> nodeTypes)
        {
            EasyTypeDeclaration td = new EasyTypeDeclaration("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.Statements.Add(new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), "BeginVisit"), new CodeExpression[] { var }));
            //					m.Statements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference(typeof(object)), "result", new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), "TrackedVisit"), new CodeExpression[] { var, new CodeVariableReferenceExpression("data") })));
            //					m.Statements.Add(new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), "EndVisit"), new CodeExpression[] { var }));
            //					m.Statements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("result")));
                    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;
        }
Exemple #5
0
        static CodeTypeDeclaration CreateAstVisitorInterface(List<Type> nodeTypes)
        {
            EasyTypeDeclaration td = new EasyTypeDeclaration("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;
        }
Exemple #6
0
        static CodeTypeDeclaration CreateAstVisitorClass(List<Type> nodeTypes, bool transformer)
        {
            EasyTypeDeclaration td = new EasyTypeDeclaration(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);

                EasyField 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);
                    EasyExpression 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;
        }
Exemple #7
0
        public override void ModifyImplementation(CodeNamespace cns, CodeTypeDeclaration ctd, Type type)
        {
            if (implementation == NullableImplementation.Default || implementation == NullableImplementation.Abstract) {
                ctd.BaseTypes.Add(new CodeTypeReference("INullable"));
                CodeMemberProperty prop = new CodeMemberProperty();
                prop.Name = "IsNull";
                prop.Type = new CodeTypeReference(typeof(bool));
                prop.Attributes = MemberAttributes.Public;
                prop.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(false)));
                ctd.Members.Add(prop);
            }
            if (implementation != NullableImplementation.Abstract) {
                EasyTypeDeclaration newType = new EasyTypeDeclaration("Null" + ctd.Name);
                newType.TypeAttributes = TypeAttributes.Class | TypeAttributes.NotPublic | TypeAttributes.Sealed;
                newType.BaseTypes.Add(new CodeTypeReference(ctd.Name));
                cns.Types.Add(newType);

                System.Reflection.ConstructorInfo baseCtor = MainClass.GetBaseCtor(type);
                if (baseCtor != null) {
                    CodeConstructor ctor = new CodeConstructor();
                    ctor.Attributes = MemberAttributes.Private;
                    foreach (object o in baseCtor.GetParameters()) {
                        ctor.BaseConstructorArgs.Add(new CodePrimitiveExpression(null));
                    }
                    newType.Members.Add(ctor);
                }

                CodeMemberField field = new CodeMemberField(newType.Name, "Instance");
                field.Attributes = MemberAttributes.Static | MemberAttributes.Assembly;
                field.InitExpression = new CodeObjectCreateExpression(new CodeTypeReference(newType.Name));
                newType.Members.Add(field);

                CodeMemberProperty prop = new CodeMemberProperty();
                prop.Name = "IsNull";
                prop.Type = new CodeTypeReference(typeof(bool));
                prop.Attributes = MemberAttributes.Public | MemberAttributes.Override;
                prop.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(true)));
                newType.Members.Add(prop);

                CodeMemberMethod method = new CodeMemberMethod();
                method.Name = "AcceptVisitor";
                method.Attributes = MemberAttributes.Public | MemberAttributes.Override;
                method.Parameters.Add(new CodeParameterDeclarationExpression("IAstVisitor", "visitor"));
                method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "data"));
                method.ReturnType = new CodeTypeReference(typeof(object));
                method.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(null)));
                newType.Members.Add(method);

                method = new CodeMemberMethod();
                method.Name = "ToString";
                method.Attributes = MemberAttributes.Public | MemberAttributes.Override;
                method.ReturnType = new CodeTypeReference(typeof(string));
                method.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression("[" + newType.Name + "]")));
                newType.Members.Add(method);

                prop = new CodeMemberProperty();
                prop.Name = "Null";
                prop.Type = new CodeTypeReference(ctd.Name);
                prop.Attributes = MemberAttributes.Public | MemberAttributes.Static;
                if (implementation == NullableImplementation.Shadow) {
                    prop.Attributes |= MemberAttributes.New;
                }
                CodeExpression ex = new CodeTypeReferenceExpression(newType.Name);
                ex = new CodePropertyReferenceExpression(ex, "Instance");
                prop.GetStatements.Add(new CodeMethodReturnStatement(ex));
                ctd.Members.Add(prop);
            }
        }