yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1#include "slang-source-map.h" 2 3namespace Slang 4{ 5 6void SourceMap ::clear () 7{ 8const String empty ; 9 10m_file = empty ; 11m_sourceRoot = empty ; 12 13m_sources .clear (); 14 15m_names .clear (); 16 17m_sourcesContent .clear (); 18 19m_lineStarts .setCount (1 ); 20m_lineStarts [0 ]= 0 ; 21 22m_lineEntries .clear (); 23 24m_slicePool .clear (); 25} 26 27void SourceMap ::swapWith (ThisType & rhs ) 28{ 29m_file .swapWith (rhs .m_file ); 30m_sourceRoot .swapWith (rhs .m_sourceRoot ); 31m_sources .swapWith (rhs .m_sources ); 32m_names .swapWith (rhs .m_names ); 33m_sourcesContent .swapWith (rhs .m_sourcesContent ); 34m_lineStarts .swapWith (rhs .m_lineStarts ); 35m_lineEntries .swapWith (rhs .m_lineEntries ); 36m_slicePool .swapWith (rhs .m_slicePool ); 37} 38 39static bool _areEqual ( 40const List < StringSlicePool ::Handle >& a , 41const List < StringSlicePool ::Handle >& b , 42const List < Index >& bToAMap ) 43{ 44const auto count = a .getCount (); 45if (count != b .getCount ()) 46 { 47return false; 48 } 49 50const auto * as = a .getBuffer (); 51const auto * bs = a .getBuffer (); 52 53for (Index i = 0 ;i < count ;++ i ) 54 { 55if (StringSlicePool ::asIndex (as [i ])!= bToAMap [StringSlicePool ::asIndex (bs [i ])]) 56 { 57return false; 58 } 59 } 60 61return true; 62} 63 64static bool _areEqual ( 65const SourceMap ::Entry & a , 66const SourceMap ::Entry & b , 67const List < Index >& bToAMap ) 68{ 69return a .generatedColumn == b .generatedColumn && a .sourceLine == b .sourceLine && 70a .sourceColumn == b .sourceColumn && a .sourceFileIndex == bToAMap [b .sourceFileIndex ]&& 71a .nameIndex == bToAMap [b .nameIndex ]; 72} 73 74static bool _areEqual ( 75const List < SourceMap ::Entry >& a , 76const List < SourceMap ::Entry >& b , 77const List < Index >& bToAMap ) 78{ 79const auto count = a .getCount (); 80if (count != b .getCount ()) 81 { 82return false; 83 } 84 85for (Index i = 0 ;i < count ;++ i ) 86 { 87if (!_areEqual (a [i ],b [i ],bToAMap )) 88 { 89return false; 90 } 91 } 92 93return true; 94} 95 96bool SourceMap ::operator== (const ThisType & rhs )const 97{ 98if (this == & rhs ) 99 { 100return true; 101 } 102 103if (m_file != rhs .m_file || m_sourceRoot != rhs .m_sourceRoot || 104m_lineStarts != rhs .m_lineStarts ) 105 { 106return false; 107 } 108 109if (m_slicePool == rhs .m_slicePool ) 110 { 111// If the slice pools are the same we can just compare indices directly 112return m_sources == rhs .m_sources && m_sourcesContent == rhs .m_sourcesContent && 113m_names == rhs .m_names && m_lineEntries == rhs .m_lineEntries ; 114 } 115else 116 { 117// Otherwise we need to remap the indices 118// Maps a pool handle from the rhs source map to the 119List < Index > rhsMap ; 120 121Count count = rhs .m_slicePool .getSlicesCount (); 122 123rhsMap .setCount (count ); 124 125const auto startIndex = rhs .m_slicePool .getFirstAddedIndex (); 126 127// Work out the map 128for (Index i = 0 ;i < startIndex ;++ i ) 129 { 130const auto rhsSlice = rhs .m_slicePool .getSlice (StringSlicePool ::Handle (i )); 131rhsMap [i ]= (i < startIndex ) ?i :m_slicePool .findIndex (rhsSlice ); 132 } 133 134// Do the comparison taking into account the mapping. 135return _areEqual (m_sources ,rhs .m_sources ,rhsMap )&& 136_areEqual (m_sourcesContent ,rhs .m_sourcesContent ,rhsMap )&& 137_areEqual (m_names ,rhs .m_names ,rhsMap )&& 138_areEqual (m_lineEntries ,rhs .m_lineEntries ,rhsMap ); 139 } 140} 141 142void SourceMap ::advanceToLine (Index nextLineIndex ) 143{ 144const Count currentLineIndex = getGeneratedLineCount ()- 1 ; 145 146SLANG_ASSERT (nextLineIndex >=currentLineIndex ); 147 148if (nextLineIndex <=currentLineIndex ) 149 { 150return ; 151 } 152 153const auto lastEntryIndex = m_lineEntries .getCount (); 154 155// For all the new entries they will need to point to the end 156m_lineStarts .growToCount (nextLineIndex + 1 ); 157 158Index * starts = m_lineStarts .getBuffer (); 159for (Index i = currentLineIndex + 1 ;i < nextLineIndex + 1 ;++ i ) 160 { 161starts [i ]= lastEntryIndex ; 162 } 163} 164 165Index SourceMap ::getNameIndex (const UnownedStringSlice & slice ) 166{ 167StringSlicePool ::Handle handle ; 168 169if (!m_slicePool .findOrAdd (slice ,handle )) 170 { 171// We know it can't possibly be used, so must be new (!) 172 173m_names .add (handle ); 174return m_names .getCount ()- 1 ; 175 } 176 177// Okay, could already be in the list 178const auto index = m_names .indexOf (handle ); 179if (index >=0 ) 180 { 181return index ; 182 } 183 184m_names .add (handle ); 185return m_names .getCount ()- 1 ; 186} 187 188UnownedStringSlice SourceMap ::getSourceFileName (Index sourceFileIndex )const 189{ 190return m_slicePool .getSlice (m_sources [sourceFileIndex ]); 191} 192 193Index SourceMap ::getSourceFileIndex (const UnownedStringSlice & slice ) 194{ 195StringSlicePool ::Handle handle ; 196 197if (!m_slicePool .findOrAdd (slice ,handle )) 198 { 199// We know it can't possibly be used, so must be new (!) 200 201m_sources .add (handle ); 202return m_sources .getCount ()- 1 ; 203 } 204 205// Okay, could already be in the list 206const auto index = m_sources .indexOf (handle ); 207if (index >=0 ) 208 { 209return index ; 210 } 211 212m_sources .add (handle ); 213return m_sources .getCount ()- 1 ; 214} 215 216Index SourceMap ::findEntry (Index lineIndex ,Index colIndex )const 217{ 218auto entries = getEntriesForLine (lineIndex ); 219 220Index closestDist = 0x7fffffff ; 221Index bestIndex = -1 ; 222 223const Count count = entries .getCount (); 224for (Index i = 0 ;i < count ;++ i ) 225 { 226const Entry & entry = entries [i ]; 227 228// We found an exact match 229if (entry .generatedColumn == colIndex ) 230 { 231bestIndex = i ; 232break ; 233 } 234 235Index dist = entry .generatedColumn - colIndex ; 236dist = (dist < 0 ) ?- dist :dist ; 237 238if (dist < closestDist ) 239 { 240closestDist = dist ; 241bestIndex = i ; 242 } 243 } 244 245if (bestIndex < 0 ) 246 { 247return bestIndex ; 248 } 249 250return m_lineStarts [lineIndex ]+ bestIndex ; 251} 252 253}// namespace Slang