polserver/pol-core/bscript/compiler/file/SourceLocation.cpp

194 lines
5.4 KiB
C++
Raw Permalink Normal View History

#include "SourceLocation.h"
#include "bscript/compiler/Antlr4Inc.h"
#include "bscript/compiler/file/SourceFileIdentifier.h"
#include "clib/filecont.h"
#include "clib/logfacility.h"
#include <iterator>
"Preview/Initial"- Version sourcecode formatting feature (#626) * Squash only prettify changes from escript_formating_try * support of "format-off" / "format-on" comments to mark areas without formatting * fix typo * added FormatterIdentLevel, FormatterMergeEmptyLines cfg entry better line splits for dicts/arrays * added several spacing options. the current setting list is now: //LineWidth FormatterLineWidth 80 // keep original keyword spelling FormatterKeepKeywords 0 // number of spaces for ident FormatterIdentLevel 2 // multiple newlines get merged to a single FormatterMergeEmptyLines 1 // space between emtpy parenthesis eg foo() vs foo( ) FormatterEmptyParenthesisSpacing 0 // space between emtpy brackets eg struct{} vs struct{ } FormatterEmptyBracketSpacing 0 // space after/before parenthesis in conditionals // eg if ( true ) vs if (true) FormatterConditionalParenthesisSpacing 1 // space after/before parenthesis // eg foo( true ) vs foo(true) FormatterParenthesisSpacing 1 // space after/before brackets // eg array{ true } vs array{true} FormatterBracketSpacing 1 // add space after delimiter comma or semi in for loops // eg {1, 2, 3} vs {1,2,3} FormatterDelimiterSpacing 1 // add space around assignment // eg a := 1; vs a:=1; FormatterAssignmentSpacing 1 // add space around comparison // eg a == 1 vs a==1 FormatterComparisonSpacing 1 // add space around operations // eg a + 1 vs a+1 FormatterOperatorSpacing 1 // use \r\n as newline instead of \n FormatterWindowsLineEndings 0 * added tab support // use tabs instead of spaces FormatterUseTabs 0 // tab width FormatterTabWidth 4 * extended example ecompile.cfg with formatter settings * cleanup * program args comma is optional... fixed line comments in group splitting * since tokenids are now correct no more guessing for linecomments needed * comments use as start tokenid the whitespace token if its on the same line * splitted processing from linebuilding * renamed TokenPart to FmtToken better matches the purpose. Comments get directly stored as FmtToken started with a context enum * better(?) formatting for groups * fix eof rawlines added check that all comments/rawlines got parsed * const correctness * datatype adapted to antlr * fixed warnings * added InsertNewlineAtEOF * add newline at the end if the original file had one dont strip comment whitespace if its somejind of "header block" use the defined lineending for /* */ comments * docs * \r\n is default on windows \n otherwise * fixed warning --------- Co-authored-by: Kevin Eady <8634912+KevinEady@users.noreply.github.com>
2024-02-26 21:21:44 +01:00
#include <climits>
namespace Pol::Bscript::Compiler
{
"Preview/Initial"- Version sourcecode formatting feature (#626) * Squash only prettify changes from escript_formating_try * support of "format-off" / "format-on" comments to mark areas without formatting * fix typo * added FormatterIdentLevel, FormatterMergeEmptyLines cfg entry better line splits for dicts/arrays * added several spacing options. the current setting list is now: //LineWidth FormatterLineWidth 80 // keep original keyword spelling FormatterKeepKeywords 0 // number of spaces for ident FormatterIdentLevel 2 // multiple newlines get merged to a single FormatterMergeEmptyLines 1 // space between emtpy parenthesis eg foo() vs foo( ) FormatterEmptyParenthesisSpacing 0 // space between emtpy brackets eg struct{} vs struct{ } FormatterEmptyBracketSpacing 0 // space after/before parenthesis in conditionals // eg if ( true ) vs if (true) FormatterConditionalParenthesisSpacing 1 // space after/before parenthesis // eg foo( true ) vs foo(true) FormatterParenthesisSpacing 1 // space after/before brackets // eg array{ true } vs array{true} FormatterBracketSpacing 1 // add space after delimiter comma or semi in for loops // eg {1, 2, 3} vs {1,2,3} FormatterDelimiterSpacing 1 // add space around assignment // eg a := 1; vs a:=1; FormatterAssignmentSpacing 1 // add space around comparison // eg a == 1 vs a==1 FormatterComparisonSpacing 1 // add space around operations // eg a + 1 vs a+1 FormatterOperatorSpacing 1 // use \r\n as newline instead of \n FormatterWindowsLineEndings 0 * added tab support // use tabs instead of spaces FormatterUseTabs 0 // tab width FormatterTabWidth 4 * extended example ecompile.cfg with formatter settings * cleanup * program args comma is optional... fixed line comments in group splitting * since tokenids are now correct no more guessing for linecomments needed * comments use as start tokenid the whitespace token if its on the same line * splitted processing from linebuilding * renamed TokenPart to FmtToken better matches the purpose. Comments get directly stored as FmtToken started with a context enum * better(?) formatting for groups * fix eof rawlines added check that all comments/rawlines got parsed * const correctness * datatype adapted to antlr * fixed warnings * added InsertNewlineAtEOF * add newline at the end if the original file had one dont strip comment whitespace if its somejind of "header block" use the defined lineending for /* */ comments * docs * \r\n is default on windows \n otherwise * fixed warning --------- Co-authored-by: Kevin Eady <8634912+KevinEady@users.noreply.github.com>
2024-02-26 21:21:44 +01:00
Position calculate_end_position( const antlr4::Token* symbol )
{
if ( !symbol )
{
return Position{ 0, 0, 0 };
}
auto line = symbol->getLine();
auto character = symbol->getCharPositionInLine() + 1;
const auto& str = symbol->getText();
const auto size = str.size();
for ( size_t i = 0; i < size; i++ )
{
if ( str[i] == '\r' && i + 1 < size && str[i + 1] == '\n' )
{
++line;
character = 1;
}
else if ( str[i] == '\r' )
{
++line;
character = 1;
}
else if ( str[i] == '\n' )
{
++line;
character = 1;
}
else
++character;
}
return Position{ line, character, symbol->getTokenIndex() };
}
Range::Range( Position start, Position end ) : start( std::move( start ) ), end( std::move( end ) )
{
}
Range::Range( const antlr4::ParserRuleContext& ctx )
: start( Position{ ctx.getStart()->getLine(), ctx.getStart()->getCharPositionInLine() + 1,
ctx.getStart()->getTokenIndex() } ),
end( calculate_end_position( ctx.getStop() ) )
{
}
Range::Range( const antlr4::tree::TerminalNode& ctx )
: start( Position{ ctx.getSymbol()->getLine(), ctx.getSymbol()->getCharPositionInLine() + 1,
ctx.getSymbol()->getTokenIndex() } ),
end( calculate_end_position( ctx.getSymbol() ) )
{
}
Range::Range( const antlr4::Token* token )
: start( Position{ token->getLine(), token->getCharPositionInLine() + 1,
token->getTokenIndex() } ),
end( calculate_end_position( token ) )
{
}
SourceLocation::SourceLocation( const SourceFileIdentifier* source_file_identifier,
"Preview/Initial"- Version sourcecode formatting feature (#626) * Squash only prettify changes from escript_formating_try * support of "format-off" / "format-on" comments to mark areas without formatting * fix typo * added FormatterIdentLevel, FormatterMergeEmptyLines cfg entry better line splits for dicts/arrays * added several spacing options. the current setting list is now: //LineWidth FormatterLineWidth 80 // keep original keyword spelling FormatterKeepKeywords 0 // number of spaces for ident FormatterIdentLevel 2 // multiple newlines get merged to a single FormatterMergeEmptyLines 1 // space between emtpy parenthesis eg foo() vs foo( ) FormatterEmptyParenthesisSpacing 0 // space between emtpy brackets eg struct{} vs struct{ } FormatterEmptyBracketSpacing 0 // space after/before parenthesis in conditionals // eg if ( true ) vs if (true) FormatterConditionalParenthesisSpacing 1 // space after/before parenthesis // eg foo( true ) vs foo(true) FormatterParenthesisSpacing 1 // space after/before brackets // eg array{ true } vs array{true} FormatterBracketSpacing 1 // add space after delimiter comma or semi in for loops // eg {1, 2, 3} vs {1,2,3} FormatterDelimiterSpacing 1 // add space around assignment // eg a := 1; vs a:=1; FormatterAssignmentSpacing 1 // add space around comparison // eg a == 1 vs a==1 FormatterComparisonSpacing 1 // add space around operations // eg a + 1 vs a+1 FormatterOperatorSpacing 1 // use \r\n as newline instead of \n FormatterWindowsLineEndings 0 * added tab support // use tabs instead of spaces FormatterUseTabs 0 // tab width FormatterTabWidth 4 * extended example ecompile.cfg with formatter settings * cleanup * program args comma is optional... fixed line comments in group splitting * since tokenids are now correct no more guessing for linecomments needed * comments use as start tokenid the whitespace token if its on the same line * splitted processing from linebuilding * renamed TokenPart to FmtToken better matches the purpose. Comments get directly stored as FmtToken started with a context enum * better(?) formatting for groups * fix eof rawlines added check that all comments/rawlines got parsed * const correctness * datatype adapted to antlr * fixed warnings * added InsertNewlineAtEOF * add newline at the end if the original file had one dont strip comment whitespace if its somejind of "header block" use the defined lineending for /* */ comments * docs * \r\n is default on windows \n otherwise * fixed warning --------- Co-authored-by: Kevin Eady <8634912+KevinEady@users.noreply.github.com>
2024-02-26 21:21:44 +01:00
size_t line_number, size_t character_column )
: source_file_identifier( source_file_identifier ),
"Preview/Initial"- Version sourcecode formatting feature (#626) * Squash only prettify changes from escript_formating_try * support of "format-off" / "format-on" comments to mark areas without formatting * fix typo * added FormatterIdentLevel, FormatterMergeEmptyLines cfg entry better line splits for dicts/arrays * added several spacing options. the current setting list is now: //LineWidth FormatterLineWidth 80 // keep original keyword spelling FormatterKeepKeywords 0 // number of spaces for ident FormatterIdentLevel 2 // multiple newlines get merged to a single FormatterMergeEmptyLines 1 // space between emtpy parenthesis eg foo() vs foo( ) FormatterEmptyParenthesisSpacing 0 // space between emtpy brackets eg struct{} vs struct{ } FormatterEmptyBracketSpacing 0 // space after/before parenthesis in conditionals // eg if ( true ) vs if (true) FormatterConditionalParenthesisSpacing 1 // space after/before parenthesis // eg foo( true ) vs foo(true) FormatterParenthesisSpacing 1 // space after/before brackets // eg array{ true } vs array{true} FormatterBracketSpacing 1 // add space after delimiter comma or semi in for loops // eg {1, 2, 3} vs {1,2,3} FormatterDelimiterSpacing 1 // add space around assignment // eg a := 1; vs a:=1; FormatterAssignmentSpacing 1 // add space around comparison // eg a == 1 vs a==1 FormatterComparisonSpacing 1 // add space around operations // eg a + 1 vs a+1 FormatterOperatorSpacing 1 // use \r\n as newline instead of \n FormatterWindowsLineEndings 0 * added tab support // use tabs instead of spaces FormatterUseTabs 0 // tab width FormatterTabWidth 4 * extended example ecompile.cfg with formatter settings * cleanup * program args comma is optional... fixed line comments in group splitting * since tokenids are now correct no more guessing for linecomments needed * comments use as start tokenid the whitespace token if its on the same line * splitted processing from linebuilding * renamed TokenPart to FmtToken better matches the purpose. Comments get directly stored as FmtToken started with a context enum * better(?) formatting for groups * fix eof rawlines added check that all comments/rawlines got parsed * const correctness * datatype adapted to antlr * fixed warnings * added InsertNewlineAtEOF * add newline at the end if the original file had one dont strip comment whitespace if its somejind of "header block" use the defined lineending for /* */ comments * docs * \r\n is default on windows \n otherwise * fixed warning --------- Co-authored-by: Kevin Eady <8634912+KevinEady@users.noreply.github.com>
2024-02-26 21:21:44 +01:00
range( Position{ line_number, character_column, 0 },
Position{ std::numeric_limits<size_t>::max(), std::numeric_limits<size_t>::max(),
std::numeric_limits<size_t>::max() } )
{
}
SourceLocation::SourceLocation( const SourceFileIdentifier* source_file_identifier,
"Preview/Initial"- Version sourcecode formatting feature (#626) * Squash only prettify changes from escript_formating_try * support of "format-off" / "format-on" comments to mark areas without formatting * fix typo * added FormatterIdentLevel, FormatterMergeEmptyLines cfg entry better line splits for dicts/arrays * added several spacing options. the current setting list is now: //LineWidth FormatterLineWidth 80 // keep original keyword spelling FormatterKeepKeywords 0 // number of spaces for ident FormatterIdentLevel 2 // multiple newlines get merged to a single FormatterMergeEmptyLines 1 // space between emtpy parenthesis eg foo() vs foo( ) FormatterEmptyParenthesisSpacing 0 // space between emtpy brackets eg struct{} vs struct{ } FormatterEmptyBracketSpacing 0 // space after/before parenthesis in conditionals // eg if ( true ) vs if (true) FormatterConditionalParenthesisSpacing 1 // space after/before parenthesis // eg foo( true ) vs foo(true) FormatterParenthesisSpacing 1 // space after/before brackets // eg array{ true } vs array{true} FormatterBracketSpacing 1 // add space after delimiter comma or semi in for loops // eg {1, 2, 3} vs {1,2,3} FormatterDelimiterSpacing 1 // add space around assignment // eg a := 1; vs a:=1; FormatterAssignmentSpacing 1 // add space around comparison // eg a == 1 vs a==1 FormatterComparisonSpacing 1 // add space around operations // eg a + 1 vs a+1 FormatterOperatorSpacing 1 // use \r\n as newline instead of \n FormatterWindowsLineEndings 0 * added tab support // use tabs instead of spaces FormatterUseTabs 0 // tab width FormatterTabWidth 4 * extended example ecompile.cfg with formatter settings * cleanup * program args comma is optional... fixed line comments in group splitting * since tokenids are now correct no more guessing for linecomments needed * comments use as start tokenid the whitespace token if its on the same line * splitted processing from linebuilding * renamed TokenPart to FmtToken better matches the purpose. Comments get directly stored as FmtToken started with a context enum * better(?) formatting for groups * fix eof rawlines added check that all comments/rawlines got parsed * const correctness * datatype adapted to antlr * fixed warnings * added InsertNewlineAtEOF * add newline at the end if the original file had one dont strip comment whitespace if its somejind of "header block" use the defined lineending for /* */ comments * docs * \r\n is default on windows \n otherwise * fixed warning --------- Co-authored-by: Kevin Eady <8634912+KevinEady@users.noreply.github.com>
2024-02-26 21:21:44 +01:00
const Range& range )
: source_file_identifier( source_file_identifier ), range( range )
{
}
SourceLocation::SourceLocation( const SourceFileIdentifier* source_file_identifier,
"Preview/Initial"- Version sourcecode formatting feature (#626) * Squash only prettify changes from escript_formating_try * support of "format-off" / "format-on" comments to mark areas without formatting * fix typo * added FormatterIdentLevel, FormatterMergeEmptyLines cfg entry better line splits for dicts/arrays * added several spacing options. the current setting list is now: //LineWidth FormatterLineWidth 80 // keep original keyword spelling FormatterKeepKeywords 0 // number of spaces for ident FormatterIdentLevel 2 // multiple newlines get merged to a single FormatterMergeEmptyLines 1 // space between emtpy parenthesis eg foo() vs foo( ) FormatterEmptyParenthesisSpacing 0 // space between emtpy brackets eg struct{} vs struct{ } FormatterEmptyBracketSpacing 0 // space after/before parenthesis in conditionals // eg if ( true ) vs if (true) FormatterConditionalParenthesisSpacing 1 // space after/before parenthesis // eg foo( true ) vs foo(true) FormatterParenthesisSpacing 1 // space after/before brackets // eg array{ true } vs array{true} FormatterBracketSpacing 1 // add space after delimiter comma or semi in for loops // eg {1, 2, 3} vs {1,2,3} FormatterDelimiterSpacing 1 // add space around assignment // eg a := 1; vs a:=1; FormatterAssignmentSpacing 1 // add space around comparison // eg a == 1 vs a==1 FormatterComparisonSpacing 1 // add space around operations // eg a + 1 vs a+1 FormatterOperatorSpacing 1 // use \r\n as newline instead of \n FormatterWindowsLineEndings 0 * added tab support // use tabs instead of spaces FormatterUseTabs 0 // tab width FormatterTabWidth 4 * extended example ecompile.cfg with formatter settings * cleanup * program args comma is optional... fixed line comments in group splitting * since tokenids are now correct no more guessing for linecomments needed * comments use as start tokenid the whitespace token if its on the same line * splitted processing from linebuilding * renamed TokenPart to FmtToken better matches the purpose. Comments get directly stored as FmtToken started with a context enum * better(?) formatting for groups * fix eof rawlines added check that all comments/rawlines got parsed * const correctness * datatype adapted to antlr * fixed warnings * added InsertNewlineAtEOF * add newline at the end if the original file had one dont strip comment whitespace if its somejind of "header block" use the defined lineending for /* */ comments * docs * \r\n is default on windows \n otherwise * fixed warning --------- Co-authored-by: Kevin Eady <8634912+KevinEady@users.noreply.github.com>
2024-02-26 21:21:44 +01:00
const antlr4::ParserRuleContext& ctx )
: source_file_identifier( source_file_identifier ), range( ctx )
{
}
SourceLocation::SourceLocation( const SourceFileIdentifier* source_file_identifier,
const antlr4::tree::TerminalNode& ctx )
: source_file_identifier( source_file_identifier ), range( ctx )
{
}
bool Range::contains( const Position& position ) const
{
return contains( position.line_number, position.character_column );
}
bool Range::contains( size_t line_number, size_t character_column ) const
{
if ( line_number < start.line_number || line_number > end.line_number )
{
return false;
}
if ( line_number == start.line_number && character_column < start.character_column )
{
return false;
}
if ( line_number == end.line_number && character_column > end.character_column )
{
return false;
}
return true;
}
bool Range::contains( const Range& otherRange ) const
{
"Preview/Initial"- Version sourcecode formatting feature (#626) * Squash only prettify changes from escript_formating_try * support of "format-off" / "format-on" comments to mark areas without formatting * fix typo * added FormatterIdentLevel, FormatterMergeEmptyLines cfg entry better line splits for dicts/arrays * added several spacing options. the current setting list is now: //LineWidth FormatterLineWidth 80 // keep original keyword spelling FormatterKeepKeywords 0 // number of spaces for ident FormatterIdentLevel 2 // multiple newlines get merged to a single FormatterMergeEmptyLines 1 // space between emtpy parenthesis eg foo() vs foo( ) FormatterEmptyParenthesisSpacing 0 // space between emtpy brackets eg struct{} vs struct{ } FormatterEmptyBracketSpacing 0 // space after/before parenthesis in conditionals // eg if ( true ) vs if (true) FormatterConditionalParenthesisSpacing 1 // space after/before parenthesis // eg foo( true ) vs foo(true) FormatterParenthesisSpacing 1 // space after/before brackets // eg array{ true } vs array{true} FormatterBracketSpacing 1 // add space after delimiter comma or semi in for loops // eg {1, 2, 3} vs {1,2,3} FormatterDelimiterSpacing 1 // add space around assignment // eg a := 1; vs a:=1; FormatterAssignmentSpacing 1 // add space around comparison // eg a == 1 vs a==1 FormatterComparisonSpacing 1 // add space around operations // eg a + 1 vs a+1 FormatterOperatorSpacing 1 // use \r\n as newline instead of \n FormatterWindowsLineEndings 0 * added tab support // use tabs instead of spaces FormatterUseTabs 0 // tab width FormatterTabWidth 4 * extended example ecompile.cfg with formatter settings * cleanup * program args comma is optional... fixed line comments in group splitting * since tokenids are now correct no more guessing for linecomments needed * comments use as start tokenid the whitespace token if its on the same line * splitted processing from linebuilding * renamed TokenPart to FmtToken better matches the purpose. Comments get directly stored as FmtToken started with a context enum * better(?) formatting for groups * fix eof rawlines added check that all comments/rawlines got parsed * const correctness * datatype adapted to antlr * fixed warnings * added InsertNewlineAtEOF * add newline at the end if the original file had one dont strip comment whitespace if its somejind of "header block" use the defined lineending for /* */ comments * docs * \r\n is default on windows \n otherwise * fixed warning --------- Co-authored-by: Kevin Eady <8634912+KevinEady@users.noreply.github.com>
2024-02-26 21:21:44 +01:00
if ( otherRange.start.line_number < start.line_number ||
otherRange.end.line_number < start.line_number )
{
return false;
}
if ( otherRange.start.line_number > end.line_number ||
otherRange.end.line_number > end.line_number )
{
return false;
}
if ( otherRange.start.line_number == start.line_number &&
otherRange.start.character_column < start.character_column )
{
return false;
}
if ( otherRange.end.line_number == end.line_number &&
otherRange.end.character_column > end.character_column )
{
return false;
}
return true;
}
void SourceLocation::debug( const std::string& msg ) const
{
ERROR_PRINTLN( "{}: {}", ( *this ), msg );
}
void SourceLocation::internal_error( const std::string& msg ) const
{
ERROR_PRINTLN( "{}: {}", ( *this ), msg );
throw std::runtime_error( msg );
}
void SourceLocation::internal_error( const std::string& msg, const SourceLocation& related ) const
{
ERROR_PRINTLN( "{}: {}\n See also: {}", ( *this ), msg, related );
throw std::runtime_error( msg );
}
std::string SourceLocation::getSourceLine() const
{
std::string lines;
if ( !range.start.line_number )
return {};
auto& content = source_file_identifier->getLines();
for ( size_t i = range.start.line_number - 1; i < range.end.line_number && i < content.size();
++i )
{
if ( !lines.empty() )
lines += '\n';
lines += content[i];
}
return lines;
}
} // namespace Pol::Bscript::Compiler
fmt::format_context::iterator fmt::formatter<Pol::Bscript::Compiler::SourceLocation>::format(
const Pol::Bscript::Compiler::SourceLocation& l, fmt::format_context& ctx ) const
{
std::string tmp = l.source_file_identifier->pathname;
"Preview/Initial"- Version sourcecode formatting feature (#626) * Squash only prettify changes from escript_formating_try * support of "format-off" / "format-on" comments to mark areas without formatting * fix typo * added FormatterIdentLevel, FormatterMergeEmptyLines cfg entry better line splits for dicts/arrays * added several spacing options. the current setting list is now: //LineWidth FormatterLineWidth 80 // keep original keyword spelling FormatterKeepKeywords 0 // number of spaces for ident FormatterIdentLevel 2 // multiple newlines get merged to a single FormatterMergeEmptyLines 1 // space between emtpy parenthesis eg foo() vs foo( ) FormatterEmptyParenthesisSpacing 0 // space between emtpy brackets eg struct{} vs struct{ } FormatterEmptyBracketSpacing 0 // space after/before parenthesis in conditionals // eg if ( true ) vs if (true) FormatterConditionalParenthesisSpacing 1 // space after/before parenthesis // eg foo( true ) vs foo(true) FormatterParenthesisSpacing 1 // space after/before brackets // eg array{ true } vs array{true} FormatterBracketSpacing 1 // add space after delimiter comma or semi in for loops // eg {1, 2, 3} vs {1,2,3} FormatterDelimiterSpacing 1 // add space around assignment // eg a := 1; vs a:=1; FormatterAssignmentSpacing 1 // add space around comparison // eg a == 1 vs a==1 FormatterComparisonSpacing 1 // add space around operations // eg a + 1 vs a+1 FormatterOperatorSpacing 1 // use \r\n as newline instead of \n FormatterWindowsLineEndings 0 * added tab support // use tabs instead of spaces FormatterUseTabs 0 // tab width FormatterTabWidth 4 * extended example ecompile.cfg with formatter settings * cleanup * program args comma is optional... fixed line comments in group splitting * since tokenids are now correct no more guessing for linecomments needed * comments use as start tokenid the whitespace token if its on the same line * splitted processing from linebuilding * renamed TokenPart to FmtToken better matches the purpose. Comments get directly stored as FmtToken started with a context enum * better(?) formatting for groups * fix eof rawlines added check that all comments/rawlines got parsed * const correctness * datatype adapted to antlr * fixed warnings * added InsertNewlineAtEOF * add newline at the end if the original file had one dont strip comment whitespace if its somejind of "header block" use the defined lineending for /* */ comments * docs * \r\n is default on windows \n otherwise * fixed warning --------- Co-authored-by: Kevin Eady <8634912+KevinEady@users.noreply.github.com>
2024-02-26 21:21:44 +01:00
if ( l.range.start.line_number || l.range.start.character_column )
fmt::format_to( std::back_inserter( tmp ), ":{}:{}", l.range.start.line_number,
l.range.start.character_column );
return fmt::formatter<std::string>::format( tmp, ctx );
}