|
|
|
@ -61,10 +61,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
@@ -61,10 +61,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
|
|
|
|
|
|
|
|
|
|
public override void VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration) |
|
|
|
|
{ |
|
|
|
|
if (!(constructorDeclaration.Body.Statements.FirstOrDefault() is ExpressionStatement stmt)) |
|
|
|
|
return; |
|
|
|
|
var currentCtor = (IMethod)constructorDeclaration.GetSymbol(); |
|
|
|
|
ConstructorInitializer ci; |
|
|
|
|
ConstructorInitializer ci = null; |
|
|
|
|
if (constructorDeclaration.Body.Statements.FirstOrDefault() is ExpressionStatement stmt) |
|
|
|
|
{ |
|
|
|
|
switch (stmt.Expression) |
|
|
|
|
{ |
|
|
|
|
// Pattern for reference types:
|
|
|
|
@ -117,11 +117,12 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
@@ -117,11 +117,12 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
|
|
|
|
|
default: |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (context.DecompileRun.RecordDecompilers.TryGetValue(currentCtor.DeclaringTypeDefinition, out var record) |
|
|
|
|
&& currentCtor.Equals(record.PrimaryConstructor) |
|
|
|
|
&& ci.ConstructorInitializerType == ConstructorInitializerType.Base) |
|
|
|
|
&& currentCtor.Equals(record.PrimaryConstructor)) |
|
|
|
|
{ |
|
|
|
|
if (record.IsInheritedRecord && |
|
|
|
|
ci?.ConstructorInitializerType == ConstructorInitializerType.Base && |
|
|
|
|
constructorDeclaration.Parent is TypeDeclaration { BaseTypes: { Count: >= 1 } } typeDecl) |
|
|
|
|
{ |
|
|
|
|
var baseType = typeDecl.BaseTypes.First(); |
|
|
|
@ -172,7 +173,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
@@ -172,7 +173,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
|
|
|
|
|
if (instanceCtorsNotChainingWithThis.Length > 0) |
|
|
|
|
{ |
|
|
|
|
var ctorMethodDef = instanceCtorsNotChainingWithThis[0].GetSymbol() as IMethod; |
|
|
|
|
if (ctorMethodDef != null && ctorMethodDef.DeclaringType.IsReferenceType == false) |
|
|
|
|
ITypeDefinition declaringTypeDefinition = ctorMethodDef?.DeclaringTypeDefinition; |
|
|
|
|
if (ctorMethodDef != null && declaringTypeDefinition?.IsReferenceType == false && !declaringTypeDefinition.IsRecord) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
bool ctorIsUnsafe = instanceCtorsNotChainingWithThis.All(c => c.HasModifier(Modifiers.Unsafe)); |
|
|
|
@ -180,13 +182,14 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
@@ -180,13 +182,14 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
|
|
|
|
|
if (!context.DecompileRun.RecordDecompilers.TryGetValue(ctorMethodDef.DeclaringTypeDefinition, out var record)) |
|
|
|
|
record = null; |
|
|
|
|
|
|
|
|
|
//Filter out copy constructor of records
|
|
|
|
|
// Filter out copy constructor of records
|
|
|
|
|
if (record != null) |
|
|
|
|
instanceCtorsNotChainingWithThis = instanceCtorsNotChainingWithThis.Where(ctor => !record.IsCopyConstructor(ctor.GetSymbol() as IMethod)).ToArray(); |
|
|
|
|
|
|
|
|
|
// Recognize field or property initializers:
|
|
|
|
|
// Translate first statement in all ctors (if all ctors have the same statement) into an initializer.
|
|
|
|
|
bool allSame; |
|
|
|
|
bool isPrimaryCtor = declaringTypeDefinition.IsReferenceType == true && declaringTypeDefinition.IsRecord; |
|
|
|
|
do |
|
|
|
|
{ |
|
|
|
|
Match m = fieldInitializerPattern.Match(instanceCtorsNotChainingWithThis[0].Body.FirstOrDefault()); |
|
|
|
@ -211,11 +214,12 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
@@ -211,11 +214,12 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
|
|
|
|
|
// remove record ctor parameter assignments
|
|
|
|
|
if (!IsPropertyDeclaredByPrimaryCtor(fieldOrPropertyOrEvent as IProperty, record)) |
|
|
|
|
break; |
|
|
|
|
isPrimaryCtor = true; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
// cannot transform if member is not found
|
|
|
|
|
if (fieldOrPropertyOrEventDecl == null) |
|
|
|
|
if (fieldOrPropertyOrEventDecl == null || !isPrimaryCtor) |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|