Browse Source

Partially port transforms

pull/1198/head
Siegfried Pammer 7 years ago
parent
commit
a70f19d536
  1. 54
      ICSharpCode.Decompiler/CSharp/Transforms/ConvertConstructorCallIntoInitializer.cs
  2. 33
      ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs

54
ICSharpCode.Decompiler/CSharp/Transforms/ConvertConstructorCallIntoInitializer.cs

@ -22,7 +22,7 @@ using System.Linq;
using ICSharpCode.Decompiler.CSharp.Syntax; using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching; using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using Mono.Cecil; using SRM = System.Reflection.Metadata;
namespace ICSharpCode.Decompiler.CSharp.Transforms namespace ICSharpCode.Decompiler.CSharp.Transforms
{ {
@ -187,31 +187,35 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
var staticCtor = members.OfType<ConstructorDeclaration>().FirstOrDefault(c => (c.Modifiers & Modifiers.Static) == Modifiers.Static); var staticCtor = members.OfType<ConstructorDeclaration>().FirstOrDefault(c => (c.Modifiers & Modifiers.Static) == Modifiers.Static);
if (staticCtor != null) { if (staticCtor != null) {
IMethod ctorMethod = staticCtor.GetSymbol() as IMethod; IMethod ctorMethod = staticCtor.GetSymbol() as IMethod;
MethodDefinition ctorMethodDef = context.TypeSystem.GetCecil(ctorMethod) as MethodDefinition; if (!ctorMethod.MetadataToken.IsNil) {
if (ctorMethodDef != null && ctorMethodDef.DeclaringType.IsBeforeFieldInit) { var metadata = context.TypeSystem.ModuleDefinition.GetMetadataReader();
while (true) { SRM.MethodDefinition ctorMethodDef = metadata.GetMethodDefinition((SRM.MethodDefinitionHandle)ctorMethod.MetadataToken);
ExpressionStatement es = staticCtor.Body.Statements.FirstOrDefault() as ExpressionStatement; SRM.TypeDefinition declaringType = metadata.GetTypeDefinition(ctorMethodDef.GetDeclaringType());
if (es == null) if (declaringType.HasFlag(System.Reflection.TypeAttributes.BeforeFieldInit)) {
break; while (true) {
AssignmentExpression assignment = es.Expression as AssignmentExpression; ExpressionStatement es = staticCtor.Body.Statements.FirstOrDefault() as ExpressionStatement;
if (assignment == null || assignment.Operator != AssignmentOperatorType.Assign) if (es == null)
break; break;
IMember fieldOrProperty = (assignment.Left.GetSymbol() as IMember)?.MemberDefinition; AssignmentExpression assignment = es.Expression as AssignmentExpression;
if (!(fieldOrProperty is IField || fieldOrProperty is IProperty) || !fieldOrProperty.IsStatic) if (assignment == null || assignment.Operator != AssignmentOperatorType.Assign)
break; break;
AstNode fieldOrPropertyDecl = members.FirstOrDefault(f => f.GetSymbol() == fieldOrProperty); IMember fieldOrProperty = (assignment.Left.GetSymbol() as IMember)?.MemberDefinition;
if (fieldOrPropertyDecl == null) if (!(fieldOrProperty is IField || fieldOrProperty is IProperty) || !fieldOrProperty.IsStatic)
break; break;
if (fieldOrPropertyDecl is FieldDeclaration fd) AstNode fieldOrPropertyDecl = members.FirstOrDefault(f => f.GetSymbol() == fieldOrProperty);
fd.Variables.Single().Initializer = assignment.Right.Detach(); if (fieldOrPropertyDecl == null)
else if (fieldOrPropertyDecl is PropertyDeclaration pd) break;
pd.Initializer = assignment.Right.Detach(); if (fieldOrPropertyDecl is FieldDeclaration fd)
else fd.Variables.Single().Initializer = assignment.Right.Detach();
break; else if (fieldOrPropertyDecl is PropertyDeclaration pd)
es.Remove(); pd.Initializer = assignment.Right.Detach();
else
break;
es.Remove();
}
if (staticCtor.Body.Statements.Count == 0)
staticCtor.Remove();
} }
if (staticCtor.Body.Statements.Count == 0)
staticCtor.Remove();
} }
} }
} }

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

@ -22,10 +22,8 @@ using System.Diagnostics;
using System.Linq; using System.Linq;
using ICSharpCode.Decompiler.CSharp.Syntax; using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching; using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;
using ICSharpCode.Decompiler.CSharp.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Semantics; using ICSharpCode.Decompiler.Semantics;
using Mono.Cecil;
namespace ICSharpCode.Decompiler.CSharp.Transforms namespace ICSharpCode.Decompiler.CSharp.Transforms
{ {
@ -484,31 +482,28 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
} }
}; };
PropertyDeclaration TransformAutomaticProperties(PropertyDeclaration property) PropertyDeclaration TransformAutomaticProperties(PropertyDeclaration propertyDeclaration)
{ {
PropertyDefinition cecilProperty = context.TypeSystem.GetCecil(property.GetSymbol() as IProperty) as PropertyDefinition; IProperty property = propertyDeclaration.GetSymbol() as IProperty;
if (cecilProperty == null || cecilProperty.GetMethod == null) if (!property.CanGet || (!property.Getter.IsCompilerGenerated() && (property.Setter?.IsCompilerGenerated() == false)))
return null; return null;
if (!cecilProperty.GetMethod.IsCompilerGenerated() && (cecilProperty.SetMethod?.IsCompilerGenerated() == false)) IField field = null;
return null; Match m = automaticPropertyPattern.Match(propertyDeclaration);
IField fieldInfo = null;
Match m = automaticPropertyPattern.Match(property);
if (m.Success) { if (m.Success) {
fieldInfo = m.Get<AstNode>("fieldReference").Single().GetSymbol() as IField; field = m.Get<AstNode>("fieldReference").Single().GetSymbol() as IField;
} else { } else {
Match m2 = automaticReadonlyPropertyPattern.Match(property); Match m2 = automaticReadonlyPropertyPattern.Match(propertyDeclaration);
if (m2.Success) { if (m2.Success) {
fieldInfo = m2.Get<AstNode>("fieldReference").Single().GetSymbol() as IField; field = m2.Get<AstNode>("fieldReference").Single().GetSymbol() as IField;
} }
} }
if (fieldInfo == null) if (field == null)
return null; return null;
FieldDefinition field = context.TypeSystem.GetCecil(fieldInfo) as FieldDefinition; if (field.IsCompilerGenerated() && field.DeclaringTypeDefinition == property.DeclaringTypeDefinition) {
if (field.IsCompilerGenerated() && field.DeclaringType == cecilProperty.DeclaringType) { RemoveCompilerGeneratedAttribute(propertyDeclaration.Getter.Attributes);
RemoveCompilerGeneratedAttribute(property.Getter.Attributes); RemoveCompilerGeneratedAttribute(propertyDeclaration.Setter.Attributes);
RemoveCompilerGeneratedAttribute(property.Setter.Attributes); propertyDeclaration.Getter.Body = null;
property.Getter.Body = null; propertyDeclaration.Setter.Body = null;
property.Setter.Body = null;
} }
// Since the property instance is not changed, we can continue in the visitor as usual, so return null // Since the property instance is not changed, we can continue in the visitor as usual, so return null
return null; return null;

Loading…
Cancel
Save