Browse Source

Reenabled CustomerAttributes unit tests and fixed most problems

pull/728/head
David Karlaš 10 years ago
parent
commit
fca29f68c4
  1. 60
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  2. 12
      ICSharpCode.Decompiler/IL/Transforms/ControlFlowSimplification.cs
  3. 2
      ICSharpCode.Decompiler/Tests/CustomAttributes/S_CustomAttributeSamples.cs
  4. 4
      ICSharpCode.Decompiler/Tests/CustomAttributes/S_CustomAttributes.cs
  5. 16
      ICSharpCode.Decompiler/Tests/DecompilerTestBase.cs
  6. 7
      ICSharpCode.Decompiler/Tests/Helpers/RemoveCompilerAttribute.cs
  7. 2
      ICSharpCode.Decompiler/Tests/Helpers/Tester.cs
  8. 6
      ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj
  9. 8
      NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/InsertParenthesesVisitor.cs
  10. 48
      NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/TypeSystemAstBuilder.cs

60
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -116,22 +116,31 @@ namespace ICSharpCode.Decompiler.CSharp @@ -116,22 +116,31 @@ namespace ICSharpCode.Decompiler.CSharp
{
var decompilationContext = new SimpleTypeResolveContext(typeSystem.MainAssembly);
SyntaxTree syntaxTree = new SyntaxTree();
foreach (var g in typeSystem.Compilation.MainAssembly.TopLevelTypeDefinitions.GroupBy(t => t.Namespace)) {
AstNode groupNode;
if (string.IsNullOrEmpty(g.Key)) {
foreach (var a in typeSystem.Compilation.MainAssembly.AssemblyAttributes)
{
var astBuilder = CreateAstBuilder(decompilationContext);
var attrSection = new AttributeSection(astBuilder.ConvertAttribute(a));
attrSection.AttributeTarget = "assembly";
syntaxTree.AddChild(attrSection, SyntaxTree.MemberRole);
}
string currentNamespace = null;
AstNode groupNode = null;
foreach (var cecilType in typeSystem.ModuleDefinition.Types) {
var typeDef = typeSystem.Resolve(cecilType).GetDefinition();
if (typeDef.Name == "<Module>" && typeDef.Members.Count == 0)
continue;
if(string.IsNullOrEmpty(cecilType.Namespace)) {
groupNode = syntaxTree;
} else {
NamespaceDeclaration ns = new NamespaceDeclaration(g.Key);
syntaxTree.AddChild(ns, SyntaxTree.MemberRole);
groupNode = ns;
}
foreach (var typeDef in g) {
if (typeDef.Name == "<Module>" && typeDef.Members.Count == 0)
continue;
var typeDecl = DoDecompile(typeDef, decompilationContext.WithCurrentTypeDefinition(typeDef));
groupNode.AddChild(typeDecl, SyntaxTree.MemberRole);
if (currentNamespace != cecilType.Namespace)
{
groupNode = new NamespaceDeclaration(cecilType.Namespace);
syntaxTree.AddChild(groupNode, SyntaxTree.MemberRole);
}
}
currentNamespace = cecilType.Namespace;
var typeDecl = DoDecompile(typeDef, decompilationContext.WithCurrentTypeDefinition(typeDef));
groupNode.AddChild(typeDecl, SyntaxTree.MemberRole);
}
RunTransforms(syntaxTree, decompilationContext);
return syntaxTree;
@ -160,6 +169,9 @@ namespace ICSharpCode.Decompiler.CSharp @@ -160,6 +169,9 @@ namespace ICSharpCode.Decompiler.CSharp
// e.g. DelegateDeclaration
return entityDecl;
}
foreach (var type in typeDef.NestedTypes) {
typeDecl.Members.Add(DoDecompile(type, decompilationContext.WithCurrentTypeDefinition(type)));
}
foreach (var field in typeDef.Fields) {
var fieldDef = typeSystem.GetCecil(field) as FieldDefinition;
if (fieldDef != null) {
@ -167,13 +179,6 @@ namespace ICSharpCode.Decompiler.CSharp @@ -167,13 +179,6 @@ namespace ICSharpCode.Decompiler.CSharp
typeDecl.Members.Add(memberDecl);
}
}
foreach (var method in typeDef.Methods) {
var methodDef = typeSystem.GetCecil(method) as MethodDefinition;
if (methodDef != null) {
var memberDecl = DoDecompile(methodDef, method, decompilationContext.WithCurrentMember(method));
typeDecl.Members.Add(memberDecl);
}
}
foreach (var property in typeDef.Properties) {
var propDef = typeSystem.GetCecil(property) as PropertyDefinition;
if (propDef != null) {
@ -181,6 +186,13 @@ namespace ICSharpCode.Decompiler.CSharp @@ -181,6 +186,13 @@ namespace ICSharpCode.Decompiler.CSharp
typeDecl.Members.Add(propDecl);
}
}
foreach (var method in typeDef.Methods) {
var methodDef = typeSystem.GetCecil(method) as MethodDefinition;
if (methodDef != null) {
var memberDecl = DoDecompile(methodDef, method, decompilationContext.WithCurrentMember(method));
typeDecl.Members.Add(memberDecl);
}
}
return typeDecl;
}
@ -258,6 +270,14 @@ namespace ICSharpCode.Decompiler.CSharp @@ -258,6 +270,14 @@ namespace ICSharpCode.Decompiler.CSharp
{
Debug.Assert(decompilationContext.CurrentMember == field);
var typeSystemAstBuilder = CreateAstBuilder(decompilationContext);
if (decompilationContext.CurrentTypeDefinition.Kind == TypeKind.Enum) {
var enumDec = new EnumMemberDeclaration() {
Name = field.Name,
Initializer = typeSystemAstBuilder.ConvertConstantValue(decompilationContext.CurrentTypeDefinition.EnumUnderlyingType, field.ConstantValue),
};
enumDec.Attributes.AddRange(field.Attributes.Select(a => new AttributeSection(typeSystemAstBuilder.ConvertAttribute(a))));
return enumDec;
}
return typeSystemAstBuilder.ConvertEntity(field);
}

12
ICSharpCode.Decompiler/IL/Transforms/ControlFlowSimplification.cs

@ -38,6 +38,18 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -38,6 +38,18 @@ namespace ICSharpCode.Decompiler.IL.Transforms
foreach (var container in function.Descendants.OfType<BlockContainer>()) {
Run(container, context);
}
// Remove "return;" at end of method
var funcBody = function.Body as BlockContainer;
if (funcBody != null)
{
var lastBlock = funcBody.Blocks.LastOrDefault();
var lastInst = lastBlock.Instructions.LastOrDefault() as Return;
if (lastInst != null && lastInst.ReturnValue == null)
{
lastInst.ReplaceWith(new Leave(funcBody));
}
}
}
BlockContainer currentContainer;

2
ICSharpCode.Decompiler/Tests/CustomAttributes/S_CustomAttributeSamples.cs

@ -249,7 +249,7 @@ namespace NamedInitializerPropertyType @@ -249,7 +249,7 @@ namespace NamedInitializerPropertyType
{
get
{
return null;
return (Type)null;
}
set
{

4
ICSharpCode.Decompiler/Tests/CustomAttributes/S_CustomAttributes.cs

@ -24,9 +24,9 @@ namespace aa @@ -24,9 +24,9 @@ namespace aa
{
}
}
[CustomAttributes.MyAttribute(CustomAttributes.EnumWithFlag.Item1 | CustomAttributes.EnumWithFlag.Item2)]
[My(EnumWithFlag.Item1 | EnumWithFlag.Item2)]
private static int field;
[CustomAttributes.MyAttribute(CustomAttributes.EnumWithFlag.All)]
[My(EnumWithFlag.All)]
public static string Property
{
get

16
ICSharpCode.Decompiler/Tests/DecompilerTestBase.cs

@ -28,6 +28,8 @@ using ICSharpCode.Decompiler.Tests.Helpers; @@ -28,6 +28,8 @@ using ICSharpCode.Decompiler.Tests.Helpers;
using Microsoft.CSharp;
using Mono.Cecil;
using NUnit.Framework;
using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.NRefactory.CSharp;
namespace ICSharpCode.Decompiler.Tests
{
@ -49,13 +51,15 @@ namespace ICSharpCode.Decompiler.Tests @@ -49,13 +51,15 @@ namespace ICSharpCode.Decompiler.Tests
var code = RemoveIgnorableLines(File.ReadLines(fileName));
AssemblyDefinition assembly = CompileLegacy(code, optimize, useDebug, compilerVersion);
AstBuilder decompiler = new AstBuilder(new DecompilerContext(assembly.MainModule));
decompiler.AddAssembly(assembly);
new Helpers.RemoveCompilerAttribute().Run(decompiler.SyntaxTree);
CSharpDecompiler decompiler = new CSharpDecompiler(assembly.MainModule);
StringWriter output = new StringWriter();
decompiler.GenerateCode(new PlainTextOutput(output));
CodeAssert.AreEqual(code, output.ToString());
decompiler.AstTransforms.Insert(0, new RemoveCompilerAttribute());
var syntaxTree = decompiler.DecompileWholeModuleAsSingleFile();
var options = FormattingOptionsFactory.CreateAllman();
options.IndentSwitchBody = false;
CodeAssert.AreEqual(code, syntaxTree.ToString(options));
}
protected static AssemblyDefinition CompileLegacy(string code, bool optimize, bool useDebug, int compilerVersion)

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

@ -4,10 +4,11 @@ using System.Linq; @@ -4,10 +4,11 @@ using System.Linq;
using System.Text;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.Decompiler.CSharp.Transforms;
namespace ICSharpCode.Decompiler.Tests.Helpers
{
class RemoveCompilerAttribute : DepthFirstAstVisitor<object, object>
class RemoveCompilerAttribute : DepthFirstAstVisitor<object, object>, IAstTransform
{
public override object VisitAttribute(NRefactory.CSharp.Attribute attribute, object data)
{
@ -29,9 +30,9 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -29,9 +30,9 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
return null;
}
public void Run(AstNode node)
public void Run(AstNode rootNode, TransformContext context)
{
node.AcceptVisitor(this, null);
rootNode.AcceptVisitor(this, null);
}
}

2
ICSharpCode.Decompiler/Tests/Helpers/Tester.cs

@ -65,8 +65,8 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -65,8 +65,8 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
{
var typeSystem = new DecompilerTypeSystem(ModuleDefinition.ReadModule(assemblyFileName));
CSharpDecompiler decompiler = new CSharpDecompiler(typeSystem);
decompiler.AstTransforms.Insert(0, new RemoveCompilerAttribute());
var syntaxTree = decompiler.DecompileWholeModuleAsSingleFile();
new Helpers.RemoveCompilerAttribute().Run(syntaxTree);
new Helpers.EscapeGeneratedIdentifiers().Run(syntaxTree);
StringWriter output = new StringWriter();

6
ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj

@ -110,6 +110,12 @@ @@ -110,6 +110,12 @@
<Compile Include="TestCases\Switch.cs" />
<Compile Include="TestRunner.cs" />
<Compile Include="Util\LongSetTests.cs" />
<Compile Include="CustomAttributes\CustomAttributeTests.cs" />
<Compile Include="CustomAttributes\S_AssemblyCustomAttribute.cs" />
<Compile Include="CustomAttributes\S_CustomAttributeSamples.cs" />
<Compile Include="CustomAttributes\S_CustomAttributes.cs" />
<Compile Include="DecompilerTestBase.cs" />
<Compile Include="CodeSampleFileParser.cs" />
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />

8
NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/InsertParenthesesVisitor.cs

@ -341,5 +341,13 @@ namespace ICSharpCode.NRefactory.CSharp @@ -341,5 +341,13 @@ namespace ICSharpCode.NRefactory.CSharp
}
base.VisitQueryExpression(queryExpression);
}
public override void VisitNamedExpression (NamedExpression namedExpression)
{
if (InsertParenthesesForReadability) {
ParenthesizeIfRequired(namedExpression.Expression, RelationalAndTypeTesting + 1);
}
base.VisitNamedExpression (namedExpression);
}
}
}

48
NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/TypeSystemAstBuilder.cs

@ -567,6 +567,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -567,6 +567,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
} else if (parameter.IsParams) {
decl.ParameterModifier = ParameterModifier.Params;
}
decl.Attributes.AddRange (parameter.Attributes.Select ((a) => new AttributeSection (ConvertAttribute (a))));
decl.Type = ConvertType(parameter.Type);
if (this.ShowParameterNames) {
decl.Name = parameter.Name;
@ -625,7 +626,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -625,7 +626,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
return ConvertDestructor((IMethod)entity);
case SymbolKind.Accessor:
IMethod accessor = (IMethod)entity;
return ConvertAccessor(accessor, accessor.AccessorOwner != null ? accessor.AccessorOwner.Accessibility : Accessibility.None);
return ConvertAccessor(accessor, accessor.AccessorOwner != null ? accessor.AccessorOwner.Accessibility : Accessibility.None, false);
default:
throw new ArgumentException("Invalid value for SymbolKind: " + entity.SymbolKind);
}
@ -679,6 +680,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -679,6 +680,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
var decl = new TypeDeclaration();
decl.ClassType = classType;
decl.Modifiers = modifiers;
decl.Attributes.AddRange (typeDefinition.Attributes.Select ((a) => new AttributeSection (ConvertAttribute (a))));
decl.Name = typeDefinition.Name;
int outerTypeParameterCount = (typeDefinition.DeclaringTypeDefinition == null) ? 0 : typeDefinition.DeclaringTypeDefinition.TypeParameterCount;
@ -691,7 +693,11 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -691,7 +693,11 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
if (this.ShowBaseTypes) {
foreach (IType baseType in typeDefinition.DirectBaseTypes) {
decl.BaseTypes.Add(ConvertType(baseType));
if (!baseType.IsKnownType (KnownTypeCode.Enum) &&
!baseType.IsKnownType (KnownTypeCode.Object) &&
!baseType.IsKnownType (KnownTypeCode.ValueType)) {
decl.BaseTypes.Add (ConvertType (baseType));
}
}
}
@ -711,6 +717,10 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -711,6 +717,10 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
DelegateDeclaration decl = new DelegateDeclaration();
decl.Modifiers = modifiers & ~Modifiers.Sealed;
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.ReturnType = ConvertType(invokeMethod.ReturnType);
decl.Name = d.Name;
@ -749,6 +759,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -749,6 +759,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
}
decl.Modifiers = m;
}
decl.Attributes.AddRange (field.Attributes.Select ((a) => new AttributeSection (ConvertAttribute (a))));
decl.ReturnType = ConvertType(field.ReturnType);
Expression initializer = null;
if (field.IsConst && this.ShowConstantValues)
@ -768,13 +779,22 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -768,13 +779,22 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
}
}
Accessor ConvertAccessor(IMethod accessor, Accessibility ownerAccessibility)
Accessor ConvertAccessor(IMethod accessor, Accessibility ownerAccessibility, bool addParamterAttribute)
{
if (accessor == null)
return Accessor.Null;
Accessor decl = new Accessor();
if (this.ShowAccessibility && accessor.Accessibility != ownerAccessibility)
decl.Modifiers = ModifierFromAccessibility(accessor.Accessibility);
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.Body = GenerateBodyBlock();
return decl;
}
@ -783,10 +803,11 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -783,10 +803,11 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
PropertyDeclaration decl = new PropertyDeclaration();
decl.Modifiers = GetMemberModifiers(property);
decl.Attributes.AddRange (property.Attributes.Select ((a) => new AttributeSection (ConvertAttribute (a))));
decl.ReturnType = ConvertType(property.ReturnType);
decl.Name = property.Name;
decl.Getter = ConvertAccessor(property.Getter, property.Accessibility);
decl.Setter = ConvertAccessor(property.Setter, property.Accessibility);
decl.Getter = ConvertAccessor(property.Getter, property.Accessibility, false);
decl.Setter = ConvertAccessor(property.Setter, property.Accessibility, true);
return decl;
}
@ -794,12 +815,13 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -794,12 +815,13 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
IndexerDeclaration decl = new IndexerDeclaration();
decl.Modifiers = GetMemberModifiers(indexer);
decl.Attributes.AddRange (indexer.Attributes.Select ((a) => new AttributeSection (ConvertAttribute (a))));
decl.ReturnType = ConvertType(indexer.ReturnType);
foreach (IParameter p in indexer.Parameters) {
decl.Parameters.Add(ConvertParameter(p));
}
decl.Getter = ConvertAccessor(indexer.Getter, indexer.Accessibility);
decl.Setter = ConvertAccessor(indexer.Setter, indexer.Accessibility);
decl.Getter = ConvertAccessor(indexer.Getter, indexer.Accessibility, false);
decl.Setter = ConvertAccessor(indexer.Setter, indexer.Accessibility, true);
return decl;
}
@ -808,14 +830,16 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -808,14 +830,16 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
if (this.UseCustomEvents) {
CustomEventDeclaration decl = new CustomEventDeclaration();
decl.Modifiers = GetMemberModifiers(ev);
decl.Attributes.AddRange (ev.Attributes.Select ((a) => new AttributeSection (ConvertAttribute (a))));
decl.ReturnType = ConvertType(ev.ReturnType);
decl.Name = ev.Name;
decl.AddAccessor = ConvertAccessor(ev.AddAccessor, ev.Accessibility);
decl.RemoveAccessor = ConvertAccessor(ev.RemoveAccessor, ev.Accessibility);
decl.AddAccessor = ConvertAccessor(ev.AddAccessor, ev.Accessibility, true);
decl.RemoveAccessor = ConvertAccessor(ev.RemoveAccessor, ev.Accessibility, true);
return decl;
} else {
EventDeclaration decl = new EventDeclaration();
decl.Modifiers = GetMemberModifiers(ev);
decl.Attributes.AddRange (ev.Attributes.Select ((a) => new AttributeSection (ConvertAttribute (a))));
decl.ReturnType = ConvertType(ev.ReturnType);
decl.Variables.Add(new VariableInitializer(ev.Name));
return decl;
@ -828,7 +852,11 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -828,7 +852,11 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
decl.Modifiers = GetMemberModifiers(method);
if (method.IsAsync && ShowModifiers)
decl.Modifiers |= Modifiers.Async;
decl.Attributes.AddRange (method.Attributes.Select ((a) => new AttributeSection (ConvertAttribute (a))));
decl.ReturnType = ConvertType(method.ReturnType);
decl.Attributes.AddRange (method.ReturnTypeAttributes.Select ((a) => new AttributeSection (ConvertAttribute (a)) {
AttributeTarget = "return"
}));
decl.Name = method.Name;
if (this.ShowTypeParameters) {
@ -875,6 +903,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -875,6 +903,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
ConstructorDeclaration decl = new ConstructorDeclaration();
decl.Modifiers = GetMemberModifiers(ctor);
decl.Attributes.AddRange (ctor.Attributes.Select ((a) => new AttributeSection (ConvertAttribute (a))));
if (ctor.DeclaringTypeDefinition != null)
decl.Name = ctor.DeclaringTypeDefinition.Name;
foreach (IParameter p in ctor.Parameters) {
@ -947,6 +976,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -947,6 +976,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
TypeParameterDeclaration decl = new TypeParameterDeclaration();
decl.Variance = tp.Variance;
decl.Name = tp.Name;
decl.Attributes.AddRange (tp.Attributes.Select ((a) => new AttributeSection (ConvertAttribute (a))));
return decl;
}

Loading…
Cancel
Save