Exemplo n.º 1
0
        protected void TranslateMethod(
            DecompilerContext context, JavascriptFormatter output, 
            MethodReference methodRef, MethodDefinition method, 
            bool stubbed, 
            HashSet<string> externalMemberNames,
            HashSet<string> staticExternalMemberNames,
            Action<JSFunctionExpression> bodyTransformer = null
        )
        {
            var methodInfo = TypeInfoProvider.GetMemberInformation<Internal.MethodInfo>(method);
            if (methodInfo == null)
                return;

            bool isReplaced = methodInfo.Metadata.HasAttribute("JSIL.Meta.JSReplacement");
            bool methodIsProxied = (methodInfo.IsFromProxy && methodInfo.Member.HasBody) &&
                !methodInfo.IsExternal && !isReplaced;

            if (methodInfo.IsExternal || (stubbed && !methodIsProxied)) {
                if (isReplaced)
                    return;

                if (externalMemberNames == null)
                    throw new ArgumentNullException("externalMemberNames");
                if (staticExternalMemberNames == null)
                    throw new ArgumentNullException("staticExternalMemberNames");

                var isProperty = methodInfo.DeclaringProperty != null;

                if (!isProperty || !methodInfo.Member.IsCompilerGenerated()) {
                    (method.IsStatic ? staticExternalMemberNames : externalMemberNames)
                        .Add(Util.EscapeIdentifier(methodInfo.GetName(true)));

                    return;
                }
            }

            if (methodInfo.IsIgnored)
                return;
            if (!method.HasBody)
                return;

            if (methodIsProxied) {
                output.Comment("Implementation from {0}", methodInfo.Member.DeclaringType.FullName);
                output.NewLine();
            }

            output.Identifier(method.DeclaringType);
            if (!method.IsStatic) {
                output.Dot();
                output.Keyword("prototype");
            }
            output.Dot();

            output.Identifier(methodInfo.GetName(true));

            output.Token(" = ");

            if (method.HasGenericParameters) {
                output.Identifier("JSIL.GenericMethod", null);
                output.LPar();
                output.NewLine();
                output.OpenBracket();

                output.CommaSeparatedList((from p in method.GenericParameters select p.Name), ListValueType.Primitive);

                output.CloseBracket();
                output.Comma();
                output.NewLine();
            }

            JSFunctionExpression function;
            function = FunctionCache.GetExpression(new QualifiedMemberIdentifier(
                methodInfo.DeclaringType.Identifier,
                methodInfo.Identifier
            ));

            if (bodyTransformer != null)
                bodyTransformer(function);

            if (function != null) {
                AstEmitter.Visit(function);
            } else {
                output.Identifier("JSIL.UntranslatableFunction", null);
                output.LPar();
                output.Value(method.FullName);
                output.RPar();
            }

            if (method.HasGenericParameters) {
                output.NewLine();
                output.RPar();
            }

            output.Semicolon();
        }
Exemplo n.º 2
0
        protected void TranslateEnum(DecompilerContext context, JavascriptFormatter output, TypeDefinition enm)
        {
            output.Identifier("JSIL.MakeEnum", null);
            output.LPar();
            output.NewLine();

            output.Value(Util.EscapeIdentifier(enm.FullName, EscapingMode.String));
            output.Comma();
            output.OpenBrace();

            var typeInformation = TypeInfoProvider.GetTypeInformation(enm);
            if (typeInformation == null)
                throw new InvalidOperationException();

            bool isFirst = true;
            foreach (var em in typeInformation.EnumMembers.Values) {
                if (!isFirst) {
                    output.Comma();
                    output.NewLine();
                }

                output.Identifier(em.Name);
                output.Token(": ");
                output.Value(em.Value);

                isFirst = false;
            }

            output.NewLine();
            output.CloseBrace(false);
            output.Comma();
            output.Value(typeInformation.IsFlagsEnum);
            output.NewLine();

            output.RPar();
            output.Semicolon();
            output.NewLine();
        }
Exemplo n.º 3
0
        protected void TranslateInterface(DecompilerContext context, JavascriptFormatter output, TypeDefinition iface)
        {
            output.Identifier("JSIL.MakeInterface", null);
            output.LPar();
            output.NewLine();

            output.Value(Util.EscapeIdentifier(iface.FullName, EscapingMode.String));
            output.Comma();

            output.OpenBracket();
            output.CommaSeparatedList(
                (from p in iface.GenericParameters select p.Name), ListValueType.Primitive
            );
            output.CloseBracket();
            output.Comma();

            output.OpenBrace();

            bool isFirst = true;
            foreach (var m in iface.Methods) {
                var methodInfo = TypeInfoProvider.GetMethod(m);
                if ((methodInfo != null) && methodInfo.IsIgnored)
                    continue;

                if (!isFirst) {
                    output.Comma();
                    output.NewLine();
                }

                output.Value(Util.EscapeIdentifier(m.Name));
                output.Token(": ");
                output.Identifier("Function");

                isFirst = false;
            }

            foreach (var p in iface.Properties) {
                var propertyInfo = TypeInfoProvider.GetProperty(p);
                if ((propertyInfo != null) && propertyInfo.IsIgnored)
                    continue;

                if (!isFirst) {
                    output.Comma();
                    output.NewLine();
                }

                output.Value(Util.EscapeIdentifier(p.Name));
                output.Token(": ");
                output.Identifier("Property");

                isFirst = false;
            }

            output.NewLine();
            output.CloseBrace(false);

            output.RPar();
            output.Semicolon();
            output.NewLine();
        }
Exemplo n.º 4
0
        protected void TranslateTypeDefinition(DecompilerContext context, JavascriptFormatter output, TypeDefinition typedef, List<Action> initializer, bool stubbed)
        {
            var typeInfo = TypeInfoProvider.GetTypeInformation(typedef);
            if (!ShouldTranslateMethods(typedef))
                return;

            context.CurrentType = typedef;

            var externalMemberNames = new HashSet<string>();
            var staticExternalMemberNames = new HashSet<string>();

            foreach (var method in typedef.Methods) {
                // We translate the static constructor explicitly later, and inject field initialization
                if (method.Name == ".cctor")
                    continue;

                TranslateMethod(
                    context, output, method, method,
                    stubbed, externalMemberNames, staticExternalMemberNames
                );
            }

            Action initializeOverloadsAndProperties = () => {
                foreach (var methodGroup in typeInfo.MethodGroups)
                    TranslateMethodGroup(context, output, methodGroup);

                foreach (var property in typedef.Properties)
                    TranslateProperty(context, output, property);
            };

            if (!stubbed)
                initializeOverloadsAndProperties();

            Func<TypeReference, bool> isInterfaceIgnored = (i) => {
                var interfaceInfo = TypeInfoProvider.GetTypeInformation(i);
                if (interfaceInfo != null)
                    return interfaceInfo.IsIgnored;
                else
                    return true;
            };

            var interfaces = (from i in typeInfo.Interfaces
                              where !i.IsIgnored
                              select i).ToArray();

            if (interfaces.Length > 0) {
                initializer.Add(() => {
                    output.Identifier("JSIL.ImplementInterfaces", null);
                    output.LPar();
                    output.Identifier(typedef);
                    output.Comma();
                    output.OpenBracket(true);
                    output.CommaSeparatedList(interfaces, ListValueType.TypeReference);
                    output.CloseBracket(true, () => {
                        output.RPar();
                        output.Semicolon();
                    });
                });
            }

            Func<FieldDefinition, bool> isFieldIgnored = (f) => {
                IMemberInfo memberInfo;
                if (typeInfo.Members.TryGetValue(MemberIdentifier.New(f), out memberInfo))
                    return memberInfo.IsIgnored;
                else
                    return true;
            };

            var structFields =
                (from field in typedef.Fields
                where !isFieldIgnored(field) &&
                    !field.HasConstant &&
                    EmulateStructAssignment.IsStruct(field.FieldType) &&
                    !field.IsStatic
                select field).ToArray();

            if (structFields.Length > 0) {
                initializer.Add(() => {
                    output.Identifier(typedef);
                    output.Dot();
                    output.Identifier("prototype");
                    output.Dot();
                    output.Identifier("__StructFields__");
                    output.Token(" = ");
                    output.OpenBracket(true);

                    bool isFirst = true;
                    foreach (var sf in structFields) {
                        if (!isFirst) {
                            output.Comma();
                            output.NewLine();
                        }

                        output.OpenBracket();
                        output.Value(sf.Name);
                        output.Comma();
                        output.Identifier(sf.FieldType);
                        output.CloseBracket();

                        isFirst = false;
                    }

                    output.CloseBracket(true, output.Semicolon);
                });
            }

            TranslateTypeStaticConstructor(context, output, typedef, typeInfo.StaticConstructor, stubbed);

            if (externalMemberNames.Count + staticExternalMemberNames.Count > 0) {
                initializer.Add(() => {
                    if (externalMemberNames.Count > 0) {
                        output.Identifier("JSIL.ExternalMembers", null);
                        output.LPar();
                        output.Identifier(typedef);
                        output.Dot();
                        output.Keyword("prototype");
                        output.Comma();
                        output.NewLine();

                        output.CommaSeparatedList(externalMemberNames, ListValueType.Primitive);
                        output.NewLine();

                        output.RPar();
                        output.Semicolon();
                    }

                    if (staticExternalMemberNames.Count > 0) {
                        output.Identifier("JSIL.ExternalMembers", null);
                        output.LPar();
                        output.Identifier(typedef);
                        output.Comma();
                        output.NewLine();

                        output.CommaSeparatedList(staticExternalMemberNames, ListValueType.Primitive);
                        output.NewLine();

                        output.RPar();
                        output.Semicolon();
                    }
                });
            }

            if (stubbed &&
                (typeInfo.MethodGroups.Count + typedef.Properties.Count) > 0
            ) {
                initializer.Add(initializeOverloadsAndProperties);
            }

            output.NewLine();

            foreach (var nestedTypedef in typedef.NestedTypes)
                TranslateTypeDefinition(context, output, nestedTypedef, initializer, stubbed);
        }