diff --git a/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs b/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs index ad27c245c378043e3adc42cf91e36452649c1773..d566ca85017f8487c8b09ffe6f42ab7563915ebe 100644 --- a/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs +++ b/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs @@ -1998,10 +1998,10 @@ private IEnumerable FreezeDeclarationDiagnostics() { _declarationDiagnosticsFrozen = true; - // Also freeze generated attribute flags by observing them - // symbols bound after getting the declaration diagnostics shouldn't need to modify the flags - _needsGeneratedIsReadOnlyAttribute_IsFrozen = true; - _needsGeneratedIsByRefLikeAttribute_IsFrozen = true; + // Also freeze generated attribute flags. + // Symbols bound after getting the declaration + // diagnostics shouldn't need to modify the flags. + _needsGeneratedAttributes_IsFrozen = true; var result = _lazyDeclarationDiagnostics?.AsEnumerable() ?? Enumerable.Empty(); return result; diff --git a/src/Compilers/CSharp/Portable/Emitter/Model/PEAssemblyBuilder.cs b/src/Compilers/CSharp/Portable/Emitter/Model/PEAssemblyBuilder.cs index d95374b62c5af23e46ed7db515605cd966a9c12b..3324153ed0cb664aed18417031bf37498501a383 100644 --- a/src/Compilers/CSharp/Portable/Emitter/Model/PEAssemblyBuilder.cs +++ b/src/Compilers/CSharp/Portable/Emitter/Model/PEAssemblyBuilder.cs @@ -1,13 +1,10 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; using System.Reflection; -using System.Threading; -using Microsoft.Cci; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.Emit; using Microsoft.CodeAnalysis.PooledObjects; @@ -165,15 +162,11 @@ protected override void AddEmbeddedResourcesFromAddedModules(ArrayBuilder.Empty, - ImmutableArray>.Empty); - } - - return base.SynthesizeEmbeddedAttribute(); + // _lazyEmbeddedAttribute should have been created before calling this method. + return new SynthesizedAttributeData( + _lazyEmbeddedAttribute.Constructor, + ImmutableArray.Empty, + ImmutableArray>.Empty); } protected override SynthesizedAttributeData TrySynthesizeIsReadOnlyAttribute() diff --git a/src/Compilers/CSharp/Portable/Emitter/Model/PEModuleBuilder.cs b/src/Compilers/CSharp/Portable/Emitter/Model/PEModuleBuilder.cs index 208d336b53dc13ae3623eb616f5bd62ceb945ba8..6f8c168cf03baf5502540b7c0dc71e6b31f01b7a 100644 --- a/src/Compilers/CSharp/Portable/Emitter/Model/PEModuleBuilder.cs +++ b/src/Compilers/CSharp/Portable/Emitter/Model/PEModuleBuilder.cs @@ -43,7 +43,7 @@ public override NoPia.EmbeddedTypesManager EmbeddedTypesManagerOpt private bool _needsGeneratedIsReadOnlyAttribute_Value; - private bool _needsGeneratedIsReadOnlyAttribute_IsFrozen; + private bool _needsGeneratedAttributes_IsFrozen; /// /// Returns a value indicating whether this builder has a symbol that needs IsReadOnlyAttribute to be generated during emit phase. @@ -54,7 +54,7 @@ internal bool NeedsGeneratedIsReadOnlyAttribute { get { - _needsGeneratedIsReadOnlyAttribute_IsFrozen = true; + _needsGeneratedAttributes_IsFrozen = true; return Compilation.NeedsGeneratedIsReadOnlyAttribute || _needsGeneratedIsReadOnlyAttribute_Value; } } @@ -1427,11 +1427,7 @@ protected override Cci.IMethodDefinition CreatePrivateImplementationDetailsStati return new SynthesizedPrivateImplementationDetailsStaticConstructor(SourceModule, details, GetUntranslatedSpecialType(SpecialType.System_Void, syntaxOpt, diagnostics)); } - internal virtual SynthesizedAttributeData SynthesizeEmbeddedAttribute() - { - // Embedded attributes should never be synthesized in modules. - throw ExceptionUtilities.Unreachable; - } + internal abstract SynthesizedAttributeData SynthesizeEmbeddedAttribute(); internal SynthesizedAttributeData SynthesizeIsReadOnlyAttribute(Symbol symbol) { @@ -1469,6 +1465,8 @@ protected virtual SynthesizedAttributeData TrySynthesizeIsByRefLikeAttribute() internal void EnsureIsReadOnlyAttributeExists() { + Debug.Assert(!_needsGeneratedAttributes_IsFrozen); + if (_needsGeneratedIsReadOnlyAttribute_Value || Compilation.NeedsGeneratedIsReadOnlyAttribute) { return; @@ -1477,7 +1475,6 @@ internal void EnsureIsReadOnlyAttributeExists() // Don't report any errors. They should be reported during binding. if (Compilation.CheckIfIsReadOnlyAttributeShouldBeEmbedded(diagnosticsOpt: null, locationOpt: null)) { - Debug.Assert(!_needsGeneratedIsReadOnlyAttribute_IsFrozen); _needsGeneratedIsReadOnlyAttribute_Value = true; } } diff --git a/src/Compilers/CSharp/Portable/Emitter/Model/PENetModuleBuilder.cs b/src/Compilers/CSharp/Portable/Emitter/Model/PENetModuleBuilder.cs index 3a120a934ab98764fa118c524c05a0a4cea39c7f..a3f018a70cd9caec9321ede4f6e5a70ee4eb10ce 100644 --- a/src/Compilers/CSharp/Portable/Emitter/Model/PENetModuleBuilder.cs +++ b/src/Compilers/CSharp/Portable/Emitter/Model/PENetModuleBuilder.cs @@ -25,6 +25,12 @@ protected override void AddEmbeddedResourcesFromAddedModules(ArrayBuilder 0; public override IEnumerable GetFiles(EmitContext context) => SpecializedCollections.EmptyEnumerable(); public override ISourceAssemblySymbolInternal SourceAssemblyOpt => null; diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.cs index b87d27c5ef29c16e7e6937545ee3908d9c0b6822..9d9b09d2b10f4c8c1011b4aee122a18139f6b17a 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; +using System.Linq; using Microsoft.CodeAnalysis.CodeGen; using Microsoft.CodeAnalysis.CSharp.Emit; using Microsoft.CodeAnalysis.CSharp.Symbols; @@ -587,25 +588,8 @@ internal static bool WouldBeAssignableIfUsedAsMethodReceiver(BoundExpression rec private void CheckRefReadOnlySymbols(MethodSymbol symbol) { - var foundRefReadOnly = false; - - if (symbol.ReturnsByRefReadonly) - { - foundRefReadOnly = true; - } - else - { - foreach (var parameter in symbol.Parameters) - { - if (parameter.RefKind == RefKind.In) - { - foundRefReadOnly = true; - break; - } - } - } - - if (foundRefReadOnly) + if (symbol.ReturnsByRefReadonly || + symbol.Parameters.Any(p => p.RefKind == RefKind.In)) { _factory.CompilationState.ModuleBuilderOpt?.EnsureIsReadOnlyAttributeExists(); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Compilation_WellKnownMembers.cs b/src/Compilers/CSharp/Portable/Symbols/Compilation_WellKnownMembers.cs index d589bb2de30bfeb2bca48abcb127402873d5054b..1d0b4c2b0e3168390d37495d90f24c2a861f92d4 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Compilation_WellKnownMembers.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Compilation_WellKnownMembers.cs @@ -35,8 +35,7 @@ public partial class CSharpCompilation private bool _needsGeneratedIsReadOnlyAttribute_Value; private bool _needsGeneratedIsByRefLikeAttribute_Value; - private bool _needsGeneratedIsReadOnlyAttribute_IsFrozen; - private bool _needsGeneratedIsByRefLikeAttribute_IsFrozen; + private bool _needsGeneratedAttributes_IsFrozen; /// /// Returns a value indicating whether this compilation has a member that needs IsReadOnlyAttribute to be generated during emit phase. @@ -47,7 +46,7 @@ internal bool NeedsGeneratedIsReadOnlyAttribute { get { - _needsGeneratedIsReadOnlyAttribute_IsFrozen = true; + _needsGeneratedAttributes_IsFrozen = true; return _needsGeneratedIsReadOnlyAttribute_Value; } } @@ -61,7 +60,7 @@ internal bool NeedsGeneratedIsByRefLikeAttribute { get { - _needsGeneratedIsByRefLikeAttribute_IsFrozen = true; + _needsGeneratedAttributes_IsFrozen = true; return _needsGeneratedIsByRefLikeAttribute_Value; } } @@ -463,7 +462,7 @@ internal SynthesizedAttributeData SynthesizeDebuggerStepThroughAttribute() internal void EnsureIsReadOnlyAttributeExists(DiagnosticBag diagnostics, Location location, bool modifyCompilationForRefReadOnly) { - Debug.Assert(!modifyCompilationForRefReadOnly || !_needsGeneratedIsReadOnlyAttribute_IsFrozen); + Debug.Assert(!modifyCompilationForRefReadOnly || !_needsGeneratedAttributes_IsFrozen); var isNeeded = CheckIfIsReadOnlyAttributeShouldBeEmbedded(diagnostics, location); @@ -475,7 +474,7 @@ internal void EnsureIsReadOnlyAttributeExists(DiagnosticBag diagnostics, Locatio internal void EnsureIsByRefLikeAttributeExists(DiagnosticBag diagnostics, Location location, bool modifyCompilationForIsByRefLike) { - Debug.Assert(!modifyCompilationForIsByRefLike || !_needsGeneratedIsByRefLikeAttribute_IsFrozen); + Debug.Assert(!modifyCompilationForIsByRefLike || !_needsGeneratedAttributes_IsFrozen); var isNeeded = CheckIfIsByRefLikeAttributeShouldBeEmbedded(diagnostics, location); diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs index 9219de45e7c63c48773721f122fc8e3bb796065e..2fb83875607f43e0db0233cfa90d0ec9bcdfba23 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs @@ -1121,6 +1121,16 @@ internal override OverriddenOrHiddenMembersResult OverriddenOrHiddenMembers } } + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + { + throw ExceptionUtilities.Unreachable; + } + + internal override void AddSynthesizedReturnTypeAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + { + throw ExceptionUtilities.Unreachable; + } + // perf, not correctness internal override CSharpCompilation DeclaringCompilation => null; diff --git a/src/Compilers/CSharp/Portable/Symbols/MethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/MethodSymbol.cs index bb89e9485e842fdbcebe7f1a2395a3f7bbaf3b17..ed2174558021ac648029fa3de4152402cb5b1e71 100644 --- a/src/Compilers/CSharp/Portable/Symbols/MethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/MethodSymbol.cs @@ -1159,6 +1159,19 @@ internal virtual void AddSynthesizedReturnTypeAttributes(PEModuleBuilder moduleB { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeIsReadOnlyAttribute(this)); } + + var compilation = this.DeclaringCompilation; + var type = this.ReturnType; + + if (type.ContainsDynamic() && compilation.HasDynamicEmitAttributes()) + { + AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(type, this.ReturnTypeCustomModifiers.Length + this.RefCustomModifiers.Length, this.RefKind)); + } + + if (type.ContainsTupleNames() && compilation.HasTupleNamesAttributes) + { + AddSynthesizedAttribute(ref attributes, compilation.SynthesizeTupleNamesAttribute(type)); + } } IMethodSymbol IMethodSymbol.Construct(params ITypeSymbol[] arguments) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceClonedParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceClonedParameterSymbol.cs index 389bb93071a44f26c45f90ece56510001ddd2b21..366a066e52bd2eaa8d2571af17b3dca11335ef01 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceClonedParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceClonedParameterSymbol.cs @@ -3,8 +3,6 @@ using System; using System.Collections.Immutable; using System.Diagnostics; -using Microsoft.CodeAnalysis.CSharp.Emit; -using Microsoft.CodeAnalysis.PooledObjects; namespace Microsoft.CodeAnalysis.CSharp.Symbols { @@ -158,16 +156,6 @@ internal override bool IsCallerMemberName get { return _originalParam.IsCallerMemberName; } } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) - { - base.AddSynthesizedAttributes(moduleBuilder, ref attributes); - - if (this.RefKind == RefKind.RefReadOnly) - { - AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeIsReadOnlyAttribute(this)); - } - } - #endregion } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs index 4598f44788ba486e5bb4bd26f4217a4d1a021bc0..6066c790ae5d00bf451d3ff0447ff7216ad54143 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs @@ -964,23 +964,6 @@ public sealed override ImmutableArray GetReturnTypeAttribut return this.GetReturnTypeAttributesBag().Attributes; } - internal override void AddSynthesizedReturnTypeAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) - { - base.AddSynthesizedReturnTypeAttributes(moduleBuilder, ref attributes); - - if (this.ReturnType.ContainsDynamic()) - { - var compilation = this.DeclaringCompilation; - AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(this.ReturnType, this.ReturnTypeCustomModifiers.Length + this.RefCustomModifiers.Length, this.RefKind)); - } - - if (ReturnType.ContainsTupleNames()) - { - AddSynthesizedAttribute(ref attributes, - DeclaringCompilation.SynthesizeTupleNamesAttribute(ReturnType)); - } - } - internal override CSharpAttributeData EarlyDecodeWellKnownAttribute(ref EarlyDecodeWellKnownAttributeArguments arguments) { Debug.Assert(arguments.SymbolPart == AttributeLocation.None || arguments.SymbolPart == AttributeLocation.Return); diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbol.cs index eb09c105feaf2e75da6728073da04a6361d2fed7..b88d04b888b7f071839f8076901ae99f985d8d59 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbol.cs @@ -3,10 +3,7 @@ using System.Collections.Immutable; using System.Diagnostics; using System.Threading; -using Microsoft.CodeAnalysis.CSharp.Emit; using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Emit; -using Microsoft.CodeAnalysis.PooledObjects; namespace Microsoft.CodeAnalysis.CSharp.Symbols { @@ -253,16 +250,6 @@ public override bool IsImplicitlyDeclared } } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) - { - base.AddSynthesizedAttributes(moduleBuilder, ref attributes); - - if (this.RefKind == RefKind.In) - { - AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeIsReadOnlyAttribute(this)); - } - } - internal override bool IsMetadataIn => RefKind == RefKind.In; internal override bool IsMetadataOut => RefKind == RefKind.Out; diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbolBase.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbolBase.cs index 0dc9c607b23dc70fd518d4322d6072ce27a743de..a688c5dd2dbcee358ddc91212dd3c81cc700b49b 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbolBase.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbolBase.cs @@ -88,6 +88,11 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r AddSynthesizedAttribute(ref attributes, compilation.SynthesizeTupleNamesAttribute(Type)); } + + if (this.RefKind == RefKind.RefReadOnly) + { + AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeIsReadOnlyAttribute(this)); + } } internal abstract ParameterSymbol WithCustomModifiersAndParams(TypeSymbol newType, ImmutableArray newCustomModifiers, ImmutableArray newRefCustomModifiers, bool newIsParams); diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedImplementationMethod.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedImplementationMethod.cs index 4a2c92102d5571ffe51963d33a0c7dfe1d280494..6ef8c54e1c5d741735c4a303ff78666e1b84b4d7 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedImplementationMethod.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedImplementationMethod.cs @@ -81,25 +81,6 @@ public sealed override ImmutableArray RefCustomModifiers #endregion - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) - { - base.AddSynthesizedAttributes(moduleBuilder, ref attributes); - - var compilation = this.DeclaringCompilation; - if (this.ReturnType.ContainsDynamic() && compilation.HasDynamicEmitAttributes() && compilation.CanEmitBoolean()) - { - AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(this.ReturnType, this.ReturnTypeCustomModifiers.Length + this.RefCustomModifiers.Length, this.RefKind)); - } - - if (ReturnType.ContainsTupleNames() && - compilation.HasTupleNamesAttributes && - compilation.CanEmitSpecialType(SpecialType.System_String)) - { - AddSynthesizedAttribute(ref attributes, - compilation.SynthesizeTupleNamesAttribute(ReturnType)); - } - } - internal sealed override bool GenerateDebugInfo { get { return _generateDebugInfo; } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDynamicTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDynamicTests.cs index d397e64f6661091fed2425daac58ccbda462ff8d..c0927dad632ce09844dec2529c04445dfdb9d30b 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDynamicTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDynamicTests.cs @@ -683,8 +683,17 @@ public IEnumerable M1() break; case SymbolKind.Method: - // Dev11 marks return type of GetEnumerator with DynamicAttribute, we don't - Assert.Equal(0, ((MethodSymbol)member).GetReturnTypeAttributes().Length); + var attributes = ((MethodSymbol)member).GetReturnTypeAttributes(); + switch (member.MetadataName) + { + case "System.Collections.Generic.IEnumerator.get_Current": + case "System.Collections.Generic.IEnumerable.GetEnumerator": + Assert.Equal(1, attributes.Length); + break; + default: + Assert.Equal(0, attributes.Length); + break; + } break; case SymbolKind.Property: diff --git a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/EEMethodSymbol.cs b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/EEMethodSymbol.cs index f1f871e22e1295eb8cdee6dc88e6ef671b6e446e..3660564e07507b9004251d0e16db7af930732b11 100644 --- a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/EEMethodSymbol.cs +++ b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/EEMethodSymbol.cs @@ -697,24 +697,6 @@ private static TypeSymbol CalculateReturnType(CSharpCompilation compilation, Bou } } - internal override void AddSynthesizedReturnTypeAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) - { - base.AddSynthesizedReturnTypeAttributes(moduleBuilder, ref attributes); - - var compilation = this.DeclaringCompilation; - var returnType = this.ReturnType; - - if (returnType.ContainsDynamic() && compilation.HasDynamicEmitAttributes()) - { - AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(returnType, ReturnTypeCustomModifiers.Length + RefCustomModifiers.Length, RefKind)); - } - - if (returnType.ContainsTupleNames() && compilation.HasTupleNamesAttributes) - { - AddSynthesizedAttribute(ref attributes, compilation.SynthesizeTupleNamesAttribute(returnType)); - } - } - internal override int CalculateLocalSyntaxOffset(int localPosition, SyntaxTree localTree) { return localPosition; diff --git a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/ReferencedModulesTests.cs b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/ReferencedModulesTests.cs index 7ca90345ff9125d95e40ba50b9a1283c3a819aea..0e2b94258810a844c218dcf5bfa8170e27d2cfc1 100644 --- a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/ReferencedModulesTests.cs +++ b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/ReferencedModulesTests.cs @@ -1010,6 +1010,11 @@ internal override IEnumerable GetTopLevelTypesCore(Emi } } + internal override SynthesizedAttributeData SynthesizeEmbeddedAttribute() + { + throw new NotImplementedException(); + } + public override int CurrentGenerationOrdinal => _builder.CurrentGenerationOrdinal; public override ISourceAssemblySymbolInternal SourceAssemblyOpt => _builder.SourceAssemblyOpt; diff --git a/src/Test/Utilities/Portable/Metadata/MetadataReaderUtils.cs b/src/Test/Utilities/Portable/Metadata/MetadataReaderUtils.cs index 3aeeaaa31569174fd271d2b1b663bb9d1c566be0..c1619061f4f7e027f0b156f668d3155fe41354b0 100644 --- a/src/Test/Utilities/Portable/Metadata/MetadataReaderUtils.cs +++ b/src/Test/Utilities/Portable/Metadata/MetadataReaderUtils.cs @@ -156,8 +156,9 @@ public static StringHandle GetName(this MetadataReader reader, EntityHandle toke switch (token.Kind) { case HandleKind.TypeReference: - var typeRef = reader.GetTypeReference((TypeReferenceHandle)token); - return typeRef.Name; + return reader.GetTypeReference((TypeReferenceHandle)token).Name; + case HandleKind.TypeDefinition: + return reader.GetTypeDefinition((TypeDefinitionHandle)token).Name; default: throw ExceptionUtilities.UnexpectedValue(token.Kind); } @@ -172,6 +173,25 @@ public static IEnumerable GetCustomAttributeRows(this Metada } } + public static string GetCustomAttributeName(this MetadataReader reader, CustomAttributeRow row) + { + EntityHandle parent; + var token = row.ConstructorToken; + switch (token.Kind) + { + case HandleKind.MemberReference: + parent = reader.GetMemberReference((MemberReferenceHandle)token).Parent; + break; + case HandleKind.MethodDefinition: + parent = reader.GetMethodDefinition((MethodDefinitionHandle)token).GetDeclaringType(); + break; + default: + throw ExceptionUtilities.UnexpectedValue(token.Kind); + } + var strHandle = reader.GetName(parent); + return reader.GetString(strHandle); + } + public static bool IsIncluded(this ImmutableArray metadata, string str) { var builder = ArrayBuilder.GetInstance();