Skip to content

Commit 5545614

Browse files
Merge pull request #3614 from mmusu3/primary-ctor-fixes
Fixes for primary constructors
2 parents 94050a4 + 88b2c43 commit 5545614

File tree

3 files changed

+57
-20
lines changed

3 files changed

+57
-20
lines changed

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

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,19 @@ private class C4(string value)
1212
public string Value { get; } = value;
1313
}
1414

15-
//private class C5(C5.ValueArray array)
16-
//{
17-
// public struct ValueArray
18-
// {
19-
// private bool b;
20-
// public bool[] ToArray()
21-
// {
22-
// return null;
23-
// }
24-
// }
15+
private class C5(C5.ValueArray array)
16+
{
17+
public struct ValueArray
18+
{
19+
private bool b;
20+
public bool[] ToArray()
21+
{
22+
return null;
23+
}
24+
}
2525

26-
// public bool[] Values = array.ToArray();
27-
//}
26+
public bool[] Values = array.ToArray();
27+
}
2828

2929
private class BaseClass
3030
{
@@ -33,14 +33,15 @@ protected BaseClass(int value)
3333
}
3434
}
3535

36-
//private class C6(C6.Data2 data) : BaseClass(data.Value)
37-
//{
38-
// public struct Data2 {
39-
// public int Value { get; set; }
40-
// }
36+
private class C6(C6.Data2 data) : BaseClass(data.Value)
37+
{
38+
public struct Data2
39+
{
40+
public int Value { get; set; }
41+
}
4142

42-
// public Data2 Data => data;
43-
//}
43+
public Data2 Data => data;
44+
}
4445

4546
private struct S3<T>(T v)
4647
{

ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,13 @@ AstType ConvertTypeHelper(IType genericType, IReadOnlyList<IType> typeArguments)
546546
{
547547
// Handle nested types
548548
result.Target = ConvertTypeHelper(genericType.DeclaringType, typeArguments);
549-
AddTypeAnnotation(result.Target, genericType.DeclaringType);
549+
// Use correct number of type arguments on the declaring type
550+
var declaringType = genericType.DeclaringType;
551+
if (outerTypeParameterCount > 0)
552+
{
553+
declaringType = new ParameterizedType(genericType.DeclaringType, typeArguments.Take(outerTypeParameterCount));
554+
}
555+
AddTypeAnnotation(result.Target, declaringType);
550556
}
551557
else
552558
{

ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,8 @@ sealed class FullyQualifyAmbiguousTypeNamesVisitor : DepthFirstAstVisitor
189189
CSharpResolver resolver;
190190
TypeSystemAstBuilder astBuilder;
191191

192+
bool inPrimaryConstructor;
193+
192194
public FullyQualifyAmbiguousTypeNamesVisitor(TransformContext context, UsingScope usingScope)
193195
{
194196
this.ignoreUsingScope = !context.Settings.UsingDeclarations;
@@ -265,9 +267,26 @@ public override void VisitTypeDeclaration(TypeDeclaration typeDeclaration)
265267
base.VisitTypeDeclaration(typeDeclaration);
266268
return;
267269
}
270+
271+
if (typeDeclaration.HasPrimaryConstructor)
272+
{
273+
inPrimaryConstructor = true;
274+
275+
try
276+
{
277+
typeDeclaration.PrimaryConstructorParameters.AcceptVisitor(this);
278+
}
279+
finally
280+
{
281+
inPrimaryConstructor = false;
282+
}
283+
}
284+
268285
var previousResolver = resolver;
269286
var previousAstBuilder = astBuilder;
287+
270288
resolver = resolver.WithCurrentTypeDefinition(typeDeclaration.GetSymbol() as ITypeDefinition);
289+
271290
try
272291
{
273292
astBuilder = CreateAstBuilder(resolver);
@@ -280,6 +299,17 @@ public override void VisitTypeDeclaration(TypeDeclaration typeDeclaration)
280299
}
281300
}
282301

302+
public override void VisitParameterDeclaration(ParameterDeclaration parameterDeclaration)
303+
{
304+
// Parameters of primary constructors are visited separately from the rest of the
305+
// type declaration since their types are at the same scope as the type declaration
306+
// and so need to use the outer resolver. This check ensures that the visitor only
307+
// runs once per parameter since their AstNodes will get revisited by the call to
308+
// `base.VisitTypeDeclaration(typeDeclaration)` in `VisitTypeDeclaration` above.
309+
if (inPrimaryConstructor || parameterDeclaration.Parent is not TypeDeclaration)
310+
base.VisitParameterDeclaration(parameterDeclaration);
311+
}
312+
283313
public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration)
284314
{
285315
Visit(methodDeclaration, base.VisitMethodDeclaration);

0 commit comments

Comments
 (0)