提交 37bd3841 编写于 作者: N Neal Gafter

Merge pull request #2506 from gafter/fix365

Do not require an assembly-level ExtensionAttribute...
......@@ -56,11 +56,6 @@ internal sealed class PEAssemblySymbol : MetadataOrSourceAssemblySymbol
/// </summary>
private ImmutableArray<CSharpAttributeData> _lazyCustomAttributes;
/// <summary>
/// Lazily initialized by MightContainExtensionMethods property.
/// </summary>
private ThreeState _lazyContainsExtensionMethods;
internal PEAssemblySymbol(PEAssembly assembly, DocumentationProvider documentationProvider, bool isLinked, MetadataImportOptions importOptions)
{
Debug.Assert(assembly != null);
......@@ -233,20 +228,11 @@ public override bool MightContainExtensionMethods
{
get
{
if (!_lazyContainsExtensionMethods.HasValue())
{
var moduleSymbol = this.PrimaryModule;
var module = moduleSymbol.Module;
// The F# compiler may not emit an assembly-level ExtensionAttribute, and previous versions of C# never checked for it.
// In order to avoid a breaking change (while preserving the perceived performance benefits of not looking for extension
// methods in assemblies that don't contain them), we'll also look for FSharpInterfaceDataVersionAttribute.
var mightContainExtensionMethods = module.HasExtensionAttribute(_assembly.Handle, ignoreCase: false) ||
module.HasFSharpInterfaceDataVersionAttribute(_assembly.Handle);
_lazyContainsExtensionMethods = mightContainExtensionMethods.ToThreeState();
}
return _lazyContainsExtensionMethods.Value();
// While the specification for ExtensionAttribute requires that the containing assembly
// have the attribute if any type in the assembly has the attribute, some compilers do
// not properly follow that spec. Therefore we pessimistically assume every assembly
// may contain extension methods.
return true;
}
}
......
......@@ -6136,21 +6136,17 @@ static void M(object o)
}
}";
var compilation = CreateCompilationWithMscorlib(source2, new[] { reference1 });
compilation.VerifyDiagnostics(
// (5,11): error CS1061: 'object' does not contain a definition for 'M' and no extension method 'M' accepting a
// first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
// o.M();
Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "M").WithArguments("object", "M"));
compilation.VerifyDiagnostics(); // we now regognize the extension method even without the assembly-level attribute
var assembly = compilation.Assembly;
Assert.Equal(assembly.GetAttributes().Length, 0);
var type = compilation.GlobalNamespace.GetMember<NamedTypeSymbol>("E");
Assert.Equal(type.GetAttributes().Length, 1);
Assert.Equal(type.GetAttributes().Length, 0);
var method = compilation.GlobalNamespace.GetMember<NamedTypeSymbol>("E").GetMember<PEMethodSymbol>("M");
Assert.Equal(method.GetAttributes().Length, 1);
Assert.Equal(method.GetAttributes().Length, 0);
Assert.True(method.TestIsExtensionBitSet);
Assert.False(method.TestIsExtensionBitTrue);
Assert.False(method.IsExtensionMethod);
Assert.True(method.TestIsExtensionBitTrue);
Assert.True(method.IsExtensionMethod);
}
[WorkItem(530524, "DevDiv")]
......
......@@ -2389,7 +2389,8 @@ public void AssemblyMightContainExtensionMethods()
// mscorlib.dll
var mscorlib = type.GetMember<FieldSymbol>("F").Type.ContainingAssembly;
Assert.Equal(mscorlib.Name, "mscorlib");
Assert.False(mscorlib.MightContainExtensionMethods);
// We assume every PE assembly may contain extension methods.
Assert.True(mscorlib.MightContainExtensionMethods);
// TODO: Original references are not included in symbol validator.
if (isFromSource)
......@@ -2432,7 +2433,9 @@ public void AssemblyMightContainExtensionMethodsReset()
{
var assembly = module.ContainingAssembly;
var mightContainExtensionMethods = assembly.MightContainExtensionMethods;
Assert.Equal(isFromSource, mightContainExtensionMethods);
// Every PE assembly is assumed to be capable of having an extension method.
// The source assembly doesn't know (so reports "true") until all methods have been inspected.
Assert.True(mightContainExtensionMethods);
if (isFromSource)
{
Assert.Null(sourceAssembly);
......
......@@ -924,11 +924,6 @@ internal bool HasExtensionAttribute(Handle token, bool ignoreCase)
return FindTargetAttribute(token, ignoreCase ? AttributeDescription.CaseInsensitiveExtensionAttribute : AttributeDescription.CaseSensitiveExtensionAttribute).HasValue;
}
internal bool HasFSharpInterfaceDataVersionAttribute(Handle token)
{
return FindTargetAttribute(token, AttributeDescription.FSharpInterfaceDataVersionAttribute).HasValue;
}
internal bool HasVisualBasicEmbeddedAttribute(Handle token)
{
return FindTargetAttribute(token, AttributeDescription.VisualBasicEmbeddedAttribute).HasValue;
......
......@@ -389,8 +389,6 @@ static AttributeDescription()
s_signature_HasThis_Void_String_DeprecationType_UInt32_Type
};
private static readonly byte[][] s_signaturesOfFSharpInterfaceDataVersionAttribute = { s_signature_HasThis_Void_Int32_Int32_Int32 };
// early decoded attributes:
internal static readonly AttributeDescription OptionalAttribute = new AttributeDescription("System.Runtime.InteropServices", "OptionalAttribute", s_signaturesOfOptionalAttribute);
internal static readonly AttributeDescription ComImportAttribute = new AttributeDescription("System.Runtime.InteropServices", "ComImportAttribute", s_signaturesOfComImportAttribute);
......@@ -398,7 +396,6 @@ static AttributeDescription()
internal static readonly AttributeDescription ConditionalAttribute = new AttributeDescription("System.Diagnostics", "ConditionalAttribute", s_signaturesOfConditionalAttribute);
internal static readonly AttributeDescription CaseInsensitiveExtensionAttribute = new AttributeDescription("System.Runtime.CompilerServices", "ExtensionAttribute", s_signaturesOfExtensionAttribute, matchIgnoringCase: true);
internal static readonly AttributeDescription CaseSensitiveExtensionAttribute = new AttributeDescription("System.Runtime.CompilerServices", "ExtensionAttribute", s_signaturesOfExtensionAttribute, matchIgnoringCase: false);
internal static readonly AttributeDescription FSharpInterfaceDataVersionAttribute = new AttributeDescription("Microsoft.FSharp.Core", "FSharpInterfaceDataVersionAttribute", s_signaturesOfFSharpInterfaceDataVersionAttribute);
internal static readonly AttributeDescription InternalsVisibleToAttribute = new AttributeDescription("System.Runtime.CompilerServices", "InternalsVisibleToAttribute", s_signaturesOfInternalsVisibleToAttribute);
internal static readonly AttributeDescription AssemblySignatureKeyAttribute = new AttributeDescription("System.Reflection", "AssemblySignatureKeyAttribute", s_signaturesOfAssemblySignatureKeyAttribute);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册