2020-03-14 00:07:44 +02:00
/*
* Copyright ( c ) 2020 , the SerenityOS developers .
*
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-02-07 14:40:36 +01:00
bool SyntaxHighlighter : : is_identifier ( void * token ) const
2020-03-12 17:23:54 +02:00
{
2020-09-28 16:21:25 +03:00
auto cpp_token = static_cast < Cpp : : Token : : Type > ( reinterpret_cast < size_t > ( token ) ) ;
return cpp_token = = Cpp : : Token : : Type : : Identifier ;
2020-03-12 17:23:54 +02:00
}
2021-02-07 14:40:36 +01:00
bool SyntaxHighlighter : : is_navigatable ( void * token ) const
2020-03-12 17:23:54 +02:00
{
2020-09-28 16:21:25 +03:00
auto cpp_token = static_cast < Cpp : : Token : : Type > ( reinterpret_cast < size_t > ( token ) ) ;
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
auto tokens = lexer . lex ( ) ;
Vector < GUI : : TextDocumentSpan > spans ;
for ( auto & token : tokens ) {
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 ;
span . data = reinterpret_cast < void * > ( token . type ( ) ) ;
2020-02-07 20:07:15 +01:00
spans . append ( span ) ;
}
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-02-07 14:40:36 +01:00
Vector < SyntaxHighlighter : : MatchingTokenPair > SyntaxHighlighter : : matching_token_pairs ( ) 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 ( ) ) {
2020-09-28 16:21:25 +03:00
pairs . append ( { reinterpret_cast < void * > ( Cpp : : Token : : Type : : LeftCurly ) , reinterpret_cast < void * > ( Cpp : : Token : : Type : : RightCurly ) } ) ;
pairs . append ( { reinterpret_cast < void * > ( Cpp : : Token : : Type : : LeftParen ) , reinterpret_cast < void * > ( Cpp : : Token : : Type : : RightParen ) } ) ;
pairs . append ( { reinterpret_cast < void * > ( Cpp : : Token : : Type : : LeftBracket ) , reinterpret_cast < void * > ( Cpp : : Token : : Type : : RightBracket ) } ) ;
2020-02-07 20:07:15 +01:00
}
2020-03-13 00:51:02 +02:00
return pairs ;
}
2021-02-07 14:40:36 +01:00
bool SyntaxHighlighter : : token_types_equal ( void * token1 , void * token2 ) const
2020-03-13 00:51:02 +02:00
{
2020-09-28 16:21:25 +03:00
return static_cast < Cpp : : Token : : Type > ( reinterpret_cast < size_t > ( token1 ) ) = = static_cast < Cpp : : Token : : Type > ( reinterpret_cast < size_t > ( token2 ) ) ;
2020-02-07 20:07:15 +01:00
}
2021-02-07 14:40:36 +01:00
SyntaxHighlighter : : ~ SyntaxHighlighter ( )
2020-02-07 20:07:15 +01:00
{
}
}