Swift: add UnknownLocation

`getLocation()` will now exists for all entities. When there is no
valid location, the location will still not be emitted in the DB, but
on the QL side we will then assign a special `UnknownLocation` with
empty filename and 0 for line/column start/end.

This unknown location is currently emitted (with a unique `@` key) at
the start of every extraction, but we can move it elsewhere (and
possibly in a unique global trap file) at a later stage, possibly after
or when we rework the trap file strategy.

This should solve flakiness that was observed on the control flow tests,
which is probably caused by the `nodes` predicate in the `TestOutput`
class in `ControlFlowGraphImplShared.qll` not able to assign a proper
rank when the node does not have a location.
This commit is contained in:
Paolo Tranquilli
2022-06-03 14:44:47 +02:00
parent 4a025053cc
commit 01e1c13c29
5 changed files with 23 additions and 3 deletions

View File

@@ -84,6 +84,15 @@ static void extractFile(const SwiftExtractorConfiguration& config,
TrapOutput trap{trapStream};
TrapArena arena{};
// TODO move default location emission elsewhere, possibly in a separate global trap file
auto unknownFileLabel = arena.allocateLabel<FileTag>();
// the following cannot conflict with actual files as those have an absolute path starting with /
trap.assignKey(unknownFileLabel, "unknown");
trap.emit(FilesTrap{unknownFileLabel});
auto unknownLocationLabel = arena.allocateLabel<LocationTag>();
trap.assignKey(unknownLocationLabel, "unknown");
trap.emit(LocationsTrap{unknownLocationLabel, unknownFileLabel});
// In the case of emtpy files, the dispatcher is not called, but we still want to 'record' the
// fact that the file was extracted
// TODO: to be moved elsewhere

View File

@@ -1,4 +1,10 @@
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
private import codeql.swift.generated.Locatable
private import codeql.swift.elements.Location
class Locatable extends LocatableBase { }
class Locatable extends LocatableBase {
override Location getLocation() {
result = LocatableBase.super.getLocation()
or
not exists(LocatableBase.super.getLocation()) and result instanceof UnknownLocation
}
}

View File

@@ -9,3 +9,7 @@ class Location extends LocationBase {
ec = getEndColumn()
}
}
class UnknownLocation extends Location {
UnknownLocation() { hasLocationInfo("", 0, 0, 0, 0) }
}

View File

@@ -12,7 +12,7 @@ predicate isKnownKind(AccessorDecl decl, string kind) {
from AccessorDecl decl, string kind
where
exists(decl.getLocation()) and
decl.getLocation().getFile().getName().matches("%swift/ql/test%") and
(
isKnownKind(decl, kind)
or

View File

@@ -1 +1,2 @@
| file://:0:0:0:0 | |
| hello.swift:0:0:0:0 | hello.swift |