示例#1
0
        protected void TranslateMethodGroup(DecompilerContext context, JavascriptFormatter output, MethodGroupInfo methodGroup)
        {
            var methods = (from m in methodGroup.Methods where !m.IsIgnored select m).ToArray();
            if (methods.Length < 1)
                return;

            foreach (var method in methods) {
                foreach (var p in method.Member.Parameters) {
                    var resolved = p.ParameterType.Resolve();
                    if ((resolved != null) &&
                        !DeclaredTypes.Contains(resolved.FullName) &&
                        (resolved.Module.Assembly == methodGroup.DeclaringType.Definition.Module.Assembly)
                    ) {
                        ForwardDeclareType(context, output, resolved);
                    }
                }
            }

            output.Identifier(
                (methods.First().IsGeneric) ? "JSIL.OverloadedGenericMethod" : "JSIL.OverloadedMethod", null
            );
            output.LPar();

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

            output.Comma();
            output.Value(Util.EscapeIdentifier(methodGroup.Name));
            output.Comma();
            output.OpenBracket(true);

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

                output.OpenBracket();
                output.Value(Util.EscapeIdentifier(method.GetName(true)));
                output.Comma();

                output.OpenBracket();
                output.CommaSeparatedList(
                    from p in method.Member.Parameters select p.ParameterType, ListValueType.TypeIdentifier
                );
                output.CloseBracket();

                output.CloseBracket();
                isFirst = false;
            }

            output.CloseBracket(true, () => {
                output.RPar();
                output.Semicolon();
            });
        }
示例#2
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);
        }
示例#3
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();
        }
示例#4
0
        protected void TranslateProperty(DecompilerContext context, JavascriptFormatter output, PropertyDefinition property)
        {
            var propertyInfo = TypeInfoProvider.GetMemberInformation<Internal.PropertyInfo>(property);
            if ((propertyInfo == null) || propertyInfo.IsIgnored)
                return;

            var isStatic = (property.SetMethod ?? property.GetMethod).IsStatic;

            if (property.DeclaringType.HasGenericParameters && isStatic)
                output.Identifier("JSIL.MakeGenericProperty", null);
            else
                output.Identifier("JSIL.MakeProperty", null);

            output.LPar();

            output.Identifier(property.DeclaringType);
            if (!isStatic) {
                output.Dot();
                output.Keyword("prototype");
            }
            output.Comma();

            output.Value(Util.EscapeIdentifier(propertyInfo.Name));

            output.Comma();
            output.NewLine();

            if (property.GetMethod != null) {
                output.Identifier(property.DeclaringType);
                if (!isStatic) {
                    output.Dot();
                    output.Keyword("prototype");
                }
                output.Dot();
                output.Identifier(property.GetMethod, false);
            } else {
                output.Keyword("null");
            }

            output.Comma();

            if (property.SetMethod != null) {
                output.Identifier(property.DeclaringType);
                if (!isStatic) {
                    output.Dot();
                    output.Keyword("prototype");
                }
                output.Dot();
                output.Identifier(property.SetMethod, false);
            } else {
                output.Keyword("null");
            }

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