C#: Make Element.getLocation (mostly) functional

This commit is contained in:
Tom Hvitved
2024-05-02 13:25:05 +02:00
parent 3c2206728d
commit f5d4b2e6cd

View File

@@ -51,8 +51,6 @@ class TopLevelExprParent extends Element, @top_level_expr_parent {
final Expr getAChildExpr() { result = this.getChildExpr(_) }
}
private predicate hasNoSourceLocation(Element e) { not e.getALocation() instanceof SourceLocation }
/** INTERNAL: Do not use. */
Expr getExpressionBody(Callable c) {
result = c.getAChildExpr() and
@@ -67,17 +65,46 @@ private ControlFlowElement getBody(Callable c) {
result = getStatementBody(c)
}
pragma[nomagic]
private Location getASourceLocation(Element e) {
result = e.getALocation().(SourceLocation) and
not exists(e.getALocation().(SourceLocation).getMappedLocation())
or
result = e.getALocation().(SourceLocation).getMappedLocation()
}
pragma[nomagic]
private predicate hasNoSourceLocation(Element e) { not exists(getASourceLocation(e)) }
pragma[nomagic]
private Location getFirstSourceLocation(Element e) {
result =
min(Location l, string filepath, int startline, int startcolumn, int endline, int endcolumn |
l = getASourceLocation(e) and
l.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
l order by filepath, startline, startcolumn, endline, endcolumn
)
}
cached
private module Cached {
cached
Location bestLocation(Element e) {
result = e.getALocation().(SourceLocation) and
not exists(e.getALocation().(SourceLocation).getMappedLocation())
or
result = e.getALocation().(SourceLocation).getMappedLocation()
(
if e.(Modifiable).isPartial() or e instanceof Namespace
then result = getASourceLocation(e)
else result = getFirstSourceLocation(e)
)
or
hasNoSourceLocation(e) and
result = min(Location l | l = e.getALocation() | l order by l.getFile().toString())
result =
min(Location l, string filepath |
l = e.getALocation() and
l.hasLocationInfo(filepath, _, _, _, _)
|
l order by filepath
)
or
not exists(e.getALocation()) and
result instanceof EmptyLocation