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"); } } }
private void copyInheritsFromImplements(ASBinCode.rtti.Class cls, Builder builder) { foreach (var supercls in cls.implements.Keys) { for (int i = 0; i < supercls.classMembers.Count; i++) { var sm = supercls.classMembers[i]; var bf = sm.bindField; if (bf is InterfaceMethodGetter) { var sig = builder.dictSignatures[((InterfaceMethodGetter)bf).refdefinedinblockid][bf]; InterfaceMethodGetter ifm = new InterfaceMethodGetter(bf.name, cls, ((InterfaceMethodGetter)bf).refdefinedinblockid); ifm.setLinkMethod((InterfaceMethodGetter)bf); bf = ifm; if (!builder.dictSignatures.ContainsKey(ifm.refdefinedinblockid)) { builder.dictSignatures.Add(ifm.refdefinedinblockid, new Dictionary <IMember, ASBinCode.rtti.FunctionSignature>()); } builder.dictSignatures[ifm.refdefinedinblockid].Add(ifm, sig); } else if (bf is ClassPropertyGetter) { ClassPropertyGetter cg = new ClassPropertyGetter(bf.name, cls, cls.classMembers.Count); cg.valueType = ((ClassPropertyGetter)bf).valueType; cg.getter = ((ClassPropertyGetter)bf).getter; cg.setter = ((ClassPropertyGetter)bf).setter; bf = cg; } ASBinCode.rtti.ClassMember member = new ASBinCode.rtti.ClassMember(sm.name, cls, bf); member.defaultValue = sm.defaultValue; member.isConst = false; member.isConstructor = false; member.isGetter = sm.isGetter; member.isInternal = false; member.isOverride = false; member.isFinal = false; member.isPrivate = false; member.isProtectd = false; member.isPublic = true; member.isSetter = sm.isSetter; member.isStatic = false; member.setTypeWhenCompile(sm.valueType); member.virtualLink = sm; //member.virtualLinkFromClass = supercls; if (sm.inheritFrom == null) { member.inheritFrom = supercls; } else { member.inheritFrom = sm.inheritFrom; } if (sm.inheritSrcMember == null) { member.inheritSrcMember = sm; } else { member.inheritSrcMember = sm.inheritSrcMember; } bool iskip = false; for (int m = 0; m < cls.classMembers.Count; m++) { var om = cls.classMembers[m]; ASTool.AS3.IAS3Stmt stmt = null; if (om.name == member.name) { if (om.bindField is ClassPropertyGetter || member.bindField is ClassPropertyGetter) { if (om.bindField is ClassPropertyGetter && member.bindField is ClassPropertyGetter) { iskip = true; break; } else { foreach (var item in builder.buildingclasses) { if (item.Value == cls) { stmt = item.Key; } } throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "重复的接口成员,一个是访问器一个不是 " + cls.name + ":" + member.name) ); } } ASBinCode.rtti.FunctionSignature sig = null; //**检查签名*** if (om.inheritFrom == null) { sig = builder.dictSignatures[cls.blockid][om.bindField]; stmt = builder._buildingmembers[om]; } else { sig = builder.dictSignatures[om.inheritFrom.blockid][om.inheritSrcMember.bindField]; stmt = builder._buildingmembers[om.inheritSrcMember]; } ASBinCode.rtti.FunctionSignature sig2 = null; if (member.inheritFrom == null) { sig2 = builder.dictSignatures[cls.blockid][member.bindField]; } else { sig2 = builder.dictSignatures[member.inheritFrom.blockid][member.inheritSrcMember.bindField]; } //***检查2个接口签名完全匹配*** if (om.isGetter != member.isGetter || om.isSetter != member.isSetter) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "重复的接口成员,访问器类型不匹配" + member.refClass.name + "::" + member.name) ); } else if (sig.returnType != sig2.returnType) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "重复的接口成员,签名不匹配" + member.refClass.name + "::" + member.name) ); } else if (sig.parameters.Count != sig2.parameters.Count) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "重复的接口成员,签名不匹配" + member.refClass.name + "::" + member.name) ); } else { //***比较所有参数*** for (int j = 0; j < sig.parameters.Count; j++) { if (sig.parameters[j].type != sig2.parameters[j].type || sig.parameters[j].isPara != sig2.parameters[j].isPara ) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "重复的接口成员,签名不匹配" + member.refClass.name + "::" + member.name) ); } } } //***检查通过,跳过这次添加*** iskip = true; } } if (!iskip) { cls.classMembers.Add(member); } } } //***拷贝完成,重新确认propertygetersetter,并设定索引*** for (int i = 0; i < cls.classMembers.Count; i++) { var m = cls.classMembers[i]; if (m.bindField is ClassPropertyGetter) { ClassPropertyGetter pg = (ClassPropertyGetter)m.bindField; //if (pg._class == cls) { pg.getter = null; pg.setter = null; for (int j = 0; j < cls.classMembers.Count; j++) { if (cls.classMembers[j].name == "@" + pg.name + "_get") { pg.getter = (InterfaceMethodGetter)cls.classMembers[j].bindField; } else if (cls.classMembers[j].name == "@" + pg.name + "_set") { pg.setter = (InterfaceMethodGetter)cls.classMembers[j].bindField; } } } } else { InterfaceMethodGetter ig = (InterfaceMethodGetter)m.bindField; ig.setIndexMember(i, cls); } } }
private void buildInterfaceMember(CompileEnv env, ASTool.AS3.IAS3Stmt stmt, ASBinCode.rtti.Class cls, Builder builder ) { if (stmt is ASTool.AS3.AS3Block) { ASTool.AS3.AS3Block as3block = (ASTool.AS3.AS3Block)stmt; for (int i = 0; i < as3block.CodeList.Count; i++) { buildInterfaceMember(env, as3block.CodeList[i], cls, builder); } } else if (stmt is ASTool.AS3.AS3Function) { ASTool.AS3.AS3Function as3function = (ASTool.AS3.AS3Function)stmt; { if (!as3function.IsAnonymous) { //List<ASBinCode.rtti.ClassMember> tooverridefunctions = new List<ASBinCode.rtti.ClassMember>(); string funcname = as3function.Name; if (as3function.IsGet || as3function.IsSet) { funcname = "@" + as3function.Name + (as3function.IsGet ? "_get" : "_set"); } //for (int j = 0; j < cls.classMembers.Count; j++) //{ // if (cls.classMembers[j].name == funcname //as3function.Name // && // ( // cls.classMembers[j].inheritFrom == null // || // (cls.classMembers[j].isPublic && as3function.Access.IsPublic // ) // ) // && // ( // cls.classMembers[j].inheritFrom != null // && // !cls.classMembers[j].inheritFrom.classMembers[j].isConstructor // ) // ) // { // if (as3function.Access.IsOverride // ) // { // if (!(cls.classMembers[j].bindField is ClassMethodGetter) // || // cls.classMembers[j].inheritFrom.classMembers[j].isConstructor // ) // { // throw new BuildException( // new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, // "Method marked override must override another method.") // ); // } // if (cls.classMembers[j].isFinal) // { // throw new BuildException( // new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, // "Cannot redefine a final method.") // ); // } // tooverridefunctions.Add(cls.classMembers[j]); // continue; // } // if (cls.classMembers[j].inheritFrom == null // ) // { // throw new BuildException( // new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, // "重复的类成员:" + as3function.Name) // ); // } // else // { // throw new BuildException( // new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, // "Overriding a function that is not marked for override") // ); // } // } //} if (as3function.Access.IsStatic) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "The static attribute may be used only on definitions inside a class.") ); } if (as3function.Access.IsOverride) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "The override attribute can only be used on a method defined in a class.") ); } //***非访问器*** if (!as3function.IsGet && !as3function.IsSet) { ASBinCode.rtti.ClassMember member = new ASBinCode.rtti.ClassMember(as3function.Name, cls, new InterfaceMethodGetter(as3function.Name, cls, env.block.id) ); member.setTypeWhenCompile(RunTimeDataType.rt_function); member.isInternal = as3function.Access.IsInternal; member.isPrivate = as3function.Access.IsPrivate; member.isProtectd = as3function.Access.IsProtected; member.isPublic = as3function.Access.IsPublic; member.isStatic = as3function.Access.IsStatic; member.isConst = true; member.isOverride = as3function.Access.IsOverride; member.isFinal = as3function.Access.IsFinal; member.isGetter = as3function.IsGet; member.isSetter = as3function.IsSet; member.isConstructor = as3function.IsConstructor; if (member.isPrivate) { ((MethodGetterBase)member.bindField).setNotReadVirtual(); } int s = 0; if (member.isPrivate) { s++; } if (member.isPublic) { s++; } if (member.isProtectd) { s++; } if (member.isInternal) { s++; } if (s != 0) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "Members of an interface cannot be declared public, private, protected, or internal.") ); } member.isPublic = true; if (as3function.FunctionBody.Nodes.Count > 0) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "Methods defined in an interface must not have a body.") ); } cls.classMembers.Add(member); builder._buildingmembers.Add(member, as3function); } else { ASBinCode.rtti.ClassMember member = new ASBinCode.rtti.ClassMember("@" + as3function.Name + (as3function.IsGet ? "_get" : "_set"), cls, new InterfaceMethodGetter("@" + as3function.Name + (as3function.IsGet ? "_get" : "_set"), cls, env.block.id) ); member.setTypeWhenCompile(RunTimeDataType.rt_function); member.isInternal = as3function.Access.IsInternal; member.isPrivate = as3function.Access.IsPrivate; member.isProtectd = as3function.Access.IsProtected; member.isPublic = as3function.Access.IsPublic; member.isStatic = as3function.Access.IsStatic; member.isConst = true; member.isOverride = as3function.Access.IsOverride; member.isFinal = as3function.Access.IsFinal; member.isGetter = as3function.IsGet; member.isSetter = as3function.IsSet; member.isConstructor = as3function.IsConstructor; if (member.isGetter && member.isSetter) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "不能同时是getter和setter") ); } int s = 0; if (member.isPrivate) { s++; } if (member.isPublic) { s++; } if (member.isProtectd) { s++; } if (member.isInternal) { s++; } if (s != 0) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "Members of an interface cannot be declared public, private, protected, or internal.") ); } member.isPublic = true; if (as3function.FunctionBody.Nodes.Count > 0) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "Methods defined in an interface must not have a body.") ); } cls.classMembers.Add(member); builder._buildingmembers.Add(member, as3function); //***查找ClassPropertyGetter**** ClassPropertyGetter pg = null; for (int i = 0; i < cls.classMembers.Count; i++) { if (cls.classMembers[i].name == as3function.Name && cls.classMembers[i].inheritFrom == null) { if (cls.classMembers[i].bindField is ClassPropertyGetter) { pg = (ClassPropertyGetter)cls.classMembers[i].bindField; if (member.isGetter && pg.getter != null && cls.classMembers[pg.getter.indexOfMembers].inheritFrom == null ) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "属性访问器重复") ); } else if (member.isSetter && pg.setter != null && cls.classMembers[pg.setter.indexOfMembers].inheritFrom == null ) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "属性设置器重复") ); } } else { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "期望一个属性") ); } } } if (pg == null) { pg = new ClassPropertyGetter(as3function.Name, cls, cls.classMembers.Count); ASBinCode.rtti.ClassMember m = new ASBinCode.rtti.ClassMember(as3function.Name, cls, pg); cls.classMembers.Add(m); m.isPublic = true; m.isStatic = member.isStatic; } if (member.isGetter) { pg.getter = (MethodGetterBase)member.bindField; } else { pg.setter = (MethodGetterBase)member.bindField; } } } else { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "'function' is not allowed here") ); } } } else if (stmt is ASTool.AS3.AS3Variable) { //字段 数据成员 throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "A 'var' declaration is not permitted in an interface.") ); // } else if (stmt is ASTool.AS3.AS3Const) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "A 'const' declaration is not permitted in an interface.") ); } else { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "接口成员中不能出现" + stmt) ); } }