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