public void Create_IfPropertyHasIndexParameters_Throws() { // Arrange PropertyInfo property = typeof(Poco).GetProperty("Item"); // Act & Assert ExceptionAssert.ThrowsArgument(() => ClassPropertyGetter <Poco, PocoProperty> .Create(property), "property", "The property must not have index parameters."); }
public void Create_IfPropertyTypeMismatchesEvenIfChildType_Throws() { // Arrange PropertyInfo property = typeof(Poco).GetProperty("Value"); // Act & Assert ExceptionAssert.ThrowsArgument(() => ClassPropertyGetter <Poco, PocoPropertyChild> .Create(property), "property", "The property's PropertyType must exactly match TProperty."); }
public void Create_IfPropertyIsWriteOnly_Throws() { // Arrange PropertyInfo property = typeof(Poco).GetProperty("WriteOnlyValue"); // Act & Assert ExceptionAssert.ThrowsArgument(() => ClassPropertyGetter <Poco, PocoProperty> .Create(property), "property", "The property must be readable."); }
public void Create_IfReflectedTypeMismatchesEvenIfDeclaringType_Throws() { // Arrange PropertyInfo property = typeof(PocoChild).GetProperty("Value"); // Act & Assert ExceptionAssert.ThrowsArgument(() => ClassPropertyGetter <Poco, PocoProperty> .Create(property), "property", "The property's ReflectedType must exactly match TReflected."); }
public void Create_IfPropertyIsNull_Throws() { // Arrange PropertyInfo property = null; // Act & Assert ExceptionAssert.ThrowsArgumentNull(() => ClassPropertyGetter <Poco, PocoProperty> .Create(property), "property"); }
private static ClassPropertyGetter <TReflected, TProperty> CreateProductUnderTest <TReflected, TProperty>( PropertyInfo property) where TReflected : class { ClassPropertyGetter <TReflected, TProperty> product = ClassPropertyGetter <TReflected, TProperty> .Create(property); Assert.NotNull(product); // Guard return(product); }
public void Create_IfPropertyIsStatic_Throws() { // Arrange PropertyInfo property = typeof(Poco).GetProperty("StaticValue"); // Act & Assert ExceptionAssert.ThrowsArgument(() => ClassPropertyGetter <Poco, PocoProperty> .Create(property), "property", "The property must not be static."); }
public void Create_ReturnsInstance() { // Arrange PropertyInfo property = typeof(Poco).GetProperty("Value"); // Act IPropertyGetter <Poco, PocoProperty> getter = ClassPropertyGetter <Poco, PocoProperty> .Create(property); // Assert Assert.NotNull(getter); }
public void buildInterfaceMemberType(ASBinCode.rtti.Class cls, Builder builder, ASTool.AS3.AS3SrcFile as3srcfile) { builder._buildingClass.Push(cls); for (int i = 0; i < cls.classMembers.Count; i++) { ASBinCode.rtti.ClassMember member = cls.classMembers[i]; if (member.bindField is ClassPropertyGetter) { ClassPropertyGetter pg = (ClassPropertyGetter)member.bindField; continue; } _doBuildMemberType(member, builder, cls); } if (builder.buildErrors.Count == 0) { copyInheritsFromImplements(cls, builder); for (int i = 0; i < cls.classMembers.Count; i++) //检查访问器类型 { //if (cls.classMembers[i].inheritFrom != null) //{ // cls.classMembers[i].setTypeWhenCompile(cls.super.classMembers[i].valueType); // continue; //} //CheckProp(cls.classMembers[i], builder); } } builder._buildingClass.Pop(); }
private void copyInheritsFromImplements(ASBinCode.rtti.Class cls, Builder builder) { foreach (var supercls in cls.implements.Keys) { for (int i = 0; i < supercls.classMembers.Count; i++) { var sm = supercls.classMembers[i]; var bf = sm.bindField; if (bf is InterfaceMethodGetter) { var sig = builder.dictSignatures[((InterfaceMethodGetter)bf).refdefinedinblockid][bf]; InterfaceMethodGetter ifm = new InterfaceMethodGetter(bf.name, cls, ((InterfaceMethodGetter)bf).refdefinedinblockid); ifm.setLinkMethod((InterfaceMethodGetter)bf); bf = ifm; if (!builder.dictSignatures.ContainsKey(ifm.refdefinedinblockid)) { builder.dictSignatures.Add(ifm.refdefinedinblockid, new Dictionary <IMember, ASBinCode.rtti.FunctionSignature>()); } builder.dictSignatures[ifm.refdefinedinblockid].Add(ifm, sig); } else if (bf is ClassPropertyGetter) { ClassPropertyGetter cg = new ClassPropertyGetter(bf.name, cls, cls.classMembers.Count); cg.valueType = ((ClassPropertyGetter)bf).valueType; cg.getter = ((ClassPropertyGetter)bf).getter; cg.setter = ((ClassPropertyGetter)bf).setter; bf = cg; } ASBinCode.rtti.ClassMember member = new ASBinCode.rtti.ClassMember(sm.name, cls, bf); member.defaultValue = sm.defaultValue; member.isConst = false; member.isConstructor = false; member.isGetter = sm.isGetter; member.isInternal = false; member.isOverride = false; member.isFinal = false; member.isPrivate = false; member.isProtectd = false; member.isPublic = true; member.isSetter = sm.isSetter; member.isStatic = false; member.setTypeWhenCompile(sm.valueType); member.virtualLink = sm; //member.virtualLinkFromClass = supercls; if (sm.inheritFrom == null) { member.inheritFrom = supercls; } else { member.inheritFrom = sm.inheritFrom; } if (sm.inheritSrcMember == null) { member.inheritSrcMember = sm; } else { member.inheritSrcMember = sm.inheritSrcMember; } bool iskip = false; for (int m = 0; m < cls.classMembers.Count; m++) { var om = cls.classMembers[m]; ASTool.AS3.IAS3Stmt stmt = null; if (om.name == member.name) { if (om.bindField is ClassPropertyGetter || member.bindField is ClassPropertyGetter) { if (om.bindField is ClassPropertyGetter && member.bindField is ClassPropertyGetter) { iskip = true; break; } else { foreach (var item in builder.buildingclasses) { if (item.Value == cls) { stmt = item.Key; } } throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "重复的接口成员,一个是访问器一个不是 " + cls.name + ":" + member.name) ); } } ASBinCode.rtti.FunctionSignature sig = null; //**检查签名*** if (om.inheritFrom == null) { sig = builder.dictSignatures[cls.blockid][om.bindField]; stmt = builder._buildingmembers[om]; } else { sig = builder.dictSignatures[om.inheritFrom.blockid][om.inheritSrcMember.bindField]; stmt = builder._buildingmembers[om.inheritSrcMember]; } ASBinCode.rtti.FunctionSignature sig2 = null; if (member.inheritFrom == null) { sig2 = builder.dictSignatures[cls.blockid][member.bindField]; } else { sig2 = builder.dictSignatures[member.inheritFrom.blockid][member.inheritSrcMember.bindField]; } //***检查2个接口签名完全匹配*** if (om.isGetter != member.isGetter || om.isSetter != member.isSetter) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "重复的接口成员,访问器类型不匹配" + member.refClass.name + "::" + member.name) ); } else if (sig.returnType != sig2.returnType) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "重复的接口成员,签名不匹配" + member.refClass.name + "::" + member.name) ); } else if (sig.parameters.Count != sig2.parameters.Count) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "重复的接口成员,签名不匹配" + member.refClass.name + "::" + member.name) ); } else { //***比较所有参数*** for (int j = 0; j < sig.parameters.Count; j++) { if (sig.parameters[j].type != sig2.parameters[j].type || sig.parameters[j].isPara != sig2.parameters[j].isPara ) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "重复的接口成员,签名不匹配" + member.refClass.name + "::" + member.name) ); } } } //***检查通过,跳过这次添加*** iskip = true; } } if (!iskip) { cls.classMembers.Add(member); } } } //***拷贝完成,重新确认propertygetersetter,并设定索引*** for (int i = 0; i < cls.classMembers.Count; i++) { var m = cls.classMembers[i]; if (m.bindField is ClassPropertyGetter) { ClassPropertyGetter pg = (ClassPropertyGetter)m.bindField; //if (pg._class == cls) { pg.getter = null; pg.setter = null; for (int j = 0; j < cls.classMembers.Count; j++) { if (cls.classMembers[j].name == "@" + pg.name + "_get") { pg.getter = (InterfaceMethodGetter)cls.classMembers[j].bindField; } else if (cls.classMembers[j].name == "@" + pg.name + "_set") { pg.setter = (InterfaceMethodGetter)cls.classMembers[j].bindField; } } } } else { InterfaceMethodGetter ig = (InterfaceMethodGetter)m.bindField; ig.setIndexMember(i, cls); } } }
private void buildInterfaceMember(CompileEnv env, ASTool.AS3.IAS3Stmt stmt, ASBinCode.rtti.Class cls, Builder builder ) { if (stmt is ASTool.AS3.AS3Block) { ASTool.AS3.AS3Block as3block = (ASTool.AS3.AS3Block)stmt; for (int i = 0; i < as3block.CodeList.Count; i++) { buildInterfaceMember(env, as3block.CodeList[i], cls, builder); } } else if (stmt is ASTool.AS3.AS3Function) { ASTool.AS3.AS3Function as3function = (ASTool.AS3.AS3Function)stmt; { if (!as3function.IsAnonymous) { //List<ASBinCode.rtti.ClassMember> tooverridefunctions = new List<ASBinCode.rtti.ClassMember>(); string funcname = as3function.Name; if (as3function.IsGet || as3function.IsSet) { funcname = "@" + as3function.Name + (as3function.IsGet ? "_get" : "_set"); } //for (int j = 0; j < cls.classMembers.Count; j++) //{ // if (cls.classMembers[j].name == funcname //as3function.Name // && // ( // cls.classMembers[j].inheritFrom == null // || // (cls.classMembers[j].isPublic && as3function.Access.IsPublic // ) // ) // && // ( // cls.classMembers[j].inheritFrom != null // && // !cls.classMembers[j].inheritFrom.classMembers[j].isConstructor // ) // ) // { // if (as3function.Access.IsOverride // ) // { // if (!(cls.classMembers[j].bindField is ClassMethodGetter) // || // cls.classMembers[j].inheritFrom.classMembers[j].isConstructor // ) // { // throw new BuildException( // new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, // "Method marked override must override another method.") // ); // } // if (cls.classMembers[j].isFinal) // { // throw new BuildException( // new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, // "Cannot redefine a final method.") // ); // } // tooverridefunctions.Add(cls.classMembers[j]); // continue; // } // if (cls.classMembers[j].inheritFrom == null // ) // { // throw new BuildException( // new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, // "重复的类成员:" + as3function.Name) // ); // } // else // { // throw new BuildException( // new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, // "Overriding a function that is not marked for override") // ); // } // } //} if (as3function.Access.IsStatic) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "The static attribute may be used only on definitions inside a class.") ); } if (as3function.Access.IsOverride) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "The override attribute can only be used on a method defined in a class.") ); } //***非访问器*** if (!as3function.IsGet && !as3function.IsSet) { ASBinCode.rtti.ClassMember member = new ASBinCode.rtti.ClassMember(as3function.Name, cls, new InterfaceMethodGetter(as3function.Name, cls, env.block.id) ); member.setTypeWhenCompile(RunTimeDataType.rt_function); member.isInternal = as3function.Access.IsInternal; member.isPrivate = as3function.Access.IsPrivate; member.isProtectd = as3function.Access.IsProtected; member.isPublic = as3function.Access.IsPublic; member.isStatic = as3function.Access.IsStatic; member.isConst = true; member.isOverride = as3function.Access.IsOverride; member.isFinal = as3function.Access.IsFinal; member.isGetter = as3function.IsGet; member.isSetter = as3function.IsSet; member.isConstructor = as3function.IsConstructor; if (member.isPrivate) { ((MethodGetterBase)member.bindField).setNotReadVirtual(); } int s = 0; if (member.isPrivate) { s++; } if (member.isPublic) { s++; } if (member.isProtectd) { s++; } if (member.isInternal) { s++; } if (s != 0) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "Members of an interface cannot be declared public, private, protected, or internal.") ); } member.isPublic = true; if (as3function.FunctionBody.Nodes.Count > 0) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "Methods defined in an interface must not have a body.") ); } cls.classMembers.Add(member); builder._buildingmembers.Add(member, as3function); } else { ASBinCode.rtti.ClassMember member = new ASBinCode.rtti.ClassMember("@" + as3function.Name + (as3function.IsGet ? "_get" : "_set"), cls, new InterfaceMethodGetter("@" + as3function.Name + (as3function.IsGet ? "_get" : "_set"), cls, env.block.id) ); member.setTypeWhenCompile(RunTimeDataType.rt_function); member.isInternal = as3function.Access.IsInternal; member.isPrivate = as3function.Access.IsPrivate; member.isProtectd = as3function.Access.IsProtected; member.isPublic = as3function.Access.IsPublic; member.isStatic = as3function.Access.IsStatic; member.isConst = true; member.isOverride = as3function.Access.IsOverride; member.isFinal = as3function.Access.IsFinal; member.isGetter = as3function.IsGet; member.isSetter = as3function.IsSet; member.isConstructor = as3function.IsConstructor; if (member.isGetter && member.isSetter) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "不能同时是getter和setter") ); } int s = 0; if (member.isPrivate) { s++; } if (member.isPublic) { s++; } if (member.isProtectd) { s++; } if (member.isInternal) { s++; } if (s != 0) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "Members of an interface cannot be declared public, private, protected, or internal.") ); } member.isPublic = true; if (as3function.FunctionBody.Nodes.Count > 0) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "Methods defined in an interface must not have a body.") ); } cls.classMembers.Add(member); builder._buildingmembers.Add(member, as3function); //***查找ClassPropertyGetter**** ClassPropertyGetter pg = null; for (int i = 0; i < cls.classMembers.Count; i++) { if (cls.classMembers[i].name == as3function.Name && cls.classMembers[i].inheritFrom == null) { if (cls.classMembers[i].bindField is ClassPropertyGetter) { pg = (ClassPropertyGetter)cls.classMembers[i].bindField; if (member.isGetter && pg.getter != null && cls.classMembers[pg.getter.indexOfMembers].inheritFrom == null ) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "属性访问器重复") ); } else if (member.isSetter && pg.setter != null && cls.classMembers[pg.setter.indexOfMembers].inheritFrom == null ) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "属性设置器重复") ); } } else { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "期望一个属性") ); } } } if (pg == null) { pg = new ClassPropertyGetter(as3function.Name, cls, cls.classMembers.Count); ASBinCode.rtti.ClassMember m = new ASBinCode.rtti.ClassMember(as3function.Name, cls, pg); cls.classMembers.Add(m); m.isPublic = true; m.isStatic = member.isStatic; } if (member.isGetter) { pg.getter = (MethodGetterBase)member.bindField; } else { pg.setter = (MethodGetterBase)member.bindField; } } } else { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "'function' is not allowed here") ); } } } else if (stmt is ASTool.AS3.AS3Variable) { //字段 数据成员 throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "A 'var' declaration is not permitted in an interface.") ); // } else if (stmt is ASTool.AS3.AS3Const) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "A 'const' declaration is not permitted in an interface.") ); } else { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "接口成员中不能出现" + stmt) ); } }
public static void _doPropAssigning(ClassPropertyGetter prop,StackFrame frame, OpStep step,Player player,RunTimeScope scope, ASBinCode.rtData.rtObjectBase bindobj,RunTimeValueBase v,StackSlot sslot) { do { if (prop.setter == null) { frame.throwError( step.token,0,"Illegal write to read-only property " ); break; } //检查访问权限 CodeBlock block = player.swc.blocks[scope.blockId]; Class finder; if (block.isoutclass) { var c = prop._class; if (c.instanceClass != null) { c = c.instanceClass; } if (c.mainClass != null) { c = c.mainClass; } if (block.define_class_id == c.classid) { finder = player.swc.classes[block.define_class_id]; } else { finder = null; } } else { finder = player.swc.classes[block.define_class_id]; } var setter = ClassMemberFinder.find(prop._class,prop.setter.name,finder); if (setter == null || setter.bindField != prop.setter) { frame.throwError( step.token,0,"Illegal write to read-only property " ); break; } //***读取setter*** RunTimeValueBase func; if (sslot.stackObjects.superPropBindClass != null) { func = ((MethodGetterBase)setter.bindField).getSuperMethod( bindobj.objScope, sslot.stackObjects.superPropBindClass ); } else { func = ((MethodGetterBase)setter.bindField).getMethod( bindobj ); } //***调用设置器*** var funCaller = frame.player.funcCallerPool.create(frame,step.token); funCaller.SetFunction((ASBinCode.rtData.rtFunction)func); ((ASBinCode.rtData.rtFunction)func).Clear(); funCaller.loadDefineFromFunction(); if (!funCaller.createParaScope()) { return; } //funCaller.releaseAfterCall = true; bool success; funCaller.pushParameter(v,0,out success); if (!success) { frame.endStep(step); return; } funCaller._tempSlot = frame._tempSlot1; funCaller.returnSlot = frame._tempSlot1; BlockCallBackBase cb = frame.player.blockCallBackPool.create(); cb.setCallBacker(_assign_callbacker); cb.step = step; cb.args = frame; funCaller.callbacker = cb; funCaller.call(); return; } while (false); frame.endStep(step); }
public static void _do_prop_read( ClassPropertyGetter prop,StackFrame frame,OpStep step,Player player,RunTimeScope scope, ASBinCode.rtData.rtObjectBase propBindObj,Class superPropBindClass ) { do { //***调用访问器。*** if (prop.getter == null) { frame.throwError( step.token,0,"Illegal read of write-only property" ); break; } //检查访问权限 CodeBlock block = player.swc.blocks[scope.blockId]; Class finder; if (block.isoutclass) { var c = prop._class; if (c.instanceClass != null) { c = c.instanceClass; } if (c.mainClass != null) { c = c.mainClass; } if (block.define_class_id == c.classid) { finder = player.swc.classes[block.define_class_id]; } else { finder = null; } } else { finder = player.swc.classes[block.define_class_id]; } var getter = ClassMemberFinder.find(prop._class,prop.getter.name,finder); if (getter == null || getter.bindField != prop.getter) { frame.throwError( step.token,0,"Illegal read of write-only property" ); break; } //***读取getter*** RunTimeValueBase func; if (superPropBindClass != null) { func = ((MethodGetterBase)getter.bindField).getSuperMethod( //propslot.bindObj.objScope propBindObj.objScope, superPropBindClass ); } else { func = ((MethodGetterBase)getter.bindField).getMethod( //propslot.bindObj.objScope propBindObj ); } //***调用访问器*** var funCaller = player.funcCallerPool.create(frame,step.token); //funCaller.releaseAfterCall = true; funCaller.SetFunction((ASBinCode.rtData.rtFunction)func); ((ASBinCode.rtData.rtFunction)func).Clear(); funCaller.loadDefineFromFunction(); if (!funCaller.createParaScope()) { return; } funCaller._tempSlot = frame._tempSlot1; funCaller.returnSlot = step.reg.getSlot(scope,frame); ((StackSlot)funCaller.returnSlot).stackObjects.propGetSet = prop; ((StackSlot)funCaller.returnSlot).refPropChanged = true; ((StackSlot)funCaller.returnSlot).stackObjects.propBindObj = propBindObj; BlockCallBackBase cb = frame.player.blockCallBackPool.create(); cb.setCallBacker(D_getter_callbacker); cb.step = step; cb.args = frame; funCaller.callbacker = cb; funCaller.call(); return; } while (false); frame.endStep(step); }
public string GetCode() { if (as3class.super.name == "Object") { StringBuilder content = new StringBuilder(); foreach (var item in as3class.staticClass.fields) { if (item.inheritFrom == null) { content.Append("\t\t"); string field = ""; //item.isPublic ? "public" : (item.isInternal ? "internal" : "private"); //if (item.isProtectd) field += " protected"; //if (item.isConst) field += " const"; //field += " " + GetTypeString(item.valueType); field += " " + GetName(item.name); if (item.defaultValue != null) { field += " = " + item.defaultValue.ToString(); } else { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("发现枚举字段没有默认值." + as3class.name + ":" + item.name); Console.ResetColor(); } field += ","; content.AppendLine(field); } } //Enum文档 foreach (var item in as3class.fields) { if (item.inheritFrom == null) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("发现枚举类中的非静态字段:" + as3class.name + ":" + item.name); Console.ResetColor(); } } var tempate = Properties.Resources.EnumTemplate; tempate = tempate.Replace("[PACKAGE]", as3class.package) .Replace("[CLASSNAME]", as3class.name) .Replace("[CONTENT]", content.ToString()); return(tempate.ToString()); } else if (as3class.super.name == "Message") { var enumtype = swc.getClassDefinitionByName("com.netease.protobuf.fieldDescriptors.FieldDescriptor_TYPE_ENUM"); var repeatEnum = swc.getClassDefinitionByName("com.netease.protobuf.fieldDescriptors.RepeatedFieldDescriptor_TYPE_ENUM"); //****查询元数据*** foreach (var item in as3class.staticClass.classMembers) { if (item.valueType == enumtype.getRtType()) { var findenum = ((ASBinCode.rtData.rtObject)player.getMemberValue(as3class.package + (string.IsNullOrEmpty(as3class.package) ? "" : ".") + as3class.name, item.name + ".enumType")).value._class.instanceClass; var bindmember = player.getMemberValue(as3class.package + (string.IsNullOrEmpty(as3class.package) ? "" : ".") + as3class.name, item.name + ".name"); enumMembers.Add(bindmember.ToString(), findenum.package + (string.IsNullOrEmpty(findenum.package) ? "" : ".") + findenum.name); } else if (item.valueType == repeatEnum.getRtType()) { var findenum = ((ASBinCode.rtData.rtObject)player.getMemberValue(as3class.package + (string.IsNullOrEmpty(as3class.package) ? "" : ".") + as3class.name, item.name + ".enumType")).value._class.instanceClass; var bindmember = player.getMemberValue(as3class.package + (string.IsNullOrEmpty(as3class.package) ? "" : ".") + as3class.name, item.name + ".name"); repeatEnumMembers.Add(bindmember.ToString(), findenum.package + (string.IsNullOrEmpty(findenum.package) ? "" : ".") + findenum.name); } } StringBuilder content = new StringBuilder(); List <ASBinCode.rtti.ClassMember> fieldlist = new List <ASBinCode.rtti.ClassMember>(); List <ASBinCode.rtti.ClassMember> propertylist = new List <ASBinCode.rtti.ClassMember>(); foreach (var member in as3class.classMembers) { if (member.inheritFrom != null && (member.inheritFrom.name != "Message" || member.inheritSrcMember.isConstructor)) { continue; } if (member.isConstructor) { continue; } if (!member.isPublic) { continue; } if (member.isGetter || member.isSetter) { continue; } if (member.valueType == RunTimeDataType.rt_function) { if (member.inheritFrom != null) { continue; } var function = swc.functions[((MethodGetterBase)member.bindField).functionId]; string type = GetTypeString(function.signature.returnType); string method = "\t\tpublic "; if (member.isOverride) { method += "override "; } method += type + " "; method += GetName(member.name); method += "("; for (int i = 0; i < function.signature.parameters.Count; i++) { var p = function.signature.parameters[i]; string paratype = GetTypeString(p.type); if (paratype == "flash.utils.IDataInput") { paratype = "System.IO.MemoryStream"; } else if (paratype == "flash.utils.IDataOutput") { paratype = "System.IO.MemoryStream"; } else if (paratype == "flash.utils.ByteArray") { paratype = "byte[]"; } else if (paratype == "com.netease.protobuf.UInt64") { paratype = "System.UInt64"; } else if (paratype == "com.netease.protobuf.Int64") { paratype = "System.Int64"; } method += paratype + " " + p.name; if (i < function.signature.parameters.Count - 1) { method += ","; } } method += "){"; method += " player.invokeMethod(as3Object, \"" + member.name + "\""; for (int i = 0; i < function.signature.parameters.Count; i++) { method += "," + GetConvertToAS3ParameterFunctionName(function.signature.parameters[i].type) + "(" + function.signature.parameters[i].name + ")"; } method += ");"; method += "}"; content.AppendLine(method); } else if (member.bindField is ASBinCode.ClassPropertyGetter) { string propertytype = GetTypeString(member.valueType); if (propertytype == "flash.utils.ByteArray") { propertytype = "byte[]"; } else if (propertytype == "com.netease.protobuf.UInt64") { propertytype = "System.UInt64"; } else if (propertytype == "com.netease.protobuf.Int64") { propertytype = "System.Int64"; } if ((propertytype == "byte[]") || (propertytype == "System.UInt64") || (propertytype == "System.Int64") || ((member.valueType < RunTimeDataType._OBJECT))) { bool isenum = false; if (enumMembers.ContainsKey(member.name)) { propertytype = enumMembers[member.name]; isenum = true; } string filed = "\t\tpublic " + propertytype + " " + GetName(member.name) + "{"; ClassPropertyGetter prop = (ClassPropertyGetter)member.bindField; if (prop.getter != null && prop.getter.classmember.isPublic) { filed += "get { return (" + propertytype + ")(" + GetConvertFromAS3ParameterFunctionName(member.valueType) + "(player.getMemberValue(as3Object, \"" + member.name + "\"))); }"; } if (prop.setter != null && prop.setter.classmember.isPublic) { filed += "set { player.setMemberValue(as3Object, \"" + member.name + "\", " + GetConvertToAS3ParameterFunctionName(member.valueType) + (isenum?"(int)":"") + "(value)); }"; } filed += "}"; content.AppendLine(filed); } else { string field = Properties.Resources.ClassPropertyTemplate .Replace("[PROPERTYTYPE]", propertytype) .Replace("[CNAME]", GetName(member.name)) .Replace("[NAME]", member.name) ; content.AppendLine(field); propertylist.Add(member); } } else if (as3class.fields.Contains(member)) { fieldlist.Add(member); string fieldtype = GetTypeString(member.valueType); if (fieldtype == "System.Collections.Generic.List<{0}>") { Field f = (Field)member.bindField; foreach (var item in f.metas) { if (item.MetaName == "ArrayElementType") { if (repeatEnumMembers.ContainsKey(member.name)) { fieldtype = string.Format(fieldtype, repeatEnumMembers[member.name]); } else { fieldtype = string.Format(fieldtype, item.MetaData.ToString()); } break; } } } else if (fieldtype == "flash.utils.ByteArray") { fieldtype = "byte[]"; } else if (fieldtype == "com.netease.protobuf.UInt64") { fieldtype = "System.UInt64"; } else if (fieldtype == "com.netease.protobuf.Int64") { fieldtype = "System.Int64"; } if (enumMembers.ContainsKey(member.name)) { fieldtype = enumMembers[member.name]; } string field = "\t\tpublic " + fieldtype + " " + GetName(member.name) + " ;"; content.AppendLine(field); } } string afterMergeFrom = string.Empty; string beforeWriteTo = string.Empty; if (fieldlist.Count > 0) { //***追加afterMergeFrom() afterMergeFrom = "\t\tprivate bool _isreadding;\n"; afterMergeFrom += "\t\tprotected override void afterMergeFrom()\n"; afterMergeFrom += "\t\t{\n"; afterMergeFrom += "\t\t\tif(_isreadding) { return;} else { _isreadding=true; }\n"; afterMergeFrom += "\t\t\ttry\n"; afterMergeFrom += "\t\t\t{\n"; for (int i = 0; i < fieldlist.Count; i++) { var member = fieldlist[i]; string fieldtype = GetTypeString(member.valueType); if (fieldtype == "System.Collections.Generic.List<{0}>") { Field f = (Field)member.bindField; string vectortype = string.Empty; string elementtype = string.Empty; foreach (var item in f.metas) { if (item.MetaName == "ArrayElementType") { vectortype = item.MetaData.ToString(); if (repeatEnumMembers.ContainsKey(member.name)) { fieldtype = string.Format(fieldtype, repeatEnumMembers[member.name]); } else { fieldtype = string.Format(fieldtype, item.MetaData.ToString()); } elementtype = vectortype; if (repeatEnumMembers.ContainsKey(member.name)) { elementtype = repeatEnumMembers[member.name]; } if (elementtype == "flash.utils.ByteArray") { elementtype = "byte[]"; } else if (elementtype == "com.netease.protobuf.UInt64") { elementtype = "System.UInt64"; } else if (elementtype == "com.netease.protobuf.Int64") { elementtype = "System.Int64"; } else if (elementtype == "Number") { elementtype = "double"; } break; } } string listtemplate = @" { [CNAME] = new [LIST](); uint len = (uint)player.getMemberValue(as3Object, ""[NAME].length""); for (int i = 0; i < len; i++) { [VECTORTYPE] v = default([VECTORTYPE]); [SETVALUE] [CNAME].Add(v); } } "; bool isclass = false; var c = swc.getClassDefinitionByName(vectortype); if (c != null) { RunTimeDataType primtype; if (ASRuntime.TypeConverter.Object_CanImplicit_ToPrimitive(c, out primtype)) { isclass = false; } else { isclass = true; } } afterMergeFrom += listtemplate.Replace("[CNAME]", GetName(member.name)) .Replace("[NAME]", member.name) .Replace("[VECTORTYPE]", elementtype) .Replace("[SETVALUE]", GetLoadFieldValueStmt("v", elementtype, member, isclass, "i", "\t\t")) .Replace("[LIST]", fieldtype) ; continue; } else if (fieldtype == "flash.utils.ByteArray") { fieldtype = "byte[]"; } else if (fieldtype == "com.netease.protobuf.UInt64") { fieldtype = "System.UInt64"; } else if (fieldtype == "com.netease.protobuf.Int64") { fieldtype = "System.Int64"; } afterMergeFrom += GetLoadFieldValueStmt(GetName(member.name), fieldtype, member, member.valueType > RunTimeDataType._OBJECT, null); } afterMergeFrom += "\t\t\t}\n"; afterMergeFrom += "\t\t\tfinally\n"; afterMergeFrom += "\t\t\t{\n"; afterMergeFrom += "\t\t\t_isreadding=false;\n"; afterMergeFrom += "\t\t\t}\n"; afterMergeFrom += "\t\t}\n"; //****追加beforeWriteTo****** beforeWriteTo = "\t\tprivate bool _iswritting;\n"; beforeWriteTo += "\t\tprotected override void beforeWriteTo()\n"; beforeWriteTo += "\t\t{\n"; beforeWriteTo += "\t\t\tif(_iswritting) { return;} else { _iswritting=true; }\n"; beforeWriteTo += "\t\t\ttry\n"; beforeWriteTo += "\t\t\t{\n"; for (int i = 0; i < fieldlist.Count; i++) { var member = fieldlist[i]; string fieldtype = GetTypeString(member.valueType); if (fieldtype == "System.Collections.Generic.List<{0}>") { Field f = (Field)member.bindField; string vectortype = string.Empty; string elementtype = string.Empty; foreach (var item in f.metas) { if (item.MetaName == "ArrayElementType") { vectortype = item.MetaData.ToString(); fieldtype = string.Format(fieldtype, item.MetaData.ToString()); elementtype = vectortype; if (elementtype == "flash.utils.ByteArray") { elementtype = "byte[]"; } else if (elementtype == "com.netease.protobuf.UInt64") { elementtype = "System.UInt64"; } else if (elementtype == "com.netease.protobuf.Int64") { elementtype = "System.Int64"; } else if (elementtype == "Number") { elementtype = "double"; } break; } } string listtemplate = @" { player.setMemberValue(as3Object, ""[CNAME].length"", [CNAME].Count); for (int i = 0; i < [CNAME].Count; i++) { var v = [CNAME][i]; [SAVEVALUE] } } "; bool isclass = false; var c = swc.getClassDefinitionByName(vectortype); if (c != null) { RunTimeDataType primtype; if (ASRuntime.TypeConverter.Object_CanImplicit_ToPrimitive(c, out primtype)) { isclass = false; } else { isclass = true; } } beforeWriteTo += listtemplate.Replace("[CNAME]", GetName(member.name)) .Replace("[SAVEVALUE]", GetSaveFieldValueStmt("v", elementtype, vectortype, member.name, isclass, "i", "\t\t")); ; continue; } else if (fieldtype == "flash.utils.ByteArray") { fieldtype = "byte[]"; } else if (fieldtype == "com.netease.protobuf.UInt64") { fieldtype = "System.UInt64"; } else if (fieldtype == "com.netease.protobuf.Int64") { fieldtype = "System.Int64"; } beforeWriteTo += GetSaveFieldValueStmt(GetName(member.name), fieldtype, GetTypeString(member.valueType), member.name, member.valueType > RunTimeDataType._OBJECT, null); } for (int i = 0; i < propertylist.Count; i++) { var member = propertylist[i]; string template = Properties.Resources.ClassPropertyBeforeWriteTo; beforeWriteTo += template.Replace("[CNAME]", GetName(member.name)) .Replace("[NAME]", member.name) ; } beforeWriteTo += "\t\t\t}\n"; beforeWriteTo += "\t\t\tfinally\n"; beforeWriteTo += "\t\t\t{\n"; beforeWriteTo += "\t\t\t_iswritting=false;\n"; beforeWriteTo += "\t\t\t}\n"; beforeWriteTo += "\t\t}\n"; } var tempate = Properties.Resources.MessageTemplate; tempate = tempate.Replace("[PACKAGE]", as3class.package) .Replace("[AS3PROTOTYPE]", as3class.package + (string.IsNullOrEmpty(as3class.package)?"":".") + as3class.name) .Replace("[CLASSNAME]", as3class.name) .Replace("[afterMergeFrom]", afterMergeFrom) .Replace("[beforeWriteTo]", beforeWriteTo) .Replace("[CONTENT]", content.ToString()); return(tempate.ToString()); } else { return(string.Empty); } }