예제 #1
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 ";
            }
            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))
                {
                    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 BindingFuncDeclareCodeGen(cg, eventBindingInfo.proxyName))
                        {
                            using (new TryCatchGuradCodeGen(cg))
                            {
                                using (new EventProxyCodeGen(cg, eventBindingInfo))
                                {
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #2
0
        public DelegateCodeGen(CodeGenerator cg, DelegateBindingInfo delegateBindingInfo, int index)
        {
            this.cg = cg;
            var nargs          = delegateBindingInfo.parameters.Length;
            var retName        = this.cg.bindingManager.GetUniqueName(delegateBindingInfo.parameters, "ret");
            var firstArgument  = typeof(ScriptDelegate) + " fn";
            var returnTypeName = this.cg.bindingManager.GetCSTypeFullName(delegateBindingInfo.returnType);
            var delegateName   = CodeGenerator.NameOfDelegates + index;
            var arglist        = this.cg.bindingManager.GetCSArglistDecl(delegateBindingInfo.parameters);

            foreach (var target in delegateBindingInfo.types)
            {
                this.cg.cs.AppendLine("[{0}(typeof({1}))]",
                                      this.cg.bindingManager.GetCSTypeFullName(typeof(JSDelegateAttribute)),
                                      this.cg.bindingManager.GetCSTypeFullName(target));
                this.cg.bindingManager.log.AppendLine("emitting delegate decl: {0}", target);
            }
            if (!string.IsNullOrEmpty(arglist))
            {
                arglist = ", " + arglist;
            }
            this.cg.cs.AppendLine($"public static unsafe {returnTypeName} {delegateName}({firstArgument}{arglist}) {{");
            this.cg.cs.AddTabLevel();
            this.cg.cs.AppendLine("var ctx = fn.ctx;");

            if (nargs > 0)
            {
                this.cg.cs.AppendLine("var argv = stackalloc JSValue[{0}];", nargs);
                for (var i = 0; i < nargs; i++)
                {
                    var parameter = delegateBindingInfo.parameters[i];
                    var pusher    = this.cg.AppendValuePusher(parameter.ParameterType, parameter.Name);
                    this.cg.cs.AppendLine("argv[{0}] = {1};", i, pusher);
                    this.cg.cs.AppendLine("if (argv[{0}].IsException())", i);
                    this.cg.cs.AppendLine("{");
                    this.cg.cs.AddTabLevel();
                    for (var j = 0; j < i; j++)
                    {
                        this.cg.cs.AppendLine("JSApi.JS_FreeValue(ctx, argv[{0}]);", j);
                    }

                    this.cg.cs.AppendLine("throw new Exception(ctx.GetExceptionString());");
                    this.cg.cs.DecTabLevel();
                    this.cg.cs.AppendLine("}");
                }
                this.cg.cs.AppendLine("var rval = fn.Invoke(ctx, {0}, argv);", nargs);
            }
            else
            {
                this.cg.cs.AppendLine("var rval = fn.Invoke(ctx);");
            }

            if (delegateBindingInfo.returnType != typeof(void))
            {
                this.cg.cs.AppendLine($"{this.cg.bindingManager.GetCSTypeFullName(delegateBindingInfo.returnType)} {retName};");
                var getter = this.cg.bindingManager.GetScriptObjectGetter(delegateBindingInfo.returnType, "ctx", "rval", retName);
                this.cg.cs.AppendLine("var succ = {0};", getter);

                FreeArgs(nargs);
                CheckReturnValue();

                this.cg.cs.AppendLine("if (succ)");
                this.cg.cs.AppendLine("{");
                this.cg.cs.AddTabLevel();
                this.cg.cs.AppendLine($"return {retName};");
                this.cg.cs.DecTabLevel();
                this.cg.cs.AppendLine("}");
                this.cg.cs.AppendLine("else");
                this.cg.cs.AppendLine("{");
                this.cg.cs.AddTabLevel();
                this.cg.cs.AppendLine($"throw new Exception(\"js exception caught\");");
                this.cg.cs.DecTabLevel();
                this.cg.cs.AppendLine("}");
            }
            else
            {
                FreeArgs(nargs);
                CheckReturnValue();
            }
        }