-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Expand file tree
/
Copy pathSyntheticExtensionParameter.cs
More file actions
77 lines (65 loc) · 2.77 KB
/
Copy pathSyntheticExtensionParameter.cs
File metadata and controls
77 lines (65 loc) · 2.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
using System.IO;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace Semmle.Extraction.CSharp.Entities
{
/// <summary>
/// Synthetic parameter for extension methods declared using the extension syntax.
/// That is, we add a synthetic parameter `s` to `IsValid` in the following example:
/// extension(string s) {
/// public bool IsValid() { ... }
/// }
///
/// Note, that we use the characteristics of the parameter of the extension type
/// to populate the database.
/// </summary>
internal class SyntheticExtensionParameter : FreshEntity, IParameter
{
private Method ExtensionMethod { get; }
private IParameterSymbol ExtensionParameter { get; }
private SyntheticExtensionParameter Original { get; }
private SyntheticExtensionParameter(Context cx, Method method, IParameterSymbol parameter, SyntheticExtensionParameter? original) : base(cx)
{
ExtensionMethod = method;
ExtensionParameter = parameter;
Original = original ?? this;
}
private static int Ordinal => 0;
private string Name => ExtensionParameter.Name;
private bool IsSourceDeclaration => ExtensionMethod.Symbol.IsSourceDeclaration();
protected override void Populate(TextWriter trapFile)
{
PopulateNullability(trapFile, ExtensionParameter.GetAnnotatedType());
PopulateRefKind(trapFile, ExtensionParameter.RefKind);
var type = Type.Create(Context, ExtensionParameter.Type);
var kind = ExtensionParameter.GetParameterKind();
trapFile.@params(this, Name, type.TypeRef, Ordinal, kind, ExtensionMethod, Original);
if (Context.OnlyScaffold)
{
return;
}
if (Context.ExtractLocation(ExtensionParameter))
{
var locations = Context.GetLocations(ExtensionParameter);
WriteLocationsToTrap(trapFile.param_location, this, locations);
}
if (IsSourceDeclaration)
{
foreach (var syntax in ExtensionParameter.DeclaringSyntaxReferences
.Select(d => d.GetSyntax())
.OfType<ParameterSyntax>()
.Where(s => s.Type is not null))
{
TypeMention.Create(Context, syntax.Type!, this, type);
}
}
}
public static SyntheticExtensionParameter Create(Context cx, Method method, IParameterSymbol parameter, SyntheticExtensionParameter? original)
{
var p = new SyntheticExtensionParameter(cx, method, parameter, original);
p.TryPopulate();
return p;
}
}
}