summaryrefslogtreecommitdiffstats
path: root/source/compiler-core/slang-source-map.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2023-04-20 13:42:20 -0400
committerGitHub <noreply@github.com>2023-04-20 13:42:20 -0400
commit088644c21c015eb60a41a59f417990023f1f4ef8 (patch)
tree596d224f99e35dcd3d66507cfe297bc25407336d /source/compiler-core/slang-source-map.cpp
parent4e67cdedbef8f643c90b48172d5419d3dd1839db (diff)
Improve SourceMap coverage/testing (#2818)
* #include an absolute path didn't work - because paths were taken to always be relative. * WIP around more value like behavior for SourceMap/StringPool. * Use default impls on SourceMap ctor/assignment. * Handle comparison of SourceMaps. Some small fixes. Expand unit tests.
Diffstat (limited to 'source/compiler-core/slang-source-map.cpp')
-rw-r--r--source/compiler-core/slang-source-map.cpp99
1 files changed, 99 insertions, 0 deletions
diff --git a/source/compiler-core/slang-source-map.cpp b/source/compiler-core/slang-source-map.cpp
index 7a6e368a4..43727838f 100644
--- a/source/compiler-core/slang-source-map.cpp
+++ b/source/compiler-core/slang-source-map.cpp
@@ -35,6 +35,105 @@ void SourceMap::swapWith(ThisType& rhs)
m_slicePool.swapWith(rhs.m_slicePool);
}
+static bool _areEqual(const List<StringSlicePool::Handle>& a, const List<StringSlicePool::Handle>& b, const List<Index>& bToAMap)
+{
+ const auto count = a.getCount();
+ if (count != b.getCount())
+ {
+ return false;
+ }
+
+ const auto* as = a.getBuffer();
+ const auto* bs = a.getBuffer();
+
+ for (Index i = 0; i < count; ++i)
+ {
+ if (StringSlicePool::asIndex(as[i]) != bToAMap[StringSlicePool::asIndex(bs[i])])
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool _areEqual(const SourceMap::Entry& a, const SourceMap::Entry& b, const List<Index>& bToAMap)
+{
+ return a.generatedColumn == b.generatedColumn &&
+ a.sourceLine == b.sourceLine &&
+ a.sourceColumn == b.sourceColumn &&
+ a.sourceFileIndex == bToAMap[b.sourceFileIndex] &&
+ a.nameIndex == bToAMap[b.nameIndex];
+}
+
+static bool _areEqual(const List<SourceMap::Entry>& a, const List<SourceMap::Entry>&b, const List<Index>& bToAMap)
+{
+ const auto count = a.getCount();
+ if (count != b.getCount())
+ {
+ return false;
+ }
+
+ for (Index i = 0; i < count; ++i)
+ {
+ if (!_areEqual(a[i], b[i], bToAMap))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SourceMap::operator==(const ThisType& rhs) const
+{
+ if (this == &rhs)
+ {
+ return true;
+ }
+
+ if (m_file != rhs.m_file ||
+ m_sourceRoot != rhs.m_sourceRoot ||
+ m_lineStarts != rhs.m_lineStarts)
+ {
+ return false;
+ }
+
+ if (m_slicePool == rhs.m_slicePool)
+ {
+ // If the slice pools are the same we can just compare indices directly
+ return m_sources == rhs.m_sources &&
+ m_sourcesContent == rhs.m_sourcesContent &&
+ m_names == rhs.m_names &&
+ m_lineEntries == rhs.m_lineEntries;
+ }
+ else
+ {
+ // Otherwise we need to remap the indices
+ // Maps a pool handle from the rhs source map to the
+ List<Index> rhsMap;
+
+ Count count = rhs.m_slicePool.getSlicesCount();
+
+ rhsMap.setCount(count);
+
+ const auto startIndex = rhs.m_slicePool.getFirstAddedIndex();
+
+ // Work out the map
+ for (Index i = 0; i < startIndex; ++i)
+ {
+ const auto rhsSlice = rhs.m_slicePool.getSlice(StringSlicePool::Handle(i));
+ rhsMap[i] = (i < startIndex) ? i : m_slicePool.findIndex(rhsSlice);
+ }
+
+ // Do the comparison taking into account the mapping.
+ return _areEqual(m_sources, rhs.m_sources, rhsMap) &&
+ _areEqual(m_sourcesContent, rhs.m_sourcesContent, rhsMap) &&
+ _areEqual(m_names, rhs.m_names, rhsMap) &&
+ _areEqual(m_lineEntries, rhs.m_lineEntries, rhsMap);
+ }
+}
+
void SourceMap::advanceToLine(Index nextLineIndex)
{
const Count currentLineIndex = getGeneratedLineCount() - 1;