Skip to content

Commit ab505e3

Browse files
committed
C#: Add class for making synthetic parameter entities.
1 parent 60bb9a9 commit ab505e3

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
using System.IO;
2+
using System.Linq;
3+
using Microsoft.CodeAnalysis;
4+
using Microsoft.CodeAnalysis.CSharp.Syntax;
5+
6+
namespace Semmle.Extraction.CSharp.Entities
7+
{
8+
/// <summary>
9+
/// Synthetic parameter for extension methods declared using the extension syntax.
10+
/// That is, we add a synthetic parameter s to IsValid in the following example:
11+
/// extension(string s) {
12+
/// public bool IsValid() { ... }
13+
/// }
14+
///
15+
/// Note, that we use the characteristics of the parameter of the extension type
16+
/// to populate the database.
17+
/// </summary>
18+
internal class SyntheticExtensionParameter : FreshEntity, IParameter
19+
{
20+
private Method ExtensionMethod { get; }
21+
private IParameterSymbol ExtensionParameter { get; }
22+
private SyntheticExtensionParameter Original { get; }
23+
24+
private SyntheticExtensionParameter(Context cx, Method method, IParameterSymbol parameter, SyntheticExtensionParameter? original) : base(cx)
25+
{
26+
ExtensionMethod = method;
27+
ExtensionParameter = parameter;
28+
Original = original ?? this;
29+
}
30+
31+
private static int Ordinal => 0;
32+
33+
private Parameter.Kind ParamKind
34+
{
35+
get
36+
{
37+
switch (ExtensionParameter.RefKind)
38+
{
39+
case RefKind.Ref:
40+
return Parameter.Kind.Ref;
41+
case RefKind.In:
42+
return Parameter.Kind.In;
43+
case RefKind.RefReadOnlyParameter:
44+
return Parameter.Kind.RefReadOnly;
45+
default:
46+
return Parameter.Kind.None;
47+
}
48+
}
49+
}
50+
51+
private string Name => ExtensionParameter.Name;
52+
53+
private bool IsSourceDeclaration => ExtensionMethod.Symbol.IsSourceDeclaration();
54+
55+
protected override void Populate(TextWriter trapFile)
56+
{
57+
PopulateNullability(trapFile, ExtensionParameter.GetAnnotatedType());
58+
PopulateRefKind(trapFile, ExtensionParameter.RefKind);
59+
60+
var type = Type.Create(Context, ExtensionParameter.Type);
61+
trapFile.@params(this, Name, type.TypeRef, Ordinal, ParamKind, ExtensionMethod, Original);
62+
63+
if (Context.OnlyScaffold)
64+
{
65+
return;
66+
}
67+
68+
if (Context.ExtractLocation(ExtensionParameter))
69+
{
70+
var locations = Context.GetLocations(ExtensionParameter);
71+
WriteLocationsToTrap(trapFile.param_location, this, locations);
72+
}
73+
74+
if (IsSourceDeclaration)
75+
{
76+
foreach (var syntax in ExtensionParameter.DeclaringSyntaxReferences
77+
.Select(d => d.GetSyntax())
78+
.OfType<ParameterSyntax>()
79+
.Where(s => s.Type is not null))
80+
{
81+
TypeMention.Create(Context, syntax.Type!, this, type);
82+
}
83+
}
84+
}
85+
86+
public static SyntheticExtensionParameter Create(Context cx, Method method, IParameterSymbol parameter, SyntheticExtensionParameter? original)
87+
{
88+
var p = new SyntheticExtensionParameter(cx, method, parameter, original);
89+
p.TryPopulate();
90+
return p;
91+
}
92+
}
93+
94+
}

0 commit comments

Comments
 (0)