mirror of
https://github.com/github/codeql.git
synced 2026-04-25 08:45:14 +02:00
Merge pull request #16836 from michaelnebel/csharp/bestlocation
C#: Be more consistent when picking between locations.
This commit is contained in:
@@ -82,12 +82,12 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
/// The location which is stored in the database and is used when highlighting source code.
|
||||
/// It's generally short, e.g. a method name.
|
||||
/// </summary>
|
||||
public override Microsoft.CodeAnalysis.Location? ReportingLocation => Symbol.Locations.FirstOrDefault();
|
||||
public override Microsoft.CodeAnalysis.Location? ReportingLocation => Symbol.Locations.BestOrDefault();
|
||||
|
||||
/// <summary>
|
||||
/// The full text span of the entity, e.g. for binding comments.
|
||||
/// </summary>
|
||||
public virtual Microsoft.CodeAnalysis.Location? FullLocation => Symbol.Locations.FirstOrDefault();
|
||||
public virtual Microsoft.CodeAnalysis.Location? FullLocation => Symbol.Locations.BestOrDefault();
|
||||
|
||||
public virtual IEnumerable<Extraction.Entities.Location> Locations
|
||||
{
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
.OfType<ConversionOperatorDeclarationSyntax>()
|
||||
.Select(s => s.FixedLocation())
|
||||
.Concat(Symbol.Locations)
|
||||
.FirstOrDefault();
|
||||
.BestOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
.OfType<IndexerDeclarationSyntax>()
|
||||
.Select(s => s.GetLocation())
|
||||
.Concat(Symbol.Locations)
|
||||
.First();
|
||||
.Best();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
.OfType<PropertyDeclarationSyntax>()
|
||||
.Select(s => s.GetLocation())
|
||||
.Concat(Symbol.Locations)
|
||||
.First();
|
||||
.Best();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
public static DynamicType Create(Context cx, IDynamicTypeSymbol type) => DynamicTypeFactory.Instance.CreateEntityFromSymbol(cx, type);
|
||||
|
||||
public override Microsoft.CodeAnalysis.Location? ReportingLocation => Context.Compilation.ObjectType.Locations.FirstOrDefault();
|
||||
public override Microsoft.CodeAnalysis.Location? ReportingLocation => Context.Compilation.ObjectType.Locations.BestOrDefault();
|
||||
|
||||
public override void Populate(TextWriter trapFile)
|
||||
{
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
);
|
||||
}
|
||||
|
||||
public override Microsoft.CodeAnalysis.Location? ReportingLocation => GetLocations(Symbol).FirstOrDefault();
|
||||
public override Microsoft.CodeAnalysis.Location? ReportingLocation => GetLocations(Symbol).BestOrDefault();
|
||||
|
||||
private bool IsAnonymousType() => Symbol.IsAnonymousType || Symbol.Name.Contains("__AnonymousType");
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ namespace Semmle.Extraction.CSharp
|
||||
return Path.ChangeExtension(entryPointFile, ".exe");
|
||||
}
|
||||
|
||||
var entryPointFilename = entry.Locations.First().SourceTree!.FilePath;
|
||||
var entryPointFilename = entry.Locations.Best().SourceTree!.FilePath;
|
||||
return Path.ChangeExtension(entryPointFilename, ".exe");
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace Semmle.Extraction.CSharp.Populators
|
||||
{
|
||||
return symbol.DeclaringSyntaxReferences.Any() ?
|
||||
symbol.DeclaringSyntaxReferences.First().GetSyntax().FixedLocation() :
|
||||
symbol.Locations.First();
|
||||
symbol.Locations.Best();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -379,7 +379,7 @@ namespace Semmle.Extraction
|
||||
{
|
||||
if (!(optionalSymbol is null))
|
||||
{
|
||||
ExtractionError(message, optionalSymbol.ToDisplayString(), CreateLocation(optionalSymbol.Locations.FirstOrDefault()));
|
||||
ExtractionError(message, optionalSymbol.ToDisplayString(), CreateLocation(optionalSymbol.Locations.BestOrDefault()));
|
||||
}
|
||||
else if (!(optionalEntity is null))
|
||||
{
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Semmle.Extraction
|
||||
{
|
||||
Text = msg;
|
||||
EntityText = symbol.ToString() ?? "";
|
||||
Location = symbol.Locations.FirstOrDefault();
|
||||
Location = symbol.Locations.BestOrDefault();
|
||||
}
|
||||
|
||||
public InternalError(SyntaxNode node, string msg)
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace Semmle.Extraction
|
||||
{
|
||||
@@ -36,5 +39,46 @@ namespace Semmle.Extraction
|
||||
var endsBefore = before.SourceSpan.End <= after.SourceSpan.Start;
|
||||
return sameFile && endsBefore;
|
||||
}
|
||||
|
||||
private static int GetLocationKindPriority(Location location) =>
|
||||
location.IsInSource
|
||||
? 2
|
||||
: location.IsInMetadata
|
||||
? 1
|
||||
: 0;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if l1 is better than l2.
|
||||
/// Source locations are considered better than non source locations.
|
||||
/// </summary>
|
||||
private static bool BetterThan(Location l1, Location l2)
|
||||
{
|
||||
if (GetLocationKindPriority(l1) > GetLocationKindPriority(l2))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// For source locations we compare the filepath and span.
|
||||
if (l1.IsInSource && l2.IsInSource)
|
||||
{
|
||||
var l1s = l1.SourceTree.FilePath + l1.SourceSpan;
|
||||
var l2s = l2.SourceTree.FilePath + l2.SourceSpan;
|
||||
return l1s.CompareTo(l2s) < 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the best location from the given list of locations.
|
||||
/// Source locations are considered better than non-source locations.
|
||||
/// In case of a (source location) tie, the location with the
|
||||
/// lexicographically smaller filepath and span is considered better.
|
||||
/// </summary>
|
||||
public static Location? BestOrDefault(this IEnumerable<Location> locations) =>
|
||||
locations.Any() ? locations.Aggregate((best, loc) => BetterThan(loc, best) ? loc : best) : null;
|
||||
|
||||
public static Location Best(this IEnumerable<Location> locations) =>
|
||||
locations.BestOrDefault() ?? throw new ArgumentException("No location found.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Semmle.Extraction
|
||||
|
||||
public static Message Create(Context cx, string text, ISymbol symbol, string? stackTrace = null, Severity severity = Severity.Error)
|
||||
{
|
||||
return new Message(text, symbol.ToString(), cx.CreateLocation(symbol.Locations.FirstOrDefault()), stackTrace, severity);
|
||||
return new Message(text, symbol.ToString(), cx.CreateLocation(symbol.Locations.BestOrDefault()), stackTrace, severity);
|
||||
}
|
||||
|
||||
public static Message Create(Context cx, string text, SyntaxNode node, string? stackTrace = null, Severity severity = Severity.Error)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
| A.cs:28:7:28:8 | C3 | B.cs:25:7:25:8 | {...} |
|
||||
| A.cs:30:21:30:23 | get_P3 | A.cs:30:28:30:37 | throw ... |
|
||||
| A.cs:34:15:34:16 | C4 | A.cs:34:15:34:16 | {...} |
|
||||
| A.cs:34:15:34:16 | C4 | C.cs:1:15:1:16 | {...} |
|
||||
| A.cs:34:15:34:16 | C4 | B.cs:30:15:30:16 | {...} |
|
||||
| A.cs:36:9:36:10 | M1 | A.cs:36:14:36:28 | {...} |
|
||||
| A.cs:36:9:36:10 | M1 | B.cs:32:17:32:17 | 0 |
|
||||
| A.cs:37:9:37:10 | M2 | A.cs:37:14:37:28 | {...} |
|
||||
|
||||
Reference in New Issue
Block a user