Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a9bb7b5

Browse files
authored
Merge pull request #4413 from hvitved/csharp/indexer-explicit-interface
C#: Fix extraction of library indexers with explicit interface implementations
2 parents cec6bbe + 68014fd commit a9bb7b5

4 files changed

Lines changed: 27 additions & 15 deletions

File tree

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

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,28 @@ protected Accessor(Context cx, IMethodSymbol init)
1010
: base(cx, init) { }
1111

1212
/// <summary>
13-
/// Gets the property symbol associated with this accessor.
13+
/// Gets the property symbol associated accessor `symbol`, or `null`
14+
/// if there is no associated symbol.
1415
/// </summary>
15-
IPropertySymbol PropertySymbol
16+
public static IPropertySymbol GetPropertySymbol(IMethodSymbol symbol)
1617
{
17-
get
18-
{
19-
// Usually, the property/indexer can be fetched from the associated symbol
20-
var prop = symbol.AssociatedSymbol as IPropertySymbol;
21-
if (prop != null)
22-
return prop;
18+
// Usually, the property/indexer can be fetched from the associated symbol
19+
var prop = symbol.AssociatedSymbol as IPropertySymbol;
20+
if (prop != null)
21+
return prop;
2322

24-
// But for properties/indexers that implement explicit interfaces, Roslyn
25-
// does not properly populate `AssociatedSymbol`
26-
var props = symbol.ContainingType.GetMembers().OfType<IPropertySymbol>();
27-
props = props.Where(p => SymbolEqualityComparer.Default.Equals(symbol, p.GetMethod) || SymbolEqualityComparer.Default.Equals(symbol, p.SetMethod));
28-
return props.SingleOrDefault();
29-
}
23+
// But for properties/indexers that implement explicit interfaces, Roslyn
24+
// does not properly populate `AssociatedSymbol`
25+
var props = symbol.ContainingType.GetMembers().OfType<IPropertySymbol>();
26+
props = props.Where(p => SymbolEqualityComparer.Default.Equals(symbol, p.GetMethod) || SymbolEqualityComparer.Default.Equals(symbol, p.SetMethod));
27+
return props.SingleOrDefault();
3028
}
3129

30+
/// <summary>
31+
/// Gets the property symbol associated with this accessor.
32+
/// </summary>
33+
IPropertySymbol PropertySymbol => GetPropertySymbol(symbol);
34+
3235
public new Accessor OriginalDefinition => Create(Context, symbol.OriginalDefinition);
3336

3437
public override void Populate(TextWriter trapFile)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ public static Method Create(Context cx, IMethodSymbol methodDecl)
240240
return Destructor.Create(cx, methodDecl);
241241
case MethodKind.PropertyGet:
242242
case MethodKind.PropertySet:
243-
return methodDecl.AssociatedSymbol is null ? OrdinaryMethod.Create(cx, methodDecl) : (Method)Accessor.Create(cx, methodDecl);
243+
return Accessor.GetPropertySymbol(methodDecl) is null ? OrdinaryMethod.Create(cx, methodDecl) : (Method)Accessor.Create(cx, methodDecl);
244244
case MethodKind.EventAdd:
245245
case MethodKind.EventRemove:
246246
return EventAccessor.Create(cx, methodDecl);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| Item[int] | get_Item(int) |
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import csharp
2+
3+
from Indexer i, Accessor a, string s
4+
where
5+
i.getDeclaringType().hasQualifiedName("System", s) and
6+
s.regexpMatch("Tuple<,*>") and
7+
a = i.getAnAccessor()
8+
select i.toStringWithTypes(), a.toStringWithTypes()

0 commit comments

Comments
 (0)