コード例 #1
0
        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.");
        }
コード例 #2
0
        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.");
        }
コード例 #3
0
        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.");
        }
コード例 #4
0
        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.");
        }
コード例 #5
0
        public void Create_IfPropertyIsNull_Throws()
        {
            // Arrange
            PropertyInfo property = null;

            // Act & Assert
            ExceptionAssert.ThrowsArgumentNull(() => ClassPropertyGetter <Poco, PocoProperty> .Create(property),
                                               "property");
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        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.");
        }
コード例 #8
0
        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);
        }
コード例 #9
0
        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();
        }
コード例 #10
0
        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);
                }
            }
        }
コード例 #11
0
        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)
                          );
            }
        }
コード例 #12
0
ファイル: OpAssigning.cs プロジェクト: ikvm/ASTool
        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);
        }
コード例 #13
0
        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);
        }
コード例 #14
0
        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);
            }
        }