static bool ReadCustomAttributeValue(CustomAttributeHandle handle, PEModule module, out int value) { // PEModule.cs var valueBlob = module.GetCustomAttributeValueOrThrow(handle); if (!valueBlob.IsNil) { // TODO: error checking offset in range var reader = module.MetadataReader.GetBlobReader(valueBlob); if (reader.Length > 4) { // check prolog if (reader.ReadByte() == 1 && reader.ReadByte() == 0) { // read Int32 if (reader.RemainingBytes >= 4) { value = reader.ReadInt32(); return(true); } } } } value = default; return(false); }
private static IEnumerable <string> GetSupportedLanguages(PEModule peModule, CustomAttributeHandle customAttrHandle) { // The DiagnosticAnalyzerAttribute has one constructor, which has a string parameter for the // first supported language and an array parameter for addition supported languages. // Parse the argument blob to extract the languages. BlobReader argsReader = peModule.GetMemoryReaderOrThrow(peModule.GetCustomAttributeValueOrThrow(customAttrHandle)); if (argsReader.Length > 4) { // Arguments are present--check prologue. if (argsReader.ReadByte() == 1 && argsReader.ReadByte() == 0) { if (!PEModule.CrackStringInAttributeValue(out string firstLanguageName, ref argsReader)) { return(SpecializedCollections.EmptyEnumerable <string>()); } if (PEModule.CrackStringArrayInAttributeValue(out ImmutableArray <string> additionalLanguageNames, ref argsReader)) { if (additionalLanguageNames.Length == 0) { return(SpecializedCollections.SingletonEnumerable(firstLanguageName)); } return(additionalLanguageNames.Insert(0, firstLanguageName)); } } } return(SpecializedCollections.EmptyEnumerable <string>()); }
private static string GetSupportedLanguage(PEModule peModule, CustomAttributeHandle customAttrHandle) { // The DiagnosticAnalyzerAttribute has two constructors: // 1. Paramterless - means that the analyzer is applicable to any language. // 2. Single string parameter specifying the language. // Parse the argument blob to extract these two cases. BlobReader argsReader = peModule.GetMemoryReaderOrThrow(peModule.GetCustomAttributeValueOrThrow(customAttrHandle)); // Single string parameter if (argsReader.Length > 4) { // check prologue if (argsReader.ReadByte() == 1 && argsReader.ReadByte() == 0) { string languageName; if (PEModule.CrackStringInAttributeValue(out languageName, ref argsReader)) { return(languageName); } } } // otherwise the attribute is applicable to all languages. else { return(string.Empty); } return(null); }
private static IEnumerable <string> GetDiagnosticsAnalyzerSupportedLanguages(PEModule peModule, CustomAttributeHandle customAttrHandle) { // The DiagnosticAnalyzerAttribute has one constructor, which has a string parameter for the // first supported language and an array parameter for additional supported languages. // Parse the argument blob to extract the languages. BlobReader argsReader = peModule.GetMemoryReaderOrThrow(peModule.GetCustomAttributeValueOrThrow(customAttrHandle)); return(ReadLanguagesFromAttribute(ref argsReader)); }
private static IEnumerable <string> GetGeneratorSupportedLanguages(PEModule peModule, CustomAttributeHandle customAttrHandle) { // The GeneratorAttribute has two constructors: one default, and one with a string parameter for the // first supported language and an array parameter for additional supported languages. BlobReader argsReader = peModule.GetMemoryReaderOrThrow(peModule.GetCustomAttributeValueOrThrow(customAttrHandle)); if (argsReader.Length == 4) { // default ctor return(ImmutableArray.Create(LanguageNames.CSharp)); } else { // Parse the argument blob to extract the languages. return(ReadLanguagesFromAttribute(ref argsReader)); } }