xref: /llvm-project/mlir/lib/Query/Matcher/Diagnostics.cpp (revision 58b44c8102afb0e76d1cb70d4a5d089f70d2f657)
102d9f4d1SDevajith //===- Diagnostic.cpp -----------------------------------------------------===//
202d9f4d1SDevajith //
302d9f4d1SDevajith // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
402d9f4d1SDevajith // See https://llvm.org/LICENSE.txt for license information.
502d9f4d1SDevajith // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
602d9f4d1SDevajith //
702d9f4d1SDevajith //===----------------------------------------------------------------------===//
802d9f4d1SDevajith 
902d9f4d1SDevajith #include "Diagnostics.h"
1002d9f4d1SDevajith #include "mlir/Query/Matcher/ErrorBuilder.h"
1102d9f4d1SDevajith 
1202d9f4d1SDevajith namespace mlir::query::matcher::internal {
1302d9f4d1SDevajith 
1402d9f4d1SDevajith Diagnostics::ArgStream &
operator <<(const llvm::Twine & arg)1502d9f4d1SDevajith Diagnostics::ArgStream::operator<<(const llvm::Twine &arg) {
1602d9f4d1SDevajith   out->push_back(arg.str());
1702d9f4d1SDevajith   return *this;
1802d9f4d1SDevajith }
1902d9f4d1SDevajith 
addError(SourceRange range,ErrorType error)2002d9f4d1SDevajith Diagnostics::ArgStream Diagnostics::addError(SourceRange range,
2102d9f4d1SDevajith                                              ErrorType error) {
2202d9f4d1SDevajith   errorValues.emplace_back();
2302d9f4d1SDevajith   ErrorContent &last = errorValues.back();
2402d9f4d1SDevajith   last.contextStack = contextStack;
2502d9f4d1SDevajith   last.messages.emplace_back();
2602d9f4d1SDevajith   last.messages.back().range = range;
2702d9f4d1SDevajith   last.messages.back().type = error;
2802d9f4d1SDevajith   return ArgStream(&last.messages.back().args);
2902d9f4d1SDevajith }
3002d9f4d1SDevajith 
errorTypeToFormatString(ErrorType type)3102d9f4d1SDevajith static llvm::StringRef errorTypeToFormatString(ErrorType type) {
3202d9f4d1SDevajith   switch (type) {
3302d9f4d1SDevajith   case ErrorType::RegistryMatcherNotFound:
3402d9f4d1SDevajith     return "Matcher not found: $0";
3502d9f4d1SDevajith   case ErrorType::RegistryWrongArgCount:
3602d9f4d1SDevajith     return "Incorrect argument count. (Expected = $0) != (Actual = $1)";
3702d9f4d1SDevajith   case ErrorType::RegistryWrongArgType:
3802d9f4d1SDevajith     return "Incorrect type for arg $0. (Expected = $1) != (Actual = $2)";
3902d9f4d1SDevajith   case ErrorType::RegistryValueNotFound:
4002d9f4d1SDevajith     return "Value not found: $0";
41*58b44c81SJacques Pienaar   case ErrorType::RegistryNotBindable:
42*58b44c81SJacques Pienaar     return "Matcher does not support binding.";
4302d9f4d1SDevajith 
4402d9f4d1SDevajith   case ErrorType::ParserStringError:
4502d9f4d1SDevajith     return "Error parsing string token: <$0>";
4602d9f4d1SDevajith   case ErrorType::ParserNoOpenParen:
4702d9f4d1SDevajith     return "Error parsing matcher. Found token <$0> while looking for '('.";
4802d9f4d1SDevajith   case ErrorType::ParserNoCloseParen:
4902d9f4d1SDevajith     return "Error parsing matcher. Found end-of-code while looking for ')'.";
5002d9f4d1SDevajith   case ErrorType::ParserNoComma:
5102d9f4d1SDevajith     return "Error parsing matcher. Found token <$0> while looking for ','.";
5202d9f4d1SDevajith   case ErrorType::ParserNoCode:
5302d9f4d1SDevajith     return "End of code found while looking for token.";
5402d9f4d1SDevajith   case ErrorType::ParserNotAMatcher:
5502d9f4d1SDevajith     return "Input value is not a matcher expression.";
5602d9f4d1SDevajith   case ErrorType::ParserInvalidToken:
5702d9f4d1SDevajith     return "Invalid token <$0> found when looking for a value.";
5802d9f4d1SDevajith   case ErrorType::ParserTrailingCode:
5902d9f4d1SDevajith     return "Unexpected end of code.";
6002d9f4d1SDevajith   case ErrorType::ParserOverloadedType:
6102d9f4d1SDevajith     return "Input value has unresolved overloaded type: $0";
62*58b44c81SJacques Pienaar   case ErrorType::ParserMalformedChainedExpr:
63*58b44c81SJacques Pienaar     return "Period not followed by valid chained call.";
64*58b44c81SJacques Pienaar   case ErrorType::ParserChainedExprInvalidArg:
65*58b44c81SJacques Pienaar     return "Missing/Invalid argument for the chained call.";
66*58b44c81SJacques Pienaar   case ErrorType::ParserChainedExprNoCloseParen:
67*58b44c81SJacques Pienaar     return "Missing ')' for the chained call.";
68*58b44c81SJacques Pienaar   case ErrorType::ParserChainedExprNoOpenParen:
69*58b44c81SJacques Pienaar     return "Missing '(' for the chained call.";
7002d9f4d1SDevajith   case ErrorType::ParserFailedToBuildMatcher:
7102d9f4d1SDevajith     return "Failed to build matcher: $0.";
7202d9f4d1SDevajith 
7302d9f4d1SDevajith   case ErrorType::None:
7402d9f4d1SDevajith     return "<N/A>";
7502d9f4d1SDevajith   }
7602d9f4d1SDevajith   llvm_unreachable("Unknown ErrorType value.");
7702d9f4d1SDevajith }
7802d9f4d1SDevajith 
formatErrorString(llvm::StringRef formatString,llvm::ArrayRef<std::string> args,llvm::raw_ostream & os)7902d9f4d1SDevajith static void formatErrorString(llvm::StringRef formatString,
8002d9f4d1SDevajith                               llvm::ArrayRef<std::string> args,
8102d9f4d1SDevajith                               llvm::raw_ostream &os) {
8202d9f4d1SDevajith   while (!formatString.empty()) {
8302d9f4d1SDevajith     std::pair<llvm::StringRef, llvm::StringRef> pieces =
8402d9f4d1SDevajith         formatString.split("$");
8502d9f4d1SDevajith     os << pieces.first.str();
8602d9f4d1SDevajith     if (pieces.second.empty())
8702d9f4d1SDevajith       break;
8802d9f4d1SDevajith 
8902d9f4d1SDevajith     const char next = pieces.second.front();
9002d9f4d1SDevajith     formatString = pieces.second.drop_front();
9102d9f4d1SDevajith     if (next >= '0' && next <= '9') {
9202d9f4d1SDevajith       const unsigned index = next - '0';
9302d9f4d1SDevajith       if (index < args.size()) {
9402d9f4d1SDevajith         os << args[index];
9502d9f4d1SDevajith       } else {
9602d9f4d1SDevajith         os << "<Argument_Not_Provided>";
9702d9f4d1SDevajith       }
9802d9f4d1SDevajith     }
9902d9f4d1SDevajith   }
10002d9f4d1SDevajith }
10102d9f4d1SDevajith 
maybeAddLineAndColumn(SourceRange range,llvm::raw_ostream & os)10202d9f4d1SDevajith static void maybeAddLineAndColumn(SourceRange range, llvm::raw_ostream &os) {
10302d9f4d1SDevajith   if (range.start.line > 0 && range.start.column > 0) {
10402d9f4d1SDevajith     os << range.start.line << ":" << range.start.column << ": ";
10502d9f4d1SDevajith   }
10602d9f4d1SDevajith }
10702d9f4d1SDevajith 
printMessage(const Diagnostics::ErrorContent::Message & message,const llvm::Twine prefix,llvm::raw_ostream & os) const10802d9f4d1SDevajith void Diagnostics::printMessage(
10902d9f4d1SDevajith     const Diagnostics::ErrorContent::Message &message, const llvm::Twine prefix,
11002d9f4d1SDevajith     llvm::raw_ostream &os) const {
11102d9f4d1SDevajith   maybeAddLineAndColumn(message.range, os);
11202d9f4d1SDevajith   os << prefix;
11302d9f4d1SDevajith   formatErrorString(errorTypeToFormatString(message.type), message.args, os);
11402d9f4d1SDevajith }
11502d9f4d1SDevajith 
printErrorContent(const Diagnostics::ErrorContent & content,llvm::raw_ostream & os) const11602d9f4d1SDevajith void Diagnostics::printErrorContent(const Diagnostics::ErrorContent &content,
11702d9f4d1SDevajith                                     llvm::raw_ostream &os) const {
11802d9f4d1SDevajith   if (content.messages.size() == 1) {
11902d9f4d1SDevajith     printMessage(content.messages[0], "", os);
12002d9f4d1SDevajith   } else {
12102d9f4d1SDevajith     for (size_t i = 0, e = content.messages.size(); i != e; ++i) {
12202d9f4d1SDevajith       if (i != 0)
12302d9f4d1SDevajith         os << "\n";
12402d9f4d1SDevajith       printMessage(content.messages[i],
12502d9f4d1SDevajith                    "Candidate " + llvm::Twine(i + 1) + ": ", os);
12602d9f4d1SDevajith     }
12702d9f4d1SDevajith   }
12802d9f4d1SDevajith }
12902d9f4d1SDevajith 
print(llvm::raw_ostream & os) const13002d9f4d1SDevajith void Diagnostics::print(llvm::raw_ostream &os) const {
13102d9f4d1SDevajith   for (const ErrorContent &error : errorValues) {
13202d9f4d1SDevajith     if (&error != &errorValues.front())
13302d9f4d1SDevajith       os << "\n";
13402d9f4d1SDevajith     printErrorContent(error, os);
13502d9f4d1SDevajith   }
13602d9f4d1SDevajith }
13702d9f4d1SDevajith 
13802d9f4d1SDevajith } // namespace mlir::query::matcher::internal
139