forked from OSchip/llvm-project
Add support for raw_ostream on the printing methods of Diagnostics.
Summary: Add printToStream*(llvm::raw_ostream&) methods to Diagnostics, and reimplement everything based on streams instead of concatenating strings. Also, fix some functions to start with lowercase to match the style guide. Reviewers: klimek CC: cfe-commits, revane Differential Revision: http://llvm-reviews.chandlerc.com/D1187 llvm-svn: 186715
This commit is contained in:
parent
569b8f83a4
commit
b837248ad4
|
@ -23,6 +23,7 @@
|
|||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
namespace clang {
|
||||
namespace ast_matchers {
|
||||
|
@ -125,8 +126,6 @@ public:
|
|||
ContextType Type;
|
||||
SourceRange Range;
|
||||
std::vector<std::string> Args;
|
||||
|
||||
std::string ToString() const;
|
||||
};
|
||||
|
||||
/// \brief Information stored for each error found.
|
||||
|
@ -135,20 +134,20 @@ public:
|
|||
SourceRange Range;
|
||||
ErrorType Type;
|
||||
std::vector<std::string> Args;
|
||||
|
||||
std::string ToString() const;
|
||||
};
|
||||
ArrayRef<ErrorContent> errors() const { return Errors; }
|
||||
|
||||
/// \brief Returns a simple string representation of each error.
|
||||
///
|
||||
/// Each error only shows the error message without any context.
|
||||
std::string ToString() const;
|
||||
void printToStream(llvm::raw_ostream &OS) const;
|
||||
std::string toString() const;
|
||||
|
||||
/// \brief Returns the full string representation of each error.
|
||||
///
|
||||
/// Each error message contains the full context.
|
||||
std::string ToStringFull() const;
|
||||
void printToStreamFull(llvm::raw_ostream &OS) const;
|
||||
std::string toStringFull() const;
|
||||
|
||||
private:
|
||||
/// \brief Helper function used by the constructors of ContextFrame.
|
||||
|
|
|
@ -55,7 +55,7 @@ Diagnostics::ArgStream Diagnostics::addError(const SourceRange &Range,
|
|||
return ArgStream(&Last.Args);
|
||||
}
|
||||
|
||||
StringRef ContextTypeToString(Diagnostics::ContextType Type) {
|
||||
StringRef contextTypeToFormatString(Diagnostics::ContextType Type) {
|
||||
switch (Type) {
|
||||
case Diagnostics::CT_MatcherConstruct:
|
||||
return "Error building matcher $0.";
|
||||
|
@ -65,7 +65,7 @@ StringRef ContextTypeToString(Diagnostics::ContextType Type) {
|
|||
llvm_unreachable("Unknown ContextType value.");
|
||||
}
|
||||
|
||||
StringRef ErrorTypeToString(Diagnostics::ErrorType Type) {
|
||||
StringRef errorTypeToFormatString(Diagnostics::ErrorType Type) {
|
||||
switch (Type) {
|
||||
case Diagnostics::ET_RegistryNotFound:
|
||||
return "Matcher not found: $0";
|
||||
|
@ -105,12 +105,11 @@ StringRef ErrorTypeToString(Diagnostics::ErrorType Type) {
|
|||
llvm_unreachable("Unknown ErrorType value.");
|
||||
}
|
||||
|
||||
std::string FormatErrorString(StringRef FormatString,
|
||||
ArrayRef<std::string> Args) {
|
||||
std::string Out;
|
||||
void formatErrorString(StringRef FormatString, ArrayRef<std::string> Args,
|
||||
llvm::raw_ostream &OS) {
|
||||
while (!FormatString.empty()) {
|
||||
std::pair<StringRef, StringRef> Pieces = FormatString.split("$");
|
||||
Out += Pieces.first.str();
|
||||
OS << Pieces.first.str();
|
||||
if (Pieces.second.empty()) break;
|
||||
|
||||
const char Next = Pieces.second.front();
|
||||
|
@ -118,53 +117,64 @@ std::string FormatErrorString(StringRef FormatString,
|
|||
if (Next >= '0' && Next <= '9') {
|
||||
const unsigned Index = Next - '0';
|
||||
if (Index < Args.size()) {
|
||||
Out += Args[Index];
|
||||
OS << Args[Index];
|
||||
} else {
|
||||
Out += "<Argument_Not_Provided>";
|
||||
OS << "<Argument_Not_Provided>";
|
||||
}
|
||||
}
|
||||
}
|
||||
return Out;
|
||||
}
|
||||
|
||||
static std::string MaybeAddLineAndColumn(Twine Input,
|
||||
const SourceRange &Range) {
|
||||
if (Range.Start.Line > 0 && Range.Start.Column > 0)
|
||||
return (Twine(Range.Start.Line) + ":" + Twine(Range.Start.Column) + ": " +
|
||||
Input).str();
|
||||
return Input.str();
|
||||
}
|
||||
|
||||
std::string Diagnostics::ContextFrame::ToString() const {
|
||||
return MaybeAddLineAndColumn(
|
||||
FormatErrorString(ContextTypeToString(Type), Args), Range);
|
||||
}
|
||||
|
||||
std::string Diagnostics::ErrorContent::ToString() const {
|
||||
return MaybeAddLineAndColumn(FormatErrorString(ErrorTypeToString(Type), Args),
|
||||
Range);
|
||||
}
|
||||
|
||||
std::string Diagnostics::ToString() const {
|
||||
std::string Result;
|
||||
for (size_t i = 0, e = Errors.size(); i != e; ++i) {
|
||||
if (i != 0) Result += "\n";
|
||||
Result += Errors[i].ToString();
|
||||
static void maybeAddLineAndColumn(const SourceRange &Range,
|
||||
llvm::raw_ostream &OS) {
|
||||
if (Range.Start.Line > 0 && Range.Start.Column > 0) {
|
||||
OS << Range.Start.Line << ":" << Range.Start.Column << ": ";
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
std::string Diagnostics::ToStringFull() const {
|
||||
std::string Result;
|
||||
static void printContextFrameToStream(const Diagnostics::ContextFrame &Frame,
|
||||
llvm::raw_ostream &OS) {
|
||||
maybeAddLineAndColumn(Frame.Range, OS);
|
||||
formatErrorString(contextTypeToFormatString(Frame.Type), Frame.Args, OS);
|
||||
}
|
||||
|
||||
static void printErrorContentToStream(const Diagnostics::ErrorContent &Content,
|
||||
llvm::raw_ostream &OS) {
|
||||
maybeAddLineAndColumn(Content.Range, OS);
|
||||
formatErrorString(errorTypeToFormatString(Content.Type), Content.Args, OS);
|
||||
}
|
||||
|
||||
void Diagnostics::printToStream(llvm::raw_ostream &OS) const {
|
||||
for (size_t i = 0, e = Errors.size(); i != e; ++i) {
|
||||
if (i != 0) Result += "\n";
|
||||
if (i != 0) OS << "\n";
|
||||
printErrorContentToStream(Errors[i], OS);
|
||||
}
|
||||
}
|
||||
|
||||
std::string Diagnostics::toString() const {
|
||||
std::string S;
|
||||
llvm::raw_string_ostream OS(S);
|
||||
printToStream(OS);
|
||||
return OS.str();
|
||||
}
|
||||
|
||||
void Diagnostics::printToStreamFull(llvm::raw_ostream &OS) const {
|
||||
for (size_t i = 0, e = Errors.size(); i != e; ++i) {
|
||||
if (i != 0) OS << "\n";
|
||||
const ErrorContent &Error = Errors[i];
|
||||
for (size_t i = 0, e = Error.ContextStack.size(); i != e; ++i) {
|
||||
Result += Error.ContextStack[i].ToString() + "\n";
|
||||
printContextFrameToStream(Error.ContextStack[i], OS);
|
||||
OS << "\n";
|
||||
}
|
||||
Result += Error.ToString();
|
||||
printErrorContentToStream(Error, OS);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
std::string Diagnostics::toStringFull() const {
|
||||
std::string S;
|
||||
llvm::raw_string_ostream OS(S);
|
||||
printToStreamFull(OS);
|
||||
return OS.str();
|
||||
}
|
||||
|
||||
} // namespace dynamic
|
||||
|
|
|
@ -73,7 +73,7 @@ public:
|
|||
VariantValue Value;
|
||||
Parser::parseExpression(Code, this, &Value, &Error);
|
||||
Values.push_back(Value);
|
||||
Errors.push_back(Error.ToStringFull());
|
||||
Errors.push_back(Error.toStringFull());
|
||||
}
|
||||
|
||||
MatcherList actOnMatcherExpression(StringRef MatcherName,
|
||||
|
@ -184,7 +184,7 @@ TEST(ParserTest, FullParserTest) {
|
|||
"varDecl(hasInitializer(binaryOperator(hasLHS(integerLiteral()),"
|
||||
" hasOperatorName(\"+\"))))",
|
||||
&Error));
|
||||
EXPECT_EQ("", Error.ToStringFull());
|
||||
EXPECT_EQ("", Error.toStringFull());
|
||||
Matcher<Decl> M = Matcher<Decl>::constructFrom(*VarDecl);
|
||||
EXPECT_TRUE(matches("int x = 1 + false;", M));
|
||||
EXPECT_FALSE(matches("int x = true + 1;", M));
|
||||
|
@ -193,7 +193,7 @@ TEST(ParserTest, FullParserTest) {
|
|||
|
||||
OwningPtr<DynTypedMatcher> HasParameter(Parser::parseMatcherExpression(
|
||||
"functionDecl(hasParameter(1, hasName(\"x\")))", &Error));
|
||||
EXPECT_EQ("", Error.ToStringFull());
|
||||
EXPECT_EQ("", Error.toStringFull());
|
||||
M = Matcher<Decl>::constructFrom(*HasParameter);
|
||||
|
||||
EXPECT_TRUE(matches("void f(int a, int x);", M));
|
||||
|
@ -206,20 +206,20 @@ TEST(ParserTest, FullParserTest) {
|
|||
"2:20: Error building matcher hasLHS.\n"
|
||||
"2:27: Incorrect type for arg 1. "
|
||||
"(Expected = Matcher<Expr>) != (Actual = String)",
|
||||
Error.ToStringFull());
|
||||
Error.toStringFull());
|
||||
}
|
||||
|
||||
std::string ParseWithError(StringRef Code) {
|
||||
Diagnostics Error;
|
||||
VariantValue Value;
|
||||
Parser::parseExpression(Code, &Value, &Error);
|
||||
return Error.ToStringFull();
|
||||
return Error.toStringFull();
|
||||
}
|
||||
|
||||
std::string ParseMatcherWithError(StringRef Code) {
|
||||
Diagnostics Error;
|
||||
Parser::parseMatcherExpression(Code, &Error);
|
||||
return Error.ToStringFull();
|
||||
return Error.toStringFull();
|
||||
}
|
||||
|
||||
TEST(ParserTest, Errors) {
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
if (!Error) Error = &DummyError;
|
||||
const MatcherList Out =
|
||||
Registry::constructMatcher(MatcherName, SourceRange(), Args(), Error);
|
||||
EXPECT_EQ("", DummyError.ToStringFull());
|
||||
EXPECT_EQ("", DummyError.toStringFull());
|
||||
return Out;
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ public:
|
|||
if (!Error) Error = &DummyError;
|
||||
const MatcherList Out = Registry::constructMatcher(
|
||||
MatcherName, SourceRange(), Args(Arg1), Error);
|
||||
EXPECT_EQ("", DummyError.ToStringFull());
|
||||
EXPECT_EQ("", DummyError.toStringFull());
|
||||
return Out;
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ public:
|
|||
if (!Error) Error = &DummyError;
|
||||
const MatcherList Out = Registry::constructMatcher(
|
||||
MatcherName, SourceRange(), Args(Arg1, Arg2), Error);
|
||||
EXPECT_EQ("", DummyError.ToStringFull());
|
||||
EXPECT_EQ("", DummyError.toStringFull());
|
||||
return Out;
|
||||
}
|
||||
};
|
||||
|
@ -203,24 +203,24 @@ TEST_F(RegistryTest, Errors) {
|
|||
OwningPtr<Diagnostics> Error(new Diagnostics());
|
||||
EXPECT_TRUE(constructMatcher("hasInitializer", Error.get()).empty());
|
||||
EXPECT_EQ("Incorrect argument count. (Expected = 1) != (Actual = 0)",
|
||||
Error->ToString());
|
||||
Error->toString());
|
||||
Error.reset(new Diagnostics());
|
||||
EXPECT_TRUE(constructMatcher("isArrow", std::string(), Error.get()).empty());
|
||||
EXPECT_EQ("Incorrect argument count. (Expected = 0) != (Actual = 1)",
|
||||
Error->ToString());
|
||||
Error->toString());
|
||||
|
||||
// Bad argument type
|
||||
Error.reset(new Diagnostics());
|
||||
EXPECT_TRUE(constructMatcher("ofClass", std::string(), Error.get()).empty());
|
||||
EXPECT_EQ("Incorrect type for arg 1. (Expected = Matcher<CXXRecordDecl>) != "
|
||||
"(Actual = String)",
|
||||
Error->ToString());
|
||||
Error->toString());
|
||||
Error.reset(new Diagnostics());
|
||||
EXPECT_TRUE(constructMatcher("recordDecl", recordDecl(), parameterCountIs(3),
|
||||
Error.get()).empty());
|
||||
EXPECT_EQ("Incorrect type for arg 2. (Expected = Matcher<CXXRecordDecl>) != "
|
||||
"(Actual = Matcher<FunctionDecl>)",
|
||||
Error->ToString());
|
||||
Error->toString());
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
|
Loading…
Reference in New Issue