Exemplo n.º 1
0
        public void EmitMethodDefinition(
            DecompilerContext context, MethodReference methodRef, MethodDefinition method,
            IAstEmitter astEmitter, bool stubbed,
            JSRawOutputIdentifier dollar, MethodInfo methodInfo = null
            )
        {
            if (methodInfo == null)
            {
                methodInfo = _TypeInfoProvider.GetMemberInformation <Internal.MethodInfo>(method);
            }

            bool isExternal, isReplaced, methodIsProxied;

            if (!Translator.ShouldTranslateMethodBody(
                    method, methodInfo, stubbed,
                    out isExternal, out isReplaced, out methodIsProxied
                    ))
            {
                return;
            }

            JSFunctionExpression function = Translator.GetFunctionBodyForMethod(
                isExternal, methodInfo
                );

            astEmitter.ReferenceContext.EnclosingType   = method.DeclaringType;
            astEmitter.ReferenceContext.EnclosingMethod = null;

            Formatter.NewLine();

            astEmitter.ReferenceContext.Push();
            astEmitter.ReferenceContext.DefiningMethod = methodRef;

            try {
                dollar.WriteTo(Formatter);
                Formatter.Dot();
                if (methodInfo.IsPInvoke)
                {
                    // FIXME: Write out dll name from DllImport
                    // FIXME: Write out alternate method name if provided
                    Formatter.Identifier("PInvokeMethod", EscapingMode.None);
                }
                else if (isExternal && !Configuration.GenerateSkeletonsForStubbedAssemblies.GetValueOrDefault(false))
                {
                    Formatter.Identifier("ExternalMethod", EscapingMode.None);
                }
                else
                {
                    Formatter.Identifier("Method", EscapingMode.None);
                }
                Formatter.LPar();

                // FIXME: Include IsVirtual?
                Formatter.MemberDescriptor(method.IsPublic, method.IsStatic, method.IsVirtual, false);

                Formatter.Comma();
                Formatter.Value(Util.EscapeIdentifier(methodInfo.GetName(true), EscapingMode.String));

                Formatter.Comma();
                Formatter.NewLine();

                Formatter.MethodSignature(methodRef, methodInfo.Signature, astEmitter.ReferenceContext);

                if (methodInfo.IsPInvoke && method.HasPInvokeInfo)
                {
                    Formatter.Comma();
                    Formatter.NewLine();
                    EmitPInvokeInfo(
                        methodRef, method, astEmitter
                        );
                }
                else if (!isExternal)
                {
                    Formatter.Comma();
                    Formatter.NewLine();

                    if (function != null)
                    {
                        Formatter.WriteRaw(Util.EscapeIdentifier(function.DisplayName));
                    }
                    else
                    {
                        Formatter.Identifier("JSIL.UntranslatableFunction", EscapingMode.None);
                        Formatter.LPar();
                        Formatter.Value(method.FullName);
                        Formatter.RPar();
                    }
                }

                Formatter.NewLine();
                Formatter.RPar();

                astEmitter.ReferenceContext.AttributesMethod = methodRef;

                EmitOverrides(context, methodInfo.DeclaringType, method, methodInfo, astEmitter);

                EmitCustomAttributes(context, method.DeclaringType, method, astEmitter);

                EmitParameterAttributes(context, method.DeclaringType, method, astEmitter);

                Formatter.Semicolon();
            } finally {
                astEmitter.ReferenceContext.Pop();
            }
        }