зеркало из https://github.com/microsoft/clang-1.git
Config file support for clang-format, part 2.
Summary: Adds actual config file reading to the clang-format utility. Configuration file name is .clang-format. It is looked up for each input file in its parent directories starting from immediate one. First found .clang-format file is used. When using standard input, .clang-format is searched starting from the current directory. Added -dump-config option to easily create configuration files. Reviewers: djasper, klimek Reviewed By: klimek CC: cfe-commits, jordan_rose, kimgr Differential Revision: http://llvm-reviews.chandlerc.com/D758 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@181589 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
acf02715ab
Коммит
dd256314cf
|
@ -93,6 +93,29 @@ struct FormatStyle {
|
|||
/// \brief If \c true, aligns escaped newlines as far left as possible.
|
||||
/// Otherwise puts them into the right-most column.
|
||||
bool AlignEscapedNewlinesLeft;
|
||||
|
||||
bool operator==(const FormatStyle &R) const {
|
||||
return AccessModifierOffset == R.AccessModifierOffset &&
|
||||
AlignEscapedNewlinesLeft == R.AlignEscapedNewlinesLeft &&
|
||||
AllowAllParametersOfDeclarationOnNextLine ==
|
||||
R.AllowAllParametersOfDeclarationOnNextLine &&
|
||||
AllowShortIfStatementsOnASingleLine ==
|
||||
R.AllowShortIfStatementsOnASingleLine &&
|
||||
BinPackParameters == R.BinPackParameters &&
|
||||
ColumnLimit == R.ColumnLimit &&
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine ==
|
||||
R.ConstructorInitializerAllOnOneLineOrOnePerLine &&
|
||||
DerivePointerBinding == R.DerivePointerBinding &&
|
||||
IndentCaseLabels == R.IndentCaseLabels &&
|
||||
MaxEmptyLinesToKeep == R.MaxEmptyLinesToKeep &&
|
||||
ObjCSpaceBeforeProtocolList == R.ObjCSpaceBeforeProtocolList &&
|
||||
PenaltyExcessCharacter == R.PenaltyExcessCharacter &&
|
||||
PenaltyReturnTypeOnItsOwnLine == R.PenaltyReturnTypeOnItsOwnLine &&
|
||||
PointerBindsToType == R.PointerBindsToType &&
|
||||
SpacesBeforeTrailingComments == R.SpacesBeforeTrailingComments &&
|
||||
Standard == R.Standard;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/// \brief Returns a format style complying with the LLVM coding standards:
|
||||
|
|
|
@ -46,10 +46,19 @@ struct ScalarEnumerationTraits<clang::format::FormatStyle::LanguageStandard> {
|
|||
|
||||
template <> struct MappingTraits<clang::format::FormatStyle> {
|
||||
static void mapping(llvm::yaml::IO &IO, clang::format::FormatStyle &Style) {
|
||||
if (!IO.outputting()) {
|
||||
if (IO.outputting()) {
|
||||
StringRef StylesArray[] = { "LLVM", "Google", "Chromium", "Mozilla" };
|
||||
ArrayRef<StringRef> Styles(StylesArray);
|
||||
for (size_t i = 0, e = Styles.size(); i < e; ++i) {
|
||||
StringRef StyleName(Styles[i]);
|
||||
if (Style == clang::format::getPredefinedStyle(StyleName)) {
|
||||
IO.mapOptional("# BasedOnStyle", StyleName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
StringRef BasedOnStyle;
|
||||
IO.mapOptional("BasedOnStyle", BasedOnStyle);
|
||||
|
||||
if (!BasedOnStyle.empty())
|
||||
Style = clang::format::getPredefinedStyle(BasedOnStyle);
|
||||
}
|
||||
|
@ -245,9 +254,9 @@ public:
|
|||
private:
|
||||
void DebugTokenState(const AnnotatedToken &AnnotatedTok) {
|
||||
const Token &Tok = AnnotatedTok.FormatTok.Tok;
|
||||
llvm::errs() << StringRef(SourceMgr.getCharacterData(Tok.getLocation()),
|
||||
llvm::dbgs() << StringRef(SourceMgr.getCharacterData(Tok.getLocation()),
|
||||
Tok.getLength());
|
||||
llvm::errs();
|
||||
llvm::dbgs();
|
||||
}
|
||||
|
||||
struct ParenState {
|
||||
|
@ -825,7 +834,7 @@ private:
|
|||
unsigned Penalty = Queue.top().first.first;
|
||||
StateNode *Node = Queue.top().second;
|
||||
if (Node->State.NextToken == NULL) {
|
||||
DEBUG(llvm::errs() << "\n---\nPenalty for line: " << Penalty << "\n");
|
||||
DEBUG(llvm::dbgs() << "\n---\nPenalty for line: " << Penalty << "\n");
|
||||
break;
|
||||
}
|
||||
Queue.pop();
|
||||
|
@ -845,8 +854,8 @@ private:
|
|||
|
||||
// Reconstruct the solution.
|
||||
reconstructPath(InitialState, Queue.top().second);
|
||||
DEBUG(llvm::errs() << "Total number of analyzed states: " << Count << "\n");
|
||||
DEBUG(llvm::errs() << "---\n");
|
||||
DEBUG(llvm::dbgs() << "Total number of analyzed states: " << Count << "\n");
|
||||
DEBUG(llvm::dbgs() << "---\n");
|
||||
|
||||
// Return the column after the last token of the solution.
|
||||
return Queue.top().second->State.Column;
|
||||
|
@ -862,7 +871,7 @@ private:
|
|||
reconstructPath(State, Current->Previous);
|
||||
DEBUG({
|
||||
if (Current->NewLine) {
|
||||
llvm::errs()
|
||||
llvm::dbgs()
|
||||
<< "Penalty for splitting before "
|
||||
<< Current->Previous->State.NextToken->FormatTok.Tok.getName()
|
||||
<< ": " << Current->Previous->State.NextToken->SplitPenalty << "\n";
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "clang/Format/Format.h"
|
||||
#include "clang/Lex/Lexer.h"
|
||||
#include "clang/Rewrite/Core/Rewriter.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/Signals.h"
|
||||
|
||||
|
@ -36,13 +37,20 @@ Lengths("length", cl::desc("Format a range of this length. "
|
|||
"Can only be used with one input file."));
|
||||
static cl::opt<std::string> Style(
|
||||
"style",
|
||||
cl::desc("Coding style, currently supports: LLVM, Google, Chromium, Mozilla."),
|
||||
cl::desc(
|
||||
"Coding style, currently supports: LLVM, Google, Chromium, Mozilla. "
|
||||
"Use '-style file' to load style configuration from .clang-format file "
|
||||
"located in one of the parent directories of the source file (or "
|
||||
"current directory for stdin)."),
|
||||
cl::init("LLVM"));
|
||||
static cl::opt<bool> Inplace("i",
|
||||
cl::desc("Inplace edit <file>s, if specified."));
|
||||
|
||||
static cl::opt<bool> OutputXML(
|
||||
"output-replacements-xml", cl::desc("Output replacements as XML."));
|
||||
static cl::opt<bool>
|
||||
DumpConfig("dump-config",
|
||||
cl::desc("Dump configuration options to stdout and exit. Can be used with -style option."));
|
||||
|
||||
static cl::list<std::string> FileNames(cl::Positional,
|
||||
cl::desc("[<file> ...]"));
|
||||
|
@ -59,18 +67,38 @@ static FileID createInMemoryFile(StringRef FileName, const MemoryBuffer *Source,
|
|||
return Sources.createFileID(Entry, SourceLocation(), SrcMgr::C_User);
|
||||
}
|
||||
|
||||
static FormatStyle getStyle() {
|
||||
FormatStyle TheStyle = getGoogleStyle();
|
||||
if (Style == "LLVM")
|
||||
TheStyle = getLLVMStyle();
|
||||
else if (Style == "Chromium")
|
||||
TheStyle = getChromiumStyle();
|
||||
else if (Style == "Mozilla")
|
||||
TheStyle = getMozillaStyle();
|
||||
else if (Style != "Google")
|
||||
llvm::errs() << "Unknown style " << Style << ", using Google style.\n";
|
||||
FormatStyle getStyle(StringRef StyleName, StringRef FileName) {
|
||||
if (!StyleName.equals_lower("file"))
|
||||
return getPredefinedStyle(StyleName);
|
||||
|
||||
return TheStyle;
|
||||
SmallString<128> Path(FileName);
|
||||
llvm::sys::fs::make_absolute(Path);
|
||||
for (StringRef Directory = llvm::sys::path::parent_path(Path);
|
||||
!Directory.empty();
|
||||
Directory = llvm::sys::path::parent_path(Directory)) {
|
||||
SmallString<128> ConfigFile(Directory);
|
||||
llvm::sys::path::append(ConfigFile, ".clang-format");
|
||||
DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
|
||||
bool IsFile = false;
|
||||
llvm::sys::fs::is_regular_file(Twine(ConfigFile), IsFile);
|
||||
if (IsFile) {
|
||||
OwningPtr<MemoryBuffer> Text;
|
||||
if (error_code ec = MemoryBuffer::getFile(ConfigFile, Text)) {
|
||||
llvm::errs() << ec.message() << "\n";
|
||||
continue;
|
||||
}
|
||||
FormatStyle Style;
|
||||
if (error_code ec = parseConfiguration(Text->getBuffer(), &Style)) {
|
||||
llvm::errs() << "Error reading " << ConfigFile << ": " << ec.message()
|
||||
<< "\n";
|
||||
continue;
|
||||
}
|
||||
DEBUG(llvm::dbgs() << "Using configuration file " << ConfigFile << "\n");
|
||||
return Style;
|
||||
}
|
||||
}
|
||||
llvm::errs() << "Can't find usable .clang-format, using LLVM style\n";
|
||||
return getLLVMStyle();
|
||||
}
|
||||
|
||||
// Returns true on error.
|
||||
|
@ -118,7 +146,8 @@ static bool format(std::string FileName) {
|
|||
}
|
||||
Ranges.push_back(CharSourceRange::getCharRange(Start, End));
|
||||
}
|
||||
tooling::Replacements Replaces = reformat(getStyle(), Lex, Sources, Ranges);
|
||||
tooling::Replacements Replaces =
|
||||
reformat(getStyle(Style, FileName), Lex, Sources, Ranges);
|
||||
if (OutputXML) {
|
||||
llvm::outs()
|
||||
<< "<?xml version='1.0'?>\n<replacements xml:space='preserve'>\n";
|
||||
|
@ -171,6 +200,13 @@ int main(int argc, const char **argv) {
|
|||
if (Help)
|
||||
cl::PrintHelpMessage();
|
||||
|
||||
if (DumpConfig) {
|
||||
std::string Config = clang::format::configurationAsText(
|
||||
clang::format::getStyle(Style, FileNames.empty() ? "-" : FileNames[0]));
|
||||
llvm::outs() << Config << "\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Error = false;
|
||||
switch (FileNames.size()) {
|
||||
case 0:
|
||||
|
|
|
@ -3933,28 +3933,6 @@ TEST_F(FormatTest, DoNotCreateUnreasonableUnwrappedLines) {
|
|||
"}");
|
||||
}
|
||||
|
||||
bool operator==(const FormatStyle &L, const FormatStyle &R) {
|
||||
return L.AccessModifierOffset == R.AccessModifierOffset &&
|
||||
L.AlignEscapedNewlinesLeft == R.AlignEscapedNewlinesLeft &&
|
||||
L.AllowAllParametersOfDeclarationOnNextLine ==
|
||||
R.AllowAllParametersOfDeclarationOnNextLine &&
|
||||
L.AllowShortIfStatementsOnASingleLine ==
|
||||
R.AllowShortIfStatementsOnASingleLine &&
|
||||
L.BinPackParameters == R.BinPackParameters &&
|
||||
L.ColumnLimit == R.ColumnLimit &&
|
||||
L.ConstructorInitializerAllOnOneLineOrOnePerLine ==
|
||||
R.ConstructorInitializerAllOnOneLineOrOnePerLine &&
|
||||
L.DerivePointerBinding == R.DerivePointerBinding &&
|
||||
L.IndentCaseLabels == R.IndentCaseLabels &&
|
||||
L.MaxEmptyLinesToKeep == R.MaxEmptyLinesToKeep &&
|
||||
L.ObjCSpaceBeforeProtocolList == R.ObjCSpaceBeforeProtocolList &&
|
||||
L.PenaltyExcessCharacter == R.PenaltyExcessCharacter &&
|
||||
L.PenaltyReturnTypeOnItsOwnLine == R.PenaltyReturnTypeOnItsOwnLine &&
|
||||
L.PointerBindsToType == R.PointerBindsToType &&
|
||||
L.SpacesBeforeTrailingComments == R.SpacesBeforeTrailingComments &&
|
||||
L.Standard == R.Standard;
|
||||
}
|
||||
|
||||
bool allStylesEqual(ArrayRef<FormatStyle> Styles) {
|
||||
for (size_t i = 1; i < Styles.size(); ++i)
|
||||
if (!(Styles[0] == Styles[i]))
|
||||
|
|
Загрузка…
Ссылка в новой задаче