Beispiel #1
0
        // 生成类型绑定
        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);
            }
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
 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(");");
 }
Beispiel #4
0
 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))
                     {
                     }
                 }
             }
         }
     }
 }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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;
        }
Beispiel #7
0
 public virtual void OnPostGenerateType(BindingManager bindingManager, TypeBindingInfo bindingInfo)
 {
 }
Beispiel #8
0
        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))
                                {
                                }
                            }
                        }
                    }
                }
            }
        }
Beispiel #9
0
        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);
        }