private ClrTypeDefinition( TypeDefinition definition, ClrAssembly assembly, TypeParent parent, QualifiedName fullName) { this.Definition = definition; this.Assembly = assembly; this.Parent = parent; this.contentsInitializer = Assembly .CreateSynchronizedInitializer(AnalyzeContents); this.OverrideInitializer = Assembly .CreateSynchronizedInitializer(AnalyzeOverrides); this.FullName = fullName; this.nestedTypeCache = Assembly .CreateSynchronizedLazy <IReadOnlyList <ClrTypeDefinition> >(() => { return(definition.NestedTypes .Select(t => new ClrTypeDefinition(t, this)) .ToArray()); }); this.genericParamCache = Assembly .CreateSynchronizedLazy <IReadOnlyList <ClrGenericParameter> >(() => { return(definition.GenericParameters .Skip( parent.IsType ? parent.TypeOrNull.GenericParameters.Count : 0) .Select(param => new ClrGenericParameter(param, this)) .ToArray()); }); }
/// <summary> /// Resolves a property reference. /// </summary> /// <param name="propertyRef">The property reference to resolve.</param> /// <param name="assembly">The assembly that declares the reference.</param> /// <returns>The property referred to by the reference.</returns> internal IProperty Resolve( PropertyReference propertyRef, ClrAssembly assembly) { var declaringType = Resolve(propertyRef.DeclaringType, assembly); var standinReplacer = CreateStandinReplacingVisitor(declaringType); var propertyType = TypeHelpers.BoxIfReferenceType( standinReplacer.Visit(Resolve(propertyRef.PropertyType, assembly, declaringType, true))); var parameterTypes = propertyRef.Parameters .Select(param => TypeHelpers.BoxIfReferenceType( standinReplacer.Visit( Resolve(param.ParameterType, assembly, declaringType, true)))) .ToImmutableArray(); return(PickSingleResolvedMember( propertyRef, propertyIndex.GetAll( declaringType, ClrPropertySignature.Create( propertyRef.Name, propertyType, 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> /// <returns>The type referred to by the reference.</returns> internal IType Resolve( TypeReference typeRef, ClrAssembly assembly, IGenericMember enclosingMember) { return(Resolve(typeRef, assembly, enclosingMember, false)); }
private ClrGenericParameter( GenericParameter definition, ClrAssembly assembly, TypeParent parent) { this.Definition = definition; this.Assembly = assembly; this.Parent = parent; this.FullName = new SimpleName(definition.Name) .Qualify(parent.Member.FullName); this.contentsInitializer = Assembly.CreateSynchronizedInitializer( AnalyzeContents); }
/// <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> /// Wraps a CIL assembly definition in a Flame assembly, setting /// up an assembly resolver and type system. /// </summary> /// <param name="definition">The assembly definition to wrap.</param> /// <returns>A Flame assembly.</returns> public static ClrAssembly Wrap(AssemblyDefinition definition) { // Bootstrap a type system resolver. var typeSystem = new MutableTypeEnvironment(null); var resolver = new CecilAssemblyResolver( definition.MainModule.AssemblyResolver, typeSystem); var flameAsm = new ClrAssembly(definition, resolver.ReferenceResolver); var objectType = flameAsm.Resolve(definition.MainModule.TypeSystem.Object); var corlib = objectType.Parent.Assembly; typeSystem.InnerEnvironment = new CorlibTypeEnvironment(corlib); return(flameAsm); }
internal static Parameter WrapReturnParameter( MethodReturnType returnParameter, ClrAssembly assembly, IGenericMember enclosingMember) { var attrBuilder = new AttributeMapBuilder(); // TODO: actually analyze the parameter's attributes. return(new Parameter( TypeHelpers.BoxIfReferenceType( assembly.Resolve( returnParameter.ReturnType, enclosingMember)), returnParameter.Name, new AttributeMap(attrBuilder))); }
/// <summary> /// Resolves a field reference. /// </summary> /// <param name="fieldRef">The field reference to resolve.</param> /// <param name="assembly">The assembly that declares the reference.</param> /// <returns>The field referred to by the reference.</returns> internal IField Resolve(FieldReference fieldRef, ClrAssembly assembly) { var declaringType = Resolve(fieldRef.DeclaringType, assembly); var standinReplacer = CreateStandinReplacingVisitor(declaringType); var fieldType = TypeHelpers.BoxIfReferenceType( standinReplacer.Visit( Resolve(fieldRef.FieldType, assembly, declaringType, true))); return(PickSingleResolvedMember( fieldRef, fieldIndex.GetAll( declaringType, new KeyValuePair <string, IType>( fieldRef.Name, fieldType)))); }
/// <inheritdoc/> public override bool TryResolve( AssemblyIdentity identity, out IAssembly assembly) { var nameRef = new Mono.Cecil.AssemblyNameReference(identity.Name, identity.VersionOrNull); try { var asmDef = Resolver.Resolve(nameRef, Parameters); assembly = new ClrAssembly(asmDef, ReferenceResolver); return(true); } catch (Mono.Cecil.AssemblyResolutionException) { assembly = null; return(false); } }
/// <summary> /// Wraps a CIL assembly definition in a Flame assembly, setting /// up an assembly resolver and type system. /// </summary> /// <param name="definition">The assembly definition to wrap.</param> /// <returns>A Flame assembly.</returns> public static ClrAssembly Wrap(AssemblyDefinition definition) { // Bootstrap a type system resolver. var typeSystem = new MutableTypeEnvironment(null); var resolver = new CecilAssemblyResolver( definition.MainModule.AssemblyResolver, typeSystem); var flameAsm = new ClrAssembly(definition, resolver.ReferenceResolver); // Register the assembly with its own resolver, so we don't get weirdness // where the assembly tries to resolve itself. resolver.ReferenceResolver.Register(definition.Name, flameAsm); var objectType = flameAsm.Resolve(definition.MainModule.TypeSystem.Object); var corlib = objectType.Parent.Assembly; typeSystem.InnerEnvironment = new CorlibTypeEnvironment(corlib); return(flameAsm); }
/// <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)); } } }
/// <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> /// <returns>The type referred to by the reference.</returns> internal IType Resolve(TypeReference typeRef, ClrAssembly assembly) { return(Resolve(typeRef, assembly, null)); }