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; @@ -22,7 +22,7 @@ using System.Linq;
using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;
using ICSharpCode.Decompiler.TypeSystem;
using Mono.Cecil;
using SRM = System.Reflection.Metadata;
namespace ICSharpCode.Decompiler.CSharp.Transforms
{
@ -187,31 +187,35 @@ 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);
if (staticCtor != null) {
IMethod ctorMethod = staticCtor.GetSymbol() as IMethod;
MethodDefinition ctorMethodDef = context.TypeSystem.GetCecil(ctorMethod) as MethodDefinition;
if (ctorMethodDef != null && ctorMethodDef.DeclaringType.IsBeforeFieldInit) {
while (true) {
ExpressionStatement es = staticCtor.Body.Statements.FirstOrDefault() as ExpressionStatement;
if (es == null)
break;
AssignmentExpression assignment = es.Expression as AssignmentExpression;
if (assignment == null || assignment.Operator != AssignmentOperatorType.Assign)
break;
IMember fieldOrProperty = (assignment.Left.GetSymbol() as IMember)?.MemberDefinition;
if (!(fieldOrProperty is IField || fieldOrProperty is IProperty) || !fieldOrProperty.IsStatic)
break;
AstNode fieldOrPropertyDecl = members.FirstOrDefault(f => f.GetSymbol() == fieldOrProperty);
if (fieldOrPropertyDecl == null)
break;
if (fieldOrPropertyDecl is FieldDeclaration fd)
fd.Variables.Single().Initializer = assignment.Right.Detach();
else if (fieldOrPropertyDecl is PropertyDeclaration pd)
pd.Initializer = assignment.Right.Detach();
else
break;
es.Remove();
if (!ctorMethod.MetadataToken.IsNil) {
var metadata = context.TypeSystem.ModuleDefinition.GetMetadataReader();
SRM.MethodDefinition ctorMethodDef = metadata.GetMethodDefinition((SRM.MethodDefinitionHandle)ctorMethod.MetadataToken);
SRM.TypeDefinition declaringType = metadata.GetTypeDefinition(ctorMethodDef.GetDeclaringType());
if (declaringType.HasFlag(System.Reflection.TypeAttributes.BeforeFieldInit)) {
while (true) {
ExpressionStatement es = staticCtor.Body.Statements.FirstOrDefault() as ExpressionStatement;
if (es == null)
break;
AssignmentExpression assignment = es.Expression as AssignmentExpression;
if (assignment == null || assignment.Operator != AssignmentOperatorType.Assign)
break;
IMember fieldOrProperty = (assignment.Left.GetSymbol() as IMember)?.MemberDefinition;
if (!(fieldOrProperty is IField || fieldOrProperty is IProperty) || !fieldOrProperty.IsStatic)
break;
AstNode fieldOrPropertyDecl = members.FirstOrDefault(f => f.GetSymbol() == fieldOrProperty);
if (fieldOrPropertyDecl == null)
break;
if (fieldOrPropertyDecl is FieldDeclaration fd)
fd.Variables.Single().Initializer = assignment.Right.Detach();
else if (fieldOrPropertyDecl is PropertyDeclaration pd)
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; @@ -22,10 +22,8 @@ using System.Diagnostics;
using System.Linq;
using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;
using ICSharpCode.Decompiler.CSharp.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Semantics;
using Mono.Cecil;
namespace ICSharpCode.Decompiler.CSharp.Transforms
{
@ -484,31 +482,28 @@ 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;
if (cecilProperty == null || cecilProperty.GetMethod == null)
IProperty property = propertyDeclaration.GetSymbol() as IProperty;
if (!property.CanGet || (!property.Getter.IsCompilerGenerated() && (property.Setter?.IsCompilerGenerated() == false)))
return null;
if (!cecilProperty.GetMethod.IsCompilerGenerated() && (cecilProperty.SetMethod?.IsCompilerGenerated() == false))
return null;
IField fieldInfo = null;
Match m = automaticPropertyPattern.Match(property);
IField field = null;
Match m = automaticPropertyPattern.Match(propertyDeclaration);
if (m.Success) {
fieldInfo = m.Get<AstNode>("fieldReference").Single().GetSymbol() as IField;
field = m.Get<AstNode>("fieldReference").Single().GetSymbol() as IField;
} else {
Match m2 = automaticReadonlyPropertyPattern.Match(property);
Match m2 = automaticReadonlyPropertyPattern.Match(propertyDeclaration);
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;
FieldDefinition field = context.TypeSystem.GetCecil(fieldInfo) as FieldDefinition;
if (field.IsCompilerGenerated() && field.DeclaringType == cecilProperty.DeclaringType) {
RemoveCompilerGeneratedAttribute(property.Getter.Attributes);
RemoveCompilerGeneratedAttribute(property.Setter.Attributes);
property.Getter.Body = null;
property.Setter.Body = null;
if (field.IsCompilerGenerated() && field.DeclaringTypeDefinition == property.DeclaringTypeDefinition) {
RemoveCompilerGeneratedAttribute(propertyDeclaration.Getter.Attributes);
RemoveCompilerGeneratedAttribute(propertyDeclaration.Setter.Attributes);
propertyDeclaration.Getter.Body = null;
propertyDeclaration.Setter.Body = null;
}
// Since the property instance is not changed, we can continue in the visitor as usual, so return null
return null;

Loading…
Cancel
Save