// 写入返回类型声明 protected virtual void WriteTSReturn(T method, List <ParameterInfo> returnParameters) { var returnType = GetReturnType(method); var outParametersCount = returnParameters.Count; if (returnType != null && returnType != typeof(void)) { if (outParametersCount != 0) { this.cg.tsDeclare.AppendL(": { "); var returnTypeTS = this.cg.bindingManager.GetTSReturnTypeFullName(returnType); var returnVarName = BindingManager.GetTSVariable("return"); this.cg.tsDeclare.AppendL($"\"{returnVarName}\": {returnTypeTS}"); for (var i = 0; i < outParametersCount; i++) { var rp = returnParameters[i]; var name = BindingManager.GetTSVariable(rp.Name); var ts = this.cg.bindingManager.GetTSTypeFullName(rp.ParameterType); if (i != outParametersCount - 1) { this.cg.tsDeclare.AppendL($", \"{name}\": {ts}"); } else { this.cg.tsDeclare.AppendL($", \"{name}\": {ts}"); } } this.cg.tsDeclare.AppendL(" }"); this.cg.tsDeclare.AppendLine(); } else { var returnTypeTS = this.cg.bindingManager.GetTSReturnTypeFullName(returnType); this.cg.tsDeclare.AppendL($": {returnTypeTS}"); this.cg.tsDeclare.AppendLine(); } } else { if (outParametersCount != 0) { this.cg.tsDeclare.AppendL(": { "); for (var i = 0; i < outParametersCount; i++) { var rp = returnParameters[i]; var name = rp.Name; var ts = this.cg.bindingManager.GetTSTypeFullName(rp.ParameterType); if (i != outParametersCount - 1) { this.cg.tsDeclare.AppendL($"\"{name}\": {ts}, "); } else { this.cg.tsDeclare.AppendL($"\"{name}\": {ts}"); } } this.cg.tsDeclare.AppendL(" }"); this.cg.tsDeclare.AppendLine(); } else { if (method.IsConstructor) { this.cg.tsDeclare.AppendLine(); } else { this.cg.tsDeclare.AppendL(": void"); this.cg.tsDeclare.AppendLine(); } } } }
protected List <ParameterInfo> WriteTSDeclaration(TypeBindingInfo typeBindingInfo, T method, MethodBaseBindingInfo <T> bindingInfo, bool isExtension) { var refParameters = new List <ParameterInfo>(); string tsMethodDeclaration; this.cg.AppendJSDoc(method); if (typeBindingInfo.transform.GetTSMethodDeclaration(method, out tsMethodDeclaration) || this.cg.bindingManager.GetTSMethodDeclaration(method, out tsMethodDeclaration)) { this.cg.tsDeclare.AppendLine(tsMethodDeclaration); return(refParameters); } string tsMethodRename; if (!this.cg.bindingManager.GetTSMethodRename(method, out tsMethodRename)) { tsMethodRename = bindingInfo.jsName; } var isRaw = method.IsDefined(typeof(JSCFunctionAttribute)); //TODO: 需要处理参数类型归并问题, 因为如果类型没有导入 ts 中, 可能会在声明中出现相同参数列表的定义 // 在 MethodVariant 中创建每个方法对应的TS类型名参数列表, 完全相同的不再输出 var prefix = ""; // if (method.Name.StartsWith("op_")) if (bindingInfo is OperatorBindingInfo) { prefix += "// js_op_overloading: "; } else { // var baseType = typeBindingInfo.type.BaseType; // if (baseType != null) // { // //TODO: 需要检查 TypeBindingInfo 对此的命名修改 // if (baseType.GetMethods().Where(baseMethodInfo => baseMethodInfo.Name == tsMethodRename).Count() != 0) // { // prefix += "// @ts-ignore" + this.cg.tsDeclare.newline + this.cg.tsDeclare.tabString; // } // } } if (method.IsStatic && !isExtension) { prefix += "static "; } this.cg.tsDeclare.Append($"{prefix}{tsMethodRename}("); if (isRaw) { this.cg.tsDeclare.AppendL("...uncertain: any[]): any /* uncertain */"); this.cg.tsDeclare.AppendLine(); } else { var parameters = method.GetParameters(); if (isExtension) { ArrayUtility.RemoveAt(ref parameters, 0); } for (int i = 0, len = parameters.Length; i < len;) { var parameter = parameters[i]; var parameterType = parameter.ParameterType; if (parameterType == typeof(Native.JSContext) || parameterType == typeof(Native.JSRuntime)) { // 剔除 JSContext, JSRuntime ArrayUtility.RemoveAt(ref parameters, i); len--; } else if (parameterType == typeof(ScriptContext) || parameterType == typeof(ScriptRuntime)) { // 剔除 ScriptContext, ScriptRuntime ArrayUtility.RemoveAt(ref parameters, i); len--; } // else if (parameter.IsOut) // { // ArrayUtility.RemoveAt(ref parameters, i); // len--; // refParameters.Add(parameter); // } else { // if (parameterType.IsByRef) // { // refParameters.Add(parameter); // } i++; } } for (int i = 0, len = parameters.Length; i < len; i++) { var parameter = parameters[i]; var parameter_prefix = ""; var parameterType = parameter.ParameterType; if (parameter.IsDefined(typeof(ParamArrayAttribute), false) && i == parameters.Length - 1) { var elementType = parameterType.GetElementType(); var elementTS = this.cg.bindingManager.GetTSTypeFullName(elementType); var parameterVarName = BindingManager.GetTSVariable(parameter); this.cg.tsDeclare.AppendL($"{parameter_prefix}...{parameterVarName}: {elementTS}[]"); } else { var parameterTS = this.cg.bindingManager.GetTSTypeFullName(parameter); var parameterVarName = BindingManager.GetTSVariable(parameter); this.cg.tsDeclare.AppendL($"{parameter_prefix}{parameterVarName}: {parameterTS}"); } if (i != parameters.Length - 1) { this.cg.tsDeclare.AppendL(", "); } } this.cg.tsDeclare.AppendL($")"); WriteTSReturn(method, refParameters); } return(refParameters); }
public override void Dispose() { using (new RegFuncCodeGen(cg)) { using (new RegFuncNamespaceCodeGen(cg, typeBindingInfo)) { var constructor = typeBindingInfo.constructors.available ? typeBindingInfo.constructors.csBindName : "JSApi.class_private_ctor"; if (!typeBindingInfo.constructors.available && !typeBindingInfo.type.IsAbstract) { if (typeBindingInfo.type.IsSubclassOf(typeof(Component))) { // 因为 ts 泛型约束需要 new() 形式, 所以在定义中产生一个 public 定义 // 例如: GetComponent<T extends Component>(type: { new(): T }): T cg.tsDeclare.AppendLine("/*protected*/ constructor()"); } else { if (!typeBindingInfo.type.IsGenericTypeDefinition) { cg.tsDeclare.AppendLine("protected constructor()"); } } } cg.cs.AppendLine("var cls = ns.CreateClass(\"{0}\", typeof({1}), {2});", typeBindingInfo.jsName, this.cg.bindingManager.GetCSTypeFullName(typeBindingInfo.type), constructor); // 运算符 foreach (var operatorBindingInfo in typeBindingInfo.operators) { var regName = operatorBindingInfo.jsName; var funcName = operatorBindingInfo.csBindName; var parameters = operatorBindingInfo.methodInfo.GetParameters(); var declaringType = operatorBindingInfo.methodInfo.DeclaringType; string redirect; if (this.typeBindingInfo.transform != null && this.typeBindingInfo.transform.TryRedirectMethod(regName, out redirect)) { funcName = redirect; } do { if (parameters.Length == 2) { if (parameters[0].ParameterType != declaringType) { var leftType = typeBindingInfo.bindingManager.GetCSTypeFullName(parameters[0].ParameterType); cg.cs.AppendLine("cls.AddLeftOperator(\"{0}\", {1}, {2}, typeof({3}));", regName, funcName, operatorBindingInfo.length, leftType); break; } else if (parameters[1].ParameterType != declaringType) { var rightType = typeBindingInfo.bindingManager.GetCSTypeFullName(parameters[1].ParameterType); cg.cs.AppendLine("cls.AddRightOperator(\"{0}\", {1}, {2}, typeof({3}));", regName, funcName, operatorBindingInfo.length, rightType); break; } } cg.cs.AppendLine("cls.AddSelfOperator(\"{0}\", {1}, {2});", regName, funcName, operatorBindingInfo.length); } while (false); } // 非静态方法 foreach (var kv in typeBindingInfo.methods) { var regName = kv.Value.jsName; var funcName = kv.Value.csBindName; string redirect; if (this.typeBindingInfo.transform != null && this.typeBindingInfo.transform.TryRedirectMethod(regName, out redirect)) { funcName = redirect; } cg.cs.AppendLine("cls.AddMethod(false, \"{0}\", {1});", regName, funcName); } // 静态方法 foreach (var kv in typeBindingInfo.staticMethods) { var methodBindingInfo = kv.Value; var regName = methodBindingInfo.jsName; if (methodBindingInfo._cfunc != null) { var attr = (JSCFunctionAttribute)methodBindingInfo._cfunc.GetCustomAttribute(typeof(JSCFunctionAttribute)); var methodDeclType = this.cg.bindingManager.GetCSTypeFullName(methodBindingInfo._cfunc.DeclaringType); var isStatic = attr.isStatic ? "true" : "false"; cg.cs.AppendLine("cls.AddRawMethod({0}, \"{1}\", {2}.{3});", isStatic, regName, methodDeclType, methodBindingInfo._cfunc.Name); if (attr.difinitions != null) { foreach (var defEntry in attr.difinitions) { string tsMethodRename; var prefix = attr.isStatic ? "static " : ""; // 附带的签名没有带命名时, 自动加上 if (defEntry.StartsWith("(") || defEntry.StartsWith("<")) { if (this.cg.bindingManager.GetTSMethodRename(methodBindingInfo._cfunc, out tsMethodRename)) { this.cg.tsDeclare.AppendLine($"{prefix}{tsMethodRename}{defEntry}"); } else { this.cg.tsDeclare.AppendLine($"{prefix}{regName}{defEntry}"); } } else { this.cg.tsDeclare.AppendLine($"{prefix}{defEntry}"); } } } else { this.cg.tsDeclare.AppendLine("(...uncertain: any[]): any /* uncertain */"); } } else { var funcName = methodBindingInfo.csBindName; string redirect; if (this.typeBindingInfo.transform != null && this.typeBindingInfo.transform.TryRedirectMethod(regName, out redirect)) { funcName = redirect; } cg.cs.AppendLine("cls.AddMethod(true, \"{0}\", {1});", regName, funcName); } } // 属性 foreach (var kv in typeBindingInfo.properties) { var bindingInfo = kv.Value; if (bindingInfo.staticPair.IsValid()) { var tsPropertyVar = BindingManager.GetTSVariable(bindingInfo.regName); cg.cs.AppendLine("cls.AddProperty(true, \"{0}\", {1}, {2});", tsPropertyVar, bindingInfo.staticPair.getterName != null ? bindingInfo.staticPair.getterName : "null", bindingInfo.staticPair.setterName != null ? bindingInfo.staticPair.setterName : "null"); var tsPropertyPrefix = "static "; if (bindingInfo.staticPair.setterName == null) { tsPropertyPrefix += "readonly "; } var tsPropertyType = this.cg.bindingManager.GetTSTypeFullName(bindingInfo.propertyInfo.PropertyType); cg.AppendJSDoc(bindingInfo.propertyInfo); cg.tsDeclare.AppendLine($"{tsPropertyPrefix}{tsPropertyVar}: {tsPropertyType}"); } if (bindingInfo.instancePair.IsValid()) { var tsPropertyVar = BindingManager.GetTSVariable(bindingInfo.regName); cg.cs.AppendLine("cls.AddProperty(false, \"{0}\", {1}, {2});", tsPropertyVar, bindingInfo.instancePair.getterName != null ? bindingInfo.instancePair.getterName : "null", bindingInfo.instancePair.setterName != null ? bindingInfo.instancePair.setterName : "null"); var tsPropertyPrefix = ""; if (bindingInfo.instancePair.setterName == null) { tsPropertyPrefix += "readonly "; } var tsPropertyType = this.cg.bindingManager.GetTSTypeFullName(bindingInfo.propertyInfo.PropertyType); cg.AppendJSDoc(bindingInfo.propertyInfo); cg.tsDeclare.AppendLine($"{tsPropertyPrefix}{tsPropertyVar}: {tsPropertyType}"); } } foreach (var kv in typeBindingInfo.fields) { var bindingInfo = kv.Value; var bStatic = bindingInfo.isStatic; var tsFieldVar = BindingManager.GetTSVariable(bindingInfo.regName); if (bindingInfo.constantValue != null) { var cv = bindingInfo.constantValue; cg.cs.AppendLine($"cls.AddConstValue(\"{tsFieldVar}\", {cv});"); } else { cg.cs.AppendLine("cls.AddField({0}, \"{1}\", {2}, {3});", bStatic ? "true" : "false", tsFieldVar, bindingInfo.getterName != null ? bindingInfo.getterName : "null", bindingInfo.setterName != null ? bindingInfo.setterName : "null"); } var tsFieldPrefix = bStatic ? "static " : ""; if (bindingInfo.setterName == null) { tsFieldPrefix += "readonly "; } var tsFieldType = this.cg.bindingManager.GetTSTypeFullName(bindingInfo.fieldInfo.FieldType); cg.AppendJSDoc(bindingInfo.fieldInfo); cg.tsDeclare.AppendLine($"{tsFieldPrefix}{tsFieldVar}: {tsFieldType}"); } foreach (var kv in typeBindingInfo.events) { var eventBindingInfo = kv.Value; var bStatic = eventBindingInfo.isStatic; var tsFieldVar = BindingManager.GetTSVariable(eventBindingInfo.regName); var tsFieldType = this.cg.bindingManager.GetTSTypeFullName(eventBindingInfo.eventInfo.EventHandlerType); var tsFieldPrefix = ""; if (bStatic) { tsFieldPrefix += "static "; cg.cs.AppendLine($"cls.AddMethod(true, \"{tsFieldVar}\", {eventBindingInfo.name});"); } else { cg.cs.AppendLine($"cls.AddMethod(false, \"{tsFieldVar}\", {eventBindingInfo.name});"); } // tsFieldPrefix += "readonly "; // cg.tsDeclare.AppendLine($"{tsFieldPrefix}{tsFieldVar}: jsb.event<{tsFieldType}>"); cg.tsDeclare.AppendLine($"{tsFieldPrefix}{tsFieldVar}(op: \"add\" | \"remove\", fn: {tsFieldType}): void"); } foreach (var kv in typeBindingInfo.delegates) { var delegateBindingInfo = kv.Value; var bStatic = delegateBindingInfo.isStatic; var tsFieldVar = BindingManager.GetTSVariable(delegateBindingInfo.regName); var tsFieldType = this.cg.bindingManager.GetTSTypeFullName(delegateBindingInfo.delegateType); var tsFieldPrefix = ""; if (bStatic) { tsFieldPrefix += "static "; cg.cs.AppendLine($"cls.AddMethod(true, \"{tsFieldVar}\", {delegateBindingInfo.name});"); } else { cg.cs.AppendLine($"cls.AddMethod(false, \"{tsFieldVar}\", {delegateBindingInfo.name});"); } // tsFieldPrefix += "readonly "; // cg.tsDeclare.AppendLine($"{tsFieldPrefix}{tsFieldVar}: jsb.event<{tsFieldType}>"); if (delegateBindingInfo.readable) { if (delegateBindingInfo.writable) { cg.tsDeclare.AppendLine($"{tsFieldPrefix}{tsFieldVar}(op: \"get\"): {tsFieldType}"); cg.tsDeclare.AppendLine($"{tsFieldPrefix}{tsFieldVar}(op: \"add\" | \"remove\" | \"set\", fn?: {tsFieldType}): void"); cg.tsDeclare.AppendLine($"{tsFieldPrefix}{tsFieldVar}(op: \"add\" | \"remove\" | \"set\" | \"get\", fn?: {tsFieldType}): {tsFieldType} | void"); } else { cg.tsDeclare.AppendLine($"{tsFieldPrefix}{tsFieldVar}(op: \"get\"): {tsFieldType}"); } } else { cg.tsDeclare.AppendLine($"{tsFieldPrefix}{tsFieldVar}(op: \"set\", fn: {tsFieldType})"); } } cg.cs.AppendLine("cls.Close();"); } } base.Dispose(); this.cg.tsDeclare.DecTabLevel(); this.cg.tsDeclare.AppendLine("}"); }