public VisitFieldInitializer ( System.Compiler.Expression expr ) : System.Compiler.Expression | ||
expr | System.Compiler.Expression | |
return | System.Compiler.Expression |
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); }
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)); } */ } }