Skip to content

Commit 3743859

Browse files
authored
Merge branch 'main' into alexdenisov/extract-emission-body-decisions
2 parents def9831 + c0f9b11 commit 3743859

File tree

63 files changed

+1947
-212
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+1947
-212
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ internal class Conversion : UserOperator
1010
private Conversion(Context cx, IMethodSymbol init)
1111
: base(cx, init) { }
1212

13+
protected override MethodKind ExplicitlyImplementsKind => MethodKind.Conversion;
14+
1315
public static new Conversion Create(Context cx, IMethodSymbol symbol) =>
1416
ConversionFactory.Instance.CreateEntityFromSymbol(cx, symbol);
1517

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,12 @@ public static void NumberOfLines(TextWriter trapFile, ISymbol symbol, IEntity ca
8383
}
8484
}
8585

86+
protected virtual MethodKind ExplicitlyImplementsKind => MethodKind.Ordinary;
87+
8688
public void Overrides(TextWriter trapFile)
8789
{
8890
foreach (var explicitInterface in Symbol.ExplicitInterfaceImplementations
89-
.Where(sym => sym.MethodKind == MethodKind.Ordinary)
91+
.Where(sym => sym.MethodKind == ExplicitlyImplementsKind)
9092
.Select(impl => Type.Create(Context, impl.ContainingType)))
9193
{
9294
trapFile.explicitly_implements(this, explicitInterface.TypeRef);

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ private static void ExtractNamedTypeModifiers(Context cx, TextWriter trapFile, I
8585
if (nt.IsRecord)
8686
HasModifier(cx, trapFile, key, Modifiers.Record);
8787

88+
if (nt.IsFileLocal)
89+
HasModifier(cx, trapFile, key, Modifiers.File);
90+
8891
if (nt.TypeKind == TypeKind.Struct)
8992
{
9093
if (nt.IsReadOnly)
@@ -97,7 +100,11 @@ private static void ExtractNamedTypeModifiers(Context cx, TextWriter trapFile, I
97100

98101
public static void ExtractModifiers(Context cx, TextWriter trapFile, IEntity key, ISymbol symbol)
99102
{
100-
HasAccessibility(cx, trapFile, key, symbol.DeclaredAccessibility);
103+
// A file scoped type has declared accessibility `internal` which we shouldn't extract.
104+
// The file modifier is extracted as a source level modifier.
105+
if (symbol.Kind != SymbolKind.NamedType || !((INamedTypeSymbol)symbol).IsFileLocal)
106+
HasAccessibility(cx, trapFile, key, symbol.DeclaredAccessibility);
107+
101108
if (symbol.Kind == SymbolKind.ErrorType)
102109
trapFile.has_modifiers(key, Modifier.Create(cx, Accessibility.Public));
103110

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ internal static class Modifiers
44
public const string Async = "async";
55
public const string Const = "const";
66
public const string Extern = "extern";
7+
public const string File = "file";
78
public const string Internal = "internal";
89
public const string New = "new";
910
public const string Override = "override";

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ internal class UserOperator : Method
1111
protected UserOperator(Context cx, IMethodSymbol init)
1212
: base(cx, init) { }
1313

14+
protected override MethodKind ExplicitlyImplementsKind => MethodKind.UserDefinedOperator;
15+
1416
public override void Populate(TextWriter trapFile)
1517
{
1618
PopulateMethod(trapFile);
@@ -37,6 +39,7 @@ public override void Populate(TextWriter trapFile)
3739
}
3840

3941
ContainingType.PopulateGenerics();
42+
Overrides(trapFile);
4043
}
4144

4245
public override bool NeedsPopulation => Context.Defines(Symbol) || IsImplicitOperator(out _);

csharp/extractor/Semmle.Extraction.CSharp/SymbolExtensions.cs

Lines changed: 41 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -282,54 +282,60 @@ private static void BuildFunctionPointerTypeId(this IFunctionPointerTypeSymbol f
282282
public static IEnumerable<IFieldSymbol?> GetTupleElementsMaybeNull(this INamedTypeSymbol type) =>
283283
type.TupleElements;
284284

285-
private static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, EscapingTextWriter trapFile, ISymbol symbolBeingDefined, bool constructUnderlyingTupleType)
285+
private static void BuildQualifierAndName(INamedTypeSymbol named, Context cx, EscapingTextWriter trapFile, ISymbol symbolBeingDefined)
286286
{
287-
if (!constructUnderlyingTupleType && named.IsTupleType)
287+
if (named.ContainingType is not null)
288288
{
289-
trapFile.Write('(');
290-
trapFile.BuildList(",", named.GetTupleElementsMaybeNull(),
291-
(i, f) =>
292-
{
293-
if (f is null)
294-
{
295-
trapFile.Write($"null({i})");
296-
}
297-
else
298-
{
299-
trapFile.Write((f.CorrespondingTupleField ?? f).Name);
300-
trapFile.Write(":");
301-
f.Type.BuildOrWriteId(cx, trapFile, symbolBeingDefined, constructUnderlyingTupleType: false);
302-
}
303-
}
304-
);
305-
trapFile.Write(")");
306-
return;
289+
named.ContainingType.BuildOrWriteId(cx, trapFile, symbolBeingDefined, constructUnderlyingTupleType: false);
290+
trapFile.Write('.');
307291
}
308-
309-
void AddContaining()
292+
else if (named.ContainingNamespace is not null)
310293
{
311-
if (named.ContainingType is not null)
312-
{
313-
named.ContainingType.BuildOrWriteId(cx, trapFile, symbolBeingDefined, constructUnderlyingTupleType: false);
314-
trapFile.Write('.');
315-
}
316-
else if (named.ContainingNamespace is not null)
294+
if (cx.ShouldAddAssemblyTrapPrefix && named.ContainingAssembly is not null)
295+
BuildAssembly(named.ContainingAssembly, trapFile);
296+
named.ContainingNamespace.BuildNamespace(cx, trapFile);
297+
}
298+
299+
var name = named.IsFileLocal ? named.MetadataName : named.Name;
300+
trapFile.Write(name);
301+
}
302+
303+
private static void BuildTupleId(INamedTypeSymbol named, Context cx, EscapingTextWriter trapFile, ISymbol symbolBeingDefined)
304+
{
305+
trapFile.Write('(');
306+
trapFile.BuildList(",", named.GetTupleElementsMaybeNull(),
307+
(i, f) =>
317308
{
318-
if (cx.ShouldAddAssemblyTrapPrefix && named.ContainingAssembly is not null)
319-
BuildAssembly(named.ContainingAssembly, trapFile);
320-
named.ContainingNamespace.BuildNamespace(cx, trapFile);
309+
if (f is null)
310+
{
311+
trapFile.Write($"null({i})");
312+
}
313+
else
314+
{
315+
trapFile.Write((f.CorrespondingTupleField ?? f).Name);
316+
trapFile.Write(":");
317+
f.Type.BuildOrWriteId(cx, trapFile, symbolBeingDefined, constructUnderlyingTupleType: false);
318+
}
321319
}
320+
);
321+
trapFile.Write(")");
322+
}
323+
324+
private static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, EscapingTextWriter trapFile, ISymbol symbolBeingDefined, bool constructUnderlyingTupleType)
325+
{
326+
if (!constructUnderlyingTupleType && named.IsTupleType)
327+
{
328+
BuildTupleId(named, cx, trapFile, symbolBeingDefined);
329+
return;
322330
}
323331

324332
if (named.TypeParameters.IsEmpty)
325333
{
326-
AddContaining();
327-
trapFile.Write(named.Name);
334+
BuildQualifierAndName(named, cx, trapFile, symbolBeingDefined);
328335
}
329336
else if (named.IsReallyUnbound())
330337
{
331-
AddContaining();
332-
trapFile.Write(named.Name);
338+
BuildQualifierAndName(named, cx, trapFile, symbolBeingDefined);
333339
trapFile.Write("`");
334340
trapFile.Write(named.TypeParameters.Length);
335341
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* C# 11: Added extractor and library support for `file` scoped types.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* C# 11: Support for explicit interface member implementation of operators.

csharp/ql/lib/semmle/code/csharp/Callable.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ class Destructor extends DotNet::Destructor, Callable, Member, Attributable, @de
434434
* Either a unary operator (`UnaryOperator`), a binary operator
435435
* (`BinaryOperator`), or a conversion operator (`ConversionOperator`).
436436
*/
437-
class Operator extends Callable, Member, Attributable, @operator {
437+
class Operator extends Callable, Member, Attributable, Overridable, @operator {
438438
/**
439439
* DEPRECATED: use `getFunctionName()` instead.
440440
*

csharp/ql/lib/semmle/code/csharp/Member.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ class Modifiable extends Declaration, @modifiable {
9393
/** Holds if this declaration has the modifier `required`. */
9494
predicate isRequired() { this.hasModifier("required") }
9595

96+
/** Holds if this declaration is `file` local. */
97+
predicate isFile() { this.hasModifier("file") }
98+
9699
/** Holds if this declaration is `unsafe`. */
97100
predicate isUnsafe() {
98101
this.hasModifier("unsafe") or
@@ -183,6 +186,8 @@ class Member extends DotNet::Member, Modifiable, @member {
183186
override predicate isStatic() { Modifiable.super.isStatic() }
184187

185188
override predicate isRequired() { Modifiable.super.isRequired() }
189+
190+
override predicate isFile() { Modifiable.super.isFile() }
186191
}
187192

188193
private class TOverridable = @virtualizable or @callable_accessor;

0 commit comments

Comments
 (0)