Browse Source

Adjust ILSpy to NRefactory API changes.

pull/129/head
Daniel Grunwald 14 years ago
parent
commit
12a8267c21
  1. 30
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  2. 18
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  3. 2
      ICSharpCode.Decompiler/Ast/CommentStatement.cs
  4. 25
      ICSharpCode.Decompiler/Ast/NRefactoryExtensions.cs
  5. 6
      ICSharpCode.Decompiler/Ast/Transforms/AddCheckedBlocks.cs
  6. 6
      ICSharpCode.Decompiler/Ast/Transforms/CombineQueryExpressions.cs
  7. 12
      ICSharpCode.Decompiler/Ast/Transforms/ConvertConstructorCallIntoInitializer.cs
  8. 2
      ICSharpCode.Decompiler/Ast/Transforms/DeclareVariables.cs
  9. 12
      ICSharpCode.Decompiler/Ast/Transforms/DelegateConstruction.cs
  10. 58
      ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs
  11. 6
      ICSharpCode.Decompiler/Ast/Transforms/PushNegation.cs
  12. 6
      ICSharpCode.Decompiler/Ast/Transforms/ReplaceMethodCallsWithOperators.cs
  13. 4
      ICSharpCode.Decompiler/Tests/Helpers/RemoveCompilerAttribute.cs
  14. 2
      ILSpy/CSharpLanguage.cs

30
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -110,7 +110,7 @@ namespace ICSharpCode.Decompiler.Ast
astCompileUnit.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true }, null); astCompileUnit.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true }, null);
var outputFormatter = new TextOutputFormatter(output); var outputFormatter = new TextOutputFormatter(output);
var formattingPolicy = new CSharpFormattingPolicy(); var formattingPolicy = new CSharpFormattingOptions();
// disable whitespace in front of parentheses: // disable whitespace in front of parentheses:
formattingPolicy.SpaceBeforeMethodCallParentheses = false; formattingPolicy.SpaceBeforeMethodCallParentheses = false;
formattingPolicy.SpaceBeforeMethodDeclarationParentheses = false; formattingPolicy.SpaceBeforeMethodDeclarationParentheses = false;
@ -121,8 +121,8 @@ namespace ICSharpCode.Decompiler.Ast
public void AddAssembly(AssemblyDefinition assemblyDefinition, bool onlyAssemblyLevel = false) public void AddAssembly(AssemblyDefinition assemblyDefinition, bool onlyAssemblyLevel = false)
{ {
ConvertCustomAttributes(astCompileUnit, assemblyDefinition, AttributeTarget.Assembly); ConvertCustomAttributes(astCompileUnit, assemblyDefinition, "assembly");
ConvertCustomAttributes(astCompileUnit, assemblyDefinition.MainModule, AttributeTarget.Module); ConvertCustomAttributes(astCompileUnit, assemblyDefinition.MainModule, "module");
if (!onlyAssemblyLevel) { if (!onlyAssemblyLevel) {
foreach (TypeDefinition typeDef in assemblyDefinition.MainModule.Types) { foreach (TypeDefinition typeDef in assemblyDefinition.MainModule.Types) {
@ -768,7 +768,7 @@ namespace ICSharpCode.Decompiler.Ast
astProp.Setter.Body = CreateMethodBody(propDef.SetMethod); astProp.Setter.Body = CreateMethodBody(propDef.SetMethod);
astProp.Setter.AddAnnotation(propDef.SetMethod); astProp.Setter.AddAnnotation(propDef.SetMethod);
ConvertAttributes(astProp.Setter, propDef.SetMethod); ConvertAttributes(astProp.Setter, propDef.SetMethod);
ConvertCustomAttributes(astProp.Setter, propDef.SetMethod.Parameters.Last(), AttributeTarget.Param); ConvertCustomAttributes(astProp.Setter, propDef.SetMethod.Parameters.Last(), "param");
if ((setterModifiers & Modifiers.VisibilityMask) != (astProp.Modifiers & Modifiers.VisibilityMask)) if ((setterModifiers & Modifiers.VisibilityMask) != (astProp.Modifiers & Modifiers.VisibilityMask))
astProp.Setter.Modifiers = setterModifiers & Modifiers.VisibilityMask; astProp.Setter.Modifiers = setterModifiers & Modifiers.VisibilityMask;
@ -872,7 +872,7 @@ namespace ICSharpCode.Decompiler.Ast
{ {
var parameters = MakeParameters(method.Parameters, isLambda); var parameters = MakeParameters(method.Parameters, isLambda);
if (method.CallingConvention == MethodCallingConvention.VarArg) { if (method.CallingConvention == MethodCallingConvention.VarArg) {
return parameters.Concat(new[] { new ParameterDeclaration { Name = "__arglist" } }); return parameters.Concat(new[] { new ParameterDeclaration { Type = new PrimitiveType("__arglist") } });
} else { } else {
return parameters; return parameters;
} }
@ -1062,14 +1062,14 @@ namespace ICSharpCode.Decompiler.Ast
} }
#endregion #endregion
ConvertCustomAttributes(attributedNode, methodDefinition.MethodReturnType, AttributeTarget.Return); ConvertCustomAttributes(attributedNode, methodDefinition.MethodReturnType, "return");
if (methodDefinition.MethodReturnType.HasMarshalInfo) { if (methodDefinition.MethodReturnType.HasMarshalInfo) {
var marshalInfo = ConvertMarshalInfo(methodDefinition.MethodReturnType, methodDefinition.Module); var marshalInfo = ConvertMarshalInfo(methodDefinition.MethodReturnType, methodDefinition.Module);
attributedNode.Attributes.Add(new AttributeSection(marshalInfo) { AttributeTarget = AttributeTarget.Return }); attributedNode.Attributes.Add(new AttributeSection(marshalInfo) { AttributeTarget = "return" });
} }
} }
internal static void ConvertAttributes(AttributedNode attributedNode, FieldDefinition fieldDefinition, AttributeTarget target = AttributeTarget.None) internal static void ConvertAttributes(AttributedNode attributedNode, FieldDefinition fieldDefinition, string attributeTarget = null)
{ {
ConvertCustomAttributes(attributedNode, fieldDefinition); ConvertCustomAttributes(attributedNode, fieldDefinition);
@ -1077,19 +1077,19 @@ namespace ICSharpCode.Decompiler.Ast
if (fieldDefinition.HasLayoutInfo) { if (fieldDefinition.HasLayoutInfo) {
Ast.Attribute fieldOffset = CreateNonCustomAttribute(typeof(FieldOffsetAttribute), fieldDefinition.Module); Ast.Attribute fieldOffset = CreateNonCustomAttribute(typeof(FieldOffsetAttribute), fieldDefinition.Module);
fieldOffset.Arguments.Add(new PrimitiveExpression(fieldDefinition.Offset)); fieldOffset.Arguments.Add(new PrimitiveExpression(fieldDefinition.Offset));
attributedNode.Attributes.Add(new AttributeSection(fieldOffset) { AttributeTarget = target }); attributedNode.Attributes.Add(new AttributeSection(fieldOffset) { AttributeTarget = attributeTarget });
} }
#endregion #endregion
#region NonSerializedAttribute #region NonSerializedAttribute
if (fieldDefinition.IsNotSerialized) { if (fieldDefinition.IsNotSerialized) {
Ast.Attribute nonSerialized = CreateNonCustomAttribute(typeof(NonSerializedAttribute), fieldDefinition.Module); Ast.Attribute nonSerialized = CreateNonCustomAttribute(typeof(NonSerializedAttribute), fieldDefinition.Module);
attributedNode.Attributes.Add(new AttributeSection(nonSerialized) { AttributeTarget = target }); attributedNode.Attributes.Add(new AttributeSection(nonSerialized) { AttributeTarget = attributeTarget });
} }
#endregion #endregion
if (fieldDefinition.HasMarshalInfo) { if (fieldDefinition.HasMarshalInfo) {
attributedNode.Attributes.Add(new AttributeSection(ConvertMarshalInfo(fieldDefinition, fieldDefinition.Module)) { AttributeTarget = target }); attributedNode.Attributes.Add(new AttributeSection(ConvertMarshalInfo(fieldDefinition, fieldDefinition.Module)) { AttributeTarget = attributeTarget });
} }
} }
@ -1120,7 +1120,7 @@ namespace ICSharpCode.Decompiler.Ast
return attr; return attr;
} }
static void ConvertCustomAttributes(AstNode attributedNode, ICustomAttributeProvider customAttributeProvider, AttributeTarget target = AttributeTarget.None) static void ConvertCustomAttributes(AstNode attributedNode, ICustomAttributeProvider customAttributeProvider, string attributeTarget = null)
{ {
if (customAttributeProvider.HasCustomAttributes) { if (customAttributeProvider.HasCustomAttributes) {
var attributes = new List<ICSharpCode.NRefactory.CSharp.Attribute>(); var attributes = new List<ICSharpCode.NRefactory.CSharp.Attribute>();
@ -1171,18 +1171,18 @@ namespace ICSharpCode.Decompiler.Ast
} }
} }
if (target == AttributeTarget.Module || target == AttributeTarget.Assembly) { if (attributeTarget == "module" || attributeTarget == "assembly") {
// use separate section for each attribute // use separate section for each attribute
foreach (var attribute in attributes) { foreach (var attribute in attributes) {
var section = new AttributeSection(); var section = new AttributeSection();
section.AttributeTarget = target; section.AttributeTarget = attributeTarget;
section.Attributes.Add(attribute); section.Attributes.Add(attribute);
attributedNode.AddChild(section, AttributedNode.AttributeRole); attributedNode.AddChild(section, AttributedNode.AttributeRole);
} }
} else if (attributes.Count > 0) { } else if (attributes.Count > 0) {
// use single section for all attributes // use single section for all attributes
var section = new AttributeSection(); var section = new AttributeSection();
section.AttributeTarget = target; section.AttributeTarget = attributeTarget;
section.Attributes.AddRange(attributes); section.Attributes.AddRange(attributes);
attributedNode.AddChild(section, AttributedNode.AttributeRole); attributedNode.AddChild(section, AttributedNode.AttributeRole);
} }

18
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -4,9 +4,11 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using ICSharpCode.Decompiler.Ast.Transforms; using ICSharpCode.Decompiler.Ast.Transforms;
using ICSharpCode.Decompiler.ILAst; using ICSharpCode.Decompiler.ILAst;
using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.PatternMatching;
using ICSharpCode.NRefactory.Utils; using ICSharpCode.NRefactory.Utils;
using Mono.Cecil; using Mono.Cecil;
using Mono.Cecil.Cil; using Mono.Cecil.Cil;
@ -477,7 +479,7 @@ namespace ICSharpCode.Decompiler.Ast
return new AssignmentExpression(new UnaryOperatorExpression(UnaryOperatorType.Dereference, arg1), arg2); return new AssignmentExpression(new UnaryOperatorExpression(UnaryOperatorType.Dereference, arg1), arg2);
#endregion #endregion
case ILCode.Arglist: case ILCode.Arglist:
return new ArgListExpression { IsAccess = true }; return new UndocumentedExpression { UndocumentedExpressionType = UndocumentedExpressionType.ArgListAccess };
case ILCode.Break: return InlineAssembly(byteCode, args); case ILCode.Break: return InlineAssembly(byteCode, args);
case ILCode.Call: case ILCode.Call:
case ILCode.CallGetter: case ILCode.CallGetter:
@ -597,10 +599,14 @@ namespace ICSharpCode.Decompiler.Ast
case ILCode.Mkrefany: case ILCode.Mkrefany:
{ {
DirectionExpression dir = arg1 as DirectionExpression; DirectionExpression dir = arg1 as DirectionExpression;
if (dir != null) if (dir != null) {
return new IdentifierExpression("__makeref").Invoke(dir.Expression.Detach()); return new UndocumentedExpression {
else UndocumentedExpressionType = UndocumentedExpressionType.MakeRef,
Arguments = { dir.Expression.Detach() }
};
} else {
return InlineAssembly(byteCode, args); return InlineAssembly(byteCode, args);
}
} }
case ILCode.Newobj: { case ILCode.Newobj: {
Cecil.TypeReference declaringType = ((MethodReference)operand).DeclaringType; Cecil.TypeReference declaringType = ((MethodReference)operand).DeclaringType;
@ -714,10 +720,10 @@ namespace ICSharpCode.Decompiler.Ast
} }
BinaryOperatorExpression boe = expr as BinaryOperatorExpression; BinaryOperatorExpression boe = expr as BinaryOperatorExpression;
if (boe != null && boe.Operator == BinaryOperatorType.Multiply && sizeOfExpression.Match(boe.Right) != null) if (boe != null && boe.Operator == BinaryOperatorType.Multiply && sizeOfExpression.IsMatch(boe.Right))
return boe.Left.Detach(); return boe.Left.Detach();
if (sizeOfExpression.Match(expr) != null) if (sizeOfExpression.IsMatch(expr))
return new PrimitiveExpression(1); return new PrimitiveExpression(1);
return new BinaryOperatorExpression(expr, BinaryOperatorType.Divide, sizeOfExpression); return new BinaryOperatorExpression(expr, BinaryOperatorType.Divide, sizeOfExpression);

2
ICSharpCode.Decompiler/Ast/CommentStatement.cs

@ -4,7 +4,7 @@
using System; using System;
using System.Linq; using System.Linq;
using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.PatternMatching; using ICSharpCode.NRefactory.PatternMatching;
namespace ICSharpCode.Decompiler.Ast namespace ICSharpCode.Decompiler.Ast
{ {

25
ICSharpCode.Decompiler/Ast/NRefactoryExtensions.cs

@ -3,7 +3,7 @@
using System; using System;
using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.PatternMatching; using ICSharpCode.NRefactory.PatternMatching;
namespace ICSharpCode.Decompiler.Ast namespace ICSharpCode.Decompiler.Ast
{ {
@ -44,5 +44,28 @@ namespace ICSharpCode.Decompiler.Ast
{ {
attribute.Arguments.Add(new AssignmentExpression(new IdentifierExpression(name), argument)); attribute.Arguments.Add(new AssignmentExpression(new IdentifierExpression(name), argument));
} }
public static AstType ToType(this Pattern pattern)
{
return pattern;
}
public static Expression ToExpression(this Pattern pattern)
{
return pattern;
}
public static Statement ToStatement(this Pattern pattern)
{
return pattern;
}
public static Statement GetNextStatement(this Statement statement)
{
AstNode next = statement.NextSibling;
while (next != null && !(next is Statement))
next = next.NextSibling;
return (Statement)next;
}
} }
} }

6
ICSharpCode.Decompiler/Ast/Transforms/AddCheckedBlocks.cs

@ -180,8 +180,8 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
BlockStatement newBlock = new BlockStatement(); BlockStatement newBlock = new BlockStatement();
// Move all statements except for the first // Move all statements except for the first
Statement next; Statement next;
for (Statement stmt = firstStatement.NextStatement; stmt != lastStatement; stmt = next) { for (Statement stmt = firstStatement.GetNextStatement(); stmt != lastStatement; stmt = next) {
next = stmt.NextStatement; next = stmt.GetNextStatement();
newBlock.Add(stmt.Detach()); newBlock.Add(stmt.Detach());
} }
// Replace the first statement with the new (un)checked block // Replace the first statement with the new (un)checked block
@ -276,7 +276,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
costUncheckedContextCheckedBlockOpen += stmtResult.CostInCheckedContext; costUncheckedContextCheckedBlockOpen += stmtResult.CostInCheckedContext;
nodesUncheckedContextCheckedBlockOpen += stmtResult.NodesToInsertInCheckedContext; nodesUncheckedContextCheckedBlockOpen += stmtResult.NodesToInsertInCheckedContext;
statement = statement.NextStatement; statement = statement.GetNextStatement();
} }
return new Result { return new Result {

6
ICSharpCode.Decompiler/Ast/Transforms/CombineQueryExpressions.cs

@ -4,7 +4,7 @@
using System; using System;
using System.Linq; using System.Linq;
using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.PatternMatching; using ICSharpCode.NRefactory.PatternMatching;
namespace ICSharpCode.Decompiler.Ast.Transforms namespace ICSharpCode.Decompiler.Ast.Transforms
{ {
@ -54,7 +54,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
} }
} else { } else {
Match m = castPattern.Match(fromClause.Expression); Match m = castPattern.Match(fromClause.Expression);
if (m != null) { if (m.Success) {
fromClause.Type = m.Get<AstType>("targetType").Single().Detach(); fromClause.Type = m.Get<AstType>("targetType").Single().Detach();
fromClause.Expression = m.Get<Expression>("inExpr").Single().Detach(); fromClause.Expression = m.Get<Expression>("inExpr").Single().Detach();
} }
@ -82,7 +82,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
if (!IsTransparentIdentifier(fromClause.Identifier)) if (!IsTransparentIdentifier(fromClause.Identifier))
return false; return false;
Match match = selectTransparentIdentifierPattern.Match(innerQuery.Clauses.Last()); Match match = selectTransparentIdentifierPattern.Match(innerQuery.Clauses.Last());
if (match == null) if (!match.Success)
return false; return false;
QuerySelectClause selectClause = (QuerySelectClause)innerQuery.Clauses.Last(); QuerySelectClause selectClause = (QuerySelectClause)innerQuery.Clauses.Last();
NamedArgumentExpression nae1 = match.Get<NamedArgumentExpression>("nae1").Single(); NamedArgumentExpression nae1 = match.Get<NamedArgumentExpression>("nae1").Single();

12
ICSharpCode.Decompiler/Ast/Transforms/ConvertConstructorCallIntoInitializer.cs

@ -4,7 +4,7 @@
using System; using System;
using System.Linq; using System.Linq;
using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.PatternMatching; using ICSharpCode.NRefactory.PatternMatching;
using Mono.Cecil; using Mono.Cecil;
namespace ICSharpCode.Decompiler.Ast.Transforms namespace ICSharpCode.Decompiler.Ast.Transforms
@ -55,17 +55,17 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
public override object VisitTypeDeclaration(TypeDeclaration typeDeclaration, object data) public override object VisitTypeDeclaration(TypeDeclaration typeDeclaration, object data)
{ {
var instanceCtors = typeDeclaration.Members.OfType<ConstructorDeclaration>().Where(c => (c.Modifiers & Modifiers.Static) == 0).ToArray(); var instanceCtors = typeDeclaration.Members.OfType<ConstructorDeclaration>().Where(c => (c.Modifiers & Modifiers.Static) == 0).ToArray();
var instanceCtorsNotChainingWithThis = instanceCtors.Where(ctor => thisCallPattern.Match(ctor.Body.Statements.FirstOrDefault()) == null).ToArray(); var instanceCtorsNotChainingWithThis = instanceCtors.Where(ctor => !thisCallPattern.IsMatch(ctor.Body.Statements.FirstOrDefault())).ToArray();
if (instanceCtorsNotChainingWithThis.Length > 0 && typeDeclaration.ClassType == NRefactory.TypeSystem.ClassType.Class) { if (instanceCtorsNotChainingWithThis.Length > 0 && typeDeclaration.ClassType == NRefactory.TypeSystem.ClassType.Class) {
// Recognize field initializers: // Recognize field initializers:
// Convert first statement in all ctors (if all ctors have the same statement) into a field initializer. // Convert first statement in all ctors (if all ctors have the same statement) into a field initializer.
bool allSame; bool allSame;
do { do {
Match m = fieldInitializerPattern.Match(instanceCtorsNotChainingWithThis[0].Body.FirstOrDefault()); Match m = fieldInitializerPattern.Match(instanceCtorsNotChainingWithThis[0].Body.FirstOrDefault());
if (m == null) if (!m.Success)
break; break;
FieldDefinition fieldDef = m.Get("fieldAccess").Single().Annotation<FieldReference>().ResolveWithinSameModule(); FieldDefinition fieldDef = m.Get<AstNode>("fieldAccess").Single().Annotation<FieldReference>().ResolveWithinSameModule();
if (fieldDef == null) if (fieldDef == null)
break; break;
AttributedNode fieldOrEventDecl = typeDeclaration.Members.FirstOrDefault(f => f.Annotation<FieldDefinition>() == fieldDef); AttributedNode fieldOrEventDecl = typeDeclaration.Members.FirstOrDefault(f => f.Annotation<FieldDefinition>() == fieldDef);
@ -74,7 +74,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
allSame = true; allSame = true;
for (int i = 1; i < instanceCtorsNotChainingWithThis.Length; i++) { for (int i = 1; i < instanceCtorsNotChainingWithThis.Length; i++) {
if (instanceCtors[0].Body.First().Match(instanceCtorsNotChainingWithThis[i].Body.FirstOrDefault()) == null) if (!instanceCtors[0].Body.First().IsMatch(instanceCtorsNotChainingWithThis[i].Body.FirstOrDefault()))
allSame = false; allSame = false;
} }
if (allSame) { if (allSame) {
@ -93,7 +93,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
ConstructorDeclaration emptyCtor = new ConstructorDeclaration(); ConstructorDeclaration emptyCtor = new ConstructorDeclaration();
emptyCtor.Modifiers = ((typeDeclaration.Modifiers & Modifiers.Abstract) == Modifiers.Abstract ? Modifiers.Protected : Modifiers.Public); emptyCtor.Modifiers = ((typeDeclaration.Modifiers & Modifiers.Abstract) == Modifiers.Abstract ? Modifiers.Protected : Modifiers.Public);
emptyCtor.Body = new BlockStatement(); emptyCtor.Body = new BlockStatement();
if (emptyCtor.Match(instanceCtors[0]) != null) if (emptyCtor.IsMatch(instanceCtors[0]))
instanceCtors[0].Remove(); instanceCtors[0].Remove();
} }

2
ICSharpCode.Decompiler/Ast/Transforms/DeclareVariables.cs

@ -200,7 +200,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
} }
// If we can move the variable into the sub-block, we need to ensure that the remaining code // If we can move the variable into the sub-block, we need to ensure that the remaining code
// does not use the value that was assigned by the first sub-block // does not use the value that was assigned by the first sub-block
Statement nextStatement = stmt.NextStatement; Statement nextStatement = stmt.GetNextStatement();
if (nextStatement != null) { if (nextStatement != null) {
// Analyze the range from the next statement to the end of the block // Analyze the range from the next statement to the end of the block
daa.SetAnalyzedRange(nextStatement, block); daa.SetAnalyzedRange(nextStatement, block);

12
ICSharpCode.Decompiler/Ast/Transforms/DelegateConstruction.cs

@ -9,7 +9,7 @@ using System.Threading;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.ILAst; using ICSharpCode.Decompiler.ILAst;
using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.PatternMatching; using ICSharpCode.NRefactory.PatternMatching;
using Mono.Cecil; using Mono.Cecil;
namespace ICSharpCode.Decompiler.Ast.Transforms namespace ICSharpCode.Decompiler.Ast.Transforms
@ -270,16 +270,16 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
base.VisitBlockStatement(blockStatement, data); base.VisitBlockStatement(blockStatement, data);
foreach (ExpressionStatement stmt in blockStatement.Statements.OfType<ExpressionStatement>().ToArray()) { foreach (ExpressionStatement stmt in blockStatement.Statements.OfType<ExpressionStatement>().ToArray()) {
Match displayClassAssignmentMatch = displayClassAssignmentPattern.Match(stmt); Match displayClassAssignmentMatch = displayClassAssignmentPattern.Match(stmt);
if (displayClassAssignmentMatch == null) if (!displayClassAssignmentMatch.Success)
continue; continue;
ILVariable variable = displayClassAssignmentMatch.Get("variable").Single().Annotation<ILVariable>(); ILVariable variable = displayClassAssignmentMatch.Get<AstNode>("variable").Single().Annotation<ILVariable>();
if (variable == null) if (variable == null)
continue; continue;
TypeDefinition type = variable.Type.ResolveWithinSameModule(); TypeDefinition type = variable.Type.ResolveWithinSameModule();
if (!IsPotentialClosure(context, type)) if (!IsPotentialClosure(context, type))
continue; continue;
if (displayClassAssignmentMatch.Get("type").Single().Annotation<TypeReference>().ResolveWithinSameModule() != type) if (displayClassAssignmentMatch.Get<AstType>("type").Single().Annotation<TypeReference>().ResolveWithinSameModule() != type)
continue; continue;
// Looks like we found a display class creation. Now let's verify that the variable is used only for field accesses: // Looks like we found a display class creation. Now let's verify that the variable is used only for field accesses:
@ -320,9 +320,9 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
) )
); );
Match m = closureFieldAssignmentPattern.Match(cur); Match m = closureFieldAssignmentPattern.Match(cur);
if (m != null) { if (m.Success) {
FieldDefinition fieldDef = m.Get<MemberReferenceExpression>("left").Single().Annotation<FieldReference>().ResolveWithinSameModule(); FieldDefinition fieldDef = m.Get<MemberReferenceExpression>("left").Single().Annotation<FieldReference>().ResolveWithinSameModule();
AstNode right = m.Get("right").Single(); AstNode right = m.Get<AstNode>("right").Single();
bool isParameter = false; bool isParameter = false;
bool isDisplayClassParentPointerAssignment = false; bool isDisplayClassParentPointerAssignment = false;
if (right is ThisReferenceExpression) { if (right is ThisReferenceExpression) {

58
ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs

@ -5,10 +5,11 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using ICSharpCode.Decompiler.ILAst; using ICSharpCode.Decompiler.ILAst;
using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.Analysis; using ICSharpCode.NRefactory.CSharp.Analysis;
using ICSharpCode.NRefactory.CSharp.PatternMatching; using ICSharpCode.NRefactory.PatternMatching;
using Mono.Cecil; using Mono.Cecil;
namespace ICSharpCode.Decompiler.Ast.Transforms namespace ICSharpCode.Decompiler.Ast.Transforms
@ -160,15 +161,15 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
public UsingStatement TransformUsings(ExpressionStatement node) public UsingStatement TransformUsings(ExpressionStatement node)
{ {
Match m1 = variableAssignPattern.Match(node); Match m1 = variableAssignPattern.Match(node);
if (m1 == null) return null; if (!m1.Success) return null;
AstNode tryCatch = node.NextSibling; AstNode tryCatch = node.NextSibling;
Match m2 = usingTryCatchPattern.Match(tryCatch); Match m2 = usingTryCatchPattern.Match(tryCatch);
if (m2 == null) return null; if (!m2.Success) return null;
string variableName = m1.Get<IdentifierExpression>("variable").Single().Identifier; string variableName = m1.Get<IdentifierExpression>("variable").Single().Identifier;
if (variableName == m2.Get<IdentifierExpression>("ident").Single().Identifier) { if (variableName == m2.Get<IdentifierExpression>("ident").Single().Identifier) {
if (m2.Has("valueType")) { if (m2.Has("valueType")) {
// if there's no if(x!=null), then it must be a value type // if there's no if(x!=null), then it must be a value type
ILVariable v = m1.Get("variable").Single().Annotation<ILVariable>(); ILVariable v = m1.Get<AstNode>("variable").Single().Annotation<ILVariable>();
if (v == null || v.Type == null || !v.Type.IsValueType) if (v == null || v.Type == null || !v.Type.IsValueType)
return null; return null;
} }
@ -270,7 +271,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
public ForeachStatement TransformForeach(UsingStatement node) public ForeachStatement TransformForeach(UsingStatement node)
{ {
Match m = foreachPattern.Match(node); Match m = foreachPattern.Match(node);
if (m == null) if (!m.Success)
return null; return null;
if (!(node.Parent is BlockStatement) && m.Has("variablesOutsideLoop")) { if (!(node.Parent is BlockStatement) && m.Has("variablesOutsideLoop")) {
// if there are variables outside the loop, we need to put those into the parent block, and that won't work if the direct parent isn't a block // if there are variables outside the loop, we need to put those into the parent block, and that won't work if the direct parent isn't a block
@ -341,10 +342,10 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
public ForStatement TransformFor(ExpressionStatement node) public ForStatement TransformFor(ExpressionStatement node)
{ {
Match m1 = variableAssignPattern.Match(node); Match m1 = variableAssignPattern.Match(node);
if (m1 == null) return null; if (!m1.Success) return null;
AstNode next = node.NextSibling; AstNode next = node.NextSibling;
Match m2 = forPattern.Match(next); Match m2 = forPattern.Match(next);
if (m2 == null) return null; if (!m2.Success) return null;
// ensure the variable in the for pattern is the same as in the declaration // ensure the variable in the for pattern is the same as in the declaration
if (m1.Get<IdentifierExpression>("variable").Single().Identifier != m2.Get<IdentifierExpression>("ident").Single().Identifier) if (m1.Get<IdentifierExpression>("variable").Single().Identifier != m2.Get<IdentifierExpression>("ident").Single().Identifier)
return null; return null;
@ -379,7 +380,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
public DoWhileStatement TransformDoWhile(WhileStatement whileLoop) public DoWhileStatement TransformDoWhile(WhileStatement whileLoop)
{ {
Match m = doWhilePattern.Match(whileLoop); Match m = doWhilePattern.Match(whileLoop);
if (m != null) { if (m.Success) {
DoWhileStatement doLoop = new DoWhileStatement(); DoWhileStatement doLoop = new DoWhileStatement();
doLoop.Condition = new UnaryOperatorExpression(UnaryOperatorType.Not, m.Get<Expression>("condition").Single().Detach()); doLoop.Condition = new UnaryOperatorExpression(UnaryOperatorType.Not, m.Get<Expression>("condition").Single().Detach());
doLoop.Condition.AcceptVisitor(new PushNegation(), null); doLoop.Condition.AcceptVisitor(new PushNegation(), null);
@ -439,19 +440,19 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
public LockStatement TransformLock(ExpressionStatement node) public LockStatement TransformLock(ExpressionStatement node)
{ {
Match m1 = lockFlagInitPattern.Match(node); Match m1 = lockFlagInitPattern.Match(node);
if (m1 == null) return null; if (!m1.Success) return null;
AstNode tryCatch = node.NextSibling; AstNode tryCatch = node.NextSibling;
Match m2 = lockTryCatchPattern.Match(tryCatch); Match m2 = lockTryCatchPattern.Match(tryCatch);
if (m2 == null) return null; if (!m2.Success) return null;
if (m1.Get<IdentifierExpression>("variable").Single().Identifier == m2.Get<IdentifierExpression>("flag").Single().Identifier) { if (m1.Get<IdentifierExpression>("variable").Single().Identifier == m2.Get<IdentifierExpression>("flag").Single().Identifier) {
Expression enter = m2.Get<Expression>("enter").Single(); Expression enter = m2.Get<Expression>("enter").Single();
IdentifierExpression exit = m2.Get<IdentifierExpression>("exit").Single(); IdentifierExpression exit = m2.Get<IdentifierExpression>("exit").Single();
if (exit.Match(enter) == null) { if (!exit.IsMatch(enter)) {
// If exit and enter are not the same, then enter must be "exit = ..." // If exit and enter are not the same, then enter must be "exit = ..."
AssignmentExpression assign = enter as AssignmentExpression; AssignmentExpression assign = enter as AssignmentExpression;
if (assign == null) if (assign == null)
return null; return null;
if (exit.Match(assign.Left) == null) if (!exit.IsMatch(assign.Left))
return null; return null;
enter = assign.Right; enter = assign.Right;
// TODO: verify that 'obj' variable can be removed // TODO: verify that 'obj' variable can be removed
@ -512,17 +513,17 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
public SwitchStatement TransformSwitchOnString(IfElseStatement node) public SwitchStatement TransformSwitchOnString(IfElseStatement node)
{ {
Match m = switchOnStringPattern.Match(node); Match m = switchOnStringPattern.Match(node);
if (m == null) if (!m.Success)
return null; return null;
if (m.Has("nonNullDefaultStmt") && !m.Has("nullStmt")) if (m.Has("nonNullDefaultStmt") && !m.Has("nullStmt"))
return null; return null;
// switchVar must be the same as switchExpr; or switchExpr must be an assignment and switchVar the left side of that assignment // switchVar must be the same as switchExpr; or switchExpr must be an assignment and switchVar the left side of that assignment
if (m.Get("switchVar").Single().Match(m.Get("switchExpr").Single()) == null) { if (!m.Get("switchVar").Single().IsMatch(m.Get("switchExpr").Single())) {
AssignmentExpression assign = m.Get("switchExpr").Single() as AssignmentExpression; AssignmentExpression assign = m.Get("switchExpr").Single() as AssignmentExpression;
if (m.Get("switchVar").Single().Match(assign.Left) == null) if (!m.Get("switchVar").Single().IsMatch(assign.Left))
return null; return null;
} }
FieldReference cachedDictField = m.Get("cachedDict").Single().Annotation<FieldReference>(); FieldReference cachedDictField = m.Get<AstNode>("cachedDict").Single().Annotation<FieldReference>();
if (cachedDictField == null || !cachedDictField.DeclaringType.Name.StartsWith("<PrivateImplementationDetails>", StringComparison.Ordinal)) if (cachedDictField == null || !cachedDictField.DeclaringType.Name.StartsWith("<PrivateImplementationDetails>", StringComparison.Ordinal))
return null; return null;
List<Statement> dictCreation = m.Get<BlockStatement>("dictCreation").Single().Statements.ToList(); List<Statement> dictCreation = m.Get<BlockStatement>("dictCreation").Single().Statements.ToList();
@ -616,8 +617,8 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
if (!(cecilProperty.GetMethod.IsCompilerGenerated() && cecilProperty.SetMethod.IsCompilerGenerated())) if (!(cecilProperty.GetMethod.IsCompilerGenerated() && cecilProperty.SetMethod.IsCompilerGenerated()))
return null; return null;
Match m = automaticPropertyPattern.Match(property); Match m = automaticPropertyPattern.Match(property);
if (m != null) { if (m.Success) {
FieldDefinition field = m.Get("fieldReference").Single().Annotation<FieldReference>().ResolveWithinSameModule(); FieldDefinition field = m.Get<AstNode>("fieldReference").Single().Annotation<FieldReference>().ResolveWithinSameModule();
if (field.IsCompilerGenerated() && field.DeclaringType == cecilProperty.DeclaringType) { if (field.IsCompilerGenerated() && field.DeclaringType == cecilProperty.DeclaringType) {
RemoveCompilerGeneratedAttribute(property.Getter.Attributes); RemoveCompilerGeneratedAttribute(property.Getter.Attributes);
RemoveCompilerGeneratedAttribute(property.Setter.Attributes); RemoveCompilerGeneratedAttribute(property.Setter.Attributes);
@ -691,13 +692,13 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
bool CheckAutomaticEventV4Match(Match m, CustomEventDeclaration ev, bool isAddAccessor) bool CheckAutomaticEventV4Match(Match m, CustomEventDeclaration ev, bool isAddAccessor)
{ {
if (m == null) if (!m.Success)
return false; return false;
if (m.Get<MemberReferenceExpression>("field").Single().MemberName != ev.Name) if (m.Get<MemberReferenceExpression>("field").Single().MemberName != ev.Name)
return false; // field name must match event name return false; // field name must match event name
if (ev.ReturnType.Match(m.Get("type").Single()) == null) if (!ev.ReturnType.IsMatch(m.Get("type").Single()))
return false; // variable types must match event type return false; // variable types must match event type
var combineMethod = m.Get("delegateCombine").Single().Parent.Annotation<MethodReference>(); var combineMethod = m.Get<AstNode>("delegateCombine").Single().Parent.Annotation<MethodReference>();
if (combineMethod == null || combineMethod.Name != (isAddAccessor ? "Combine" : "Remove")) if (combineMethod == null || combineMethod.Name != (isAddAccessor ? "Combine" : "Remove"))
return false; return false;
return combineMethod.DeclaringType.FullName == "System.Delegate"; return combineMethod.DeclaringType.FullName == "System.Delegate";
@ -723,7 +724,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
FieldDefinition field = eventDef.DeclaringType.Fields.FirstOrDefault(f => f.Name == ev.Name); FieldDefinition field = eventDef.DeclaringType.Fields.FirstOrDefault(f => f.Name == ev.Name);
if (field != null) { if (field != null) {
ed.AddAnnotation(field); ed.AddAnnotation(field);
AstBuilder.ConvertAttributes(ed, field, AttributeTarget.Field); AstBuilder.ConvertAttributes(ed, field, "field");
} }
} }
@ -751,7 +752,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
DestructorDeclaration TransformDestructor(MethodDeclaration methodDef) DestructorDeclaration TransformDestructor(MethodDeclaration methodDef)
{ {
Match m = destructorPattern.Match(methodDef); Match m = destructorPattern.Match(methodDef);
if (m != null) { if (m.Success) {
DestructorDeclaration dd = new DestructorDeclaration(); DestructorDeclaration dd = new DestructorDeclaration();
methodDef.Attributes.MoveTo(dd.Attributes); methodDef.Attributes.MoveTo(dd.Attributes);
dd.Modifiers = methodDef.Modifiers & ~(Modifiers.Protected | Modifiers.Override); dd.Modifiers = methodDef.Modifiers & ~(Modifiers.Protected | Modifiers.Override);
@ -781,7 +782,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
/// </summary> /// </summary>
TryCatchStatement TransformTryCatchFinally(TryCatchStatement tryFinally) TryCatchStatement TransformTryCatchFinally(TryCatchStatement tryFinally)
{ {
if (tryCatchFinallyPattern.Match(tryFinally) != null) { if (tryCatchFinallyPattern.IsMatch(tryFinally)) {
TryCatchStatement tryCatch = (TryCatchStatement)tryFinally.TryBlock.Statements.Single(); TryCatchStatement tryCatch = (TryCatchStatement)tryFinally.TryBlock.Statements.Single();
tryFinally.TryBlock = tryCatch.TryBlock.Detach(); tryFinally.TryBlock = tryCatch.TryBlock.Detach();
tryCatch.CatchClauses.MoveTo(tryFinally.CatchClauses); tryCatch.CatchClauses.MoveTo(tryFinally.CatchClauses);
@ -803,15 +804,16 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
this.name = type.Name; this.name = type.Name;
} }
protected override bool DoMatch(AstNode other, Match match) public override bool DoMatch(INode other, Match match)
{ {
if (other == null) AstNode o = other as AstNode;
if (o == null)
return false; return false;
TypeReference tr = other.Annotation<TypeReference>(); TypeReference tr = o.Annotation<TypeReference>();
return tr != null && tr.Namespace == ns && tr.Name == name; return tr != null && tr.Namespace == ns && tr.Name == name;
} }
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data) public override S AcceptVisitor<T, S>(IPatternAstVisitor<T, S> visitor, T data)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

6
ICSharpCode.Decompiler/Ast/Transforms/PushNegation.cs

@ -2,7 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.PatternMatching; using ICSharpCode.NRefactory.PatternMatching;
namespace ICSharpCode.Decompiler.Ast.Transforms namespace ICSharpCode.Decompiler.Ast.Transforms
{ {
@ -109,11 +109,11 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
} else { } else {
bool negate = false; bool negate = false;
Match m = asCastIsNotNullPattern.Match(binaryOperatorExpression); Match m = asCastIsNotNullPattern.Match(binaryOperatorExpression);
if (m == null) { if (!m.Success) {
m = asCastIsNullPattern.Match(binaryOperatorExpression); m = asCastIsNullPattern.Match(binaryOperatorExpression);
negate = true; negate = true;
} }
if (m != null) { if (m.Success) {
Expression expr = m.Get<Expression>("expr").Single().Detach().IsType(m.Get<AstType>("type").Single().Detach()); Expression expr = m.Get<Expression>("expr").Single().Detach().IsType(m.Get<AstType>("type").Single().Detach());
if (negate) if (negate)
expr = new UnaryOperatorExpression(UnaryOperatorType.Not, expr); expr = new UnaryOperatorExpression(UnaryOperatorType.Not, expr);

6
ICSharpCode.Decompiler/Ast/Transforms/ReplaceMethodCallsWithOperators.cs

@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using ICSharpCode.NRefactory.CSharp.PatternMatching; using ICSharpCode.NRefactory.PatternMatching;
using Mono.Cecil; using Mono.Cecil;
using Ast = ICSharpCode.NRefactory.CSharp; using Ast = ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.CSharp;
@ -176,7 +176,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
// Combine "x = x op y" into "x op= y" // Combine "x = x op y" into "x op= y"
BinaryOperatorExpression binary = assignment.Right as BinaryOperatorExpression; BinaryOperatorExpression binary = assignment.Right as BinaryOperatorExpression;
if (binary != null && assignment.Operator == AssignmentOperatorType.Assign) { if (binary != null && assignment.Operator == AssignmentOperatorType.Assign) {
if (CanConvertToCompoundAssignment(assignment.Left) && assignment.Left.Match(binary.Left) != null) { if (CanConvertToCompoundAssignment(assignment.Left) && assignment.Left.IsMatch(binary.Left)) {
assignment.Operator = GetAssignmentOperatorForBinaryOperator(binary.Operator); assignment.Operator = GetAssignmentOperatorForBinaryOperator(binary.Operator);
if (assignment.Operator != AssignmentOperatorType.Assign) { if (assignment.Operator != AssignmentOperatorType.Assign) {
// If we found a shorter operator, get rid of the BinaryOperatorExpression: // If we found a shorter operator, get rid of the BinaryOperatorExpression:
@ -188,7 +188,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
} }
if (assignment.Operator == AssignmentOperatorType.Add || assignment.Operator == AssignmentOperatorType.Subtract) { if (assignment.Operator == AssignmentOperatorType.Add || assignment.Operator == AssignmentOperatorType.Subtract) {
// detect increment/decrement // detect increment/decrement
if (assignment.Right.Match(new PrimitiveExpression(1)) != null) { if (assignment.Right.IsMatch(new PrimitiveExpression(1))) {
// only if it's not a custom operator // only if it's not a custom operator
if (assignment.Annotation<MethodReference>() == null) { if (assignment.Annotation<MethodReference>() == null) {
UnaryOperatorType type; UnaryOperatorType type;

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

@ -14,14 +14,14 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
{ {
var section = (AttributeSection)attribute.Parent; var section = (AttributeSection)attribute.Parent;
SimpleType type = attribute.Type as SimpleType; SimpleType type = attribute.Type as SimpleType;
if (section.AttributeTarget == AttributeTarget.Assembly && if (section.AttributeTarget == "assembly" &&
(type.Identifier == "CompilationRelaxations" || type.Identifier == "RuntimeCompatibility")) (type.Identifier == "CompilationRelaxations" || type.Identifier == "RuntimeCompatibility"))
{ {
attribute.Remove(); attribute.Remove();
if (section.Attributes.Count == 0) if (section.Attributes.Count == 0)
section.Remove(); section.Remove();
} }
if (section.AttributeTarget == AttributeTarget.Module && type.Identifier == "UnverifiableCode") if (section.AttributeTarget == "module" && type.Identifier == "UnverifiableCode")
{ {
attribute.Remove(); attribute.Remove();
if (section.Attributes.Count == 0) if (section.Attributes.Count == 0)

2
ILSpy/CSharpLanguage.cs

@ -425,7 +425,7 @@ namespace ICSharpCode.ILSpy
((ComposedType)astType).PointerRank--; ((ComposedType)astType).PointerRank--;
} }
astType.AcceptVisitor(new OutputVisitor(w, new CSharpFormattingPolicy()), null); astType.AcceptVisitor(new OutputVisitor(w, new CSharpFormattingOptions()), null);
return w.ToString(); return w.ToString();
} }

Loading…
Cancel
Save