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;
private static TypeDefinition DefineNotNullWhenAttribute(AssemblyDefinition assemblyDefinition, WellKnownTypes wellKnownTypes, CustomAttributeFactory attributeFactory) { var attribute = new TypeDefinition( @namespace: "System.Diagnostics.CodeAnalysis", name: "NotNullWhenAttribute", TypeAttributes.NotPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, wellKnownTypes.Module.ImportReference(wellKnownTypes.SystemAttribute)); var constructor = MethodFactory.Constructor(wellKnownTypes); constructor.Parameters.Add(new ParameterDefinition("returnValue", ParameterAttributes.None, wellKnownTypes.TypeSystem.Boolean)); attribute.Methods.Add(constructor); attribute.CustomAttributes.Add(attributeFactory.AttributeUsage(AttributeTargets.Parameter, inherited: false)); assemblyDefinition.MainModule.Types.Add(attribute); return(attribute); }
private static TypeDefinition DefineNotNullIfNotNullAttribute(AssemblyDefinition assemblyDefinition, WellKnownTypes wellKnownTypes, CustomAttributeFactory attributeFactory) { var attribute = new TypeDefinition( @namespace: "System.Diagnostics.CodeAnalysis", name: "NotNullIfNotNullAttribute", TypeAttributes.NotPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, wellKnownTypes.Module.ImportReference(wellKnownTypes.SystemAttribute)); attribute.CustomAttributes.Add(attributeFactory.NullableContext(1)); attribute.CustomAttributes.Add(attributeFactory.Nullable(0)); attribute.CustomAttributes.Add(attributeFactory.AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, allowMultiple: true, inherited: false)); var constructor = MethodFactory.Constructor(wellKnownTypes); constructor.Parameters.Add(new ParameterDefinition("parameterName", ParameterAttributes.None, wellKnownTypes.TypeSystem.String)); attribute.Methods.Add(constructor); assemblyDefinition.MainModule.Types.Add(attribute); return(attribute); }
private static TypeDefinition DefineNotNullAttribute(AssemblyDefinition assemblyDefinition, WellKnownTypes wellKnownTypes, CustomAttributeFactory attributeFactory) { var attribute = new TypeDefinition( @namespace: "System.Diagnostics.CodeAnalysis", name: "NotNullAttribute", TypeAttributes.NotPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, wellKnownTypes.Module.ImportReference(wellKnownTypes.SystemAttribute)); attribute.AddDefaultConstructor(wellKnownTypes); attribute.CustomAttributes.Add(attributeFactory.AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, inherited: false)); assemblyDefinition.MainModule.Types.Add(attribute); return(attribute); }
internal static void Main(string[] args) { string referenceAssembly = args[0]; string annotatedReferenceAssembly = args[1]; string outputAssembly = args[2]; var assemblyResolver = new DefaultAssemblyResolver(); assemblyResolver.AddSearchDirectory(Path.GetDirectoryName(referenceAssembly)); using var assemblyDefinition = AssemblyDefinition.ReadAssembly(referenceAssembly, new ReaderParameters(ReadingMode.Immediate) { AssemblyResolver = assemblyResolver }); var annotatedAssemblyResolver = new DefaultAssemblyResolver(); annotatedAssemblyResolver.AddSearchDirectory(Path.GetDirectoryName(annotatedReferenceAssembly)); using var annotatedAssemblyDefinition = AssemblyDefinition.ReadAssembly(annotatedReferenceAssembly, new ReaderParameters(ReadingMode.Immediate) { AssemblyResolver = annotatedAssemblyResolver }); var wellKnownTypes = new WellKnownTypes(assemblyDefinition.MainModule); // 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); 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(assemblyDefinition, annotatedAssemblyDefinition, attributesOfInterest); assemblyDefinition.Write(outputAssembly); }
protected override void ImplementAttribute(ModuleDefinition module, TypeDefinition attribute, WellKnownTypes wellKnownTypes, CustomAttributeFactory attributeFactory) { var constructor = attribute.AddDefaultConstructor(wellKnownTypes.TypeSystem); attribute.CustomAttributes.Add(attributeFactory.CompilerGenerated()); attribute.CustomAttributes.Add(new CustomAttribute(constructor)); }
protected override void ImplementAttribute(ModuleDefinition module, TypeDefinition attribute, WellKnownTypes wellKnownTypes, CustomAttributeFactory attributeFactory) { attribute.AddDefaultConstructor(wellKnownTypes.TypeSystem); attribute.CustomAttributes.Add(attributeFactory.AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, inherited: false)); }
protected override void ImplementAttribute(ModuleDefinition module, TypeDefinition attribute, WellKnownTypes wellKnownTypes, CustomAttributeFactory attributeFactory) { attribute.CustomAttributes.Add(attributeFactory.CompilerGenerated()); attribute.CustomAttributes.Add(attributeFactory.Embedded()); var constructor = MethodFactory.Constructor(wellKnownTypes.TypeSystem); constructor.Parameters.Add(new ParameterDefinition(wellKnownTypes.TypeSystem.Boolean)); attribute.Methods.Add(constructor); }
protected override void ImplementAttribute(ModuleDefinition module, TypeDefinition attribute, WellKnownTypes wellKnownTypes, CustomAttributeFactory attributeFactory) { attribute.CustomAttributes.Add(attributeFactory.NullableContext(1)); attribute.CustomAttributes.Add(attributeFactory.Nullable(0)); attribute.CustomAttributes.Add(attributeFactory.AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, allowMultiple: true, inherited: false)); var constructor = MethodFactory.Constructor(wellKnownTypes.TypeSystem); constructor.Parameters.Add(new ParameterDefinition("parameterName", ParameterAttributes.None, wellKnownTypes.TypeSystem.String)); attribute.Methods.Add(constructor); }
protected override void ImplementAttribute(ModuleDefinition module, TypeDefinition attribute, WellKnownTypes wellKnownTypes, CustomAttributeFactory attributeFactory) { var constructor = MethodFactory.Constructor(wellKnownTypes.TypeSystem); constructor.Parameters.Add(new ParameterDefinition("returnValue", ParameterAttributes.None, wellKnownTypes.TypeSystem.Boolean)); attribute.Methods.Add(constructor); attribute.CustomAttributes.Add(attributeFactory.AttributeUsage(AttributeTargets.Parameter, inherited: false)); }
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); }
protected abstract TypeReference DefineType(ModuleDefinition module, WellKnownTypes wellKnownTypes, CustomAttributeFactory attributeFactory);
protected abstract void ImplementAttribute(ModuleDefinition module, TypeDefinition attribute, WellKnownTypes wellKnownTypes, CustomAttributeFactory attributeFactory);
protected override sealed TypeReference DefineType(ModuleDefinition module, WellKnownTypes wellKnownTypes, CustomAttributeFactory attributeFactory) { var attribute = new TypeDefinition( @namespace: NamespaceName, name: TypeName, TypeAttributes.NotPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, module.ImportReference(wellKnownTypes.SystemAttribute)); ImplementAttribute(module, attribute, wellKnownTypes, attributeFactory); module.Types.Add(attribute); return(attribute); }
protected override void ImplementAttribute(ModuleDefinition module, TypeDefinition attribute, WellKnownTypes wellKnownTypes, CustomAttributeFactory attributeFactory) { attribute.AddDefaultConstructor(wellKnownTypes.TypeSystem); attribute.CustomAttributes.Add(attributeFactory.AttributeUsage(AttributeTargets.Method, inherited: false)); }