Browse Source

Don't cache attributes in the type system.

pull/1030/head
Daniel Grunwald 7 years ago
parent
commit
4ec0028356
  1. 81
      ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs
  2. 8
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  3. 18
      ICSharpCode.Decompiler/CSharp/RequiredNamespaceCollector.cs
  4. 5
      ICSharpCode.Decompiler/CSharp/Resolver/CSharpOperators.cs
  5. 29
      ICSharpCode.Decompiler/CSharp/Resolver/CSharpResolver.cs
  6. 13
      ICSharpCode.Decompiler/CSharp/Resolver/ReducedExtensionMethod.cs
  7. 91
      ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
  8. 26
      ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs
  9. 5
      ICSharpCode.Decompiler/NRExtensions.cs
  10. 2
      ICSharpCode.Decompiler/TypeSystem/ComHelper.cs
  11. 3
      ICSharpCode.Decompiler/TypeSystem/IEntity.cs
  12. 5
      ICSharpCode.Decompiler/TypeSystem/IMethod.cs
  13. 4
      ICSharpCode.Decompiler/TypeSystem/IParameter.cs
  14. 4
      ICSharpCode.Decompiler/TypeSystem/ITypeParameter.cs
  15. 1
      ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractResolvedEntity.cs
  16. 4
      ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractResolvedTypeParameter.cs
  17. 4
      ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultParameter.cs
  18. 1
      ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedMethod.cs
  19. 4
      ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs
  20. 2
      ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedTypeParameter.cs
  21. 1
      ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultUnresolvedParameter.cs
  22. 4
      ICSharpCode.Decompiler/TypeSystem/Implementation/DummyTypeParameter.cs
  23. 4
      ICSharpCode.Decompiler/TypeSystem/Implementation/FakeMember.cs
  24. 12
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataEvent.cs
  25. 14
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataField.cs
  26. 24
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs
  27. 12
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataParameter.cs
  28. 12
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataProperty.cs
  29. 12
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs
  30. 11
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeParameter.cs
  31. 6
      ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedMember.cs
  32. 8
      ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedMethod.cs
  33. 2
      ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedParameter.cs
  34. 43
      ICSharpCode.Decompiler/TypeSystem/InheritanceHelper.cs
  35. 173
      ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs
  36. 11
      ICSharpCode.Decompiler/TypeSystem/VarArgInstanceMethod.cs

81
ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs

@ -106,7 +106,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -106,7 +106,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
Assert.IsFalse(method.IsVirtual);
Assert.IsFalse(method.IsStatic);
Assert.AreEqual(0, method.Parameters.Count);
Assert.AreEqual(0, method.Attributes.Count);
Assert.AreEqual(0, method.GetAttributes().Count());
Assert.IsTrue(method.HasBody);
Assert.IsNull(method.AccessorOwner);
}
@ -117,7 +117,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -117,7 +117,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
ITypeDefinition testClass = GetTypeDefinition(typeof(DynamicTest));
Assert.AreEqual(SpecialType.Dynamic, testClass.Fields.Single(f => f.Name == "DynamicField").ReturnType);
Assert.AreEqual(SpecialType.Dynamic, testClass.Properties.Single().ReturnType);
Assert.AreEqual(0, testClass.Properties.Single().Attributes.Count);
Assert.AreEqual(0, testClass.Properties.Single().GetAttributes().Count());
}
[Test]
@ -153,7 +153,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -153,7 +153,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
{
ITypeDefinition testClass = GetTypeDefinition(typeof(DynamicTest));
IMethod m1 = testClass.Methods.Single(me => me.Name == "DynamicGenerics1");
Assert.AreEqual(0, m1.Parameters[0].Attributes.Count);
Assert.AreEqual(0, m1.Parameters[0].GetAttributes().Count());
}
[Test]
@ -550,7 +550,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -550,7 +550,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
[Test]
public void SerializableAttribute()
{
IAttribute attr = GetTypeDefinition(typeof(NonCustomAttributes)).Attributes.Single();
IAttribute attr = GetTypeDefinition(typeof(NonCustomAttributes)).GetAttributes().Single();
Assert.AreEqual("System.SerializableAttribute", attr.AttributeType.FullName);
}
@ -558,13 +558,13 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -558,13 +558,13 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
public void NonSerializedAttribute()
{
IField field = GetTypeDefinition(typeof(NonCustomAttributes)).Fields.Single(f => f.Name == "NonSerializedField");
Assert.AreEqual("System.NonSerializedAttribute", field.Attributes.Single().AttributeType.FullName);
Assert.AreEqual("System.NonSerializedAttribute", field.GetAttributes().Single().AttributeType.FullName);
}
[Test]
public void ExplicitStructLayoutAttribute()
{
IAttribute attr = GetTypeDefinition(typeof(ExplicitFieldLayoutStruct)).Attributes.Single();
IAttribute attr = GetTypeDefinition(typeof(ExplicitFieldLayoutStruct)).GetAttributes().Single();
Assert.AreEqual("System.Runtime.InteropServices.StructLayoutAttribute", attr.AttributeType.FullName);
var arg1 = attr.FixedArguments.Single();
Assert.AreEqual("System.Runtime.InteropServices.LayoutKind", arg1.Type.FullName);
@ -585,14 +585,14 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -585,14 +585,14 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
public void FieldOffsetAttribute()
{
IField field = GetTypeDefinition(typeof(ExplicitFieldLayoutStruct)).Fields.Single(f => f.Name == "Field0");
Assert.AreEqual("System.Runtime.InteropServices.FieldOffsetAttribute", field.Attributes.Single().AttributeType.FullName);
var arg = field.Attributes.Single().FixedArguments.Single();
Assert.AreEqual("System.Runtime.InteropServices.FieldOffsetAttribute", field.GetAttributes().Single().AttributeType.FullName);
var arg = field.GetAttributes().Single().FixedArguments.Single();
Assert.AreEqual("System.Int32", arg.Type.FullName);
Assert.AreEqual(0, arg.Value);
field = GetTypeDefinition(typeof(ExplicitFieldLayoutStruct)).Fields.Single(f => f.Name == "Field100");
Assert.AreEqual("System.Runtime.InteropServices.FieldOffsetAttribute", field.Attributes.Single().AttributeType.FullName);
arg = field.Attributes.Single().FixedArguments.Single();
Assert.AreEqual("System.Runtime.InteropServices.FieldOffsetAttribute", field.GetAttributes().Single().AttributeType.FullName);
arg = field.GetAttributes().Single().FixedArguments.Single();
Assert.AreEqual("System.Int32", arg.Type.FullName);
Assert.AreEqual(100, arg.Value);
}
@ -601,7 +601,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -601,7 +601,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
public void DllImportAttribute()
{
IMethod method = GetTypeDefinition(typeof(NonCustomAttributes)).Methods.Single(m => m.Name == "DllMethod");
IAttribute dllImport = method.Attributes.Single();
IAttribute dllImport = method.GetAttributes().Single();
Assert.AreEqual("System.Runtime.InteropServices.DllImportAttribute", dllImport.AttributeType.FullName);
Assert.AreEqual("unmanaged.dll", dllImport.FixedArguments[0].Value);
Assert.AreEqual((int)CharSet.Unicode, dllImport.NamedArguments.Single().Value);
@ -613,16 +613,17 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -613,16 +613,17 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
IParameter p = GetTypeDefinition(typeof(NonCustomAttributes)).Methods.Single(m => m.Name == "DllMethod").Parameters.Single();
Assert.IsTrue(p.IsRef);
Assert.IsFalse(p.IsOut);
Assert.AreEqual(2, p.Attributes.Count);
Assert.AreEqual("System.Runtime.InteropServices.InAttribute", p.Attributes[0].AttributeType.FullName);
Assert.AreEqual("System.Runtime.InteropServices.OutAttribute", p.Attributes[1].AttributeType.FullName);
var attr = p.GetAttributes().ToList();
Assert.AreEqual(2, attr.Count);
Assert.AreEqual("System.Runtime.InteropServices.InAttribute", attr[0].AttributeType.FullName);
Assert.AreEqual("System.Runtime.InteropServices.OutAttribute", attr[1].AttributeType.FullName);
}
[Test]
public void MarshalAsAttributeOnMethod()
{
IMethod method = GetTypeDefinition(typeof(NonCustomAttributes)).Methods.Single(m => m.Name == "DllMethod");
IAttribute marshalAs = method.ReturnTypeAttributes.Single();
IAttribute marshalAs = method.GetReturnTypeAttributes().Single();
Assert.AreEqual((int)UnmanagedType.Bool, marshalAs.FixedArguments.Single().Value);
}
@ -633,7 +634,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -633,7 +634,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
Assert.IsFalse(p.IsOptional);
Assert.IsFalse(p.IsRef);
Assert.IsTrue(p.IsOut);
Assert.AreEqual(0, p.Attributes.Count);
Assert.AreEqual(0, p.GetAttributes().Count());
Assert.IsTrue(p.Type.Kind == TypeKind.ByReference);
}
@ -645,7 +646,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -645,7 +646,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
Assert.IsFalse(p.IsRef);
Assert.IsFalse(p.IsOut);
Assert.IsTrue(p.IsParams);
Assert.AreEqual(0, p.Attributes.Count);
Assert.AreEqual(0, p.GetAttributes().Count());
Assert.IsTrue(p.Type.Kind == TypeKind.Array);
}
@ -657,7 +658,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -657,7 +658,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
Assert.IsFalse(p.IsRef);
Assert.IsFalse(p.IsOut);
Assert.IsFalse(p.IsParams);
Assert.AreEqual(0, p.Attributes.Count);
Assert.AreEqual(0, p.GetAttributes().Count());
Assert.AreEqual(4, p.ConstantValue);
}
@ -670,7 +671,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -670,7 +671,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
Assert.IsFalse(p.IsOut);
Assert.IsFalse(p.IsParams);
// explicit optional parameter appears in type system if it's read from C#, but not when read from IL
//Assert.AreEqual(1, p.Attributes.Count);
//Assert.AreEqual(1, p.GetAttributes().Count());
}
[Test]
@ -681,7 +682,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -681,7 +682,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
Assert.IsFalse(p.IsRef);
Assert.IsFalse(p.IsOut);
Assert.IsFalse(p.IsParams);
Assert.AreEqual(0, p.Attributes.Count);
Assert.AreEqual(0, p.GetAttributes().Count());
Assert.AreEqual((int)StringComparison.OrdinalIgnoreCase, p.ConstantValue);
}
@ -693,7 +694,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -693,7 +694,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
Assert.IsFalse(p.IsRef);
Assert.IsFalse(p.IsOut);
Assert.IsFalse(p.IsParams);
Assert.AreEqual(0, p.Attributes.Count);
Assert.AreEqual(0, p.GetAttributes().Count());
Assert.IsNull(p.ConstantValue);
}
@ -781,7 +782,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -781,7 +782,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
{
ITypeDefinition type = GetTypeDefinition(typeof(IAssemblyEnum));
// [ComImport]
Assert.AreEqual(1, type.Attributes.Count(a => a.AttributeType.FullName == typeof(ComImportAttribute).FullName));
Assert.AreEqual(1, type.GetAttributes().Count(a => a.AttributeType.FullName == typeof(ComImportAttribute).FullName));
IMethod m = type.Methods.Single();
Assert.AreEqual("GetNextAssembly", m.Name);
@ -892,7 +893,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -892,7 +893,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
CustomAttributeTypedArgument<IType> GetParamsAttributeArgument(int index)
{
ITypeDefinition type = GetTypeDefinition(typeof(ParamsAttribute));
var arr = (AttributeArray)type.Attributes.Single().FixedArguments.Single().Value;
var arr = (AttributeArray)type.GetAttributes().Single().FixedArguments.Single().Value;
Assert.AreEqual(5, arr.Length);
return arr[index];
}
@ -942,7 +943,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -942,7 +943,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
{
ITypeDefinition type = GetTypeDefinition(typeof(ParamsAttribute));
IProperty prop = type.Properties.Single(p => p.Name == "Property");
var attr = prop.Attributes.Single();
var attr = prop.GetAttributes().Single();
Assert.AreEqual(type, attr.AttributeType);
var elements = (AttributeArray)attr.FixedArguments.Single().Value;
@ -959,15 +960,15 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -959,15 +960,15 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
{
ITypeDefinition type = GetTypeDefinition(typeof(ParamsAttribute));
IProperty prop = type.Properties.Single(p => p.Name == "Property");
Assert.AreEqual(0, prop.Getter.Attributes.Count);
Assert.AreEqual(1, prop.Getter.ReturnTypeAttributes.Count);
Assert.AreEqual(0, prop.Getter.GetAttributes().Count());
Assert.AreEqual(1, prop.Getter.GetReturnTypeAttributes().Count());
}
[Test]
public void DoubleAttribute_ImplicitNumericConversion()
{
ITypeDefinition type = GetTypeDefinition(typeof(DoubleAttribute));
var arg = type.Attributes.Single().FixedArguments.Single();
var arg = type.GetAttributes().Single().FixedArguments.Single();
Assert.AreEqual("System.Double", arg.Type.ReflectionName);
Assert.AreEqual(1.0, arg.Value);
}
@ -1397,7 +1398,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -1397,7 +1398,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
var f = type.GetFields().Single(x => x.Name == name);
Assert.IsTrue(f.IsConst);
Assert.AreEqual(expected, f.ConstantValue);
Assert.AreEqual(0, f.Attributes.Count);
Assert.AreEqual(0, f.GetAttributes().Count());
}
[Test]
@ -1518,33 +1519,33 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -1518,33 +1519,33 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
var type = GetTypeDefinition(typeof(ClassWithAttributesUsingNestedMembers));
var inner = type.GetNestedTypes().Single(t => t.Name == "Inner");
var myAttribute = type.GetNestedTypes().Single(t => t.Name == "MyAttribute");
var typeTypeTestAttr = type.Attributes.Single(a => a.AttributeType.Name == "TypeTestAttribute");
var typeTypeTestAttr = type.GetAttributes().Single(a => a.AttributeType.Name == "TypeTestAttribute");
Assert.AreEqual(42, typeTypeTestAttr.FixedArguments[0].Value);
Assert.AreEqual(inner, typeTypeTestAttr.FixedArguments[1].Value);
var typeMyAttr = type.Attributes.Single(a => a.AttributeType.Name == "MyAttribute");
var typeMyAttr = type.GetAttributes().Single(a => a.AttributeType.Name == "MyAttribute");
Assert.AreEqual(myAttribute, typeMyAttr.AttributeType);
var prop = type.GetProperties().Single(p => p.Name == "P");
var propTypeTestAttr = prop.Attributes.Single(a => a.AttributeType.Name == "TypeTestAttribute");
var propTypeTestAttr = prop.GetAttributes().Single(a => a.AttributeType.Name == "TypeTestAttribute");
Assert.AreEqual(42, propTypeTestAttr.FixedArguments[0].Value);
Assert.AreEqual(inner, propTypeTestAttr.FixedArguments[1].Value);
var propMyAttr = prop.Attributes.Single(a => a.AttributeType.Name == "MyAttribute");
var propMyAttr = prop.GetAttributes().Single(a => a.AttributeType.Name == "MyAttribute");
Assert.AreEqual(myAttribute, propMyAttr.AttributeType);
var attributedInner = (ITypeDefinition)type.GetNestedTypes().Single(t => t.Name == "AttributedInner");
var innerTypeTestAttr = attributedInner.Attributes.Single(a => a.AttributeType.Name == "TypeTestAttribute");
var innerTypeTestAttr = attributedInner.GetAttributes().Single(a => a.AttributeType.Name == "TypeTestAttribute");
Assert.AreEqual(42, innerTypeTestAttr.FixedArguments[0].Value);
Assert.AreEqual(inner, innerTypeTestAttr.FixedArguments[1].Value);
var innerMyAttr = attributedInner.Attributes.Single(a => a.AttributeType.Name == "MyAttribute");
var innerMyAttr = attributedInner.GetAttributes().Single(a => a.AttributeType.Name == "MyAttribute");
Assert.AreEqual(myAttribute, innerMyAttr.AttributeType);
var attributedInner2 = (ITypeDefinition)type.GetNestedTypes().Single(t => t.Name == "AttributedInner2");
var inner2 = attributedInner2.GetNestedTypes().Single(t => t.Name == "Inner");
var myAttribute2 = attributedInner2.GetNestedTypes().Single(t => t.Name == "MyAttribute");
var inner2TypeTestAttr = attributedInner2.Attributes.Single(a => a.AttributeType.Name == "TypeTestAttribute");
var inner2TypeTestAttr = attributedInner2.GetAttributes().Single(a => a.AttributeType.Name == "TypeTestAttribute");
Assert.AreEqual(43, inner2TypeTestAttr.FixedArguments[0].Value);
Assert.AreEqual(inner2, inner2TypeTestAttr.FixedArguments[1].Value);
var inner2MyAttr = attributedInner2.Attributes.Single(a => a.AttributeType.Name == "MyAttribute");
var inner2MyAttr = attributedInner2.GetAttributes().Single(a => a.AttributeType.Name == "MyAttribute");
Assert.AreEqual(myAttribute2, inner2MyAttr.AttributeType);
}
@ -1552,7 +1553,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -1552,7 +1553,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
public void ClassWithAttributeOnTypeParameter()
{
var tp = GetTypeDefinition(typeof(ClassWithAttributeOnTypeParameter<>)).TypeParameters.Single();
var attr = tp.Attributes.Single();
var attr = tp.GetAttributes().Single();
Assert.AreEqual("DoubleAttribute", attr.AttributeType.Name);
}
@ -1658,7 +1659,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -1658,7 +1659,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
public void Void_SerializableAttribute()
{
ITypeDefinition c = compilation.FindType(typeof(void)).GetDefinition();
var attr = c.Attributes.Single(a => a.AttributeType.FullName == "System.SerializableAttribute");
var attr = c.GetAttributes().Single(a => a.AttributeType.FullName == "System.SerializableAttribute");
Assert.AreEqual(0, attr.Constructor.Parameters.Count);
Assert.AreEqual(0, attr.FixedArguments.Length);
Assert.AreEqual(0, attr.NamedArguments.Length);
@ -1668,7 +1669,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -1668,7 +1669,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
public void Void_StructLayoutAttribute()
{
ITypeDefinition c = compilation.FindType(typeof(void)).GetDefinition();
var attr = c.Attributes.Single(a => a.AttributeType.FullName == "System.Runtime.InteropServices.StructLayoutAttribute");
var attr = c.GetAttributes().Single(a => a.AttributeType.FullName == "System.Runtime.InteropServices.StructLayoutAttribute");
Assert.AreEqual(1, attr.Constructor.Parameters.Count);
Assert.AreEqual(1, attr.FixedArguments.Length);
Assert.AreEqual(0, attr.FixedArguments[0].Value);
@ -1681,7 +1682,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -1681,7 +1682,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
public void Void_ComVisibleAttribute()
{
ITypeDefinition c = compilation.FindType(typeof(void)).GetDefinition();
var attr = c.Attributes.Single(a => a.AttributeType.FullName == "System.Runtime.InteropServices.ComVisibleAttribute");
var attr = c.GetAttributes().Single(a => a.AttributeType.FullName == "System.Runtime.InteropServices.ComVisibleAttribute");
Assert.AreEqual(1, attr.Constructor.Parameters.Count);
Assert.AreEqual(1, attr.FixedArguments.Length);
Assert.AreEqual(true, attr.FixedArguments[0].Value);

8
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -794,7 +794,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -794,7 +794,7 @@ namespace ICSharpCode.Decompiler.CSharp
EnumValueDisplayMode DetectBestEnumValueDisplayMode(ITypeDefinition typeDef, PEFile module)
{
if (typeDef.GetAttribute(KnownAttribute.Flags) != null)
if (typeDef.HasAttribute(KnownAttribute.Flags, inherit: false))
return EnumValueDisplayMode.All;
bool first = true;
long firstValue = 0, previousValue = 0;
@ -997,7 +997,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -997,7 +997,7 @@ namespace ICSharpCode.Decompiler.CSharp
void AddDefinesForConditionalAttributes(ILFunction function, DecompileRun decompileRun, ITypeResolveContext decompilationContext)
{
foreach (var call in function.Descendants.OfType<CallInstruction>()) {
var attr = call.Method.GetAttribute(KnownAttribute.Conditional);
var attr = call.Method.GetAttribute(KnownAttribute.Conditional, inherit: true);
var symbolName = attr?.FixedArguments.FirstOrDefault().Value as string;
if (symbolName == null || !decompileRun.DefinedSymbols.Add(symbolName))
continue;
@ -1014,12 +1014,12 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1014,12 +1014,12 @@ namespace ICSharpCode.Decompiler.CSharp
long initValue = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, field.ConstantValue, false);
enumDec.Initializer = typeSystemAstBuilder.ConvertConstantValue(decompilationContext.CurrentTypeDefinition.EnumUnderlyingType, field.ConstantValue);
if (enumDec.Initializer is PrimitiveExpression primitive
&& (decompilationContext.CurrentTypeDefinition.Attributes.Any(a => a.AttributeType.FullName == "System.FlagsAttribute")
&& (decompilationContext.CurrentTypeDefinition.HasAttribute(KnownAttribute.Flags)
|| (initValue > 9 && ((initValue & (initValue - 1)) == 0 || (initValue & (initValue + 1)) == 0))))
{
primitive.SetValue(initValue, $"0x{initValue:X}");
}
enumDec.Attributes.AddRange(field.Attributes.Select(a => new AttributeSection(typeSystemAstBuilder.ConvertAttribute(a))));
enumDec.Attributes.AddRange(field.GetAttributes().Select(a => new AttributeSection(typeSystemAstBuilder.ConvertAttribute(a))));
enumDec.AddAnnotation(new MemberResolveResult(null, field));
return enumDec;
}

18
ICSharpCode.Decompiler/CSharp/RequiredNamespaceCollector.cs

@ -40,10 +40,10 @@ namespace ICSharpCode.Decompiler.CSharp @@ -40,10 +40,10 @@ namespace ICSharpCode.Decompiler.CSharp
switch (entity) {
case ITypeDefinition td:
namespaces.Add(td.Namespace);
HandleAttributes(td.Attributes, namespaces);
HandleAttributes(td.GetAttributes(), namespaces);
foreach (var typeParam in td.TypeParameters) {
HandleAttributes(typeParam.Attributes, namespaces);
HandleAttributes(typeParam.GetAttributes(), namespaces);
}
foreach (var baseType in td.DirectBaseTypes) {
@ -71,19 +71,19 @@ namespace ICSharpCode.Decompiler.CSharp @@ -71,19 +71,19 @@ namespace ICSharpCode.Decompiler.CSharp
}
break;
case IField field:
HandleAttributes(field.Attributes, namespaces);
HandleAttributes(field.GetAttributes(), namespaces);
CollectNamespacesForTypeReference(field.ReturnType, namespaces);
break;
case IMethod method:
HandleAttributes(method.Attributes, namespaces);
HandleAttributes(method.ReturnTypeAttributes, namespaces);
HandleAttributes(method.GetAttributes(), namespaces);
HandleAttributes(method.GetReturnTypeAttributes(), namespaces);
CollectNamespacesForTypeReference(method.ReturnType, namespaces);
foreach (var param in method.Parameters) {
HandleAttributes(param.Attributes, namespaces);
HandleAttributes(param.GetAttributes(), namespaces);
CollectNamespacesForTypeReference(param.Type, namespaces);
}
foreach (var typeParam in method.TypeParameters) {
HandleAttributes(typeParam.Attributes, namespaces);
HandleAttributes(typeParam.GetAttributes(), namespaces);
}
if (!method.MetadataToken.IsNil && method.HasBody) {
var reader = typeSystem.ModuleDefinition.Reader;
@ -93,12 +93,12 @@ namespace ICSharpCode.Decompiler.CSharp @@ -93,12 +93,12 @@ namespace ICSharpCode.Decompiler.CSharp
}
break;
case IProperty property:
HandleAttributes(property.Attributes, namespaces);
HandleAttributes(property.GetAttributes(), namespaces);
CollectNamespaces(property.Getter, typeSystem, namespaces);
CollectNamespaces(property.Setter, typeSystem, namespaces);
break;
case IEvent @event:
HandleAttributes(@event.Attributes, namespaces);
HandleAttributes(@event.GetAttributes(), namespaces);
CollectNamespaces(@event.AddAccessor, typeSystem, namespaces);
CollectNamespaces(@event.RemoveAccessor, typeSystem, namespaces);
break;

5
ICSharpCode.Decompiler/CSharp/Resolver/CSharpOperators.cs

@ -150,8 +150,9 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver @@ -150,8 +150,9 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
get { return SymbolKind.Operator; }
}
IReadOnlyList<IAttribute> IEntity.Attributes {
get { return EmptyList<IAttribute>.Instance; }
IEnumerable<IAttribute> IEntity.GetAttributes()
{
return EmptyList<IAttribute>.Instance;
}
Accessibility IEntity.Accessibility {

29
ICSharpCode.Decompiler/CSharp/Resolver/CSharpResolver.cs

@ -1741,7 +1741,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver @@ -1741,7 +1741,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
void CheckForEnumerableInterface(ResolveResult expression, out IType collectionType, out IType enumeratorType, out IType elementType, out ResolveResult getEnumeratorInvocation)
{
bool? isGeneric;
elementType = GetElementTypeFromIEnumerable(expression.Type, compilation, false, out isGeneric);
elementType = expression.Type.GetElementTypeFromIEnumerable(compilation, false, out isGeneric);
if (isGeneric == true) {
ITypeDefinition enumerableOfT = compilation.FindType(KnownTypeCode.IEnumerableOfT).GetDefinition();
if (enumerableOfT != null)
@ -1765,33 +1765,6 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver @@ -1765,33 +1765,6 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
getEnumeratorInvocation = ResolveMemberAccess(getEnumeratorInvocation, "GetEnumerator", EmptyList<IType>.Instance, NameLookupMode.InvocationTarget);
getEnumeratorInvocation = ResolveInvocation(getEnumeratorInvocation, new ResolveResult[0]);
}
static IType GetElementTypeFromIEnumerable(IType collectionType, ICompilation compilation, bool allowIEnumerator, out bool? isGeneric)
{
bool foundNonGenericIEnumerable = false;
foreach (IType baseType in collectionType.GetAllBaseTypes()) {
ITypeDefinition baseTypeDef = baseType.GetDefinition();
if (baseTypeDef != null) {
KnownTypeCode typeCode = baseTypeDef.KnownTypeCode;
if (typeCode == KnownTypeCode.IEnumerableOfT || (allowIEnumerator && typeCode == KnownTypeCode.IEnumeratorOfT)) {
ParameterizedType pt = baseType as ParameterizedType;
if (pt != null) {
isGeneric = true;
return pt.GetTypeArgument(0);
}
}
if (typeCode == KnownTypeCode.IEnumerable || (allowIEnumerator && typeCode == KnownTypeCode.IEnumerator))
foundNonGenericIEnumerable = true;
}
}
// System.Collections.IEnumerable found in type hierarchy -> Object is element type.
if (foundNonGenericIEnumerable) {
isGeneric = false;
return compilation.FindType(KnownTypeCode.Object);
}
isGeneric = null;
return SpecialType.UnknownType;
}
#endregion
#region GetExtensionMethods

13
ICSharpCode.Decompiler/CSharp/Resolver/ReducedExtensionMethod.cs

@ -136,12 +136,6 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver @@ -136,12 +136,6 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
#region IMethod implementation
public IReadOnlyList<IAttribute> ReturnTypeAttributes {
get {
return baseMethod.ReturnTypeAttributes;
}
}
public IReadOnlyList<ITypeParameter> TypeParameters {
get {
return baseMethod.TypeParameters;
@ -243,11 +237,8 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver @@ -243,11 +237,8 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
}
}
public IReadOnlyList<IAttribute> Attributes {
get {
return baseMethod.Attributes;
}
}
IEnumerable<IAttribute> IEntity.GetAttributes() => baseMethod.GetAttributes();
IEnumerable<IAttribute> IMethod.GetReturnTypeAttributes() => baseMethod.GetReturnTypeAttributes();
public bool IsStatic {
get {

91
ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs

@ -455,7 +455,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -455,7 +455,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
public Attribute ConvertAttribute(IAttribute attribute)
{
Attribute attr = new Attribute();
attr.Type = ConvertType(attribute.AttributeType);
attr.Type = ConvertAttributeType(attribute.AttributeType);
SimpleType st = attr.Type as SimpleType;
MemberType mt = attr.Type as MemberType;
if (st != null && st.Identifier.EndsWith("Attribute", StringComparison.Ordinal)) {
@ -482,6 +482,18 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -482,6 +482,18 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
}
return attr;
}
private IEnumerable<AttributeSection> ConvertAttributes(IEnumerable<IAttribute> attibutes)
{
return attibutes.Select(a => new AttributeSection(ConvertAttribute(a)));
}
private IEnumerable<AttributeSection> ConvertAttributes(IEnumerable<IAttribute> attibutes, string target)
{
return attibutes.Select(a => new AttributeSection(ConvertAttribute(a)) {
AttributeTarget = target
});
}
#endregion
#region Convert Attribute Type
@ -495,6 +507,28 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -495,6 +507,28 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
if (type.Name.Length > 9 && type.Name.EndsWith("Attribute", StringComparison.Ordinal)) {
shortName = type.Name.Remove(type.Name.Length - 9);
}
if (AlwaysUseShortTypeNames) {
switch (astType) {
case SimpleType st:
st.Identifier = shortName;
break;
case MemberType mt:
mt.MemberName = shortName;
break;
}
} else if (resolver != null) {
ApplyShortAttributeNameIfPossible(type, astType, shortName);
}
if (AddTypeReferenceAnnotations)
astType.AddAnnotation(type);
if (AddResolveResultAnnotations)
astType.AddAnnotation(new TypeResolveResult(type));
return astType;
}
private void ApplyShortAttributeNameIfPossible(IType type, AstType astType, string shortName)
{
switch (astType) {
case SimpleType st:
ResolveResult shortRR = null;
@ -529,12 +563,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -529,12 +563,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
}
break;
}
if (AddTypeReferenceAnnotations)
astType.AddAnnotation(type);
if (AddResolveResultAnnotations)
astType.AddAnnotation(new TypeResolveResult(type));
return astType;
}
private bool IsAttributeType(IType type)
@ -792,8 +820,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -792,8 +820,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
bool IsFlagsEnum(ITypeDefinition type)
{
IType flagsAttributeType = type.Compilation.FindType(typeof(System.FlagsAttribute));
return type.GetAttribute(flagsAttributeType) != null;
return type.HasAttribute(KnownAttribute.Flags, inherit: false);
}
Expression ConvertEnumValue(IType type, long val)
@ -880,7 +907,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -880,7 +907,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
decl.ParameterModifier = ParameterModifier.Params;
}
if (ShowAttributes) {
decl.Attributes.AddRange (parameter.Attributes.Select ((a) => new AttributeSection (ConvertAttribute (a))));
decl.Attributes.AddRange(ConvertAttributes(parameter.GetAttributes()));
}
if (parameter.Type.Kind == TypeKind.ByReference) {
// avoid 'out ref'
@ -997,7 +1024,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -997,7 +1024,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
decl.ClassType = classType;
decl.Modifiers = modifiers;
if (ShowAttributes) {
decl.Attributes.AddRange (typeDefinition.Attributes.Select ((a) => new AttributeSection (ConvertAttribute (a))));
decl.Attributes.AddRange(ConvertAttributes(typeDefinition.GetAttributes()));
}
if (AddResolveResultAnnotations) {
decl.AddAnnotation(new TypeResolveResult(typeDefinition));
@ -1034,7 +1061,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1034,7 +1061,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
}
return decl;
}
DelegateDeclaration ConvertDelegate(IMethod invokeMethod, Modifiers modifiers)
{
ITypeDefinition d = invokeMethod.DeclaringTypeDefinition;
@ -1042,10 +1069,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1042,10 +1069,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
DelegateDeclaration decl = new DelegateDeclaration();
decl.Modifiers = modifiers & ~Modifiers.Sealed;
if (ShowAttributes) {
decl.Attributes.AddRange (d.Attributes.Select (a => new AttributeSection (ConvertAttribute (a))));
decl.Attributes.AddRange (invokeMethod.ReturnTypeAttributes.Select ((a) => new AttributeSection (ConvertAttribute (a)) {
AttributeTarget = "return"
}));
decl.Attributes.AddRange(ConvertAttributes(d.GetAttributes()));
decl.Attributes.AddRange(ConvertAttributes(invokeMethod.GetReturnTypeAttributes(), "return"));
}
if (AddResolveResultAnnotations) {
decl.AddAnnotation(new TypeResolveResult(d));
@ -1091,7 +1116,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1091,7 +1116,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
decl.Modifiers = m;
}
if (ShowAttributes) {
decl.Attributes.AddRange (field.Attributes.Select ((a) => new AttributeSection (ConvertAttribute (a))));
decl.Attributes.AddRange(ConvertAttributes(field.GetAttributes()));
}
if (AddResolveResultAnnotations) {
decl.AddAnnotation(new MemberResolveResult(null, field));
@ -1115,7 +1140,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1115,7 +1140,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
}
}
Accessor ConvertAccessor(IMethod accessor, Accessibility ownerAccessibility, bool addParamterAttribute)
Accessor ConvertAccessor(IMethod accessor, Accessibility ownerAccessibility, bool addParameterAttribute)
{
if (accessor == null)
return Accessor.Null;
@ -1123,14 +1148,10 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1123,14 +1148,10 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
if (this.ShowAccessibility && accessor.Accessibility != ownerAccessibility)
decl.Modifiers = ModifierFromAccessibility(accessor.Accessibility);
if (ShowAttributes) {
decl.Attributes.AddRange (accessor.Attributes.Select ((a) => new AttributeSection (ConvertAttribute (a))));
decl.Attributes.AddRange (accessor.ReturnTypeAttributes.Select ((a) => new AttributeSection (ConvertAttribute (a)) {
AttributeTarget = "return"
}));
if (addParamterAttribute && accessor.Parameters.Count > 0) {
decl.Attributes.AddRange (accessor.Parameters.Last ().Attributes.Select ((a) => new AttributeSection (ConvertAttribute (a)) {
AttributeTarget = "param"
}));
decl.Attributes.AddRange(ConvertAttributes(accessor.GetAttributes()));
decl.Attributes.AddRange(ConvertAttributes(accessor.GetReturnTypeAttributes(), "return"));
if (addParameterAttribute && accessor.Parameters.Count > 0) {
decl.Attributes.AddRange(ConvertAttributes(accessor.Parameters.Last().GetAttributes(), "param"));
}
}
if (AddResolveResultAnnotations) {
@ -1145,7 +1166,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1145,7 +1166,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
PropertyDeclaration decl = new PropertyDeclaration();
decl.Modifiers = GetMemberModifiers(property);
if (ShowAttributes) {
decl.Attributes.AddRange (property.Attributes.Select ((a) => new AttributeSection (ConvertAttribute (a))));
decl.Attributes.AddRange(ConvertAttributes(property.GetAttributes()));
}
if (AddResolveResultAnnotations) {
decl.AddAnnotation(new MemberResolveResult(null, property));
@ -1163,7 +1184,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1163,7 +1184,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
IndexerDeclaration decl = new IndexerDeclaration();
decl.Modifiers = GetMemberModifiers(indexer);
if (ShowAttributes) {
decl.Attributes.AddRange (indexer.Attributes.Select ((a) => new AttributeSection (ConvertAttribute (a))));
decl.Attributes.AddRange(ConvertAttributes(indexer.GetAttributes()));
}
if (AddResolveResultAnnotations) {
decl.AddAnnotation(new MemberResolveResult(null, indexer));
@ -1184,7 +1205,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1184,7 +1205,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
CustomEventDeclaration decl = new CustomEventDeclaration();
decl.Modifiers = GetMemberModifiers(ev);
if (ShowAttributes) {
decl.Attributes.AddRange (ev.Attributes.Select ((a) => new AttributeSection (ConvertAttribute (a))));
decl.Attributes.AddRange(ConvertAttributes(ev.GetAttributes()));
}
if (AddResolveResultAnnotations) {
decl.AddAnnotation(new MemberResolveResult(null, ev));
@ -1199,7 +1220,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1199,7 +1220,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
EventDeclaration decl = new EventDeclaration();
decl.Modifiers = GetMemberModifiers(ev);
if (ShowAttributes) {
decl.Attributes.AddRange (ev.Attributes.Select ((a) => new AttributeSection (ConvertAttribute (a))));
decl.Attributes.AddRange(ConvertAttributes(ev.GetAttributes()));
}
if (AddResolveResultAnnotations) {
decl.AddAnnotation(new MemberResolveResult(null, ev));
@ -1215,10 +1236,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1215,10 +1236,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
MethodDeclaration decl = new MethodDeclaration();
decl.Modifiers = GetMemberModifiers(method);
if (ShowAttributes) {
decl.Attributes.AddRange (method.Attributes.Select ((a) => new AttributeSection (ConvertAttribute (a))));
decl.Attributes.AddRange (method.ReturnTypeAttributes.Select ((a) => new AttributeSection (ConvertAttribute (a)) {
AttributeTarget = "return"
}));
decl.Attributes.AddRange(ConvertAttributes(method.GetAttributes()));
decl.Attributes.AddRange(ConvertAttributes(method.GetReturnTypeAttributes(), "return"));
}
if (AddResolveResultAnnotations) {
decl.AddAnnotation(new MemberResolveResult(null, method));
@ -1275,7 +1294,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1275,7 +1294,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
ConstructorDeclaration decl = new ConstructorDeclaration();
decl.Modifiers = GetMemberModifiers(ctor);
if (ShowAttributes)
decl.Attributes.AddRange (ctor.Attributes.Select ((a) => new AttributeSection (ConvertAttribute (a))));
decl.Attributes.AddRange(ConvertAttributes(ctor.GetAttributes()));
if (ctor.DeclaringTypeDefinition != null)
decl.Name = ctor.DeclaringTypeDefinition.Name;
foreach (IParameter p in ctor.Parameters) {
@ -1369,7 +1388,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1369,7 +1388,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
decl.Variance = tp.Variance;
decl.Name = tp.Name;
if (ShowAttributes)
decl.Attributes.AddRange (tp.Attributes.Select ((a) => new AttributeSection (ConvertAttribute (a))));
decl.Attributes.AddRange(ConvertAttributes(tp.GetAttributes()));
return decl;
}

26
ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs

@ -507,17 +507,17 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -507,17 +507,17 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
propertyDeclaration.Getter.Body = null;
propertyDeclaration.Setter.Body = null;
// Add C# 7.3 attributes on backing field:
var attributes = field.Attributes
.Where(a => !attributeTypesToRemoveFromAutoProperties.Any(t => t == a.AttributeType.FullName))
.Select(context.TypeSystemAstBuilder.ConvertAttribute).ToArray();
if (attributes.Length > 0) {
var section = new AttributeSection {
AttributeTarget = "field"
};
section.Attributes.AddRange(attributes);
propertyDeclaration.Attributes.Add(section);
}
// Add C# 7.3 attributes on backing field:
var attributes = field.GetAttributes()
.Where(a => !attributeTypesToRemoveFromAutoProperties.Contains(a.AttributeType.FullName))
.Select(context.TypeSystemAstBuilder.ConvertAttribute).ToArray();
if (attributes.Length > 0) {
var section = new AttributeSection {
AttributeTarget = "field"
};
section.Attributes.AddRange(attributes);
propertyDeclaration.Attributes.Add(section);
}
}
// Since the property instance is not changed, we can continue in the visitor as usual, so return null
return null;
@ -788,8 +788,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -788,8 +788,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
IField field = eventDef.DeclaringType.GetFields(f => f.Name == ev.Name, GetMemberOptions.IgnoreInheritedMembers).SingleOrDefault();
if (field != null) {
ed.AddAnnotation(field);
var attributes = field.Attributes
.Where(a => !attributeTypesToRemoveFromAutoEvents.Any(t => t == a.AttributeType.FullName))
var attributes = field.GetAttributes()
.Where(a => !attributeTypesToRemoveFromAutoEvents.Contains(a.AttributeType.FullName))
.Select(context.TypeSystemAstBuilder.ConvertAttribute).ToArray();
if (attributes.Length > 0) {
var section = new AttributeSection {

5
ICSharpCode.Decompiler/NRExtensions.cs

@ -44,10 +44,7 @@ namespace ICSharpCode.Decompiler @@ -44,10 +44,7 @@ namespace ICSharpCode.Decompiler
public static bool IsCompilerGenerated(this IEntity entity)
{
if (entity != null) {
foreach (IAttribute a in entity.Attributes) {
if (a.AttributeType.FullName == "System.Runtime.CompilerServices.CompilerGeneratedAttribute")
return true;
}
return entity.HasAttribute(KnownAttribute.CompilerGenerated);
}
return false;
}

2
ICSharpCode.Decompiler/TypeSystem/ComHelper.cs

@ -33,7 +33,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -33,7 +33,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
{
return typeDefinition != null
&& typeDefinition.Kind == TypeKind.Interface
&& typeDefinition.GetAttributes(KnownAttribute.ComImport, inherit: false) != null;
&& typeDefinition.HasAttribute(KnownAttribute.ComImport, inherit: false);
}
/// <summary>

3
ICSharpCode.Decompiler/TypeSystem/IEntity.cs

@ -123,8 +123,9 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -123,8 +123,9 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// <summary>
/// Gets the attributes on this entity.
/// Does not include inherited attributes.
/// </summary>
IReadOnlyList<IAttribute> Attributes { get; }
IEnumerable<IAttribute> GetAttributes();
/// <summary>
/// Gets the accessibility of this entity.

5
ICSharpCode.Decompiler/TypeSystem/IMethod.cs

@ -79,7 +79,10 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -79,7 +79,10 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// <summary>
/// Gets the attributes associated with the return type. (e.g. [return: MarshalAs(...)])
/// </summary>
IReadOnlyList<IAttribute> ReturnTypeAttributes { get; }
/// <remarks>
/// Does not include inherited attributes.
/// </remarks>
IEnumerable<IAttribute> GetReturnTypeAttributes();
/// <summary>
/// Gets the type parameters of this method; or an empty list if the method is not generic.

4
ICSharpCode.Decompiler/TypeSystem/IParameter.cs

@ -63,9 +63,9 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -63,9 +63,9 @@ namespace ICSharpCode.Decompiler.TypeSystem
public interface IParameter : IVariable
{
/// <summary>
/// Gets the list of attributes.
/// Gets the attributes on this parameter.
/// </summary>
IReadOnlyList<IAttribute> Attributes { get; }
IEnumerable<IAttribute> GetAttributes();
/// <summary>
/// Gets whether this parameter is a C# 'ref' parameter.

4
ICSharpCode.Decompiler/TypeSystem/ITypeParameter.cs

@ -82,9 +82,9 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -82,9 +82,9 @@ namespace ICSharpCode.Decompiler.TypeSystem
new string Name { get; }
/// <summary>
/// Gets the list of attributes declared on this type parameter.
/// Gets the attributes declared on this type parameter.
/// </summary>
IReadOnlyList<IAttribute> Attributes { get; }
IEnumerable<IAttribute> GetAttributes();
/// <summary>
/// Gets the variance of this type parameter.

1
ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractResolvedEntity.cs

@ -59,6 +59,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -59,6 +59,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
}
public IReadOnlyList<IAttribute> Attributes { get; protected set; }
IEnumerable<IAttribute> IEntity.GetAttributes() => Attributes;
public bool IsStatic { get { return unresolved.IsStatic; } }
public bool IsAbstract { get { return unresolved.IsAbstract; } }

4
ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractResolvedTypeParameter.cs

@ -71,8 +71,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -71,8 +71,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public int Index {
get { return index; }
}
public abstract IReadOnlyList<IAttribute> Attributes { get; }
public abstract IEnumerable<IAttribute> GetAttributes();
public VarianceModifier Variance {
get { return variance; }

4
ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultParameter.cs

@ -72,9 +72,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -72,9 +72,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
get { return owner; }
}
public IReadOnlyList<IAttribute> Attributes {
get { return attributes; }
}
public IEnumerable<IAttribute> GetAttributes() => attributes;
public bool IsRef {
get { return isRef; }

1
ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedMethod.cs

@ -170,6 +170,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -170,6 +170,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public IReadOnlyList<IParameter> Parameters { get; private set; }
public IReadOnlyList<IAttribute> ReturnTypeAttributes { get; private set; }
IEnumerable<IAttribute> IMethod.GetReturnTypeAttributes() => ReturnTypeAttributes;
public IReadOnlyList<ITypeParameter> TypeParameters { get; private set; }
public IReadOnlyList<IType> TypeArguments {

4
ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs

@ -105,7 +105,9 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -105,7 +105,9 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return LazyInit.GetOrSet(ref this.attributes, result);
}
}
public IEnumerable<IAttribute> GetAttributes() => Attributes;
public System.Reflection.Metadata.EntityHandle MetadataToken => parts[0].MetadataToken;
public SymbolKind SymbolKind {

2
ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedTypeParameter.cs

@ -61,7 +61,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -61,7 +61,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
this.attributes = attributes ?? EmptyList<IAttribute>.Instance;
}
public override IReadOnlyList<IAttribute> Attributes => attributes;
public override IEnumerable<IAttribute> GetAttributes() => attributes;
public override bool HasValueTypeConstraint => hasValueTypeConstraint;
public override bool HasReferenceTypeConstraint => hasReferenceTypeConstraint;

1
ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultUnresolvedParameter.cs

@ -229,6 +229,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -229,6 +229,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public IType Type { get; internal set; }
public string Name { get; internal set; }
public IReadOnlyList<IAttribute> Attributes { get; internal set; }
public IEnumerable<IAttribute> GetAttributes() => Attributes;
public bool IsRef { get; internal set; }
public bool IsOut { get; internal set; }
public bool IsParams { get; internal set; }

4
ICSharpCode.Decompiler/TypeSystem/Implementation/DummyTypeParameter.cs

@ -141,9 +141,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -141,9 +141,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
get { return index; }
}
IReadOnlyList<IAttribute> ITypeParameter.Attributes {
get { return EmptyList<IAttribute>.Instance; }
}
IEnumerable<IAttribute> ITypeParameter.GetAttributes() =>EmptyList<IAttribute>.Instance;
SymbolKind ITypeParameter.OwnerType {
get { return ownerType; }

4
ICSharpCode.Decompiler/TypeSystem/Implementation/FakeMember.cs

@ -58,7 +58,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -58,7 +58,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
IAssembly IEntity.ParentAssembly => DeclaringType?.GetDefinition()?.ParentAssembly;
IReadOnlyList<IAttribute> IEntity.Attributes => EmptyList<IAttribute>.Instance;
IEnumerable<IAttribute> IEntity.GetAttributes() => EmptyList<IAttribute>.Instance;
public Accessibility Accessibility { get; set; } = Accessibility.Public;
@ -130,7 +130,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -130,7 +130,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public override SymbolKind SymbolKind => symbolKind;
IReadOnlyList<IAttribute> IMethod.ReturnTypeAttributes => EmptyList<IAttribute>.Instance;
IEnumerable<IAttribute> IMethod.GetReturnTypeAttributes() => EmptyList<IAttribute>.Instance;
public IReadOnlyList<ITypeParameter> TypeParameters { get; set; } = EmptyList<ITypeParameter>.Instance;

12
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataEvent.cs

@ -38,7 +38,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -38,7 +38,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
readonly string name;
// lazy-loaded:
IAttribute[] customAttributes;
IType returnType;
internal MetadataEvent(MetadataAssembly assembly, EventDefinitionHandle handle)
@ -103,16 +102,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -103,16 +102,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
TypeParameterSubstitution IMember.Substitution => TypeParameterSubstitution.Identity;
#region Attributes
public IReadOnlyList<IAttribute> Attributes {
get {
var attr = LazyInit.VolatileRead(ref this.customAttributes);
if (attr != null)
return attr;
return LazyInit.GetOrSet(ref this.customAttributes, DecodeAttributes());
}
}
IAttribute[] DecodeAttributes()
public IEnumerable<IAttribute> GetAttributes()
{
var b = new AttributeListBuilder(assembly);
var metadata = assembly.metadata;

14
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataField.cs

@ -43,7 +43,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -43,7 +43,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
IType type;
bool isVolatile; // initialized together with this.type
byte decimalConstant; // 0=no, 1=yes, 2=unknown
IAttribute[] customAttributes;
internal MetadataField(MetadataAssembly assembly, FieldDefinitionHandle handle)
{
@ -127,17 +126,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -127,17 +126,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public IType DeclaringType => DeclaringTypeDefinition;
public IAssembly ParentAssembly => assembly;
public ICompilation Compilation => assembly.Compilation;
public IReadOnlyList<IAttribute> Attributes {
get {
var attr = LazyInit.VolatileRead(ref this.customAttributes);
if (attr != null)
return attr;
return LazyInit.GetOrSet(ref this.customAttributes, DecodeAttributes());
}
}
IAttribute[] DecodeAttributes()
public IEnumerable<IAttribute> GetAttributes()
{
var b = new AttributeListBuilder(assembly);
var metadata = assembly.metadata;

24
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs

@ -45,8 +45,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -45,8 +45,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
// lazy-loaded fields:
ITypeDefinition declaringType;
string name;
IAttribute[] customAttributes;
IAttribute[] returnTypeAttributes;
IParameter[] parameters;
IType returnType;
@ -232,15 +230,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -232,15 +230,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public ICompilation Compilation => assembly.Compilation;
#region Attributes
public IReadOnlyList<IAttribute> Attributes {
get {
var attr = LazyInit.VolatileRead(ref this.customAttributes);
if (attr != null)
return attr;
return LazyInit.GetOrSet(ref this.customAttributes, DecodeAttributes());
}
}
IType FindInteropType(string name)
{
return assembly.Compilation.FindType(new TopLevelTypeName(
@ -248,7 +237,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -248,7 +237,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
));
}
IAttribute[] DecodeAttributes()
public IEnumerable<IAttribute> GetAttributes()
{
var b = new AttributeListBuilder(assembly);
@ -365,16 +354,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -365,16 +354,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
#endregion
#region Return type attributes
public IReadOnlyList<IAttribute> ReturnTypeAttributes {
get {
var attr = LazyInit.VolatileRead(ref this.returnTypeAttributes);
if (attr != null)
return attr;
return LazyInit.GetOrSet(ref this.returnTypeAttributes, DecodeReturnTypeAttributes());
}
}
private IAttribute[] DecodeReturnTypeAttributes()
public IEnumerable<IAttribute> GetReturnTypeAttributes()
{
var b = new AttributeListBuilder(assembly);
var metadata = assembly.metadata;

12
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataParameter.cs

@ -37,7 +37,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -37,7 +37,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
// lazy-loaded:
string name;
IAttribute[] customAttributes;
internal MetadataParameter(MetadataAssembly assembly, IParameterizedMember owner, IType type, ParameterHandle handle)
{
@ -53,16 +52,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -53,16 +52,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public EntityHandle MetadataToken => handle;
#region Attributes
public IReadOnlyList<IAttribute> Attributes {
get {
var attr = LazyInit.VolatileRead(ref this.customAttributes);
if (attr != null)
return attr;
return LazyInit.GetOrSet(ref this.customAttributes, DecodeAttributes());
}
}
IAttribute[] DecodeAttributes()
public IEnumerable<IAttribute> GetAttributes()
{
var b = new AttributeListBuilder(assembly);
var metadata = assembly.metadata;

12
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataProperty.cs

@ -42,7 +42,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -42,7 +42,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
readonly SymbolKind symbolKind;
// lazy-loaded:
IAttribute[] customAttributes;
volatile Accessibility cachedAccessiblity = InvalidAccessibility;
IParameter[] parameters;
IType returnType;
@ -144,16 +143,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -144,16 +143,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
TypeParameterSubstitution IMember.Substitution => TypeParameterSubstitution.Identity;
#region Attributes
public IReadOnlyList<IAttribute> Attributes {
get {
var attr = LazyInit.VolatileRead(ref this.customAttributes);
if (attr != null)
return attr;
return LazyInit.GetOrSet(ref this.customAttributes, DecodeAttributes());
}
}
IAttribute[] DecodeAttributes()
public IEnumerable<IAttribute> GetAttributes()
{
var b = new AttributeListBuilder(assembly);
var metadata = assembly.metadata;

12
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs

@ -51,7 +51,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -51,7 +51,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public bool HasExtensionMethods { get; }
// lazy-loaded:
IAttribute[] customAttributes;
IMember[] members;
IField[] fields;
IProperty[] properties;
@ -284,16 +283,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -284,16 +283,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public IAssembly ParentAssembly => assembly;
#region Type Attributes
public IReadOnlyList<IAttribute> Attributes {
get {
var attr = LazyInit.VolatileRead(ref this.customAttributes);
if (attr != null)
return attr;
return LazyInit.GetOrSet(ref this.customAttributes, DecodeAttributes());
}
}
IAttribute[] DecodeAttributes()
public IEnumerable<IAttribute> GetAttributes()
{
var b = new AttributeListBuilder(assembly);
var metadata = assembly.metadata;

11
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeParameter.cs

@ -98,16 +98,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -98,16 +98,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public GenericParameterHandle MetadataToken => handle;
public override IReadOnlyList<IAttribute> Attributes {
get {
var attr = LazyInit.VolatileRead(ref this.customAttributes);
if (attr != null)
return attr;
return LazyInit.GetOrSet(ref this.customAttributes, DecodeAttributes());
}
}
IAttribute[] DecodeAttributes()
public override IEnumerable<IAttribute> GetAttributes()
{
var metadata = assembly.metadata;
var gp = metadata.GetGenericParameter(handle);

6
ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedMember.cs

@ -150,10 +150,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -150,10 +150,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public ITypeDefinition DeclaringTypeDefinition {
get { return baseMember.DeclaringTypeDefinition; }
}
public IReadOnlyList<IAttribute> Attributes {
get { return baseMember.Attributes; }
}
IEnumerable<IAttribute> IEntity.GetAttributes() => baseMember.GetAttributes();
public IEnumerable<IMember> ExplicitlyImplementedInterfaceMembers {
get {

8
ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedMethod.cs

@ -92,10 +92,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -92,10 +92,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public IReadOnlyList<IType> TypeArguments {
get { return this.Substitution.MethodTypeArguments ?? EmptyList<IType>.Instance; }
}
public IReadOnlyList<IAttribute> ReturnTypeAttributes {
get { return methodDefinition.ReturnTypeAttributes; }
}
public IEnumerable<IAttribute> GetReturnTypeAttributes() => methodDefinition.GetReturnTypeAttributes();
public IReadOnlyList<ITypeParameter> TypeParameters {
get {
@ -230,7 +228,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -230,7 +228,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
this.baseTp = baseTp;
}
public override IReadOnlyList<IAttribute> Attributes => baseTp.Attributes;
public override IEnumerable<IAttribute> GetAttributes() => baseTp.GetAttributes();
public override int GetHashCode()
{

2
ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedParameter.cs

@ -35,7 +35,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -35,7 +35,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
this.newOwner = newOwner;
}
IReadOnlyList<IAttribute> IParameter.Attributes => baseParameter.Attributes;
IEnumerable<IAttribute> IParameter.GetAttributes() => baseParameter.GetAttributes();
bool IParameter.IsRef => baseParameter.IsRef;
bool IParameter.IsOut => baseParameter.IsOut;
bool IParameter.IsParams => baseParameter.IsParams;

43
ICSharpCode.Decompiler/TypeSystem/InheritanceHelper.cs

@ -29,7 +29,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -29,7 +29,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
{
// TODO: maybe these should be extension methods?
// or even part of the interface itself? (would allow for easy caching)
#region GetBaseMember
/// <summary>
/// Gets the base member that has the same signature.
@ -58,16 +58,16 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -58,16 +58,16 @@ namespace ICSharpCode.Decompiler.TypeSystem
yield return member;
}*/
}
// Remove generic specialization
var substitution = member.Substitution;
member = member.MemberDefinition;
if (member.DeclaringTypeDefinition == null) {
// For global methods, return empty list. (prevent SharpDevelop UDC crash 4524)
yield break;
}
IEnumerable<IType> allBaseTypes;
if (includeImplementedInterfaces) {
allBaseTypes = member.DeclaringTypeDefinition.GetAllBaseTypes();
@ -93,7 +93,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -93,7 +93,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
}
#endregion
#region GetDerivedMember
/// <summary>
/// Finds the member declared in 'derivedType' that has the same signature (could override) 'baseMember'.
@ -104,10 +104,10 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -104,10 +104,10 @@ namespace ICSharpCode.Decompiler.TypeSystem
throw new ArgumentNullException("baseMember");
if (derivedType == null)
throw new ArgumentNullException("derivedType");
if (baseMember.Compilation != derivedType.Compilation)
throw new ArgumentException("baseMember and derivedType must be from the same compilation");
baseMember = baseMember.MemberDefinition;
bool includeInterfaces = baseMember.DeclaringTypeDefinition.Kind == TypeKind.Interface;
IMethod method = baseMember as IMethod;
@ -147,5 +147,34 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -147,5 +147,34 @@ namespace ICSharpCode.Decompiler.TypeSystem
return null;
}
#endregion
#region Attributes
internal static IEnumerable<IAttribute> GetAttributes(ITypeDefinition typeDef)
{
foreach (var baseType in typeDef.GetNonInterfaceBaseTypes().Reverse()) {
ITypeDefinition baseTypeDef = baseType.GetDefinition();
if (baseTypeDef == null)
continue;
foreach (var attr in baseTypeDef.GetAttributes()) {
yield return attr;
}
}
}
internal static IEnumerable<IAttribute> GetAttributes(IMember member)
{
HashSet<IMember> visitedMembers = new HashSet<IMember>();
do {
member = member.MemberDefinition; // it's sufficient to look at the definitions
if (!visitedMembers.Add(member)) {
// abort if we seem to be in an infinite loop (cyclic inheritance)
break;
}
foreach (var attr in member.GetAttributes()) {
yield return attr;
}
} while (member.IsOverride && (member = InheritanceHelper.GetBaseMember(member)) != null);
}
#endregion
}
}

173
ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs

@ -420,181 +420,70 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -420,181 +420,70 @@ namespace ICSharpCode.Decompiler.TypeSystem
return null;
}
#endregion
#region ITypeReference.Resolve(ICompilation)
/// <summary>
/// Resolves a type reference in the compilation's main type resolve context.
/// Some type references require a more specific type resolve context and will not resolve using this method.
/// </summary>
/// <returns>
/// Returns the resolved type.
/// In case of an error, returns <see cref="SpecialType.UnknownType"/>.
/// Never returns null.
/// </returns>
public static IType Resolve (this ITypeReference reference, ICompilation compilation)
{
if (reference == null)
throw new ArgumentNullException ("reference");
if (compilation == null)
throw new ArgumentNullException ("compilation");
return reference.Resolve (compilation.TypeResolveContext);
}
#endregion
#region ITypeDefinition.GetAttribute
#region IEntity.GetAttribute
/// <summary>
/// Gets the attribute of the specified attribute type (or derived attribute types).
/// Gets whether the entity has an attribute of the specified attribute type (or derived attribute types).
/// </summary>
/// <param name="entity">The entity on which the attributes are declared.</param>
/// <param name="attributeType">The attribute type to look for.</param>
/// <param name="inherit">
/// Specifies whether attributes inherited from base classes and base members (if the given <paramref name="entity"/> in an <c>override</c>)
/// should be returned. The default is <c>true</c>.
/// Specifies whether attributes inherited from base classes and base members
/// (if the given <paramref name="entity"/> in an <c>override</c>)
/// should be returned.
/// </param>
/// <returns>
/// Returns the attribute that was found; or <c>null</c> if none was found.
/// If inherit is true, an from the entity itself will be returned if possible;
/// and the base entity will only be searched if none exists.
/// </returns>
public static IAttribute GetAttribute(this IEntity entity, IType attributeType, bool inherit = true)
public static bool HasAttribute(this IEntity entity, KnownAttribute attrType, bool inherit=false)
{
return GetAttributes(entity, attributeType, inherit).FirstOrDefault();
return GetAttribute(entity, attrType, inherit) != null;
}
/// <summary>
/// Gets the attributes of the specified attribute type (or derived attribute types).
/// </summary>
/// <param name="entity">The entity on which the attributes are declared.</param>
/// <param name="attributeType">The attribute type to look for.</param>
/// <param name="inherit">
/// Specifies whether attributes inherited from base classes and base members (if the given <paramref name="entity"/> in an <c>override</c>)
/// should be returned. The default is <c>true</c>.
/// </param>
/// <returns>
/// Returns the list of attributes that were found.
/// If inherit is true, attributes from the entity itself are returned first; followed by attributes inherited from the base entity.
/// </returns>
public static IEnumerable<IAttribute> GetAttributes(this IEntity entity, IType attributeType, bool inherit = true)
{
if (entity == null)
throw new ArgumentNullException("entity");
if (attributeType == null)
throw new ArgumentNullException("attributeType");
return GetAttributes(entity, attributeType.Equals, inherit);
}
/// <summary>
/// Gets the attribute of the specified attribute type (or derived attribute types).
/// </summary>
/// <param name="entity">The entity on which the attributes are declared.</param>
/// <param name="attributeType">The attribute type to look for.</param>
/// <param name="inherit">
/// Specifies whether attributes inherited from base classes and base members (if the given <paramref name="entity"/> in an <c>override</c>)
/// should be returned. The default is <c>true</c>.
/// Specifies whether attributes inherited from base classes and base members
/// (if the given <paramref name="entity"/> in an <c>override</c>)
/// should be returned.
/// </param>
/// <returns>
/// Returns the attribute that was found; or <c>null</c> if none was found.
/// If inherit is true, an from the entity itself will be returned if possible;
/// and the base entity will only be searched if none exists.
/// </returns>
public static IAttribute GetAttribute(this IEntity entity, KnownAttribute attributeType, bool inherit = true)
{
return GetAttributes(entity, attributeType, inherit).FirstOrDefault();
}
/// <summary>
/// Gets the attributes of the specified attribute type (or derived attribute types).
/// </summary>
/// <param name="entity">The entity on which the attributes are declared.</param>
/// <param name="attributeType">The attribute type to look for.</param>
/// <param name="inherit">
/// Specifies whether attributes inherited from base classes and base members (if the given <paramref name="entity"/> in an <c>override</c>)
/// should be returned. The default is <c>true</c>.
/// </param>
/// <returns>
/// Returns the list of attributes that were found.
/// If inherit is true, attributes from the entity itself are returned first; followed by attributes inherited from the base entity.
/// </returns>
public static IEnumerable<IAttribute> GetAttributes(this IEntity entity, KnownAttribute attributeType, bool inherit = true)
public static IAttribute GetAttribute(this IEntity entity, KnownAttribute attributeType, bool inherit=false)
{
if (entity == null)
throw new ArgumentNullException("entity");
return GetAttributes(entity, attrType => {
ITypeDefinition typeDef = attrType.GetDefinition();
return typeDef != null && typeDef.FullTypeName == attributeType.GetTypeName();
}, inherit);
return GetAttributes(entity, inherit).FirstOrDefault(a => a.AttributeType.IsKnownType(attributeType));
}
/// <summary>
/// Gets the attribute of the specified attribute type (or derived attribute types).
/// Gets the attributes on the entity.
/// </summary>
/// <param name="entity">The entity on which the attributes are declared.</param>
/// <param name="inherit">
/// Specifies whether attributes inherited from base classes and base members (if the given <paramref name="entity"/> in an <c>override</c>)
/// should be returned. The default is <c>true</c>.
/// Specifies whether attributes inherited from base classes and base members
/// (if the given <paramref name="entity"/> in an <c>override</c>)
/// should be returned.
/// </param>
/// <returns>
/// Returns the attribute that was found; or <c>null</c> if none was found.
/// If inherit is true, an from the entity itself will be returned if possible;
/// and the base entity will only be searched if none exists.
/// Returns the list of attributes that were found.
/// If inherit is true, attributes from the entity itself are returned first;
/// followed by attributes inherited from the base entity.
/// </returns>
public static IEnumerable<IAttribute> GetAttributes(this IEntity entity, bool inherit = true)
{
if (entity == null)
throw new ArgumentNullException ("entity");
return GetAttributes(entity, a => true, inherit);
}
static IEnumerable<IAttribute> GetAttributes(IEntity entity, Predicate<IType> attributeTypePredicate, bool inherit)
{
if (!inherit) {
foreach (var attr in entity.Attributes) {
if (attributeTypePredicate(attr.AttributeType))
yield return attr;
public static IEnumerable<IAttribute> GetAttributes(this IEntity entity, bool inherit)
{
if (inherit) {
if (entity is ITypeDefinition td) {
return InheritanceHelper.GetAttributes(td);
} else if (entity is IMember m) {
return InheritanceHelper.GetAttributes(m);
} else {
throw new NotSupportedException("Unknown entity type");
}
yield break;
} else {
return entity.GetAttributes();
}
ITypeDefinition typeDef = entity as ITypeDefinition;
if (typeDef != null) {
foreach (var baseType in typeDef.GetNonInterfaceBaseTypes().Reverse()) {
ITypeDefinition baseTypeDef = baseType.GetDefinition();
if (baseTypeDef == null)
continue;
foreach (var attr in baseTypeDef.Attributes) {
if (attributeTypePredicate(attr.AttributeType))
yield return attr;
}
}
yield break;
}
IMember member = entity as IMember;
if (member != null) {
HashSet<IMember> visitedMembers = new HashSet<IMember>();
do {
member = member.MemberDefinition; // it's sufficient to look at the definitions
if (!visitedMembers.Add(member)) {
// abort if we seem to be in an infinite loop (cyclic inheritance)
break;
}
foreach (var attr in member.Attributes) {
if (attributeTypePredicate(attr.AttributeType))
yield return attr;
}
} while (member.IsOverride && (member = InheritanceHelper.GetBaseMember(member)) != null);
yield break;
}
throw new NotSupportedException("Unknown entity type");
}
#endregion
#region IsCompilerGenerated
public static bool IsCompilerGenereated(this IEntity entity)
{
if (entity == null)
throw new ArgumentNullException(nameof(entity));
return entity.GetAttribute(KnownAttribute.CompilerGenerated) != null;
}
#endregion

11
ICSharpCode.Decompiler/TypeSystem/VarArgInstanceMethod.cs

@ -109,10 +109,9 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -109,10 +109,9 @@ namespace ICSharpCode.Decompiler.TypeSystem
baseMethod.Specialize(substitution),
parameters.Skip(baseMethod.Parameters.Count - 1).Select(p => p.Type.AcceptVisitor(substitution)).ToList());
}
public IReadOnlyList<IAttribute> ReturnTypeAttributes {
get { return baseMethod.ReturnTypeAttributes; }
}
IEnumerable<IAttribute> IEntity.GetAttributes() => baseMethod.GetAttributes();
IEnumerable<IAttribute> IMethod.GetReturnTypeAttributes() => baseMethod.GetReturnTypeAttributes();
public IReadOnlyList<ITypeParameter> TypeParameters {
get { return baseMethod.TypeParameters; }
@ -225,10 +224,6 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -225,10 +224,6 @@ namespace ICSharpCode.Decompiler.TypeSystem
get { return baseMethod.ParentAssembly; }
}
public IReadOnlyList<IAttribute> Attributes {
get { return baseMethod.Attributes; }
}
public bool IsStatic {
get { return baseMethod.IsStatic; }
}

Loading…
Cancel
Save