Skip to content

Commit 47ae76f

Browse files
authored
Merge pull request #6890 from hvitved/csharp/nullable-default-param
C#: Handle `Nullable<T>` default parameter values in assemblies
2 parents af6a21f + 888a1b3 commit 47ae76f

File tree

5 files changed

+34
-9
lines changed

5 files changed

+34
-9
lines changed

csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,13 @@ private static bool ContainsPattern(SyntaxNode node) =>
178178

179179
var defaultValue = parameter.ExplicitDefaultValue;
180180

181-
if (parameter.Type is INamedTypeSymbol nt && nt.EnumUnderlyingType is not null)
181+
var type = parameter.Type;
182+
if (type.IsBoundNullable() && type is INamedTypeSymbol named)
183+
{
184+
type = named.TypeArguments[0];
185+
}
186+
187+
if (type is INamedTypeSymbol nt && nt.EnumUnderlyingType is not null)
182188
{
183189
// = (MyEnum)1, = MyEnum.Value1, = default(MyEnum), = new MyEnum()
184190
// we're generating a (MyEnum)value cast expression:
@@ -194,7 +200,7 @@ private static bool ContainsPattern(SyntaxNode node) =>
194200
return Default.CreateGenerated(cx, parent, childIndex, location, parameter.Type.IsReferenceType ? ValueAsString(null) : null);
195201
}
196202

197-
if (parameter.Type.SpecialType == SpecialType.System_Object)
203+
if (parameter.Type.SpecialType is SpecialType.System_Object)
198204
{
199205
// this can happen in VB.NET
200206
cx.ExtractionError($"Extracting default argument value 'object {parameter.Name} = default' instead of 'object {parameter.Name} = {defaultValue}'. The latter is not supported in C#.",
@@ -205,7 +211,7 @@ private static bool ContainsPattern(SyntaxNode node) =>
205211
}
206212

207213
// const literal:
208-
return Literal.CreateGenerated(cx, parent, childIndex, parameter.Type, defaultValue, location);
214+
return Literal.CreateGenerated(cx, parent, childIndex, type, defaultValue, location);
209215
}
210216

211217
/// <summary>

csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Factory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ internal static Expression Create(ExpressionNodeInfo info)
1414
{
1515
if (info.Node is null)
1616
{
17-
info.Context.ModelError("Attempt to create a null expression");
17+
info.Context.ModelError(info.Location, "Attempt to create a null expression");
1818
return new Unknown(info);
1919
}
2020

csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Literal.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ private static ExprKind GetKind(ExpressionNodeInfo info)
3232
}
3333

3434
var type = info.Type?.Symbol;
35-
return GetExprKind(type, info.Node, info.Context);
35+
return GetExprKind(type, info.Node, info.Location, info.Context);
3636
}
3737

38-
private static ExprKind GetExprKind(ITypeSymbol? type, ExpressionSyntax? expr, Context context)
38+
private static ExprKind GetExprKind(ITypeSymbol? type, ExpressionSyntax? expr, Extraction.Entities.Location loc, Context context)
3939
{
4040
switch (type?.SpecialType)
4141
{
@@ -75,22 +75,24 @@ private static ExprKind GetExprKind(ITypeSymbol? type, ExpressionSyntax? expr, C
7575

7676
case null:
7777
default:
78+
var kind = type?.SpecialType.ToString() ?? "null";
7879
if (expr is not null)
79-
context.ModelError(expr, "Unhandled literal type");
80+
context.ModelError(expr, $"Unhandled literal type {kind}");
8081
else
81-
context.ModelError("Unhandled literal type");
82+
context.ModelError(loc, $"Unhandled literal type {kind}");
8283
return ExprKind.UNKNOWN;
8384
}
8485
}
8586

8687
public static Expression CreateGenerated(Context cx, IExpressionParentEntity parent, int childIndex, ITypeSymbol type, object? value,
8788
Extraction.Entities.Location location)
8889
{
90+
var kind = value is null ? ExprKind.NULL_LITERAL : GetExprKind(type, null, location, cx);
8991
var info = new ExpressionInfo(
9092
cx,
9193
AnnotatedTypeSymbol.CreateNotAnnotated(type),
9294
location,
93-
GetExprKind(type, null, cx),
95+
kind,
9496
parent,
9597
childIndex,
9698
true,

csharp/extractor/Semmle.Extraction/Context.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,16 @@ public void ModelError(ISymbol symbol, string msg)
426426
ReportError(new InternalError(symbol, msg));
427427
}
428428

429+
/// <summary>
430+
/// Signal an error in the program model.
431+
/// </summary>
432+
/// <param name="loc">The location of the error.</param>
433+
/// <param name="msg">The error message.</param>
434+
public void ModelError(Entities.Location loc, string msg)
435+
{
436+
ReportError(new InternalError(loc.ReportingLocation, msg));
437+
}
438+
429439
/// <summary>
430440
/// Signal an error in the program model.
431441
/// </summary>

csharp/extractor/Semmle.Extraction/InternalError.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ public InternalError(SyntaxNode node, string msg)
2323
Location = node.GetLocation();
2424
}
2525

26+
public InternalError(Location? loc, string msg)
27+
{
28+
Text = msg;
29+
EntityText = "";
30+
Location = loc;
31+
}
32+
2633
public InternalError(string msg)
2734
{
2835
Text = msg;

0 commit comments

Comments
 (0)