コード例 #1
0
        private void _doBuildMemberType(ASBinCode.rtti.ClassMember member, Builder builder, ASBinCode.rtti.Class cls)
        {
            ASTool.AS3.IAS3Stmt stmt = builder._buildingmembers[member];

            CompileEnv env;// = builder._classbuildingEnv[cls];

            if (member.isStatic)
            {
                env = builder._classbuildingEnv[cls.staticClass];
            }
            else
            {
                env = builder._classbuildingEnv[cls];
            }

            {
                if (stmt is ASTool.AS3.AS3Function)
                {
                    member.setTypeWhenCompile(RunTimeDataType.rt_function);

                    //**编译函数签名
                    builder.buildNamedFunctionSignature(env, (ASTool.AS3.AS3Function)stmt);
                }
                else
                {
                    throw new Exception("异常的成员类型");
                }

                //((Variable)env.block.scope.members[member.index]).valueType = member.valueType;
                if (member.bindField is Field)
                {
                    throw new Exception("在接口中异常出现Field");
                }
            }
        }
コード例 #2
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);
                }
            }
        }
コード例 #3
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)
                          );
            }
        }