/// <summary>
        /// Creates a wrapper around an IL method definition.
        /// </summary>
        /// <param name="definition">
        /// The definition to wrap in a Flame method.
        /// </param>
        /// <param name="parentType">
        /// The definition's declaring type.
        /// </param>
        public ClrMethodDefinition(
            MethodDefinition definition,
            ClrTypeDefinition parentType)
        {
            this.Definition    = definition;
            this.ParentType    = parentType;
            this.IsConstructor = Definition.IsConstructor;
            this.IsStatic      = Definition.IsStatic;

            this.FullName = NameConversion
                            .ParseSimpleName(definition.Name)
                            .Qualify(parentType.FullName);

            this.genericParameterCache = parentType.Assembly
                                         .CreateSynchronizedLazy <IReadOnlyList <IGenericParameter> >(() =>
                                                                                                      definition.GenericParameters
                                                                                                      .Select(param => new ClrGenericParameter(param, this))
                                                                                                      .ToArray());

            this.signatureInitializer = parentType.Assembly
                                        .CreateSynchronizedInitializer(AnalyzeSignature);

            this.methodBody = parentType.Assembly
                              .CreateSynchronizedLazy(AnalyzeBody);
        }
Exemple #2
0
        private IType FindInAssembly(TypeReference typeRef, IAssembly assembly)
        {
            var qualName = NameConversion.ParseSimpleName(typeRef.Name)
                           .Qualify(NameConversion.ParseNamespace(typeRef.Namespace));

            return(PickSingleResolvedType(
                       typeRef,
                       GetTypeResolver(assembly).ResolveTypes(qualName)));
        }
 /// <summary>
 /// Creates a Flame type that wraps a particular nested type
 /// definition.
 /// </summary>
 /// <param name="definition">The definition to wrap.</param>
 /// <param name="parentType">
 /// The type that directly defines this type.
 /// </param>
 public ClrTypeDefinition(
     TypeDefinition definition,
     ClrTypeDefinition parentType)
     : this(
         definition,
         parentType.Assembly,
         new TypeParent(parentType),
         NameConversion
         .ParseSimpleName(definition.Name)
         .Qualify(parentType.FullName))
 {
 }
 /// <summary>
 /// Creates a Flame type that wraps a particular type
 /// definition.
 /// </summary>
 /// <param name="definition">The definition to wrap.</param>
 /// <param name="assembly">
 /// The assembly that directly defines this type.
 /// </param>
 public ClrTypeDefinition(
     TypeDefinition definition,
     ClrAssembly assembly)
     : this(
         definition,
         assembly,
         new TypeParent(assembly),
         NameConversion
         .ParseSimpleName(definition.Name)
         .Qualify(
             NameConversion.ParseNamespace(
                 definition.Namespace)))
 {
 }
Exemple #5
0
        /// <summary>
        /// Resolves a method reference.
        /// </summary>
        /// <param name="methodRef">The method reference to resolve.</param>
        /// <param name="assembly">The assembly that declares the reference.</param>
        /// <returns>The method referred to by the reference.</returns>
        internal IMethod Resolve(MethodReference methodRef, ClrAssembly assembly)
        {
            if (methodRef is MethodSpecification)
            {
                if (methodRef is GenericInstanceMethod)
                {
                    var genInstMethod = (GenericInstanceMethod)methodRef;
                    var elemMethod    = Resolve(genInstMethod.ElementMethod, assembly);
                    return(elemMethod.MakeGenericMethod(
                               genInstMethod.GenericArguments
                               .Select(arg => Resolve(arg, assembly))
                               .Zip(elemMethod.GenericParameters, BoxTypeArgumentIfNecessary)
                               .ToArray()));
                }
                else
                {
                    throw new NotSupportedException(
                              "Cannot resolve unsupported method specification type " +
                              $"'{methodRef.GetType()}' for method reference '{methodRef}'.");
                }
            }

            var declaringType = Resolve(methodRef.DeclaringType, assembly);
            var name          = NameConversion.ParseSimpleName(methodRef.Name);

            var standinReplacer = CreateStandinReplacingVisitor(declaringType);

            var standinRetType = Resolve(methodRef.ReturnType, assembly, declaringType, true);
            var returnType     = TypeHelpers.BoxIfReferenceType(
                standinReplacer.Visit(standinRetType));

            var parameterTypes = methodRef.Parameters
                                 .Select(param =>
                                         TypeHelpers.BoxIfReferenceType(
                                             standinReplacer.Visit(
                                                 Resolve(param.ParameterType, assembly, declaringType, true))))
                                 .ToArray();

            return(PickSingleResolvedMember(
                       methodRef,
                       methodIndex.GetAll(
                           declaringType,
                           ClrMethodSignature.Create(
                               name,
                               methodRef.GenericParameters.Count,
                               returnType,
                               parameterTypes))));
        }
Exemple #6
0
        /// <summary>
        /// Resolves a type reference.
        /// </summary>
        /// <param name="typeRef">The type reference to resolve.</param>
        /// <param name="assembly">The assembly in which the reference occurs.</param>
        /// <param name="enclosingMember">
        /// The generic member that references a particular type. If non-null, type
        /// parameters are resolved from this member.
        /// </param>
        /// <param name="useStandins">
        /// A Boolean that specifies if stand-ins should be used for generic parameters.
        /// </param>
        /// <returns>The type referred to by the reference.</returns>
        private IType Resolve(
            TypeReference typeRef,
            ClrAssembly assembly,
            IGenericMember enclosingMember,
            bool useStandins)
        {
            if (typeRef is TypeSpecification)
            {
                var typeSpec = (TypeSpecification)typeRef;
                var elemType = Resolve(typeSpec.ElementType, assembly, enclosingMember, useStandins);
                if (typeSpec is GenericInstanceType)
                {
                    var genInstType = (GenericInstanceType)typeSpec;
                    return(elemType.MakeRecursiveGenericType(
                               genInstType.GenericArguments
                               .Select(arg => Resolve(arg, assembly, enclosingMember, useStandins))
                               .Zip(elemType.GetRecursiveGenericParameters(), BoxTypeArgumentIfNecessary)
                               .ToArray()));
                }
                else if (typeSpec is Mono.Cecil.PointerType)
                {
                    return(TypeHelpers.BoxIfReferenceType(elemType)
                           .MakePointerType(PointerKind.Transient));
                }
                else if (typeSpec is ByReferenceType)
                {
                    return(TypeHelpers.BoxIfReferenceType(elemType)
                           .MakePointerType(PointerKind.Reference));
                }
                else if (typeSpec is Mono.Cecil.ArrayType)
                {
                    var   arraySpec = (Mono.Cecil.ArrayType)typeSpec;
                    var   boxedElem = TypeHelpers.BoxIfReferenceType(elemType);
                    IType arrayType;
                    if (TypeEnvironment.TryMakeArrayType(
                            boxedElem,
                            arraySpec.Rank,
                            out arrayType))
                    {
                        return(arrayType);
                    }
                    else
                    {
                        throw new NotSupportedException(
                                  "Cannot resolve array specification '" +
                                  typeSpec.ToString() + "' because the type environment " +
                                  "does not support arrays with that element type and rank.");
                    }
                }
                else if (typeSpec is Mono.Cecil.IModifierType)
                {
                    var modType = Resolve(
                        ((Mono.Cecil.IModifierType)typeSpec).ModifierType,
                        assembly,
                        enclosingMember,
                        useStandins);

                    return(ClrModifierType.Create(elemType, modType, typeSpec.IsRequiredModifier));
                }
                else
                {
                    throw new NotSupportedException(
                              "Unsupported kind of type specification '" +
                              typeSpec.ToString() + "'.");
                }
            }
            else if (typeRef is GenericParameter)
            {
                var genericParam = (GenericParameter)typeRef;
                if (useStandins)
                {
                    return(ClrGenericParameterStandin.Create(
                               genericParam.Type,
                               genericParam.Position));
                }
                else if (genericParam.DeclaringMethod == null)
                {
                    var declType = enclosingMember is IType
                        ? (IType)enclosingMember
                        : enclosingMember is IMethod
                            ? ((IMethod)enclosingMember).ParentType
                            : Resolve(
                        genericParam.DeclaringType,
                        assembly,
                        enclosingMember,
                        useStandins);

                    return(declType.GetRecursiveGenericParameters()[genericParam.Position]);
                }
                else
                {
                    var declMethod = enclosingMember is IMethod
                        ? (IMethod)enclosingMember
                        : Resolve(genericParam.DeclaringMethod, assembly);
                    return(declMethod.GenericParameters[genericParam.Position]);
                }
            }
            else
            {
                if (typeRef.DeclaringType != null)
                {
                    var declType = Resolve(
                        typeRef.DeclaringType,
                        assembly,
                        enclosingMember,
                        useStandins);

                    var nestedTypes = GetTypeResolver(assembly).ResolveNestedTypes(
                        declType,
                        NameConversion.ParseSimpleName(typeRef.Name));
                    return(PickSingleResolvedType(typeRef, nestedTypes));
                }

                var scope = typeRef.Scope;

                if (scope == null)
                {
                    throw new ResolutionException(typeRef);
                }

                switch (scope.MetadataScopeType)
                {
                case MetadataScopeType.AssemblyNameReference:
                    return(FindInAssembly(typeRef, Resolve((AssemblyNameReference)scope)));

                case MetadataScopeType.ModuleDefinition:
                case MetadataScopeType.ModuleReference:
                default:
                    return(FindInAssembly(typeRef, assembly));
                }
            }
        }