コード例 #1
0
        // 写入返回类型声明
        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();
                    }
                }
            }
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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("}");
        }