internal static void Main(SuppressibleLoggingHelper?log, string referenceAssembly, ImmutableArray <string> targetFrameworkDirectories, string annotatedReferenceAssembly, string outputAssembly) { using var assemblyResolver = new AssemblyResolver(targetFrameworkDirectories); using var assemblyDefinition = AssemblyDefinition.ReadAssembly(referenceAssembly, new ReaderParameters(ReadingMode.Deferred) { AssemblyResolver = assemblyResolver }); foreach (var module in assemblyDefinition.Modules) { if (!module.Attributes.HasFlag(ModuleAttributes.ILOnly)) { log?.LogWarning("RA1000", "Skipping mixed-mode implementation assembly '{0}'", assemblyDefinition.Name); return; } if (module.TypeSystem.Object.Resolve() is null) { log?.LogWarning("RA1001", "Cannot resolve core library for assembly '{0}', skipping", assemblyDefinition.Name); return; } } using var annotatedAssemblyResolver = new AssemblyResolver(ImmutableArray.Create(Path.GetDirectoryName(Path.GetFullPath(annotatedReferenceAssembly)) !)); using var annotatedAssemblyDefinition = AssemblyDefinition.ReadAssembly(annotatedReferenceAssembly, new ReaderParameters(ReadingMode.Deferred) { AssemblyResolver = annotatedAssemblyResolver }); var wellKnownTypes = new WellKnownTypes(assemblyDefinition); var attributeFactory = new CustomAttributeFactory(wellKnownTypes); // Ensure the assembly is marked with ReferenceAssemblyAttribute EnsureReferenceAssemblyAttribute(assemblyDefinition, attributeFactory); var attributesOfInterest = new Dictionary <string, TypeDefinition>(); AddAttributeOfInterest(attributesOfInterest, wellKnownTypes.SystemRuntimeCompilerServicesNullableAttribute); AddAttributeOfInterest(attributesOfInterest, wellKnownTypes.SystemRuntimeCompilerServicesNullableContextAttribute); AddAttributeOfInterest(attributesOfInterest, wellKnownTypes.SystemRuntimeCompilerServicesNullablePublicOnlyAttribute); AddAttributeOfInterest(attributesOfInterest, wellKnownTypes.SystemDiagnosticsCodeAnalysisAllowNullAttribute); AddAttributeOfInterest(attributesOfInterest, wellKnownTypes.SystemDiagnosticsCodeAnalysisDisallowNullAttribute); AddAttributeOfInterest(attributesOfInterest, wellKnownTypes.SystemDiagnosticsCodeAnalysisDoesNotReturnAttribute); AddAttributeOfInterest(attributesOfInterest, wellKnownTypes.SystemDiagnosticsCodeAnalysisDoesNotReturnIfAttribute); AddAttributeOfInterest(attributesOfInterest, wellKnownTypes.SystemDiagnosticsCodeAnalysisMaybeNullAttribute); AddAttributeOfInterest(attributesOfInterest, wellKnownTypes.SystemDiagnosticsCodeAnalysisMaybeNullWhenAttribute); AddAttributeOfInterest(attributesOfInterest, wellKnownTypes.SystemDiagnosticsCodeAnalysisNotNullAttribute); AddAttributeOfInterest(attributesOfInterest, wellKnownTypes.SystemDiagnosticsCodeAnalysisNotNullIfNotNullAttribute); AddAttributeOfInterest(attributesOfInterest, wellKnownTypes.SystemDiagnosticsCodeAnalysisNotNullWhenAttribute); AnnotateAssembly(log, assemblyDefinition, annotatedAssemblyDefinition, attributesOfInterest); assemblyDefinition.Write(outputAssembly); return;
internal static void Main(SuppressibleLoggingHelper?log, string referenceAssembly, string annotatedReferenceAssembly, string outputAssembly) { var assemblyResolver = new DefaultAssemblyResolver(); assemblyResolver.AddSearchDirectory(Path.GetDirectoryName(referenceAssembly)); using var assemblyDefinition = AssemblyDefinition.ReadAssembly(referenceAssembly, new ReaderParameters(ReadingMode.Deferred) { AssemblyResolver = assemblyResolver }); foreach (var module in assemblyDefinition.Modules) { if (!module.Attributes.HasFlag(ModuleAttributes.ILOnly)) { log?.LogWarning("RA1000", "Skipping mixed-mode implementation assembly '{0}'", assemblyDefinition.Name); return; } } var annotatedAssemblyResolver = new DefaultAssemblyResolver(); annotatedAssemblyResolver.AddSearchDirectory(Path.GetDirectoryName(annotatedReferenceAssembly)); using var annotatedAssemblyDefinition = AssemblyDefinition.ReadAssembly(annotatedReferenceAssembly, new ReaderParameters(ReadingMode.Deferred) { AssemblyResolver = annotatedAssemblyResolver }); var wellKnownTypes = new WellKnownTypes(assemblyDefinition, DefineReferenceAssemblyAttribute); // Define embedded types used by the compiler var embeddedAttribute = DefineEmbeddedAttribute(assemblyDefinition, wellKnownTypes); var nullableAttribute = DefineNullableAttribute(assemblyDefinition, embeddedAttribute, wellKnownTypes); var nullableContextAttribute = DefineNullableContextAttribute(assemblyDefinition, embeddedAttribute, wellKnownTypes); var nullablePublicOnlyAttribute = DefineNullablePublicOnlyAttribute(assemblyDefinition, embeddedAttribute, wellKnownTypes); var attributeFactory = new CustomAttributeFactory(wellKnownTypes, embeddedAttribute, nullableAttribute, nullableContextAttribute, nullablePublicOnlyAttribute); // Define attributes for annotating nullable types var allowNullAttribute = DefineAllowNullAttribute(assemblyDefinition, wellKnownTypes, attributeFactory); var disallowNullAttribute = DefineDisallowNullAttribute(assemblyDefinition, wellKnownTypes, attributeFactory); var doesNotReturnAttribute = DefineDoesNotReturnAttribute(assemblyDefinition, wellKnownTypes, attributeFactory); var doesNotReturnIfAttribute = DefineDoesNotReturnIfAttribute(assemblyDefinition, wellKnownTypes, attributeFactory); var maybeNullAttribute = DefineMaybeNullAttribute(assemblyDefinition, wellKnownTypes, attributeFactory); var maybeNullWhenAttribute = DefineMaybeNullWhenAttribute(assemblyDefinition, wellKnownTypes, attributeFactory); var notNullAttribute = DefineNotNullAttribute(assemblyDefinition, wellKnownTypes, attributeFactory); var notNullIfNotNullAttribute = DefineNotNullIfNotNullAttribute(assemblyDefinition, wellKnownTypes, attributeFactory); var notNullWhenAttribute = DefineNotNullWhenAttribute(assemblyDefinition, wellKnownTypes, attributeFactory); // Ensure the assembly is marked with ReferenceAssemblyAttribute EnsureReferenceAssemblyAttribute(assemblyDefinition, attributeFactory); var attributesOfInterest = new Dictionary <string, TypeDefinition>(); attributesOfInterest.Add(nullableAttribute.FullName, nullableAttribute); attributesOfInterest.Add(nullableContextAttribute.FullName, nullableContextAttribute); attributesOfInterest.Add(nullablePublicOnlyAttribute.FullName, nullablePublicOnlyAttribute); attributesOfInterest.Add(allowNullAttribute.FullName, allowNullAttribute); attributesOfInterest.Add(disallowNullAttribute.FullName, disallowNullAttribute); attributesOfInterest.Add(doesNotReturnAttribute.FullName, doesNotReturnAttribute); attributesOfInterest.Add(doesNotReturnIfAttribute.FullName, doesNotReturnIfAttribute); attributesOfInterest.Add(maybeNullAttribute.FullName, maybeNullAttribute); attributesOfInterest.Add(maybeNullWhenAttribute.FullName, maybeNullWhenAttribute); attributesOfInterest.Add(notNullAttribute.FullName, notNullAttribute); attributesOfInterest.Add(notNullIfNotNullAttribute.FullName, notNullIfNotNullAttribute); attributesOfInterest.Add(notNullWhenAttribute.FullName, notNullWhenAttribute); AnnotateAssembly(log, assemblyDefinition, annotatedAssemblyDefinition, attributesOfInterest); assemblyDefinition.Write(outputAssembly); }