VisitFieldInitializer() public method

public VisitFieldInitializer ( System.Compiler.Expression expr ) : System.Compiler.Expression
expr System.Compiler.Expression
return System.Compiler.Expression
示例#1
0
        private void GenerateClass(Class c)
        {
            // The following code added by Jiri Adamek
            // Do not generate any code for native ZOM classes (they were manually written
            // and their code is placed in another assmbly)
            if (c is NativeZOM) return;
            // END of added code

            TypeNode newClass = Templates.GetTypeTemplateByName("Class");
            if (c.Interfaces != null)
            {
                for (int i = 0, n = c.Interfaces.Count; i < n; i++)
                {
                    string iname = c.Interfaces[i].Name.Name;
                    QualifiedIdentifier id = new QualifiedIdentifier(new Identifier(iname), new Identifier("CreateMethods"));
                    newClass.Interfaces.Add(new InterfaceExpression(id));
                }
            }

            Method writer = (Method)Templates.GetMemberByName(newClass.Members, "WriteString");
            Method traverser = (Method)Templates.GetMemberByName(newClass.Members, "TraverseFields");

            // Replace all references to the class name
            Replacer.Replace(newClass, newClass.Name, c.Name);
            SetTypeId(newClass);

            Block cloneFields = new Block();
            cloneFields.Statements = new StatementList();

            Method getValue = (Method)Templates.GetMemberByName(newClass.Members, "GetValue");
            Method setValue = (Method)Templates.GetMemberByName(newClass.Members, "SetValue");
            System.Compiler.Switch switchGetValue =
                (System.Compiler.Switch)Templates.GetStatementTemplate("GetFieldInfoSwitch");
            getValue.Body.Statements.Add(switchGetValue);
            System.Compiler.Switch switchSetValue =
                (System.Compiler.Switch)Templates.GetStatementTemplate("SetFieldInfoSwitch");
            setValue.Body.Statements.Add(switchSetValue);

            // Transfer non-static fields to the emitted class
            for (int i = 0, n = c.Members.Count; i < n; i++)
            {
                Field f = c.Members[i] as Field;

                if (f != null && f.Type != null && !f.IsStatic)
                {
                    // Clone the field since we might tinker with it
                    Field newField = (Field)f.Clone();
                    // change name of the field, so that the accessor can be named appropriately
                    newField.Name = new Identifier("priv_" + f.Name.Name);

                    if (GetTypeClassification(f.Type) == TypeClassification.Heap)
                        newField.Type = this.ZingPtrType;
                    else if (!IsPredefinedType(f.Type))
                        newField.Type = new TypeExpression(new QualifiedIdentifier(
                            new Identifier("Application"), f.Type.Name), f.Type.SourceContext);

                    if (newField.Initializer != null)
                    {
                        // Move the initialization to our constructor.
                        Expression initializer = newField.Initializer;
                        newField.Initializer = null;

                        Statement initStmt = Templates.GetStatementTemplate("InitComplexInstanceField");
                        Replacer.Replace(initStmt, "_FieldName", newField.Name);
                        Normalizer normalizer = new Normalizer(false);
                        Replacer.Replace(initStmt, "_expr", normalizer.VisitFieldInitializer(initializer));
                        Method ctor = (Method)newClass.Members[0];
                        Debug.Assert(ctor.Parameters.Count == 1);
                        ctor.Body.Statements.Add(initStmt);
                    }

                    Identifier idFieldName = new Identifier("id_" + f.Name.Name);
                    Field idf = new Field(newClass, null, FieldFlags.Public | FieldFlags.Static,
                        idFieldName,
                        SystemTypes.Int32, null);
                    idf.Initializer = new Literal(i, SystemTypes.Int32);
                    SwitchCase getCase = ((System.Compiler.Switch)Templates.GetStatementTemplate("GetFieldInfoCase")).Cases[0];
                    Replacer.Replace(getCase, "_fieldId", new Literal(i, SystemTypes.Int32));
                    Replacer.Replace(getCase, "_fieldName", new Identifier(newField.Name.Name));
                    switchGetValue.Cases.Add(getCase);

                    SwitchCase setCase = ((System.Compiler.Switch)Templates.GetStatementTemplate("SetFieldInfoCase")).Cases[0];
                    Replacer.Replace(setCase, "_fieldId", new Literal(i, SystemTypes.Int32));
                    Replacer.Replace(setCase, "_fieldName", new Identifier(newField.Name.Name));
                    TypeExpression tn = newField.Type as TypeExpression;
                    Replacer.Replace(setCase, "_fieldType", tn != null ? tn.Expression : new Identifier(newField.Type.Name.Name));
                    switchSetValue.Cases.Add(setCase);

                    newClass.Members.Add(newField);
                    newField.DeclaringType = newClass;
                    newClass.Members.Add(idf);
                    idf.DeclaringType = newClass;

                    // add property for the field
                    Property accessor = GetFieldAccessorProperty(f.Type, newField.Type, f.Name, newField.Name, idFieldName);
                    newClass.Members.Add(accessor);
                    accessor.DeclaringType = newClass;
                    if (accessor.Getter != null)
                    {
                        newClass.Members.Add(accessor.Getter);
                        accessor.Getter.DeclaringType = newClass;
                    }
                    if (accessor.Setter != null)
                    {
                        newClass.Members.Add(accessor.Setter);
                        accessor.Setter.DeclaringType = newClass;
                    }

                    writer.Body.Statements.Add(GetWriterStatement("this", f.Type, newField.Name));

                    traverser.Body.Statements.Add(GetTraverserStatement("this", f.Type, newField.Name));
                    /*if(GetTypeClassification(f.Type) == TypeClassification.Heap)
                    {
                        refTraverser.Body.Statements.Add(GetTraverserStatement("this", f.Type, newField.Name));
                    }
                    */

                    Statement cloneStmt = GetCloneStatement(newField.Name);
                    cloneFields.Statements.Add(cloneStmt);
                }

                ZMethod zMethod = c.Members[i] as ZMethod;
                if (zMethod != null)
                {
                    InterfaceList xs = FindMatchingInterfaces(c, zMethod);
                    Interface x = null;
                    if (xs.Count != 0)
                    {
                        // TODO: Handle the case when one method implements methods declared in multiple interfaces
                        Debug.Assert(xs.Count == 1);
                        x = xs[0];
                    }
                    Class methodClass = GenerateClassMethod(zMethod, x);
                    newClass.Members.Add(methodClass);
                    methodClass.DeclaringType = newClass;
                    methodClass.Flags = (methodClass.Flags & ~TypeFlags.VisibilityMask) | TypeFlags.NestedFamORAssem;

                    if (x != null)
                    {
                        TypeNode tn = Templates.GetTypeTemplateByName("ClassExtras");
                        Method member = (Method)Templates.GetMemberByName(tn.Members, "__CreateInterfaceMethod");
                        member.Name = new Identifier("Create" + methodClass.Name.Name);
                        member.DeclaringType = newClass;
                        Replacer.Replace(member,
                            new Identifier("__InterfaceMethod"),
                            new QualifiedIdentifier(x.Name, methodClass.Name));
                        Replacer.Replace(member,
                            new Identifier("__ClassMethod"),
                            new QualifiedIdentifier(c.Name, methodClass.Name));
                        newClass.Members.Add(member);
                    }
                }
            }

            // Splice the cloning assignment statements into the class's Clone method
            // at the appropriate place.
            Method cloner = (Method)Templates.GetMemberByName(newClass.Members, "Clone");
            Replacer.Replace(cloner.Body, "cloneFields", cloneFields);

            // Add the emitted class to our Zing application class
            InstallType(newClass);
        }
示例#2
0
        private void ProcessGlobals(MemberList globals)
        {
            // Locate the "Globals" struct so we can add fields to it.
            Class globalsClass = (Class)Templates.GetMemberByName(appClass.Members,
                                                                   "GlobalVars");

            // Locate the "initialization" constructor so we can add initialization
            // statements to it.
            Debug.Assert(appClass.Members[1].Name.Name == ".ctor");
            Method initCtor = (Method)appClass.Members[1];

            // Locate the WriteString method so we can add statements to write out the globals
            Method writer =
                (Method)Templates.GetMemberByName(globalsClass.Members, "WriteString");
            Method copier =
                (Method)Templates.GetMemberByName(globalsClass.Members, "CopyContents");
            Method traverser = (Method)Templates.GetMemberByName(globalsClass.Members, "TraverseFields");

            Normalizer normalizer = new Normalizer(false);

            Method getValue = (Method)Templates.GetMemberByName(globalsClass.Members, "GetValue");
            Method setValue = (Method)Templates.GetMemberByName(globalsClass.Members, "SetValue");
            System.Compiler.Switch switchGetValue =
                (System.Compiler.Switch)Templates.GetStatementTemplate("GetFieldInfoSwitch");
            getValue.Body.Statements.Add(switchGetValue);
            System.Compiler.Switch switchSetValue =
                (System.Compiler.Switch)Templates.GetStatementTemplate("SetFieldInfoSwitch");
            setValue.Body.Statements.Add(switchSetValue);

            for (int i = 0, n = globals.Count; i < n; i++)
            {
                // Make a shallow copy of the field since we're going to tinker with it
                Field f = (Field)((Field)globals[i]).Clone();
                string name = f.DeclaringType.Name.Name + "_" + f.Name.Name;

                TypeNode zingType = f.Type;

                if (GetTypeClassification(f.Type) == TypeClassification.Heap)
                    f.Type = this.ZingPtrType;
                else if (!IsPredefinedType(f.Type))
                    f.Type = new TypeExpression(new QualifiedIdentifier(
                        new Identifier("Application"), zingType.Name), f.Type.SourceContext);

                // Mangle the name to guarantee uniqueness across the globals
                f.Name = new Identifier("priv_" + name);
                f.Flags &= ~FieldFlags.Static;
                // Sriram: I have made this into a public field so that
                // the fieldInfo below works. If the field is internal
                // then fieldInfo gets set to null (there is some access
                // permission problem)
                // Need to check with Tony as to
                // whether this is tbe best solution

                // The following two lines are Tony's code
                //-----------------------------------------------------------
                // f.Flags &= (FieldFlags)(~TypeFlags.VisibilityMask);
                //f.Flags |= FieldFlags.Assembly;
                //-----------------------------------------------------------

                //This is my replacement
                f.Flags |= FieldFlags.Public;

                /*
                Identifier idFieldName = new Identifier("id_" + name);
                System.Compiler.Expression idTypeExpr =
                    new QualifiedIdentifier(
                        new QualifiedIdentifier(new Identifier("System"), new Identifier("Reflection")),
                        new Identifier("FieldInfo"));
                System.Compiler.TypeNode idfType =  new System.Compiler.TypeExpression(idTypeExpr);
                Field idf = new Field(globalsClass, null, FieldFlags.Public|FieldFlags.Static,
                                       idFieldName,
                                       idfType, null);
                idf.Initializer = Templates.GetExpressionTemplate("GetFieldInfo");
                Replacer.Replace(idf.Initializer, "_class", globalsClass.Name);
                Replacer.Replace(idf.Initializer, "_fieldName", new Literal(f.Name.Name, SystemTypes.String));
                */

                Identifier idFieldName = new Identifier("id_" + name);
                Field idf = new Field(globalsClass, null, FieldFlags.Public | FieldFlags.Static,
                    idFieldName,
                    SystemTypes.Int32, null);
                idf.Initializer = new Literal(i, SystemTypes.Int32);
                SwitchCase getCase = ((System.Compiler.Switch)Templates.GetStatementTemplate("GetFieldInfoCase")).Cases[0];
                Replacer.Replace(getCase, "_fieldId", new Literal(i, SystemTypes.Int32));
                Replacer.Replace(getCase, "_fieldName", new Identifier(f.Name.Name));
                switchGetValue.Cases.Add(getCase);

                SwitchCase setCase = ((System.Compiler.Switch)Templates.GetStatementTemplate("SetFieldInfoCase")).Cases[0];
                Replacer.Replace(setCase, "_fieldId", new Literal(i, SystemTypes.Int32));
                Replacer.Replace(setCase, "_fieldName", new Identifier(f.Name.Name));
                TypeExpression tn = f.Type as TypeExpression;
                Replacer.Replace(setCase, "_fieldType", tn != null ? tn.Expression : new Identifier(f.Type.Name.Name));
                switchSetValue.Cases.Add(setCase);

                //The last argument to the call below is a dont care
                Property accessor = GetAccessorProperty("globalAccessor", f.Type,
                                                        new Identifier(name), f.Name, idFieldName, f.Name);

                globalsClass.Members.Add(f);
                globalsClass.Members.Add(idf);
                globalsClass.Members.Add(accessor);
                f.DeclaringType = globalsClass;
                idf.DeclaringType = globalsClass;
                accessor.DeclaringType = globalsClass;
                if (accessor.Getter != null)
                {
                    globalsClass.Members.Add(accessor.Getter);
                    accessor.Getter.DeclaringType = globalsClass;
                }
                if (accessor.Setter != null)
                {
                    globalsClass.Members.Add(accessor.Setter);
                    accessor.Setter.DeclaringType = globalsClass;
                }

                if (zingType is Struct && !zingType.IsPrimitive && f.Type != SystemTypes.Decimal)
                    collectStructAccessors(true, (Struct)zingType, f.Name,
                                           name, globalsClass);

                if (f.Initializer != null)
                {
                    Statement stmt = Templates.GetStatementTemplate("InitializeGlobal");
                    Replacer.Replace(stmt, "_FieldName", f.Name);
                    Replacer.Replace(stmt, "_FieldInitializer", normalizer.VisitFieldInitializer(f.Initializer));
                    initCtor.Body.Statements.Add(stmt);
                    f.Initializer = null;
                }

                writer.Body.Statements.Add(GetWriterStatement(null, zingType, f.Name));
                copier.Body.Statements.Add(GetCopyStatement(f.Name));
                traverser.Body.Statements.Add(GetTraverserStatement(null, zingType, f.Name));
                /*if(GetTypeClassification(f.Type) == TypeClassification.Heap)
                {
                    refTraverser.Body.Statements.Add(GetTraverserStatement(null, zingType, f.Name));
                }
                */
            }
        }