private static bool MatchParameters(GenericContext <ParameterDefinition> baseParameterType, GenericContext <ParameterDefinition> parameterType) { if (baseParameterType.Item.IsIn != parameterType.Item.IsIn || baseParameterType.Item.IsOut != parameterType.Item.IsOut) { return(false); } var baseParam = baseParameterType.ResolveWithContext(baseParameterType.Item.ParameterType); var param = parameterType.ResolveWithContext(parameterType.Item.ParameterType); return(IsSameType(baseParam, param)); }
private static bool MatchMethod(GenericContext <MethodDefinition> candidate, GenericContext <MethodDefinition> method) { var mCandidate = candidate.Item; var mMethod = method.Item; if (mCandidate.Name != mMethod.Name) { return(false); } if (mCandidate.HasOverrides) { return(false); } if (mCandidate.IsSpecialName != method.Item.IsSpecialName) { return(false); } if (mCandidate.HasGenericParameters || mMethod.HasGenericParameters) { if (!mCandidate.HasGenericParameters || !mMethod.HasGenericParameters || mCandidate.GenericParameters.Count != mMethod.GenericParameters.Count) { return(false); } } if (mCandidate.HasParameters || mMethod.HasParameters) { if (!mCandidate.HasParameters || !mMethod.HasParameters || mCandidate.Parameters.Count != mMethod.Parameters.Count) { return(false); } for (int index = 0; index < mCandidate.Parameters.Count; index++) { if (!MatchParameters(candidate.ApplyTo(mCandidate.Parameters[index]), method.ApplyTo(mMethod.Parameters[index]))) { return(false); } } } return(true); }
private static IEnumerable <GenericContext <TypeDefinition> > BaseTypes(GenericContext <TypeDefinition> type) { while (type.Item.BaseType != null) { var baseType = type.Item.BaseType; var genericBaseType = baseType as GenericInstanceType; if (genericBaseType != null) { type = new GenericContext <TypeDefinition>(genericBaseType.ResolveOrThrow(), genericBaseType.GenericArguments.Select(t => type.ResolveWithContext(t))); } else { type = new GenericContext <TypeDefinition>(baseType.ResolveOrThrow()); } yield return(type); } }
public static bool MatchInterfaceMethod(MethodDefinition candidate, MethodDefinition method, TypeReference interfaceContextType) { var candidateContext = CreateGenericContext(candidate.DeclaringType); var gCandidate = candidateContext.ApplyTo(candidate); if (interfaceContextType is GenericInstanceType) { var methodContext = new GenericContext <TypeDefinition>(interfaceContextType.Resolve(), ((GenericInstanceType)interfaceContextType).GenericArguments); var gMethod = methodContext.ApplyTo(method); return(MatchMethod(gCandidate, gMethod)); } else { var methodContext = CreateGenericContext(interfaceContextType.Resolve()); var gMethod = candidateContext.ApplyTo(method); return(MatchMethod(gCandidate, gMethod)); } }
/// <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"); } }
private static bool MatchEvent(GenericContext <EventDefinition> candidate, GenericContext <EventDefinition> ev) { var mCandidate = candidate.Item; var mEvent = ev.Item; if (mCandidate.Name != mEvent.Name) { return(false); } if ((mCandidate.AddMethod ?? mCandidate.RemoveMethod).HasOverrides) { return(false); } if (!IsSameType(candidate.ResolveWithContext(mCandidate.EventType), ev.ResolveWithContext(mEvent.EventType))) { return(false); } return(true); }
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, Nullability nullableContext = Nullability.Oblivious) { return(ResolveType(typeRefDefSpec, context, options, typeAttributes, nullableContext)); }
public (SignatureHeader, FunctionPointerType) 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); var fpt = FunctionPointerType.FromSignature(sig, this); return(sig.Header, (FunctionPointerType)IntroduceTupleTypes(fpt)); }
public IType ResolveType(EntityHandle typeRefDefSpec, GenericContext context, CustomAttributeHandleCollection?typeAttributes = null) { return(ResolveType(typeRefDefSpec, context, options, typeAttributes)); }
private static bool MatchProperty(GenericContext <PropertyDefinition> candidate, GenericContext <PropertyDefinition> property) { var mCandidate = candidate.Item; var mProperty = property.Item; if (mCandidate.Name != mProperty.Name) { return(false); } if ((mCandidate.GetMethod ?? mCandidate.SetMethod).HasOverrides) { return(false); } if (mCandidate.HasParameters || mProperty.HasParameters) { if (!mCandidate.HasParameters || !mProperty.HasParameters || mCandidate.Parameters.Count != mProperty.Parameters.Count) { return(false); } for (int index = 0; index < mCandidate.Parameters.Count; index++) { if (!MatchParameters(candidate.ApplyTo(mCandidate.Parameters[index]), property.ApplyTo(mProperty.Parameters[index]))) { return(false); } } } return(true); }