public void buildAS3YieldBreak(CompileEnv env, ASTool.AS3.AS3YieldBreak as3yieldbreak, Builder builder)
        {
            if (builder.buildingfunctons.Count > 0)
            {
                ASTool.AS3.AS3Function as3function = builder.buildingfunctons.Peek();
                if (as3function.IsConstructor)
                {
                    throw new BuildException(as3yieldbreak.Token.line, as3yieldbreak.Token.ptr, as3yieldbreak.Token.sourceFile,
                                             "构造函数不能用yield");
                }

                OpStep opyieldbreak = new OpStep(OpCode.yield_break, new SourceToken(as3yieldbreak.Token.line, as3yieldbreak.Token.ptr, as3yieldbreak.Token.sourceFile));
                env.block.opSteps.Add(opyieldbreak);
            }
            else
            {
                throw new BuildException(as3yieldbreak.Token.line, as3yieldbreak.Token.ptr, as3yieldbreak.Token.sourceFile,
                                         "yield break 只能在函数中");
            }
        }
Ejemplo n.º 2
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)
                          );
            }
        }