use crate::*; use log::LogLevel; use SemanticTokenVariant as SemVar; use SemanticParseError as SemErr; use SyntacticParseError as SynErr; /// Print all errors found in the semantic tokens, including those inside macro /// definitions. Returns true if at least one error was printed. pub fn print_semantic_errors(semantic_tokens: &[SemanticToken], source_code: &str) -> bool { let mut found_error = false; for semantic_token in semantic_tokens { match &semantic_token.variant { SemVar::Error(err) => { let context = Context { source_code: source_code, source: &semantic_token.source, }; found_error = true; print_semantic_error(&err, context) } SemVar::MacroDefinition(definition) => { for body_token in &definition.body_tokens { if let SemVar::Error(err) = &body_token.variant { let context = Context { source_code: source_code, source: &body_token.source, }; found_error = true; print_semantic_error(err, context) } } } _ => (), } } return found_error; } fn print_semantic_error(error: &SemanticParseError, context: Context) { let message = get_message_for_semantic_error(error); report_source_issue(LogLevel::Error, &context, &message); } fn get_message_for_semantic_error(error: &SemanticParseError) -> String { match error { SemErr::LabelDefinitionInMacroDefinition => format!("Label cannot be defined inside a macro"), SemErr::MacroDefinitionInMacroDefinition => format!("Macro cannot be defined inside a macro"), SemErr::StrayMacroTerminator => format!("Macro definition terminator is missing a macro definition"), SemErr::StrayBlockClose => format!("Block was not opened, add a '{{' character to open"), SemErr::UnclosedBlock => format!("Block was not closed, add a '}}' character to close"), SemErr::UndefinedSymbol(name) => format!("Undefined symbol, no label or macro has been defined with the name {name:?}"), SemErr::RedefinedSymbol((_, source)) => format!("Redefined symbol, first defined at {}", source.location()), SemErr::MacroInvocationBeforeDefinition((_, source)) => format!("Macro used before definition, definition is at {}", source.location()), SemErr:: SyntaxError(syntax_error) => match syntax_error { SynErr::UnterminatedComment => format!("Unclosed comment, add a ')' character to close"), SynErr::UnterminatedRawString => format!("Unclosed string, add a ' character to close"), SynErr::UnterminatedNullString => format!("Unclosed string, add a \" character to close"), SynErr::InvalidPaddingValue(_) => format!("Padding value must be two or four hexadecimal digits"), } } }