diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.cs index c4b3f3f6f..0be38a28c 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.cs @@ -147,6 +147,23 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty B = A + 1; } } + + private struct StructInitializerDependsOnQualifiedField + { + public int value; + + public int b; + + // The parameter shadows the field, so reading the field keeps its qualifier. A + // field initializer cannot name the instance, so this has to stay a constructor + // rather than becoming a primary one - the same rule as the fixture above, which + // only differs in how the read happens to be spelled. + public StructInitializerDependsOnQualifiedField(int value) + { + this.value = value; + b = this.value + 1; + } + } #endif public class ClassWithConstant diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index 3df219962..6d1e9ef7a 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -2788,6 +2788,20 @@ namespace ICSharpCode.Decompiler.CSharp .WithoutILInstruction(); } translatedTarget = EnsureTargetNotNullable(translatedTarget, target); + if (translatedTarget.Expression is ThisReferenceExpression) + { + // Give an explicit `this` the same resolve result the base-reference branch + // above gives `base`, and that the resolver gives the unqualified spelling of + // the same access. ConvertVariable annotates it as an ordinary local, so + // without this a consumer asking "does this expression reach instance state" + // gets a different answer depending on whether the qualifier happened to be + // printed - and the qualifier is printed for reasons (a parameter of the same + // name, AlwaysQualifyMemberReferences) that have nothing to do with the + // question being asked. + translatedTarget = new ThisReferenceExpression() + .WithILInstruction(target) + .WithRR(new ThisResolveResult(translatedTarget.Type, nonVirtualInvocation)); + } return translatedTarget; } }