Browse Source

Merge pull request #3614 from mmusu3/primary-ctor-fixes

Fixes for primary constructors
pull/3588/head
Siegfried Pammer 1 month ago committed by GitHub
parent
commit
5545614d66
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 39
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3611.cs
  2. 8
      ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
  3. 30
      ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs

39
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3611.cs

@ -12,19 +12,19 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public string Value { get; } = value; public string Value { get; } = value;
} }
//private class C5(C5.ValueArray array) private class C5(C5.ValueArray array)
//{ {
// public struct ValueArray public struct ValueArray
// { {
// private bool b; private bool b;
// public bool[] ToArray() public bool[] ToArray()
// { {
// return null; return null;
// } }
// } }
// public bool[] Values = array.ToArray(); public bool[] Values = array.ToArray();
//} }
private class BaseClass private class BaseClass
{ {
@ -33,14 +33,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
} }
} }
//private class C6(C6.Data2 data) : BaseClass(data.Value) private class C6(C6.Data2 data) : BaseClass(data.Value)
//{ {
// public struct Data2 { public struct Data2
// public int Value { get; set; } {
// } public int Value { get; set; }
}
// public Data2 Data => data; public Data2 Data => data;
//} }
private struct S3<T>(T v) private struct S3<T>(T v)
{ {

8
ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs

@ -546,7 +546,13 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
{ {
// Handle nested types // Handle nested types
result.Target = ConvertTypeHelper(genericType.DeclaringType, typeArguments); result.Target = ConvertTypeHelper(genericType.DeclaringType, typeArguments);
AddTypeAnnotation(result.Target, genericType.DeclaringType); // Use correct number of type arguments on the declaring type
var declaringType = genericType.DeclaringType;
if (outerTypeParameterCount > 0)
{
declaringType = new ParameterizedType(genericType.DeclaringType, typeArguments.Take(outerTypeParameterCount));
}
AddTypeAnnotation(result.Target, declaringType);
} }
else else
{ {

30
ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs

@ -189,6 +189,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
CSharpResolver resolver; CSharpResolver resolver;
TypeSystemAstBuilder astBuilder; TypeSystemAstBuilder astBuilder;
bool inPrimaryConstructor;
public FullyQualifyAmbiguousTypeNamesVisitor(TransformContext context, UsingScope usingScope) public FullyQualifyAmbiguousTypeNamesVisitor(TransformContext context, UsingScope usingScope)
{ {
this.ignoreUsingScope = !context.Settings.UsingDeclarations; this.ignoreUsingScope = !context.Settings.UsingDeclarations;
@ -265,9 +267,26 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
base.VisitTypeDeclaration(typeDeclaration); base.VisitTypeDeclaration(typeDeclaration);
return; return;
} }
if (typeDeclaration.HasPrimaryConstructor)
{
inPrimaryConstructor = true;
try
{
typeDeclaration.PrimaryConstructorParameters.AcceptVisitor(this);
}
finally
{
inPrimaryConstructor = false;
}
}
var previousResolver = resolver; var previousResolver = resolver;
var previousAstBuilder = astBuilder; var previousAstBuilder = astBuilder;
resolver = resolver.WithCurrentTypeDefinition(typeDeclaration.GetSymbol() as ITypeDefinition); resolver = resolver.WithCurrentTypeDefinition(typeDeclaration.GetSymbol() as ITypeDefinition);
try try
{ {
astBuilder = CreateAstBuilder(resolver); astBuilder = CreateAstBuilder(resolver);
@ -280,6 +299,17 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
} }
} }
public override void VisitParameterDeclaration(ParameterDeclaration parameterDeclaration)
{
// Parameters of primary constructors are visited separately from the rest of the
// type declaration since their types are at the same scope as the type declaration
// and so need to use the outer resolver. This check ensures that the visitor only
// runs once per parameter since their AstNodes will get revisited by the call to
// `base.VisitTypeDeclaration(typeDeclaration)` in `VisitTypeDeclaration` above.
if (inPrimaryConstructor || parameterDeclaration.Parent is not TypeDeclaration)
base.VisitParameterDeclaration(parameterDeclaration);
}
public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration) public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration)
{ {
Visit(methodDeclaration, base.VisitMethodDeclaration); Visit(methodDeclaration, base.VisitMethodDeclaration);

Loading…
Cancel
Save