/// <summary> /// Resolves a symbol. /// </summary> /// <remarks> /// * Types are resolved to their definition, as IType does not implement ISymbol. /// * types without definition will resolve to <c>null</c> /// * use ResolveType() to properly resolve types /// * When resolving methods, varargs signatures are not expanded. /// * use ResolveMethod() instead to get an IMethod instance suitable for call-sites /// * May return specialized members, where generics are involved. /// * Other types of handles that don't correspond to TS entities, will return <c>null</c>. /// </remarks> public IEntity ResolveEntity(EntityHandle entityHandle, GenericContext context = default) { switch (entityHandle.Kind) { case HandleKind.TypeReference: case HandleKind.TypeDefinition: case HandleKind.TypeSpecification: case HandleKind.ExportedType: return(ResolveType(entityHandle, context).GetDefinition()); case HandleKind.MemberReference: var memberReferenceHandle = (MemberReferenceHandle)entityHandle; switch (metadata.GetMemberReference(memberReferenceHandle).GetKind()) { case MemberReferenceKind.Method: // for consistency with the MethodDefinition case, never expand varargs return(ResolveMethodReference(memberReferenceHandle, context, expandVarArgs: false)); case MemberReferenceKind.Field: return(ResolveFieldReference(memberReferenceHandle, context)); default: throw new BadImageFormatException("Unknown MemberReferenceKind"); } case HandleKind.MethodDefinition: return(GetDefinition((MethodDefinitionHandle)entityHandle)); case HandleKind.MethodSpecification: return(ResolveMethodSpecification((MethodSpecificationHandle)entityHandle, context, expandVarArgs: false)); case HandleKind.FieldDefinition: return(GetDefinition((FieldDefinitionHandle)entityHandle)); case HandleKind.EventDefinition: return(GetDefinition((EventDefinitionHandle)entityHandle)); case HandleKind.PropertyDefinition: return(GetDefinition((PropertyDefinitionHandle)entityHandle)); default: return(null); } }
public IMethod ResolveMethod(EntityHandle methodReference, GenericContext context) { if (methodReference.IsNil) { throw new ArgumentNullException(nameof(methodReference)); } switch (methodReference.Kind) { case HandleKind.MethodDefinition: return(ResolveMethodDefinition((MethodDefinitionHandle)methodReference, expandVarArgs: true)); case HandleKind.MemberReference: return(ResolveMethodReference((MemberReferenceHandle)methodReference, context, expandVarArgs: true)); case HandleKind.MethodSpecification: return(ResolveMethodSpecification((MethodSpecificationHandle)methodReference, context, expandVarArgs: true)); default: throw new BadImageFormatException("Metadata token must be either a methoddef, memberref or methodspec"); } }
IField ResolveFieldReference(MemberReferenceHandle memberReferenceHandle, GenericContext context) { var memberRef = metadata.GetMemberReference(memberReferenceHandle); var declaringType = ResolveDeclaringType(memberRef.Parent, context); var declaringTypeDefinition = declaringType.GetDefinition(); string name = metadata.GetString(memberRef.Name); // field signature is for the definition, not the generic instance var signature = memberRef.DecodeFieldSignature(TypeProvider, new GenericContext(declaringTypeDefinition?.TypeParameters)); // 'f' in the predicate is also the definition, even if declaringType is a ParameterizedType var field = declaringType.GetFields(f => f.Name == name && CompareTypes(f.ReturnType, signature), GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault(); if (field == null) { field = new FakeField(Compilation) { ReturnType = signature, Name = name, DeclaringType = declaringType, }; } return(field); }
public ImmutableArray <IType> DecodeLocalSignature(StandaloneSignatureHandle handle, GenericContext genericContext) { var standaloneSignature = metadata.GetStandaloneSignature(handle); if (standaloneSignature.GetKind() != StandaloneSignatureKind.LocalVariables) { throw new BadImageFormatException("Expected LocalVariables signature"); } var types = standaloneSignature.DecodeLocalSignature(TypeProvider, genericContext); return(ImmutableArray.CreateRange(types, IntroduceTupleTypes)); }
public MethodSignature <IType> DecodeMethodSignature(StandaloneSignatureHandle handle, GenericContext genericContext) { var standaloneSignature = metadata.GetStandaloneSignature(handle); if (standaloneSignature.GetKind() != StandaloneSignatureKind.Method) { throw new BadImageFormatException("Expected Method signature"); } var sig = standaloneSignature.DecodeMethodSignature(TypeProvider, genericContext); return(new MethodSignature <IType>( sig.Header, IntroduceTupleTypes(sig.ReturnType), sig.RequiredParameterCount, sig.GenericParameterCount, ImmutableArray.CreateRange( sig.ParameterTypes, IntroduceTupleTypes ) )); }
/// <summary> /// Resolves a method reference. /// </summary> /// <remarks> /// Class type arguments are provided by the declaring type stored in the memberRef. /// Method type arguments are provided by the caller. /// </remarks> IMethod ResolveMethodReference(MemberReferenceHandle memberRefHandle, GenericContext context, IReadOnlyList <IType> methodTypeArguments = null, bool expandVarArgs = true) { var memberRef = metadata.GetMemberReference(memberRefHandle); Debug.Assert(memberRef.GetKind() == MemberReferenceKind.Method); MethodSignature <IType> signature; IReadOnlyList <IType> classTypeArguments = null; IMethod method; if (memberRef.Parent.Kind == HandleKind.MethodDefinition) { method = ResolveMethodDefinition((MethodDefinitionHandle)memberRef.Parent, expandVarArgs: false); signature = memberRef.DecodeMethodSignature(TypeProvider, context); } else { var declaringType = ResolveDeclaringType(memberRef.Parent, context); var declaringTypeDefinition = declaringType.GetDefinition(); if (declaringType.TypeArguments.Count > 0) { classTypeArguments = declaringType.TypeArguments; } // Note: declaringType might be parameterized, but the signature is for the original method definition. // We'll have to search the member directly on declaringTypeDefinition. string name = metadata.GetString(memberRef.Name); signature = memberRef.DecodeMethodSignature(TypeProvider, new GenericContext(declaringTypeDefinition?.TypeParameters)); if (declaringTypeDefinition != null) { // Find the set of overloads to search: IEnumerable <IMethod> methods; if (name == ".ctor") { methods = declaringTypeDefinition.GetConstructors(); } else if (name == ".cctor") { methods = declaringTypeDefinition.Methods.Where(m => m.IsConstructor && m.IsStatic); } else { methods = declaringTypeDefinition.GetMethods(m => m.Name == name, GetMemberOptions.IgnoreInheritedMembers) .Concat(declaringTypeDefinition.GetAccessors(m => m.Name == name, GetMemberOptions.IgnoreInheritedMembers)); } // Determine the expected parameters from the signature: ImmutableArray <IType> parameterTypes; if (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs) { parameterTypes = signature.ParameterTypes .Take(signature.RequiredParameterCount) .Concat(new[] { SpecialType.ArgList }) .ToImmutableArray(); } else { parameterTypes = signature.ParameterTypes; } // Search for the matching method: method = null; foreach (var m in methods) { if (m.TypeParameters.Count != signature.GenericParameterCount) { continue; } if (CompareSignatures(m.Parameters, parameterTypes) && CompareTypes(m.ReturnType, signature.ReturnType)) { method = m; break; } } } else { method = null; } if (method == null) { method = CreateFakeMethod(declaringType, name, signature); } } if (classTypeArguments != null || methodTypeArguments != null) { method = method.Specialize(new TypeParameterSubstitution(classTypeArguments, methodTypeArguments)); } if (expandVarArgs && signature.Header.CallingConvention == SignatureCallingConvention.VarArgs) { method = new VarArgInstanceMethod(method, signature.ParameterTypes.Skip(signature.RequiredParameterCount)); } return(method); }
IMethod ResolveMethodSpecification(MethodSpecificationHandle methodSpecHandle, GenericContext context, bool expandVarArgs) { var methodSpec = metadata.GetMethodSpecification(methodSpecHandle); var methodTypeArgs = methodSpec.DecodeSignature(TypeProvider, context) .SelectReadOnlyArray(IntroduceTupleTypes); IMethod method; if (methodSpec.Method.Kind == HandleKind.MethodDefinition) { // generic instance of a methoddef (=generic method in non-generic class in current assembly) method = ResolveMethodDefinition((MethodDefinitionHandle)methodSpec.Method, expandVarArgs); method = method.Specialize(new TypeParameterSubstitution(null, methodTypeArgs)); } else { method = ResolveMethodReference((MemberReferenceHandle)methodSpec.Method, context, methodTypeArgs, expandVarArgs); } return(method); }
public IType ResolveType(EntityHandle typeRefDefSpec, GenericContext context, CustomAttributeHandleCollection?typeAttributes = null) { return(ResolveType(typeRefDefSpec, context, options, typeAttributes)); }