// 生成类型绑定 public void Generate(TypeBindingInfo typeBindingInfo) { this.cs.enabled = (typeBindingInfo.bindingFlags & TypeBindingFlags.BindingCode) != 0 && (typeBindingFlags & TypeBindingFlags.BindingCode) != 0; this.tsDeclare.enabled = (typeBindingInfo.bindingFlags & TypeBindingFlags.TypeDefinition) != 0 && (typeBindingFlags & TypeBindingFlags.TypeDefinition) != 0; if (typeBindingInfo.isEditorRuntime) { using (new EditorOnlyCodeGen(this)) { GenerateInternal(typeBindingInfo); } } else { GenerateInternal(typeBindingInfo); } }
public EventBindingInfo(Type declaringType, EventInfo eventInfo) { this.declaringType = declaringType; this.eventInfo = eventInfo; do { if (this.isStatic) { this.adderName = "BindStaticAdd_" + eventInfo.Name; this.removerName = "BindStaticRemove_" + eventInfo.Name; } else { this.adderName = "BindAdd_" + eventInfo.Name; this.removerName = "BindRemove_" + eventInfo.Name; this.proxyName = "BindProxy_" + eventInfo.Name; } } while (false); this.regName = TypeBindingInfo.GetNamingAttribute(eventInfo); }
public RegFuncNamespaceCodeGen(CodeGenerator cg, TypeBindingInfo typeBindingInfo) { this.cg = cg; this.cg.cs.Append("var ns = register.CreateNamespace("); // Debug.LogErrorFormat("{0}: {1}", bindingInfo.type, bindingInfo.Namespace); if (!string.IsNullOrEmpty(typeBindingInfo.jsNamespace)) { var split_ns = typeBindingInfo.jsNamespace.Split('.'); var ns_count = split_ns.Length; for (var i = 0; i < ns_count; i++) { var el_ns = split_ns[i]; if (i == ns_count - 1) { this.cg.cs.AppendL("\"{0}\"", el_ns); } else { this.cg.cs.AppendL("\"{0}\", ", el_ns); } } } this.cg.cs.AppendLineL(");"); }
private void GenerateInternal(TypeBindingInfo typeBindingInfo) { using (new PlatformCodeGen(this)) { using (new TopLevelCodeGen(this, typeBindingInfo)) { using (new NamespaceCodeGen(this, this.bindingManager.prefs.ns, typeBindingInfo.jsNamespace)) { if (typeBindingInfo.IsEnum) { using (new EnumCodeGen(this, typeBindingInfo)) { } } else { using (new ClassCodeGen(this, typeBindingInfo)) { } } } } } }
public void AddMethod(MethodInfo methodInfo, bool isIndexer, string renameRegName) { if (this.transform != null) { if (this.transform.IsBlocked(methodInfo)) { bindingManager.Info("skip blocked method: {0}", methodInfo.Name); return; } } var isExtension = methodInfo.IsDefined(typeof(System.Runtime.CompilerServices.ExtensionAttribute)); var isStatic = methodInfo.IsStatic && !isExtension; if (IsSupportedOperators(methodInfo)) { var methodName = TypeBindingInfo.GetNamingAttribute(methodInfo); var parameters = methodInfo.GetParameters(); var declaringType = methodInfo.DeclaringType; switch (methodName) { case "op_Addition": if (parameters.Length == 2) { if (parameters[0].ParameterType == declaringType && parameters[1].ParameterType == declaringType) { var bindingInfo = new OperatorBindingInfo(methodInfo, isExtension, isStatic, methodName, "+", "+", 2); operators.Add(bindingInfo); } } break; case "op_Subtraction": if (parameters.Length == 2) { if (parameters[0].ParameterType == declaringType && parameters[1].ParameterType == declaringType) { var bindingInfo = new OperatorBindingInfo(methodInfo, isExtension, isStatic, methodName, "-", "-", 2); operators.Add(bindingInfo); } } break; case "op_Equality": if (parameters.Length == 2) { if (parameters[0].ParameterType == declaringType && parameters[1].ParameterType == declaringType) { var bindingInfo = new OperatorBindingInfo(methodInfo, isExtension, isStatic, methodName, "==", "==", 2); operators.Add(bindingInfo); } } break; case "op_Multiply": if (parameters.Length == 2) { var op0 = bindingManager.GetExportedType(parameters[0].ParameterType); var op1 = bindingManager.GetExportedType(parameters[1].ParameterType); if (op0 == null || op1 == null) { return; } var bindingName = methodName + "_" + op0.name + "_" + op1.name; var bindingInfo = new OperatorBindingInfo(methodInfo, isExtension, isStatic, bindingName, "*", "*", 2); operators.Add(bindingInfo); } break; case "op_Division": if (parameters.Length == 2) { var op0 = bindingManager.GetExportedType(parameters[0].ParameterType); var op1 = bindingManager.GetExportedType(parameters[1].ParameterType); if (op0 == null || op1 == null) { return; } var bindingName = methodName + "_" + op0.name + "_" + op1.name; var bindingInfo = new OperatorBindingInfo(methodInfo, isExtension, isStatic, bindingName, "/", "/", 2); operators.Add(bindingInfo); } break; case "op_UnaryNegation": { var bindingInfo = new OperatorBindingInfo(methodInfo, isExtension, isStatic, methodName, "neg", "-", 1); operators.Add(bindingInfo); } break; default: bindingManager.Info("skip unsupported operator method: {0}", methodInfo.Name); return; } } else { var group = isStatic ? staticMethods : methods; MethodBindingInfo overrides; var methodName = TypeBindingInfo.GetNamingAttribute(methodInfo); if (!group.TryGetValue(methodName, out overrides)) { overrides = new MethodBindingInfo(isIndexer, isStatic, methodName, renameRegName ?? methodName); group.Add(methodName, overrides); } overrides.Add(methodInfo, isExtension); } CollectDelegate(methodInfo); bindingManager.Info("[AddMethod] {0}.{1}", type, methodInfo); }
public FieldBindingInfo(FieldInfo fieldInfo) { do { if (fieldInfo.IsLiteral) { try { var cv = fieldInfo.GetRawConstantValue(); var cvType = cv.GetType(); if (cvType == typeof(string)) { constantValue = $"\"{cv}\""; break; } if (cvType == typeof(int) || cvType == typeof(uint) || cvType == typeof(byte) || cvType == typeof(sbyte) || cvType == typeof(short) || cvType == typeof(ushort) || cvType == typeof(bool)) { constantValue = $"{cv}"; break; } if (cvType == typeof(float)) { var fcv = (float)cv; if (!float.IsInfinity(fcv) && !float.IsNaN(fcv)) { constantValue = $"{cv}"; break; } } // if (cvType.IsPrimitive && cvType.IsValueType) // { // constantValue = $"{cv}"; // break; // } } catch (Exception) { } } if (fieldInfo.IsStatic) { this.getterName = "BindStaticRead_" + fieldInfo.Name; if (!fieldInfo.IsInitOnly && !fieldInfo.IsLiteral) { this.setterName = "BindStaticWrite_" + fieldInfo.Name; } } else { this.getterName = "BindRead_" + fieldInfo.Name; if (!fieldInfo.IsInitOnly && !fieldInfo.IsLiteral) { this.setterName = "BindWrite_" + fieldInfo.Name; } } } while (false); this.regName = TypeBindingInfo.GetNamingAttribute(fieldInfo); this.fieldInfo = fieldInfo; }
public virtual void OnPostGenerateType(BindingManager bindingManager, TypeBindingInfo bindingInfo) { }
public ClassCodeGen(CodeGenerator cg, TypeBindingInfo typeBindingInfo) : base(cg, typeBindingInfo) { this.cg.AppendJSDoc(this.typeBindingInfo.type); var transform = this.typeBindingInfo.transform; var prefix = string.IsNullOrEmpty(this.typeBindingInfo.jsNamespace) ? "declare " : ""; var super = this.cg.bindingManager.GetTSSuperName(this.typeBindingInfo); var interfaces = this.cg.bindingManager.GetTSInterfacesName(this.typeBindingInfo); var extends = string.IsNullOrEmpty(super) ? "" : $" extends {super}"; var implements = string.IsNullOrEmpty(interfaces) ? "" : $" implements {interfaces}"; var regName = this.typeBindingInfo.jsName; if (typeBindingInfo.type.IsAbstract) { prefix += "abstract "; } if (typeBindingInfo.isEditorRuntime) { this.cg.tsDeclare.AppendLine("@jsb.EditorRuntime"); } this.cg.tsDeclare.AppendLine($"{prefix}class {regName}{extends}{implements} {{"); this.cg.tsDeclare.AddTabLevel(); // 生成函数体 // 构造函数 if (this.typeBindingInfo.constructors.available) { using (new PInvokeGuardCodeGen(cg, typeof(Native.JSCFunctionMagic))) { using (new BindingConstructorDeclareCodeGen(cg, this.typeBindingInfo.constructors.name)) { using (new TryCatchGuradCodeGen(cg)) { using (new ConstructorCodeGen(cg, this.typeBindingInfo)) { } } } } } // 非静态成员方法 foreach (var kv in this.typeBindingInfo.methods) { var methodBindingInfo = kv.Value; if (transform == null || !transform.IsRedirectedMethod(methodBindingInfo.regName)) { using (new PInvokeGuardCodeGen(cg)) { using (new BindingFuncDeclareCodeGen(cg, methodBindingInfo.name)) { using (new TryCatchGuradCodeGen(cg)) { using (new MethodCodeGen(cg, methodBindingInfo)) { } } } } } using (new TSMethodCodeGen(cg, methodBindingInfo)) { } } //TODO: C# 抽象类可以不提供方法实现, d.ts 需要补充声明 // if (this.bindingInfo.type.IsAbstract && !this.bindingInfo.type.IsInterface) // { // } // 静态成员方法 foreach (var kv in this.typeBindingInfo.staticMethods) { var methodBindingInfo = kv.Value; if (transform == null || !transform.IsRedirectedMethod(methodBindingInfo.regName)) { if (methodBindingInfo._cfunc != null) { continue; } using (new PInvokeGuardCodeGen(cg)) { using (new BindingFuncDeclareCodeGen(cg, methodBindingInfo.name)) { using (new TryCatchGuradCodeGen(cg)) { using (new MethodCodeGen(cg, methodBindingInfo)) { } } } } } using (new TSMethodCodeGen(cg, methodBindingInfo)) { } } foreach (var operatorBindingInfo in this.typeBindingInfo.operators) { if (transform == null || !transform.IsRedirectedMethod(operatorBindingInfo.regName)) { using (new PInvokeGuardCodeGen(cg)) { using (new BindingFuncDeclareCodeGen(cg, operatorBindingInfo.name)) { using (new TryCatchGuradCodeGen(cg)) { using (new OperatorCodeGen(cg, operatorBindingInfo)) { } } } } } using (new TSOperatorCodeGen(cg, operatorBindingInfo)) { } } // 所有附加方法 if (transform != null) { transform.ForEachAdditionalTSMethodDeclaration(decl => { this.cg.tsDeclare.AppendLine(decl); }); } // 所有属性 foreach (var kv in this.typeBindingInfo.properties) { var propertyBindingInfo = kv.Value; // 静态 if (propertyBindingInfo.staticPair.IsValid()) { // 可读属性 if (propertyBindingInfo.staticPair.getterName != null) { using (new PInvokeGuardCodeGen(cg, typeof(JSGetterCFunction))) { using (new BindingGetterFuncDeclareCodeGen(cg, propertyBindingInfo.staticPair.getterName)) { using (new TryCatchGuradCodeGen(cg)) { using (new PropertyGetterCodeGen(cg, propertyBindingInfo)) { } } } } } // 可写属性 if (propertyBindingInfo.staticPair.setterName != null) { using (new PInvokeGuardCodeGen(cg, typeof(JSSetterCFunction))) { using (new BindingSetterFuncDeclareCodeGen(cg, propertyBindingInfo.staticPair.setterName)) { using (new TryCatchGuradCodeGen(cg)) { using (new PropertySetterCodeGen(cg, propertyBindingInfo)) { } } } } } } // 非静态 if (propertyBindingInfo.instancePair.IsValid()) { // 可读属性 if (propertyBindingInfo.instancePair.getterName != null) { using (new PInvokeGuardCodeGen(cg, typeof(JSGetterCFunction))) { using (new BindingGetterFuncDeclareCodeGen(cg, propertyBindingInfo.instancePair.getterName)) { using (new TryCatchGuradCodeGen(cg)) { using (new PropertyGetterCodeGen(cg, propertyBindingInfo)) { } } } } } // 可写属性 if (propertyBindingInfo.instancePair.setterName != null) { using (new PInvokeGuardCodeGen(cg, typeof(JSSetterCFunction))) { using (new BindingSetterFuncDeclareCodeGen(cg, propertyBindingInfo.instancePair.setterName)) { using (new TryCatchGuradCodeGen(cg)) { using (new PropertySetterCodeGen(cg, propertyBindingInfo)) { } } } } } } } // 所有字段 foreach (var kv in this.typeBindingInfo.fields) { var fieldBindingInfo = kv.Value; if (fieldBindingInfo.getterName != null) { using (new PInvokeGuardCodeGen(cg, typeof(JSGetterCFunction))) { using (new BindingGetterFuncDeclareCodeGen(cg, fieldBindingInfo.getterName)) { using (new TryCatchGuradCodeGen(cg)) { using (new FieldGetterCodeGen(cg, fieldBindingInfo)) { } } } } } // 可写字段 if (fieldBindingInfo.setterName != null) { using (new PInvokeGuardCodeGen(cg, typeof(JSSetterCFunction))) { using (new BindingSetterFuncDeclareCodeGen(cg, fieldBindingInfo.setterName)) { using (new TryCatchGuradCodeGen(cg)) { using (new FieldSetterCodeGen(cg, fieldBindingInfo)) { } } } } } } // 所有事件 (当做field相似处理) foreach (var kv in this.typeBindingInfo.events) { var eventBindingInfo = kv.Value; using (new PInvokeGuardCodeGen(cg)) { using (new BindingFuncDeclareCodeGen(cg, eventBindingInfo.adderName)) { using (new TryCatchGuradCodeGen(cg)) { using (new EventAdderCodeGen(cg, eventBindingInfo)) { } } } } using (new PInvokeGuardCodeGen(cg)) { using (new BindingFuncDeclareCodeGen(cg, eventBindingInfo.removerName)) { using (new TryCatchGuradCodeGen(cg)) { using (new EventRemoverCodeGen(cg, eventBindingInfo)) { } } } } if (!eventBindingInfo.isStatic) { using (new PInvokeGuardCodeGen(cg)) { using (new BindingGetterFuncDeclareCodeGen(cg, eventBindingInfo.proxyName)) { using (new TryCatchGuradCodeGen(cg)) { using (new EventProxyCodeGen(cg, eventBindingInfo)) { } } } } } } }
public void AddMethod(MethodInfo methodInfo, bool isIndexer, string renameRegName) { if (this.transform != null) { if (this.transform.IsBlocked(methodInfo)) { bindingManager.Info("skip blocked method: {0}", methodInfo.Name); return; } } var isExtension = BindingManager.IsExtensionMethod(methodInfo); var isStatic = methodInfo.IsStatic && !isExtension; var methodName = TypeBindingInfo.GetNamingAttribute(methodInfo); if (IsSupportedOperators(methodInfo)) { var parameters = methodInfo.GetParameters(); var declaringType = methodInfo.DeclaringType; OperatorBindingInfo operatorBindingInfo = null; switch (methodName) { case "op_LessThan": if (parameters.Length == 2) { if (parameters[0].ParameterType == declaringType && parameters[1].ParameterType == declaringType) { operatorBindingInfo = new OperatorBindingInfo(methodInfo, isExtension, isStatic, methodName, "<", "<", 2); } } break; case "op_Addition": if (parameters.Length == 2) { if (parameters[0].ParameterType == declaringType && parameters[1].ParameterType == declaringType) { operatorBindingInfo = new OperatorBindingInfo(methodInfo, isExtension, isStatic, methodName, "+", "+", 2); } } break; case "op_Subtraction": if (parameters.Length == 2) { if (parameters[0].ParameterType == declaringType && parameters[1].ParameterType == declaringType) { operatorBindingInfo = new OperatorBindingInfo(methodInfo, isExtension, isStatic, methodName, "-", "-", 2); } } break; case "op_Equality": if (parameters.Length == 2) { if (parameters[0].ParameterType == declaringType && parameters[1].ParameterType == declaringType) { operatorBindingInfo = new OperatorBindingInfo(methodInfo, isExtension, isStatic, methodName, "==", "==", 2); } } break; case "op_Multiply": if (parameters.Length == 2) { var op0 = bindingManager.GetExportedType(parameters[0].ParameterType); var op1 = bindingManager.GetExportedType(parameters[1].ParameterType); if (op0 != null && op1 != null) { var bindingName = methodName + "_" + op0.name + "_" + op1.name; operatorBindingInfo = new OperatorBindingInfo(methodInfo, isExtension, isStatic, bindingName, "*", "*", 2); } } break; case "op_Division": if (parameters.Length == 2) { var op0 = bindingManager.GetExportedType(parameters[0].ParameterType); var op1 = bindingManager.GetExportedType(parameters[1].ParameterType); if (op0 != null && op1 != null) { var bindingName = methodName + "_" + op0.name + "_" + op1.name; operatorBindingInfo = new OperatorBindingInfo(methodInfo, isExtension, isStatic, bindingName, "/", "/", 2); } } break; case "op_UnaryNegation": { operatorBindingInfo = new OperatorBindingInfo(methodInfo, isExtension, isStatic, methodName, "neg", "-", 1); } break; } if (operatorBindingInfo != null) { operators.Add(operatorBindingInfo); CollectDelegate(methodInfo); bindingManager.Info("[AddOperator] {0}.{1}", type, methodInfo); return; } // fallback to normal method binding } var group = isStatic ? staticMethods : methods; MethodBindingInfo methodBindingInfo; if (!group.TryGetValue(methodName, out methodBindingInfo)) { methodBindingInfo = new MethodBindingInfo(isIndexer, isStatic, methodName, renameRegName ?? methodName); group.Add(methodName, methodBindingInfo); } if (!methodBindingInfo.Add(methodInfo, isExtension)) { bindingManager.Info("fail to add method: {0}", methodInfo.Name); return; } CollectDelegate(methodInfo); bindingManager.Info("[AddMethod] {0}.{1}", type, methodInfo); }