public void Run() { HashSet<short> interfaceClasses = GetClassList(); // Make the interfaces known first, otherwise Translator won't work correctly. foreach (short idx in interfaceClasses) { Smoke.Class* klass = data.Smoke->classes + idx; string className = ByteArrayManager.GetString(klass->className); int colon = className.LastIndexOf("::", StringComparison.Ordinal); string prefix = (colon != -1) ? className.Substring(0, colon) : string.Empty; string name = (colon != -1) ? className.Substring(colon + 2) : className; CodeTypeDeclaration ifaceDecl = new CodeTypeDeclaration('I' + name); ifaceDecl.IsInterface = true; CodeAttributeDeclaration attr = new CodeAttributeDeclaration("SmokeClass", new CodeAttributeArgument( new CodePrimitiveExpression(className))); ifaceDecl.CustomAttributes.Add(attr); data.GetTypeCollection(prefix).Add(ifaceDecl); data.InterfaceTypeMap[className] = ifaceDecl; } // Now generate the methods. foreach (short idx in interfaceClasses) { Smoke.Class* klass = data.Smoke->classes + idx; string className = ByteArrayManager.GetString(klass->className); CodeTypeDeclaration ifaceDecl = data.InterfaceTypeMap[className]; short* parent = data.Smoke->inheritanceList + klass->parents; while (*parent > 0) { ifaceDecl.BaseTypes.Add(translator.CppToCSharp(data.Smoke->classes + *parent, ifaceDecl)); parent++; } MethodsGenerator mg = new MethodsGenerator(data, translator, ifaceDecl, klass); AttributeGenerator ag = new AttributeGenerator(data, translator, ifaceDecl); List<IntPtr> methods = new List<IntPtr>(); ///TODO: replace this algorithm, it's highly inefficient for (short i = 0; i <= data.Smoke->numMethods && data.Smoke->methods[i].classId <= idx; i++) { Smoke.Method* meth = data.Smoke->methods + i; if (meth->classId != idx) continue; string methName = ByteArrayManager.GetString(data.Smoke->methodNames[meth->name]); // we don't want anything except protected, const or empty flags if ((meth->flags & (ushort) Smoke.MethodFlags.mf_enum) > 0 || (meth->flags & (ushort) Smoke.MethodFlags.mf_ctor) > 0 || (meth->flags & (ushort) Smoke.MethodFlags.mf_copyctor) > 0 || (meth->flags & (ushort) Smoke.MethodFlags.mf_dtor) > 0 || (meth->flags & (ushort) Smoke.MethodFlags.mf_static) > 0 || (meth->flags & (ushort) Smoke.MethodFlags.mf_internal) > 0 || (meth->flags & (ushort) Smoke.MethodFlags.mf_protected) > 0 || methName.StartsWith("operator")) { continue; } if ((meth->flags & (ushort) Smoke.MethodFlags.mf_attribute) > 0) { ag.ScheduleAttributeAccessor(meth); continue; } methods.Add((IntPtr) meth); } methods.Sort(CompareSmokeMethods); foreach (Smoke.Method* method in methods) { CodeMemberMethod cmm = mg.GenerateBasicMethodDefinition(data.Smoke, method); if (cmm != null && !ifaceDecl.HasMethod(cmm)) { ifaceDecl.Members.Add(cmm); } } mg.GenerateProperties(); foreach (CodeMemberProperty prop in ag.GenerateBasicAttributeDefinitions()) { ifaceDecl.Members.Add(prop); } } }
public void Run() { HashSet <short> interfaceClasses = GetClassList(); // Make the interfaces known first, otherwise Translator won't work correctly. foreach (short idx in interfaceClasses) { Smoke.Class *klass = data.Smoke->classes + idx; string className = ByteArrayManager.GetString(klass->className); int colon = className.LastIndexOf("::", StringComparison.Ordinal); string prefix = (colon != -1) ? className.Substring(0, colon) : string.Empty; string name = (colon != -1) ? className.Substring(colon + 2) : className; CodeTypeDeclaration ifaceDecl = new CodeTypeDeclaration('I' + name); ifaceDecl.IsInterface = true; CodeAttributeDeclaration attr = new CodeAttributeDeclaration("SmokeClass", new CodeAttributeArgument( new CodePrimitiveExpression(className))); ifaceDecl.CustomAttributes.Add(attr); data.GetTypeCollection(prefix).Add(ifaceDecl); data.InterfaceTypeMap[className] = ifaceDecl; } // Now generate the methods. foreach (short idx in interfaceClasses) { Smoke.Class * klass = data.Smoke->classes + idx; string className = ByteArrayManager.GetString(klass->className); CodeTypeDeclaration ifaceDecl = data.InterfaceTypeMap[className]; short *parent = data.Smoke->inheritanceList + klass->parents; while (*parent > 0) { ifaceDecl.BaseTypes.Add(translator.CppToCSharp(data.Smoke->classes + *parent)); parent++; } MethodsGenerator mg = new MethodsGenerator(data, translator, ifaceDecl, klass); AttributeGenerator ag = new AttributeGenerator(data, translator, ifaceDecl); List <IntPtr> methods = new List <IntPtr>(); ///TODO: replace this algorithm, it's highly inefficient for (short i = 0; i <= data.Smoke->numMethods && data.Smoke->methods[i].classId <= idx; i++) { Smoke.Method *meth = data.Smoke->methods + i; if (meth->classId != idx) { continue; } string methName = ByteArrayManager.GetString(data.Smoke->methodNames[meth->name]); // we don't want anything except protected, const or empty flags if ((meth->flags & (ushort)Smoke.MethodFlags.mf_enum) > 0 || (meth->flags & (ushort)Smoke.MethodFlags.mf_ctor) > 0 || (meth->flags & (ushort)Smoke.MethodFlags.mf_copyctor) > 0 || (meth->flags & (ushort)Smoke.MethodFlags.mf_dtor) > 0 || (meth->flags & (ushort)Smoke.MethodFlags.mf_static) > 0 || (meth->flags & (ushort)Smoke.MethodFlags.mf_internal) > 0 || (meth->flags & (ushort)Smoke.MethodFlags.mf_protected) > 0 || methName.StartsWith("operator")) { continue; } if ((meth->flags & (ushort)Smoke.MethodFlags.mf_attribute) > 0) { ag.ScheduleAttributeAccessor(meth); continue; } methods.Add((IntPtr)meth); } methods.Sort(CompareSmokeMethods); foreach (Smoke.Method *method in methods) { CodeMemberMethod cmm = mg.GenerateBasicMethodDefinition(data.Smoke, method); if (cmm != null && !ifaceDecl.HasMethod(cmm)) { ifaceDecl.Members.Add(cmm); } } mg.GenerateProperties(); foreach (CodeMemberProperty prop in ag.GenerateBasicAttributeDefinitions()) { ifaceDecl.Members.Add(prop); } } }