#include "diagnostics.h"
namespace goose::diagnostics
{
unordered_set< string > Location::ms_filenames;
vector< Location > Location::ms_locations;
uint32_t LocationPoint::toLoc( uint32_t length ) const
{
return Location::Create( *this, length );
}
uint32_t LocationPoint::toLoc( const LocationPoint& end ) const
{
return Location::Create( *this, end.m_offset - m_offset );
}
const string& Location::GetCachedFilename( const string& filename )
{
return *ms_filenames.insert( filename ).first;
}
optional< Location > Location::Get( uint32_t locationId )
{
// 0 is used for values that don't have a location
if( locationId == 0 )
return nullopt;
--locationId;
if( locationId >= ms_locations.size() )
return nullopt;
return ms_locations[locationId];
}
uint32_t Location::CreateSpanningLocation( uint32_t loc1, uint32_t loc2 )
{
if( loc1 == ~0 || loc2 == ~0 )
return ~0;
auto l1 = Get( loc1 );
auto l2 = Get( loc2 );
if( !l1 || !l2 )
return 0;
assert( l1->filename() == l2->filename() );
auto offset = min( l1->offset(), l2->offset() );
auto end = max( l1->offset() + l1->length(), l2->offset() + l2->length() );
auto length = end - offset;
auto line = min( l1->line(), l2->line() );
auto col = l1->offset() < l2->offset() ? l1->column() : l2->column();
return Create( l1->filename(), offset, length, line, col );
}
bool Location::Overlaps( uint32_t loc1, uint32_t loc2 )
{
if( loc1 == ~0 || loc2 == ~0 )
return false;
auto l1 = Get( loc1 );
auto l2 = Get( loc2 );
if( !l1 || !l2 )
return false;
if( l1->filename() != l2->filename() )
return false;
if( l1->line() != l2->line() )
return false;
auto l1end = l1->column() + l1->length();
auto l2end = l2->column() + l2->length();
if( l1end < l2->column() )
return false;
if( l2end < l1->column() )
return false;
return true;
}
}