IEnumerable <ISymbol> HandleCustomAttribute(ITypeDefinition attributeType, AnalyzerScope scope, CancellationToken ct) { var genericContext = new Decompiler.TypeSystem.GenericContext(); // type arguments do not matter for this analyzer. foreach (var module in scope.GetModulesInScope(ct)) { var ts = scope.ConstructTypeSystem(module); ct.ThrowIfCancellationRequested(); var decoder = new FindTypeDecoder(ts.MainModule, attributeType); var referencedParameters = new HashSet <ParameterHandle>(); foreach (var h in module.Metadata.CustomAttributes) { var customAttribute = module.Metadata.GetCustomAttribute(h); if (IsCustomAttributeOfType(customAttribute.Constructor, module.Metadata, decoder)) { if (customAttribute.Parent.Kind == HandleKind.Parameter) { referencedParameters.Add((ParameterHandle)customAttribute.Parent); } else { var parent = AnalyzerHelpers.GetParentEntity(ts, customAttribute); if (parent != null) { yield return(parent); } } } } if (referencedParameters.Count > 0) { foreach (var h in module.Metadata.MethodDefinitions) { var md = module.Metadata.GetMethodDefinition(h); foreach (var p in md.GetParameters()) { if (referencedParameters.Contains(p)) { var method = ts.MainModule.ResolveMethod(h, genericContext); if (method != null) { if (method.IsAccessor) { yield return(method.AccessorOwner); } else { yield return(method); } } break; } } } } } }
IEnumerable <ISymbol> HandleCustomAttribute(ITypeDefinition attributeType, AnalyzerScope scope) { var genericContext = new GenericContext(); // type arguments do not matter for this analyzer. foreach (var module in scope.GetAllModules()) { var ts = new DecompilerTypeSystem(module, module.GetAssemblyResolver()); var referencedParameters = new HashSet <ParameterHandle>(); foreach (var h in module.Metadata.CustomAttributes) { var customAttribute = module.Metadata.GetCustomAttribute(h); var attributeCtor = ts.MainModule.ResolveMethod(customAttribute.Constructor, genericContext); if (attributeCtor.DeclaringTypeDefinition != null && attributeCtor.ParentModule.PEFile == attributeType.ParentModule.PEFile && attributeCtor.DeclaringTypeDefinition.MetadataToken == attributeType.MetadataToken) { if (customAttribute.Parent.Kind == HandleKind.Parameter) { referencedParameters.Add((ParameterHandle)customAttribute.Parent); } else { var parent = GetParentEntity(ts, customAttribute); if (parent != null) { yield return(parent); } } } } if (referencedParameters.Count > 0) { foreach (var h in module.Metadata.MethodDefinitions) { var md = module.Metadata.GetMethodDefinition(h); foreach (var p in md.GetParameters()) { if (referencedParameters.Contains(p)) { var method = ts.MainModule.ResolveMethod(h, genericContext); if (method != null) { if (method.IsAccessor) { yield return(method.AccessorOwner); } else { yield return(method); } } break; } } } } } }
IEnumerable <IEnumerable <ISymbol> > HandleBuiltinAttribute(KnownAttribute attribute, AnalyzerScope scope) { IEnumerable <ISymbol> ScanTypes(DecompilerTypeSystem ts) { return(ts.MainModule.TypeDefinitions .Where(t => t.HasAttribute(attribute))); } IEnumerable <ISymbol> ScanMethods(DecompilerTypeSystem ts) { return(ts.MainModule.TypeDefinitions .SelectMany(t => t.Members.OfType <IMethod>()) .Where(m => m.HasAttribute(attribute)) .Select(m => m.AccessorOwner ?? m)); } IEnumerable <ISymbol> ScanFields(DecompilerTypeSystem ts) { return(ts.MainModule.TypeDefinitions .SelectMany(t => t.Fields) .Where(f => f.HasAttribute(attribute))); } IEnumerable <ISymbol> ScanProperties(DecompilerTypeSystem ts) { return(ts.MainModule.TypeDefinitions .SelectMany(t => t.Properties) .Where(p => p.HasAttribute(attribute))); } IEnumerable <ISymbol> ScanParameters(DecompilerTypeSystem ts) { return(ts.MainModule.TypeDefinitions .SelectMany(t => t.Members.OfType <IMethod>()) .Where(m => m.Parameters.Any(p => p.HasAttribute(attribute))) .Select(m => m.AccessorOwner ?? m)); } foreach (Decompiler.Metadata.PEFile module in scope.GetAllModules()) { var ts = new DecompilerTypeSystem(module, module.GetAssemblyResolver()); switch (attribute) { case KnownAttribute.Serializable: case KnownAttribute.ComImport: case KnownAttribute.StructLayout: yield return(ScanTypes(ts)); break; case KnownAttribute.DllImport: case KnownAttribute.PreserveSig: case KnownAttribute.MethodImpl: yield return(ScanMethods(ts)); break; case KnownAttribute.FieldOffset: case KnownAttribute.NonSerialized: yield return(ScanFields(ts)); break; case KnownAttribute.MarshalAs: yield return(ScanFields(ts)); yield return(ScanParameters(ts)); goto case KnownAttribute.Out; case KnownAttribute.Optional: case KnownAttribute.In: case KnownAttribute.Out: yield return(ScanParameters(ts)); break; case KnownAttribute.IndexerName: yield return(ScanProperties(ts)); break; } } }
static IEnumerable <ISymbol> AnalyzeModule(ITypeDefinition analyzedType, AnalyzerScope scope, PEFile module) { var metadata = module.Metadata; var typeSystem = scope.ConstructTypeSystem(module); var decoder = new FindTypeDecoder(typeSystem.MainModule, analyzedType); //// resolve type refs //int rowCount = metadata.GetTableRowCount(TableIndex.TypeRef); //BitSet typeReferences = new BitSet(rowCount); //for (int row = 0; row < rowCount; row++) //{ // var h = MetadataTokens.TypeReferenceHandle(row + 1); // typeReferences[row] = decoder.GetTypeFromReference(metadata, h, 0); //} //// resolve type specs //rowCount = metadata.GetTableRowCount(TableIndex.TypeSpec); //BitSet typeSpecifications = new BitSet(rowCount); //for (int row = 0; row < rowCount; row++) //{ // var h = MetadataTokens.TypeSpecificationHandle(row + 1); // typeSpecifications[row] = decoder.GetTypeFromSpecification(metadata, default, h, 0); //} foreach (ISymbol result in FindUsesInAttributes(typeSystem, metadata, decoder, analyzedType)) { yield return(result); } foreach (var h in metadata.TypeDefinitions) { var td = metadata.GetTypeDefinition(h); bool found = decoder.GetTypeFromEntity(metadata, td.GetBaseTypeOrNil()); foreach (var ih in td.GetInterfaceImplementations()) { var ii = metadata.GetInterfaceImplementation(ih); found |= decoder.GetTypeFromEntity(metadata, ii.Interface); } found |= FindUsesInGenericConstraints(metadata, td.GetGenericParameters(), decoder); if (found) { yield return(typeSystem.MainModule.GetDefinition(h)); } } foreach (var h in metadata.MethodDefinitions) { var md = metadata.GetMethodDefinition(h); var msig = md.DecodeSignature(decoder, default); bool found = FindTypeDecoder.AnyInMethodSignature(msig); found |= FindUsesInGenericConstraints(metadata, md.GetGenericParameters(), decoder); if (found || ScanMethodBody(analyzedType, module, md, decoder)) { var method = typeSystem.MainModule.GetDefinition(h); yield return(method?.AccessorOwner ?? method); } } foreach (var h in metadata.FieldDefinitions) { var fd = metadata.GetFieldDefinition(h); if (fd.DecodeSignature(decoder, default)) { yield return(typeSystem.MainModule.GetDefinition(h)); } } foreach (var h in metadata.PropertyDefinitions) { var pd = metadata.GetPropertyDefinition(h); var psig = pd.DecodeSignature(decoder, default); if (FindTypeDecoder.AnyInMethodSignature(psig)) { yield return(typeSystem.MainModule.GetDefinition(h)); } } foreach (var h in metadata.EventDefinitions) { var ed = metadata.GetEventDefinition(h); if (decoder.GetTypeFromEntity(metadata, ed.Type)) { yield return(typeSystem.MainModule.GetDefinition(h)); } } }