/// <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); }
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))) { }
/// <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)))); }
/// <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)); } } }