Esempio n. 1
0
        protected void TypeReferenceInternal(GenericParameter gp, TypeReferenceContext context)
        {
            var ownerType   = gp.Owner as TypeReference;
            var ownerMethod = gp.Owner as MethodReference;

            if (context != null)
            {
                if (ownerType != null)
                {
                    if (TypeUtil.TypesAreAssignable(TypeInfo, ownerType, context.SignatureMethodType))
                    {
                        var resolved = JSIL.Internal.MethodSignature.ResolveGenericParameter(gp, context.SignatureMethodType);

                        if (resolved != null)
                        {
                            if (resolved != gp)
                            {
                                TypeReference(resolved, context);
                                return;
                            }
                            else
                            {
                                TypeIdentifier(resolved, context, false);
                                return;
                            }
                        }
                    }

                    if (TypeUtil.TypesAreEqual(ownerType, context.EnclosingMethodType))
                    {
                        TypeIdentifier(gp, context, false);
                        return;
                    }

                    if (TypeUtil.TypesAreEqual(ownerType, context.DefiningType))
                    {
                        OpenGenericParameter(gp, context.DefiningType.FullName);
                        return;
                    }

                    if (TypeUtil.TypesAreEqual(ownerType, context.EnclosingType))
                    {
                        LocalOpenGenericParameter(gp);
                        return;
                    }

                    var ownerTypeResolved = ownerType.Resolve();
                    if (ownerTypeResolved != null)
                    {
                        // Is it a generic parameter of a compiler-generated class (i.e. enumerator function, delegate, etc)
                        //  nested inside our EnclosingType? If so, uhhhh, shit.
                        if (
                            TypeUtil.TypesAreEqual(context.EnclosingType, ownerTypeResolved.DeclaringType) &&
                            ownerTypeResolved.CustomAttributes.Any(
                                (ca) => ca.AttributeType.FullName == "System.Runtime.CompilerServices.CompilerGeneratedAttribute"
                                )
                            )
                        {
                            // FIXME: I HAVE NO IDEA WHAT I AM DOING
                            OpenGenericParameter(gp, ownerTypeResolved.FullName);
                            return;
                        }
                    }

                    throw new NotImplementedException(String.Format(
                                                          "Unimplemented form of generic type parameter: '{0}'.",
                                                          gp
                                                          ));
                }
                else if (ownerMethod != null)
                {
                    Func <MethodReference, int> getPosition = (mr) => {
                        for (var i = 0; i < mr.GenericParameters.Count; i++)
                        {
                            if (mr.GenericParameters[i].Name == gp.Name)
                            {
                                return(i);
                            }
                        }

                        throw new NotImplementedException(String.Format(
                                                              "Generic parameter '{0}' not found in method '{1}' parameter list",
                                                              gp, ownerMethod
                                                              ));
                    };

                    var ownerMethodIdentifier = new QualifiedMemberIdentifier(
                        new TypeIdentifier(ownerMethod.DeclaringType.Resolve()),
                        new MemberIdentifier(TypeInfo, ownerMethod)
                        );

                    if (ownerMethodIdentifier.Equals(ownerMethod, context.InvokingMethod, TypeInfo))
                    {
                        var gim = (GenericInstanceMethod)context.InvokingMethod;
                        TypeReference(gim.GenericArguments[getPosition(ownerMethod)], context);

                        return;
                    }

                    if (ownerMethodIdentifier.Equals(ownerMethod, context.EnclosingMethod, TypeInfo))
                    {
                        Identifier(gp.Name);

                        return;
                    }

                    if (
                        ownerMethodIdentifier.Equals(ownerMethod, context.DefiningMethod, TypeInfo) ||
                        ownerMethodIdentifier.Equals(ownerMethod, context.SignatureMethod, TypeInfo)
                        )
                    {
                        Value(String.Format("!!{0}", getPosition(ownerMethod)));

                        return;
                    }

                    throw new NotImplementedException(String.Format(
                                                          "Unimplemented form of generic method parameter: '{0}'.",
                                                          gp
                                                          ));
                }
            }
            else
            {
                throw new NotImplementedException("Cannot resolve generic parameter without a TypeReferenceContext.");
            }

            throw new NotImplementedException(String.Format(
                                                  "Unimplemented form of generic parameter: '{0}'.",
                                                  gp
                                                  ));
        }
Esempio n. 2
0
        protected void TypeReferenceInternal(GenericParameter gp, TypeReferenceContext context)
        {
            var ownerType   = gp.Owner as TypeReference;
            var ownerMethod = gp.Owner as MethodReference;

            if (context != null)
            {
                if (ownerType != null)
                {
                    if (TypeUtil.TypesAreAssignable(TypeInfo, ownerType, context.SignatureMethodType))
                    {
                        TypeReference resolved = null;

                        var git = (context.SignatureMethodType as GenericInstanceType);
                        if (git != null)
                        {
                            for (var i = 0; i < git.ElementType.GenericParameters.Count; i++)
                            {
                                var _ = git.ElementType.GenericParameters[i];
                                if ((_.Name == gp.Name) || (_.Position == gp.Position))
                                {
                                    resolved = git.GenericArguments[i];
                                    break;
                                }
                            }

                            if (resolved == null)
                            {
                                throw new NotImplementedException(String.Format(
                                                                      "Could not find generic parameter '{0}' in type {1}",
                                                                      gp, context.SignatureMethodType
                                                                      ));
                            }
                        }

                        if (resolved != null)
                        {
                            if (resolved != gp)
                            {
                                TypeReference(resolved, context);
                                return;
                            }
                            else
                            {
                                TypeIdentifier(resolved, context, false);
                                return;
                            }
                        }
                    }

                    if (TypeUtil.TypesAreEqual(ownerType, context.EnclosingMethodType))
                    {
                        TypeIdentifier(gp, context, false);
                        return;
                    }

                    if (TypeUtil.TypesAreEqual(ownerType, context.DefiningType))
                    {
                        OpenGenericParameter(gp.Name, context.DefiningType.FullName);
                        return;
                    }

                    if (TypeUtil.TypesAreEqual(ownerType, context.EnclosingType))
                    {
                        WriteRaw("$.GenericParameter");
                        LPar();
                        Value(gp.Name);
                        RPar();

                        return;
                    }

                    throw new NotImplementedException(String.Format(
                                                          "Unimplemented form of generic type parameter: '{0}'.",
                                                          gp
                                                          ));
                }
                else if (ownerMethod != null)
                {
                    Func <MethodReference, int> getPosition = (mr) => {
                        for (var i = 0; i < mr.GenericParameters.Count; i++)
                        {
                            if (mr.GenericParameters[i].Name == gp.Name)
                            {
                                return(i);
                            }
                        }

                        throw new NotImplementedException(String.Format(
                                                              "Generic parameter '{0}' not found in method '{1}' parameter list",
                                                              gp, ownerMethod
                                                              ));
                    };

                    var ownerMethodIdentifier = new QualifiedMemberIdentifier(
                        new TypeIdentifier(ownerMethod.DeclaringType),
                        new MemberIdentifier(TypeInfo, ownerMethod)
                        );

                    if (ownerMethodIdentifier.Equals(ownerMethod, context.InvokingMethod, TypeInfo))
                    {
                        var gim = (GenericInstanceMethod)context.InvokingMethod;
                        TypeReference(gim.GenericArguments[getPosition(ownerMethod)], context);

                        return;
                    }

                    if (ownerMethodIdentifier.Equals(ownerMethod, context.DefiningMethod, TypeInfo))
                    {
                        Value(String.Format("!!{0}", getPosition(ownerMethod)));

                        return;
                    }

                    if (ownerMethodIdentifier.Equals(ownerMethod, context.EnclosingMethod, TypeInfo))
                    {
                        throw new NotImplementedException(String.Format(
                                                              "Unimplemented form of generic method parameter: '{0}'.",
                                                              gp
                                                              ));
                    }

                    Value(String.Format("!!{0}", getPosition(ownerMethod)));
                    return;
                }
            }
            else
            {
                throw new NotImplementedException("Cannot resolve generic parameter without a TypeReferenceContext.");
            }

            throw new NotImplementedException(String.Format(
                                                  "Unimplemented form of generic parameter: '{0}'.",
                                                  gp
                                                  ));
        }