2020-03-14 00:07:44 +02:00
/*
2022-02-26 10:30:59 -07:00
* Copyright ( c ) 2020 - 2022 , the SerenityOS developers .
2020-03-14 00:07:44 +02:00
*
2021-04-22 01:24:48 -07:00
* SPDX - License - Identifier : BSD - 2 - Clause
2020-03-14 00:07:44 +02:00
*/
2021-01-16 15:51:56 +01:00
# include <AK/Debug.h>
2020-09-28 16:21:25 +03:00
# include <LibCpp/Lexer.h>
2021-02-07 14:40:36 +01:00
# include <LibCpp/SyntaxHighlighter.h>
2020-02-07 20:07:15 +01:00
# include <LibGUI/TextEditor.h>
2020-02-15 00:24:14 +01:00
# include <LibGfx/Font.h>
2020-03-16 01:05:06 +02:00
# include <LibGfx/Palette.h>
2020-02-07 20:07:15 +01:00
2021-02-07 14:40:36 +01:00
namespace Cpp {
2020-02-07 20:07:15 +01:00
2021-06-03 23:17:34 +02:00
static Syntax : : TextStyle style_for_token_type ( Gfx : : Palette const & palette , Cpp : : Token : : Type type )
2020-02-07 20:07:15 +01:00
{
switch ( type ) {
2020-09-28 16:21:25 +03:00
case Cpp : : Token : : Type : : Keyword :
2020-12-28 15:51:43 +01:00
return { palette . syntax_keyword ( ) , true } ;
2020-09-28 16:21:25 +03:00
case Cpp : : Token : : Type : : KnownType :
2020-12-28 15:51:43 +01:00
return { palette . syntax_type ( ) , true } ;
2020-09-28 16:21:25 +03:00
case Cpp : : Token : : Type : : Identifier :
2020-12-28 15:51:43 +01:00
return { palette . syntax_identifier ( ) , false } ;
2020-09-28 16:21:25 +03:00
case Cpp : : Token : : Type : : DoubleQuotedString :
case Cpp : : Token : : Type : : SingleQuotedString :
case Cpp : : Token : : Type : : RawString :
2020-12-28 15:51:43 +01:00
return { palette . syntax_string ( ) , false } ;
2020-09-28 16:21:25 +03:00
case Cpp : : Token : : Type : : Integer :
case Cpp : : Token : : Type : : Float :
2020-12-28 15:51:43 +01:00
return { palette . syntax_number ( ) , false } ;
2020-09-28 16:21:25 +03:00
case Cpp : : Token : : Type : : IncludePath :
2020-12-28 15:51:43 +01:00
return { palette . syntax_preprocessor_value ( ) , false } ;
2020-09-28 16:21:25 +03:00
case Cpp : : Token : : Type : : EscapeSequence :
2020-12-28 15:51:43 +01:00
return { palette . syntax_keyword ( ) , true } ;
2020-09-28 16:21:25 +03:00
case Cpp : : Token : : Type : : PreprocessorStatement :
case Cpp : : Token : : Type : : IncludeStatement :
2020-12-28 15:51:43 +01:00
return { palette . syntax_preprocessor_statement ( ) , false } ;
2020-09-28 16:21:25 +03:00
case Cpp : : Token : : Type : : Comment :
2020-12-28 15:51:43 +01:00
return { palette . syntax_comment ( ) , false } ;
2020-02-07 20:07:15 +01:00
default :
2020-12-28 15:51:43 +01:00
return { palette . base_text ( ) , false } ;
2020-02-07 20:07:15 +01:00
}
}
2021-06-07 12:03:09 +04:30
bool SyntaxHighlighter : : is_identifier ( u64 token ) const
2020-03-12 17:23:54 +02:00
{
2021-06-07 12:03:09 +04:30
auto cpp_token = static_cast < Cpp : : Token : : Type > ( token ) ;
2020-09-28 16:21:25 +03:00
return cpp_token = = Cpp : : Token : : Type : : Identifier ;
2020-03-12 17:23:54 +02:00
}
2021-06-07 12:03:09 +04:30
bool SyntaxHighlighter : : is_navigatable ( u64 token ) const
2020-03-12 17:23:54 +02:00
{
2021-06-07 12:03:09 +04:30
auto cpp_token = static_cast < Cpp : : Token : : Type > ( token ) ;
2020-09-28 16:21:25 +03:00
return cpp_token = = Cpp : : Token : : Type : : IncludePath ;
2020-03-12 17:23:54 +02:00
}
2021-06-03 23:17:34 +02:00
void SyntaxHighlighter : : rehighlight ( Palette const & palette )
2020-02-07 20:07:15 +01:00
{
2021-02-07 16:56:02 +01:00
auto text = m_client - > get_text ( ) ;
2020-09-28 16:21:25 +03:00
Cpp : : Lexer lexer ( text ) ;
2020-02-07 20:07:15 +01:00
Vector < GUI : : TextDocumentSpan > spans ;
2021-08-21 16:48:21 +03:00
lexer . lex_iterable ( [ & ] ( auto token ) {
2021-06-04 21:12:19 +02:00
// FIXME: The +1 for the token end column is a quick hack due to not wanting to modify the lexer (which is also used by the parser). Maybe there's a better way to do this.
dbgln_if ( SYNTAX_HIGHLIGHTING_DEBUG , " {} @ {}:{} - {}:{} " , token . type_as_string ( ) , token . start ( ) . line , token . start ( ) . column , token . end ( ) . line , token . end ( ) . column + 1 ) ;
2020-02-07 20:07:15 +01:00
GUI : : TextDocumentSpan span ;
2021-03-12 12:46:40 +02:00
span . range . set_start ( { token . start ( ) . line , token . start ( ) . column } ) ;
2021-06-04 21:12:19 +02:00
span . range . set_end ( { token . end ( ) . line , token . end ( ) . column + 1 } ) ;
2021-03-12 12:46:40 +02:00
auto style = style_for_token_type ( palette , token . type ( ) ) ;
2021-01-02 20:31:45 +01:00
span . attributes . color = style . color ;
span . attributes . bold = style . bold ;
2021-03-12 12:46:40 +02:00
span . is_skippable = token . type ( ) = = Cpp : : Token : : Type : : Whitespace ;
2021-06-07 12:03:09 +04:30
span . data = static_cast < u64 > ( token . type ( ) ) ;
2020-02-07 20:07:15 +01:00
spans . append ( span ) ;
2021-08-21 16:48:21 +03:00
} ) ;
2021-02-07 16:56:02 +01:00
m_client - > do_set_spans ( move ( spans ) ) ;
2020-02-07 20:07:15 +01:00
m_has_brace_buddies = false ;
highlight_matching_token_pair ( ) ;
2021-02-07 16:56:02 +01:00
m_client - > do_update ( ) ;
2020-02-07 20:07:15 +01:00
}
2021-06-07 12:03:09 +04:30
Vector < SyntaxHighlighter : : MatchingTokenPair > SyntaxHighlighter : : matching_token_pairs_impl ( ) const
2020-02-07 20:07:15 +01:00
{
2020-03-13 00:51:02 +02:00
static Vector < SyntaxHighlighter : : MatchingTokenPair > pairs ;
if ( pairs . is_empty ( ) ) {
2021-06-07 12:03:09 +04:30
pairs . append ( { static_cast < u64 > ( Cpp : : Token : : Type : : LeftCurly ) , static_cast < u64 > ( Cpp : : Token : : Type : : RightCurly ) } ) ;
pairs . append ( { static_cast < u64 > ( Cpp : : Token : : Type : : LeftParen ) , static_cast < u64 > ( Cpp : : Token : : Type : : RightParen ) } ) ;
pairs . append ( { static_cast < u64 > ( Cpp : : Token : : Type : : LeftBracket ) , static_cast < u64 > ( Cpp : : Token : : Type : : RightBracket ) } ) ;
2020-02-07 20:07:15 +01:00
}
2020-03-13 00:51:02 +02:00
return pairs ;
}
2021-06-07 12:03:09 +04:30
bool SyntaxHighlighter : : token_types_equal ( u64 token1 , u64 token2 ) const
2020-03-13 00:51:02 +02:00
{
2021-06-07 12:03:09 +04:30
return static_cast < Cpp : : Token : : Type > ( token1 ) = = static_cast < Cpp : : Token : : Type > ( token2 ) ;
2020-02-07 20:07:15 +01:00
}
}