// 写入绑定代码 protected void WriteCSMethodBinding(MethodBaseBindingInfo <T> bindingInfo, T method, string argc, bool isVararg) { // 是否接管 cs 绑定代码生成 var transform = cg.bindingManager.GetTypeTransform(method.DeclaringType); if (transform != null && transform.OnBinding(BindingPoints.METHOD_BINDING_FULL, method, cg)) { return; } var isExtension = BindingManager.IsExtensionMethod(method); // var isRaw = method.IsDefined(typeof(JSCFunctionAttribute)); var parameters = method.GetParameters(); var in_params = new List <ParameterInfo>(); var out_params = new List <ParameterInfo>(); SplitParamters(parameters, isExtension ? 1 : 0, in_params, out_params); var caller = this.cg.AppendGetThisCS(method); var returnType = GetReturnType(method); // if (isRaw) // { // do // { // if (!isExtension) // { // if (returnType == typeof(int) && in_params.Count == 1) // { // var p = in_params[0]; // if (p.ParameterType == typeof(IntPtr) && !p.IsOut) // { // cg.cs.AppendLine($"return {caller}.{method.Name}(ctx);"); // return; // } // } // cg.bindingManager.Error($"invalid JSCFunction definition: {method}"); // break; // } // cg.bindingManager.Error($"Extension as JSCFunction is not supported: {method}"); // } while (false); // } if (returnType == null || returnType == typeof(void)) { // 方法本身没有返回值 this.BeginInvokeBinding(); cg.cs.AppendLine($"{this.GetInvokeBinding(caller, method, isVararg, isExtension, argc, parameters)};"); this.EndInvokeBinding(); var backVars = out_params.Count > 0 ? _WriteBackParametersByRef(isExtension, out_params, null) : null; if (!method.IsStatic && method.DeclaringType.IsValueType) // struct 非静态方法 检查 Mutable 属性 { if (!string.IsNullOrEmpty(caller)) { cg.cs.AppendLine($"js_rebind_this(ctx, this_obj, {caller});"); } } if (string.IsNullOrEmpty(backVars)) { this.InvokeVoidReturn(); } else { cg.cs.AppendLine("return {0};", backVars); } } else { var retVar = "ret"; // cs return value var name var retJsVar = "ret_js"; this.BeginInvokeBinding(); cg.cs.AppendLine($"var {retVar} = {this.GetInvokeBinding(caller, method, isVararg, isExtension, argc, parameters)};"); this.EndInvokeBinding(); var retPusher = cg.AppendMethodReturnValuePusher(method, returnType, retVar); cg.cs.AppendLine("var {0} = {1};", retJsVar, retPusher); cg.cs.AppendLine("if (JSApi.JS_IsException({0}))", retJsVar); using (cg.cs.Block()) { cg.cs.AppendLine("return {0};", retJsVar); } var backVars = out_params.Count > 0 ? _WriteBackParametersByRef(isExtension, out_params, retJsVar) : retJsVar; cg.cs.AppendLine("return {0};", backVars); } }
// 写入绑定代码 protected void WriteCSMethodBinding(MethodBaseBindingInfo <T> bindingInfo, T method, string argc, bool isVararg) { // 是否接管 cs 绑定代码生成 var transform = cg.bindingManager.GetTypeTransform(method.DeclaringType); if (transform != null && transform.OnBinding(BindingPoints.METHOD_BINDING_FULL, method, cg)) { return; } var parameters = method.GetParameters(); var isExtension = method.IsDefined(typeof(System.Runtime.CompilerServices.ExtensionAttribute)); var isRaw = method.IsDefined(typeof(JSCFunctionAttribute)); if (isExtension) { ArrayUtility.RemoveAt(ref parameters, 0); } var parametersByRef = new List <ParameterInfo>(); var caller = this.cg.AppendGetThisCS(method); var returnType = GetReturnType(method); if (isRaw) { do { if (!isExtension) { if (returnType == typeof(int) && parameters.Length == 1) { var p = parameters[0]; if (p.ParameterType == typeof(IntPtr) && !p.IsOut) { cg.cs.AppendLine($"return {caller}.{method.Name}(ctx);"); return; } } cg.bindingManager.Error($"invalid JSCFunction definition: {method}"); break; } cg.bindingManager.Error($"Extension as JSCFunction is not supported: {method}"); } while (false); } if (returnType == null || returnType == typeof(void)) { // 方法本身没有返回值 this.BeginInvokeBinding(); cg.cs.AppendLine($"{this.GetInvokeBinding(caller, method, isVararg, isExtension, argc, parameters, parametersByRef)};"); this.EndInvokeBinding(); if (parametersByRef.Count > 0) { _WriteBackParametersByRef(isExtension, parametersByRef); } if (!method.IsStatic && method.DeclaringType.IsValueType) // struct 非静态方法 检查 Mutable 属性 { if (!string.IsNullOrEmpty(caller)) { cg.cs.AppendLine($"js_rebind_this(ctx, this_obj, {caller});"); } } this.InvokeVoidReturn(); } else { this.BeginInvokeBinding(); cg.cs.AppendLine($"var ret = {this.GetInvokeBinding(caller, method, isVararg, isExtension, argc, parameters, parametersByRef)};"); this.EndInvokeBinding(); if (parametersByRef.Count > 0) { _WriteBackParametersByRef(isExtension, parametersByRef); } var pusher = cg.AppendMethodReturnValuePusher(method, returnType, "ret"); cg.cs.AppendLine("return {0};", pusher); } }