Browse Source

more attribute targets implemented.

pull/52/head
Artur Zgodziski 15 years ago
parent
commit
19993ff43b
  1. 32
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  2. 6
      ICSharpCode.Decompiler/Tests/CustomAttributes/AssemblyCustomAttribute.cs
  3. 152
      ICSharpCode.Decompiler/Tests/CustomAttributes/CustomAttributeSamples.cs
  4. 6
      ICSharpCode.Decompiler/Tests/CustomAttributes/CustomAttributeTests.cs
  5. 1
      ICSharpCode.Decompiler/Tests/CustomAttributes/CustomAttributes.cs
  6. 1
      ICSharpCode.Decompiler/Tests/DecompilerTestBase.cs
  7. 31
      ICSharpCode.Decompiler/Tests/Helpers/RemoveCompilerAttribute.cs
  8. 11
      ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj
  9. 5
      ILSpy/CSharpLanguage.cs
  10. 2
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/CompilationUnit.cs

32
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -64,21 +64,25 @@ namespace Decompiler
astCompileUnit.AcceptVisitor(new OutputVisitor(outputFormatter, formattingPolicy), null); astCompileUnit.AcceptVisitor(new OutputVisitor(outputFormatter, formattingPolicy), null);
} }
public void AddAssembly(AssemblyDefinition assemblyDefinition) public void AddAssembly(AssemblyDefinition assemblyDefinition, bool onlyAssemblyLevel = false)
{ {
astCompileUnit.AddChild( astCompileUnit.AddChild(
new UsingDeclaration { new UsingDeclaration {
Import = new SimpleType("System") Import = new SimpleType("System")
}, CompilationUnit.MemberRole); }, CompilationUnit.MemberRole);
foreach(TypeDefinition typeDef in assemblyDefinition.MainModule.Types) { ConvertCustomAtributes(astCompileUnit, assemblyDefinition, AttributeTarget.Assembly);
// Skip nested types - they will be added by the parent type
if (typeDef.DeclaringType != null) continue; if(!onlyAssemblyLevel)
// Skip the <Module> class foreach (TypeDefinition typeDef in assemblyDefinition.MainModule.Types)
if (typeDef.Name == "<Module>") continue; {
// Skip nested types - they will be added by the parent type
AddType(typeDef); if (typeDef.DeclaringType != null) continue;
} // Skip the <Module> class
if (typeDef.Name == "<Module>") continue;
AddType(typeDef);
}
} }
NamespaceDeclaration GetCodeNamespace(string name) NamespaceDeclaration GetCodeNamespace(string name)
@ -193,6 +197,11 @@ namespace Decompiler
ConvertCustomAtributes(astType, typeDef); ConvertCustomAtributes(astType, typeDef);
return astType; return astType;
} }
public void Transform(IAstTransform transform)
{
transform.Run(astCompileUnit);
}
string CleanName(string name) string CleanName(string name)
{ {
@ -525,11 +534,16 @@ namespace Decompiler
astProp.Getter = new Accessor { astProp.Getter = new Accessor {
Body = AstMethodBodyBuilder.CreateMethodBody(propDef.GetMethod, context) Body = AstMethodBodyBuilder.CreateMethodBody(propDef.GetMethod, context)
}.WithAnnotation(propDef.GetMethod); }.WithAnnotation(propDef.GetMethod);
ConvertCustomAtributes(astProp.Getter, propDef.GetMethod);
ConvertCustomAtributes(astProp.Getter, propDef.GetMethod.MethodReturnType, AttributeTarget.Return);
} }
if (propDef.SetMethod != null) { if (propDef.SetMethod != null) {
astProp.Setter = new Accessor { astProp.Setter = new Accessor {
Body = AstMethodBodyBuilder.CreateMethodBody(propDef.SetMethod, context) Body = AstMethodBodyBuilder.CreateMethodBody(propDef.SetMethod, context)
}.WithAnnotation(propDef.SetMethod); }.WithAnnotation(propDef.SetMethod);
ConvertCustomAtributes(astProp.Setter, propDef.SetMethod);
ConvertCustomAtributes(astProp.Setter, propDef.SetMethod.MethodReturnType, AttributeTarget.Return);
ConvertCustomAtributes(astProp.Setter, propDef.SetMethod.Parameters.Last(), AttributeTarget.Param);
} }
ConvertCustomAtributes(astProp, propDef); ConvertCustomAtributes(astProp, propDef);
return astProp; return astProp;

6
ICSharpCode.Decompiler/Tests/CustomAttributes/AssemblyCustomAttribute.cs

@ -0,0 +1,6 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
[assembly: CLSCompliant(false)]

152
ICSharpCode.Decompiler/Tests/CustomAttributes/CustomAttributeSamples.cs

@ -5,6 +5,8 @@
using System; using System;
//$CE //$CE
//$$ TargetModule (ignored)
//[module: CLSCompliantAttribute(false)]
//$$ ParameterlessAttributeUsage //$$ ParameterlessAttributeUsage
namespace ParameterLessAttributeUsage namespace ParameterLessAttributeUsage
{ {
@ -95,6 +97,48 @@ namespace AppliedToProperty
} }
} }
} }
//$$ AppliedToPropertyGet
namespace AppliedToPropertyGet
{
[AttributeUsage(AttributeTargets.All)]
public class MyAttributeAttribute : Attribute
{
}
public class TestClass
{
public int Property
{
[MyAttribute]
get
{
return 0;
}
}
}
}
//$$ AppliedToPropertySet
namespace AppliedToPropertySet
{
[AttributeUsage(AttributeTargets.All)]
public class MyAttributeAttribute : Attribute
{
}
public class TestClass
{
public int Property
{
get
{
return 3;
}
[MyAttribute]
set
{
return;
}
}
}
}
//$$ AppliedToDelegate //$$ AppliedToDelegate
[Obsolete("reason")] [Obsolete("reason")]
public delegate int AppliedToDelegate(); public delegate int AppliedToDelegate();
@ -244,3 +288,111 @@ namespace TargetReturn
} }
} }
} }
//$$ TargetPropertyGetReturn
namespace TargetPropertyGetReturn
{
[AttributeUsage(AttributeTargets.All)]
public class MyAttributeAttribute : Attribute
{
}
public class MyClass
{
public int Prop
{
[return: MyAttribute]
get
{
return 3;
}
}
}
}
//$$ TargetPropertySetParam
namespace TargetPropertySetParam
{
[AttributeUsage(AttributeTargets.All)]
public class MyAttributeAttribute : Attribute
{
}
public class MyClass
{
public int Prop
{
[param: MyAttribute]
set
{
return;
}
}
}
}
//$$ TargetPropertySetReturn
namespace TargetPropertySetReturn
{
[AttributeUsage(AttributeTargets.All)]
public class MyAttributeAttribute : Attribute
{
}
public class MyClass
{
public int Prop
{
get
{
return 3;
}
[return: MyAttribute]
set
{
return;
}
}
}
}
//$$ TargetPropertyIndexSetParam
namespace TargetPropertyIndexSetParam
{
[AttributeUsage(AttributeTargets.All)]
public class MyAttributeAttribute : Attribute
{
}
public class MyClass
{
public string this[int index]
{
get
{
return "";
}
[param: MyAttribute]
set
{
return;
}
}
}
}
//$$ TargetPropertyIndexSetMultiParam
namespace TargetPropertyIndexSetMultiParam
{
[AttributeUsage(AttributeTargets.All)]
public class MyAttributeAttribute : Attribute
{
public int Field;
}
public class MyClass
{
public string this[[MyAttribute(Field = 2)]int index1, [MyAttribute(Field = 3)]int index2]
{
get
{
return "";
}
[param: MyAttribute]
set
{
return;
}
}
}
}

6
ICSharpCode.Decompiler/Tests/CustomAttributes/CustomAttributeTests.cs

@ -19,5 +19,11 @@ namespace ICSharpCode.Decompiler.Tests.CustomAttributes
{ {
ValidateFileRoundtrip(@"CustomAttributes\CustomAttributes.cs"); ValidateFileRoundtrip(@"CustomAttributes\CustomAttributes.cs");
} }
[Test]
public void AssemblyCustomAttributesMultiTest()
{
ValidateFileRoundtrip(@"CustomAttributes\AssemblyCustomAttribute.cs");
}
} }
} }

1
ICSharpCode.Decompiler/Tests/CustomAttributes/CustomAttributes.cs

@ -3,7 +3,6 @@
using System; using System;
namespace aa namespace aa
{ {
public static class CustomAtributes public static class CustomAtributes

1
ICSharpCode.Decompiler/Tests/DecompilerTestBase.cs

@ -55,6 +55,7 @@ namespace ICSharpCode.Decompiler.Tests
AssemblyDefinition assembly = Compile(code); AssemblyDefinition assembly = Compile(code);
AstBuilder decompiler = new AstBuilder(new DecompilerContext()); AstBuilder decompiler = new AstBuilder(new DecompilerContext());
decompiler.AddAssembly(assembly); decompiler.AddAssembly(assembly);
decompiler.Transform(new Helpers.RemoveCompilerAttribute());
StringWriter output = new StringWriter(); StringWriter output = new StringWriter();
decompiler.GenerateCode(new PlainTextOutput(output)); decompiler.GenerateCode(new PlainTextOutput(output));
return output.ToString(); return output.ToString();

31
ICSharpCode.Decompiler/Tests/Helpers/RemoveCompilerAttribute.cs

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ICSharpCode.NRefactory.CSharp;
using Decompiler.Transforms;
namespace ICSharpCode.Decompiler.Tests.Helpers
{
class RemoveCompilerAttribute : DepthFirstAstVisitor<object, object>, IAstTransform
{
public override object VisitAttribute(NRefactory.CSharp.Attribute attribute, object data)
{
var section = (AttributeSection)attribute.Parent;
SimpleType type = attribute.Type as SimpleType;
if (section.AttributeTarget == AttributeTarget.Assembly &&
(type.Identifier == "CompilationRelaxationsAttribute" || type.Identifier == "RuntimeCompatibilityAttribute"))
{
attribute.Remove();
if (section.Attributes.Count == 0)
section.Remove();
}
return null;
}
public void Run(AstNode node)
{
node.AcceptVisitor(this, null);
}
}
}

11
ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj

@ -57,6 +57,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="Types\EnumSamples.cs" /> <None Include="Types\EnumSamples.cs" />
<None Include="CustomAttributes\AssemblyCustomAttribute.cs" />
<Compile Include="Helpers\RemoveCompilerAttribute.cs" />
<Compile Include="Types\EnumTests.cs" /> <Compile Include="Types\EnumTests.cs" />
<Compile Include="Types\TypeTests.cs" /> <Compile Include="Types\TypeTests.cs" />
<None Include="Types\DelegateConstruction.cs" /> <None Include="Types\DelegateConstruction.cs" />
@ -70,7 +72,6 @@
<Compile Include="ArrayInitializers.cs" /> <Compile Include="ArrayInitializers.cs" />
<Compile Include="ExceptionHandling.cs" /> <Compile Include="ExceptionHandling.cs" />
<Compile Include="MultidimensionalArray.cs" /> <Compile Include="MultidimensionalArray.cs" />
<Compile Include="TestRunner.cs" /> <Compile Include="TestRunner.cs" />
<None Include="Types\ValueTypes.cs" /> <None Include="Types\ValueTypes.cs" />
</ItemGroup> </ItemGroup>
@ -79,14 +80,16 @@
<Project>{D68133BD-1E63-496E-9EDE-4FBDBF77B486}</Project> <Project>{D68133BD-1E63-496E-9EDE-4FBDBF77B486}</Project>
<Name>Mono.Cecil</Name> <Name>Mono.Cecil</Name>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\..\NRefactory\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj">
<Project>{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}</Project>
<Name>ICSharpCode.NRefactory</Name>
</ProjectReference>
<ProjectReference Include="..\ICSharpCode.Decompiler.csproj"> <ProjectReference Include="..\ICSharpCode.Decompiler.csproj">
<Project>{984CC812-9470-4A13-AFF9-CC44068D666C}</Project> <Project>{984CC812-9470-4A13-AFF9-CC44068D666C}</Project>
<Name>ICSharpCode.Decompiler</Name> <Name>ICSharpCode.Decompiler</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup />
<Folder Include="StackTests" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="BooleanConsumedAsInteger.il" /> <None Include="BooleanConsumedAsInteger.il" />
<None Include="StackTests\StackTests.il" /> <None Include="StackTests\StackTests.il" />

5
ILSpy/CSharpLanguage.cs

@ -132,6 +132,9 @@ namespace ICSharpCode.ILSpy
} }
} else { } else {
base.DecompileAssembly(assembly, fileName, output, options); base.DecompileAssembly(assembly, fileName, output, options);
AstBuilder codeDomBuilder = CreateAstBuilder(options, currentType: null);
codeDomBuilder.AddAssembly(assembly, onlyAssemblyLevel: true);
codeDomBuilder.GenerateCode(output, transformAbortCondition);
} }
} }
@ -375,7 +378,7 @@ namespace ICSharpCode.ILSpy
CurrentType = currentType CurrentType = currentType
}); });
} }
public override string TypeToString(TypeReference type, bool includeNamespace, ICustomAttributeProvider typeAttributes) public override string TypeToString(TypeReference type, bool includeNamespace, ICustomAttributeProvider typeAttributes)
{ {
AstType astType = AstBuilder.ConvertType(type, typeAttributes); AstType astType = AstBuilder.ConvertType(type, typeAttributes);

2
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/CompilationUnit.cs

@ -28,7 +28,7 @@ using System.Collections.Generic;
namespace ICSharpCode.NRefactory.CSharp namespace ICSharpCode.NRefactory.CSharp
{ {
public class CompilationUnit : AstNode public class CompilationUnit : AttributedNode
{ {
public static readonly Role<AstNode> MemberRole = new Role<AstNode>("Member", AstNode.Null); public static readonly Role<AstNode> MemberRole = new Role<AstNode>("Member", AstNode.Null);

Loading…
Cancel
Save