diff --git a/swift/extractor/infra/SwiftLocationExtractor.cpp b/swift/extractor/infra/SwiftLocationExtractor.cpp new file mode 100644 index 00000000000..a1b138f1f95 --- /dev/null +++ b/swift/extractor/infra/SwiftLocationExtractor.cpp @@ -0,0 +1,59 @@ +#include +#include + +#include "swift/extractor/trap/TrapDomain.h" +#include "swift/extractor/trap/generated/TrapEntries.h" +#include "swift/extractor/trap/generated/TrapClasses.h" +#include "swift/extractor/infra/SwiftLocationExtractor.h" + +using namespace codeql; + +static std::filesystem::path getFilePath(std::string_view path) { + // TODO: this needs more testing + // TODO: check canonicalization of names on a case insensitive filesystems + // TODO: make symlink resolution conditional on CODEQL_PRESERVE_SYMLINKS=true + std::error_code ec; + auto ret = std::filesystem::canonical(path, ec); + if (ec) { + std::cerr << "Cannot get real path: " << std::quoted(path) << ": " << ec.message() << "\n"; + return {}; + } + return ret; +} + +void SwiftLocationExtractor::attachLocation(const swift::SourceManager& sourceManager, + swift::SourceLoc start, + swift::SourceLoc end, + TrapLabel locatableLabel) { + if (!start.isValid() || !end.isValid()) { + // invalid locations seem to come from entities synthesized by the compiler + return; + } + auto file = getFilePath(sourceManager.getDisplayNameForLoc(start)); + DbLocation entry{{}}; + entry.file = fetchFileLabel(file); + std::tie(entry.start_line, entry.start_column) = sourceManager.getLineAndColumnInBuffer(start); + std::tie(entry.end_line, entry.end_column) = sourceManager.getLineAndColumnInBuffer(end); + entry.id = trap.createLabel('{', entry.file, "}:", entry.start_line, ':', + entry.start_column, ':', entry.end_line, ':', + entry.end_column); + trap.emit(entry); + trap.emit(LocatableLocationsTrap{locatableLabel, entry.id}); +} + +void SwiftLocationExtractor::emitFile(llvm::StringRef path) { + fetchFileLabel(getFilePath(path)); +} + +TrapLabel SwiftLocationExtractor::fetchFileLabel(const std::filesystem::path& file) { + if (store.count(file)) { + return store[file]; + } + + DbFile entry({}); + entry.id = trap.createLabel(file.string()); + entry.name = file.string(); + trap.emit(entry); + store[file] = entry.id; + return entry.id; +} diff --git a/swift/extractor/infra/SwiftLocationExtractor.h b/swift/extractor/infra/SwiftLocationExtractor.h index e0c3800ea02..1960aeed7f3 100644 --- a/swift/extractor/infra/SwiftLocationExtractor.h +++ b/swift/extractor/infra/SwiftLocationExtractor.h @@ -1,11 +1,10 @@ #pragma once -#include #include +#include +#include -#include "swift/extractor/trap/TrapDomain.h" #include "swift/extractor/trap/generated/TrapEntries.h" -#include "swift/extractor/trap/generated/TrapClasses.h" #include "swift/extractor/infra/file/PathHash.h" namespace codeql { @@ -19,52 +18,12 @@ class SwiftLocationExtractor { void attachLocation(const swift::SourceManager& sourceManager, swift::SourceLoc start, swift::SourceLoc end, - TrapLabel locatableLabel) { - if (!start.isValid() || !end.isValid()) { - // invalid locations seem to come from entities synthesized by the compiler - return; - } - auto file = getFilePath(sourceManager.getDisplayNameForLoc(start)); - DbLocation entry{{}}; - entry.file = fetchFileLabel(file); - std::tie(entry.start_line, entry.start_column) = sourceManager.getLineAndColumnInBuffer(start); - std::tie(entry.end_line, entry.end_column) = sourceManager.getLineAndColumnInBuffer(end); - entry.id = trap.createLabel('{', entry.file, "}:", entry.start_line, ':', - entry.start_column, ':', entry.end_line, ':', - entry.end_column); - trap.emit(entry); - trap.emit(LocatableLocationsTrap{locatableLabel, entry.id}); - } + TrapLabel locatableLabel); - void emitFile(llvm::StringRef path) { fetchFileLabel(getFilePath(path)); } + void emitFile(llvm::StringRef path); private: - TrapLabel fetchFileLabel(const std::filesystem::path& file) { - if (store.count(file)) { - return store[file]; - } - - DbFile entry({}); - entry.id = trap.createLabel(file.string()); - entry.name = file.string(); - trap.emit(entry); - store[file] = entry.id; - return entry.id; - } - - static std::filesystem::path getFilePath(std::string_view path) { - // TODO: this needs more testing - // TODO: check canonicalization of names on a case insensitive filesystems - // TODO: make symlink resolution conditional on CODEQL_PRESERVE_SYMLINKS=true - std::error_code ec; - auto ret = std::filesystem::canonical(path, ec); - if (ec) { - std::cerr << "Cannot get real path: " << std::quoted(path) << ": " << ec.message() << "\n"; - return {}; - } - return ret; - } - + TrapLabel fetchFileLabel(const std::filesystem::path& file); TrapDomain& trap; std::unordered_map> store; }; diff --git a/swift/extractor/invocation/SwiftDiagnosticsConsumer.cpp b/swift/extractor/invocation/SwiftDiagnosticsConsumer.cpp index de9d2258070..12cbd381801 100644 --- a/swift/extractor/invocation/SwiftDiagnosticsConsumer.cpp +++ b/swift/extractor/invocation/SwiftDiagnosticsConsumer.cpp @@ -1,5 +1,6 @@ #include "swift/extractor/invocation/SwiftDiagnosticsConsumer.h" #include "swift/extractor/trap/generated/TrapEntries.h" +#include "swift/extractor/trap/TrapDomain.h" #include #include