aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Format/Format.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Format/Format.cpp')
-rw-r--r--clang/lib/Format/Format.cpp298
1 files changed, 254 insertions, 44 deletions
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 5f5bb8585ac1..2b860d2a25f7 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -63,6 +63,7 @@ template <> struct ScalarEnumerationTraits<FormatStyle::LanguageKind> {
IO.enumCase(Value, "TableGen", FormatStyle::LK_TableGen);
IO.enumCase(Value, "TextProto", FormatStyle::LK_TextProto);
IO.enumCase(Value, "CSharp", FormatStyle::LK_CSharp);
+ IO.enumCase(Value, "Json", FormatStyle::LK_Json);
}
};
@@ -85,6 +86,15 @@ template <> struct ScalarEnumerationTraits<FormatStyle::LanguageStandard> {
}
};
+template <>
+struct ScalarEnumerationTraits<FormatStyle::LambdaBodyIndentationKind> {
+ static void enumeration(IO &IO,
+ FormatStyle::LambdaBodyIndentationKind &Value) {
+ IO.enumCase(Value, "Signature", FormatStyle::LBI_Signature);
+ IO.enumCase(Value, "OuterScope", FormatStyle::LBI_OuterScope);
+ }
+};
+
template <> struct ScalarEnumerationTraits<FormatStyle::UseTabStyle> {
static void enumeration(IO &IO, FormatStyle::UseTabStyle &Value) {
IO.enumCase(Value, "Never", FormatStyle::UT_Never);
@@ -143,13 +153,25 @@ template <> struct ScalarEnumerationTraits<FormatStyle::AlignConsecutiveStyle> {
}
};
+template <>
+struct ScalarEnumerationTraits<FormatStyle::ArrayInitializerAlignmentStyle> {
+ static void enumeration(IO &IO,
+ FormatStyle::ArrayInitializerAlignmentStyle &Value) {
+ IO.enumCase(Value, "None", FormatStyle::AIAS_None);
+ IO.enumCase(Value, "Left", FormatStyle::AIAS_Left);
+ IO.enumCase(Value, "Right", FormatStyle::AIAS_Right);
+ }
+};
+
template <> struct ScalarEnumerationTraits<FormatStyle::ShortIfStyle> {
static void enumeration(IO &IO, FormatStyle::ShortIfStyle &Value) {
IO.enumCase(Value, "Never", FormatStyle::SIS_Never);
- IO.enumCase(Value, "Always", FormatStyle::SIS_Always);
IO.enumCase(Value, "WithoutElse", FormatStyle::SIS_WithoutElse);
+ IO.enumCase(Value, "OnlyFirstIf", FormatStyle::SIS_OnlyFirstIf);
+ IO.enumCase(Value, "AllIfsAndElse", FormatStyle::SIS_AllIfsAndElse);
// For backward compatibility.
+ IO.enumCase(Value, "Always", FormatStyle::SIS_OnlyFirstIf);
IO.enumCase(Value, "false", FormatStyle::SIS_Never);
IO.enumCase(Value, "true", FormatStyle::SIS_WithoutElse);
}
@@ -238,6 +260,17 @@ struct ScalarEnumerationTraits<FormatStyle::BreakInheritanceListStyle> {
IO.enumCase(Value, "BeforeColon", FormatStyle::BILS_BeforeColon);
IO.enumCase(Value, "BeforeComma", FormatStyle::BILS_BeforeComma);
IO.enumCase(Value, "AfterColon", FormatStyle::BILS_AfterColon);
+ IO.enumCase(Value, "AfterComma", FormatStyle::BILS_AfterComma);
+ }
+};
+
+template <>
+struct ScalarEnumerationTraits<FormatStyle::EmptyLineAfterAccessModifierStyle> {
+ static void
+ enumeration(IO &IO, FormatStyle::EmptyLineAfterAccessModifierStyle &Value) {
+ IO.enumCase(Value, "Never", FormatStyle::ELAAMS_Never);
+ IO.enumCase(Value, "Leave", FormatStyle::ELAAMS_Leave);
+ IO.enumCase(Value, "Always", FormatStyle::ELAAMS_Always);
}
};
@@ -386,14 +419,24 @@ struct ScalarEnumerationTraits<FormatStyle::SpaceAroundPointerQualifiersStyle> {
};
template <>
+struct ScalarEnumerationTraits<FormatStyle::ReferenceAlignmentStyle> {
+ static void enumeration(IO &IO, FormatStyle::ReferenceAlignmentStyle &Value) {
+ IO.enumCase(Value, "Pointer", FormatStyle::RAS_Pointer);
+ IO.enumCase(Value, "Middle", FormatStyle::RAS_Middle);
+ IO.enumCase(Value, "Left", FormatStyle::RAS_Left);
+ IO.enumCase(Value, "Right", FormatStyle::RAS_Right);
+ }
+};
+
+template <>
struct ScalarEnumerationTraits<FormatStyle::SpaceBeforeParensOptions> {
static void enumeration(IO &IO,
FormatStyle::SpaceBeforeParensOptions &Value) {
IO.enumCase(Value, "Never", FormatStyle::SBPO_Never);
IO.enumCase(Value, "ControlStatements",
FormatStyle::SBPO_ControlStatements);
- IO.enumCase(Value, "ControlStatementsExceptForEachMacros",
- FormatStyle::SBPO_ControlStatementsExceptForEachMacros);
+ IO.enumCase(Value, "ControlStatementsExceptControlMacros",
+ FormatStyle::SBPO_ControlStatementsExceptControlMacros);
IO.enumCase(Value, "NonEmptyParentheses",
FormatStyle::SBPO_NonEmptyParentheses);
IO.enumCase(Value, "Always", FormatStyle::SBPO_Always);
@@ -401,6 +444,8 @@ struct ScalarEnumerationTraits<FormatStyle::SpaceBeforeParensOptions> {
// For backward compatibility.
IO.enumCase(Value, "false", FormatStyle::SBPO_Never);
IO.enumCase(Value, "true", FormatStyle::SBPO_ControlStatements);
+ IO.enumCase(Value, "ControlStatementsExceptForEachMacros",
+ FormatStyle::SBPO_ControlStatementsExceptControlMacros);
}
};
@@ -415,6 +460,18 @@ struct ScalarEnumerationTraits<FormatStyle::BitFieldColonSpacingStyle> {
}
};
+template <> struct ScalarEnumerationTraits<FormatStyle::SortIncludesOptions> {
+ static void enumeration(IO &IO, FormatStyle::SortIncludesOptions &Value) {
+ IO.enumCase(Value, "Never", FormatStyle::SI_Never);
+ IO.enumCase(Value, "CaseInsensitive", FormatStyle::SI_CaseInsensitive);
+ IO.enumCase(Value, "CaseSensitive", FormatStyle::SI_CaseSensitive);
+
+ // For backward compatibility.
+ IO.enumCase(Value, "false", FormatStyle::SI_Never);
+ IO.enumCase(Value, "true", FormatStyle::SI_CaseSensitive);
+ }
+};
+
template <>
struct ScalarEnumerationTraits<FormatStyle::SortJavaStaticImportOptions> {
static void enumeration(IO &IO,
@@ -424,6 +481,18 @@ struct ScalarEnumerationTraits<FormatStyle::SortJavaStaticImportOptions> {
}
};
+template <> struct ScalarEnumerationTraits<FormatStyle::SpacesInAnglesStyle> {
+ static void enumeration(IO &IO, FormatStyle::SpacesInAnglesStyle &Value) {
+ IO.enumCase(Value, "Never", FormatStyle::SIAS_Never);
+ IO.enumCase(Value, "Always", FormatStyle::SIAS_Always);
+ IO.enumCase(Value, "Leave", FormatStyle::SIAS_Leave);
+
+ // For backward compatibility.
+ IO.enumCase(Value, "false", FormatStyle::SIAS_Never);
+ IO.enumCase(Value, "true", FormatStyle::SIAS_Always);
+ }
+};
+
template <> struct MappingTraits<FormatStyle> {
static void mapping(IO &IO, FormatStyle &Style) {
// When reading, read the language first, we need it for getPredefinedStyle.
@@ -470,6 +539,7 @@ template <> struct MappingTraits<FormatStyle> {
IO.mapOptional("AccessModifierOffset", Style.AccessModifierOffset);
IO.mapOptional("AlignAfterOpenBracket", Style.AlignAfterOpenBracket);
+ IO.mapOptional("AlignArrayOfStructures", Style.AlignArrayOfStructures);
IO.mapOptional("AlignConsecutiveMacros", Style.AlignConsecutiveMacros);
IO.mapOptional("AlignConsecutiveAssignments",
Style.AlignConsecutiveAssignments);
@@ -572,19 +642,22 @@ template <> struct MappingTraits<FormatStyle> {
IO.mapOptional("DeriveLineEnding", Style.DeriveLineEnding);
IO.mapOptional("DerivePointerAlignment", Style.DerivePointerAlignment);
IO.mapOptional("DisableFormat", Style.DisableFormat);
+ IO.mapOptional("EmptyLineAfterAccessModifier",
+ Style.EmptyLineAfterAccessModifier);
IO.mapOptional("EmptyLineBeforeAccessModifier",
Style.EmptyLineBeforeAccessModifier);
IO.mapOptional("ExperimentalAutoDetectBinPacking",
Style.ExperimentalAutoDetectBinPacking);
IO.mapOptional("FixNamespaceComments", Style.FixNamespaceComments);
IO.mapOptional("ForEachMacros", Style.ForEachMacros);
- IO.mapOptional("StatementAttributeLikeMacros",
- Style.StatementAttributeLikeMacros);
+ IO.mapOptional("IfMacros", Style.IfMacros);
+
IO.mapOptional("IncludeBlocks", Style.IncludeStyle.IncludeBlocks);
IO.mapOptional("IncludeCategories", Style.IncludeStyle.IncludeCategories);
IO.mapOptional("IncludeIsMainRegex", Style.IncludeStyle.IncludeIsMainRegex);
IO.mapOptional("IncludeIsMainSourceRegex",
Style.IncludeStyle.IncludeIsMainSourceRegex);
+ IO.mapOptional("IndentAccessModifiers", Style.IndentAccessModifiers);
IO.mapOptional("IndentCaseLabels", Style.IndentCaseLabels);
IO.mapOptional("IndentCaseBlocks", Style.IndentCaseBlocks);
IO.mapOptional("IndentGotoLabels", Style.IndentGotoLabels);
@@ -600,6 +673,7 @@ template <> struct MappingTraits<FormatStyle> {
IO.mapOptional("JavaScriptWrapImports", Style.JavaScriptWrapImports);
IO.mapOptional("KeepEmptyLinesAtTheStartOfBlocks",
Style.KeepEmptyLinesAtTheStartOfBlocks);
+ IO.mapOptional("LambdaBodyIndentation", Style.LambdaBodyIndentation);
IO.mapOptional("MacroBlockBegin", Style.MacroBlockBegin);
IO.mapOptional("MacroBlockEnd", Style.MacroBlockEnd);
IO.mapOptional("MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep);
@@ -627,8 +701,11 @@ template <> struct MappingTraits<FormatStyle> {
IO.mapOptional("PenaltyIndentedWhitespace",
Style.PenaltyIndentedWhitespace);
IO.mapOptional("PointerAlignment", Style.PointerAlignment);
+ IO.mapOptional("PPIndentWidth", Style.PPIndentWidth);
IO.mapOptional("RawStringFormats", Style.RawStringFormats);
+ IO.mapOptional("ReferenceAlignment", Style.ReferenceAlignment);
IO.mapOptional("ReflowComments", Style.ReflowComments);
+ IO.mapOptional("ShortNamespaceLines", Style.ShortNamespaceLines);
IO.mapOptional("SortIncludes", Style.SortIncludes);
IO.mapOptional("SortJavaStaticImport", Style.SortJavaStaticImport);
IO.mapOptional("SortUsingDeclarations", Style.SortUsingDeclarations);
@@ -661,12 +738,16 @@ template <> struct MappingTraits<FormatStyle> {
Style.SpacesInContainerLiterals);
IO.mapOptional("SpacesInCStyleCastParentheses",
Style.SpacesInCStyleCastParentheses);
+ IO.mapOptional("SpacesInLineCommentPrefix",
+ Style.SpacesInLineCommentPrefix);
IO.mapOptional("SpacesInParentheses", Style.SpacesInParentheses);
IO.mapOptional("SpacesInSquareBrackets", Style.SpacesInSquareBrackets);
IO.mapOptional("SpaceBeforeSquareBrackets",
Style.SpaceBeforeSquareBrackets);
IO.mapOptional("BitFieldColonSpacing", Style.BitFieldColonSpacing);
IO.mapOptional("Standard", Style.Standard);
+ IO.mapOptional("StatementAttributeLikeMacros",
+ Style.StatementAttributeLikeMacros);
IO.mapOptional("StatementMacros", Style.StatementMacros);
IO.mapOptional("TabWidth", Style.TabWidth);
IO.mapOptional("TypenameMacros", Style.TypenameMacros);
@@ -710,6 +791,20 @@ template <> struct MappingTraits<FormatStyle::RawStringFormat> {
}
};
+template <> struct MappingTraits<FormatStyle::SpacesInLineComment> {
+ static void mapping(IO &IO, FormatStyle::SpacesInLineComment &Space) {
+ // Transform the maximum to signed, to parse "-1" correctly
+ int signedMaximum = static_cast<int>(Space.Maximum);
+ IO.mapOptional("Minimum", Space.Minimum);
+ IO.mapOptional("Maximum", signedMaximum);
+ Space.Maximum = static_cast<unsigned>(signedMaximum);
+
+ if (Space.Maximum != -1u) {
+ Space.Minimum = std::min(Space.Minimum, Space.Maximum);
+ }
+ }
+};
+
// Allows to read vector<FormatStyle> while keeping default values.
// IO.getContext() should contain a pointer to the FormatStyle structure, that
// will be used to get default values for missing keys.
@@ -880,10 +975,12 @@ static FormatStyle expandPresets(const FormatStyle &Style) {
FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
FormatStyle LLVMStyle;
+ LLVMStyle.InheritsParentConfig = false;
LLVMStyle.Language = Language;
LLVMStyle.AccessModifierOffset = -2;
LLVMStyle.AlignEscapedNewlines = FormatStyle::ENAS_Right;
LLVMStyle.AlignAfterOpenBracket = FormatStyle::BAS_Align;
+ LLVMStyle.AlignArrayOfStructures = FormatStyle::AIAS_None;
LLVMStyle.AlignOperands = FormatStyle::OAS_Align;
LLVMStyle.AlignTrailingComments = true;
LLVMStyle.AlignConsecutiveAssignments = FormatStyle::ACS_None;
@@ -943,18 +1040,21 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.Cpp11BracedListStyle = true;
LLVMStyle.DeriveLineEnding = true;
LLVMStyle.DerivePointerAlignment = false;
+ LLVMStyle.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Never;
LLVMStyle.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_LogicalBlock;
LLVMStyle.ExperimentalAutoDetectBinPacking = false;
LLVMStyle.FixNamespaceComments = true;
LLVMStyle.ForEachMacros.push_back("foreach");
LLVMStyle.ForEachMacros.push_back("Q_FOREACH");
LLVMStyle.ForEachMacros.push_back("BOOST_FOREACH");
+ LLVMStyle.IfMacros.push_back("KJ_IF_MAYBE");
LLVMStyle.IncludeStyle.IncludeCategories = {
{"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0, false},
{"^(<|\"(gtest|gmock|isl|json)/)", 3, 0, false},
{".*", 1, 0, false}};
LLVMStyle.IncludeStyle.IncludeIsMainRegex = "(Test)?$";
LLVMStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Preserve;
+ LLVMStyle.IndentAccessModifiers = false;
LLVMStyle.IndentCaseLabels = false;
LLVMStyle.IndentCaseBlocks = false;
LLVMStyle.IndentGotoLabels = true;
@@ -962,10 +1062,12 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.IndentRequires = false;
LLVMStyle.IndentWrappedFunctionNames = false;
LLVMStyle.IndentWidth = 2;
+ LLVMStyle.PPIndentWidth = -1;
LLVMStyle.InsertTrailingCommas = FormatStyle::TCS_None;
LLVMStyle.JavaScriptQuotes = FormatStyle::JSQS_Leave;
LLVMStyle.JavaScriptWrapImports = true;
LLVMStyle.TabWidth = 8;
+ LLVMStyle.LambdaBodyIndentation = FormatStyle::LBI_Signature;
LLVMStyle.MaxEmptyLinesToKeep = 1;
LLVMStyle.KeepEmptyLinesAtTheStartOfBlocks = true;
LLVMStyle.NamespaceIndentation = FormatStyle::NI_None;
@@ -975,6 +1077,8 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.ObjCSpaceAfterProperty = false;
LLVMStyle.ObjCSpaceBeforeProtocolList = true;
LLVMStyle.PointerAlignment = FormatStyle::PAS_Right;
+ LLVMStyle.ReferenceAlignment = FormatStyle::RAS_Pointer;
+ LLVMStyle.ShortNamespaceLines = 1;
LLVMStyle.SpacesBeforeTrailingComments = 1;
LLVMStyle.Standard = FormatStyle::LS_Latest;
LLVMStyle.UseCRLF = false;
@@ -986,6 +1090,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.SpaceInEmptyParentheses = false;
LLVMStyle.SpacesInContainerLiterals = true;
LLVMStyle.SpacesInCStyleCastParentheses = false;
+ LLVMStyle.SpacesInLineCommentPrefix = {/*Minimum=*/1, /*Maximum=*/-1u};
LLVMStyle.SpaceAfterCStyleCast = false;
LLVMStyle.SpaceAfterLogicalNot = false;
LLVMStyle.SpaceAfterTemplateKeyword = true;
@@ -999,7 +1104,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.SpaceBeforeCpp11BracedList = false;
LLVMStyle.SpaceBeforeSquareBrackets = false;
LLVMStyle.BitFieldColonSpacing = FormatStyle::BFCS_Both;
- LLVMStyle.SpacesInAngles = false;
+ LLVMStyle.SpacesInAngles = FormatStyle::SIAS_Never;
LLVMStyle.SpacesInConditionalStatement = false;
LLVMStyle.PenaltyBreakAssignment = prec::Assignment;
@@ -1013,7 +1118,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.PenaltyIndentedWhitespace = 0;
LLVMStyle.DisableFormat = false;
- LLVMStyle.SortIncludes = true;
+ LLVMStyle.SortIncludes = FormatStyle::SI_CaseSensitive;
LLVMStyle.SortJavaStaticImport = FormatStyle::SJSIO_Before;
LLVMStyle.SortUsingDeclarations = true;
LLVMStyle.StatementAttributeLikeMacros.push_back("Q_EMIT");
@@ -1029,6 +1134,9 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
if (Language == FormatStyle::LK_TableGen) {
LLVMStyle.SpacesInContainerLiterals = false;
}
+ if (LLVMStyle.isJson()) {
+ LLVMStyle.ColumnLimit = 0;
+ }
return LLVMStyle;
}
@@ -1103,7 +1211,7 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
"ParseTestProto",
"ParsePartialTestProto",
},
- /*CanonicalDelimiter=*/"",
+ /*CanonicalDelimiter=*/"pb",
/*BasedOnStyle=*/"google",
},
};
@@ -1216,7 +1324,7 @@ FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) {
"java",
"javax",
};
- ChromiumStyle.SortIncludes = true;
+ ChromiumStyle.SortIncludes = FormatStyle::SI_CaseSensitive;
} else if (Language == FormatStyle::LK_JavaScript) {
ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
ChromiumStyle.AllowShortLoopsOnASingleLine = false;
@@ -1330,29 +1438,31 @@ FormatStyle getMicrosoftStyle(FormatStyle::LanguageKind Language) {
FormatStyle getNoStyle() {
FormatStyle NoStyle = getLLVMStyle();
NoStyle.DisableFormat = true;
- NoStyle.SortIncludes = false;
+ NoStyle.SortIncludes = FormatStyle::SI_Never;
NoStyle.SortUsingDeclarations = false;
return NoStyle;
}
bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language,
FormatStyle *Style) {
- if (Name.equals_lower("llvm")) {
+ if (Name.equals_insensitive("llvm")) {
*Style = getLLVMStyle(Language);
- } else if (Name.equals_lower("chromium")) {
+ } else if (Name.equals_insensitive("chromium")) {
*Style = getChromiumStyle(Language);
- } else if (Name.equals_lower("mozilla")) {
+ } else if (Name.equals_insensitive("mozilla")) {
*Style = getMozillaStyle();
- } else if (Name.equals_lower("google")) {
+ } else if (Name.equals_insensitive("google")) {
*Style = getGoogleStyle(Language);
- } else if (Name.equals_lower("webkit")) {
+ } else if (Name.equals_insensitive("webkit")) {
*Style = getWebKitStyle();
- } else if (Name.equals_lower("gnu")) {
+ } else if (Name.equals_insensitive("gnu")) {
*Style = getGNUStyle();
- } else if (Name.equals_lower("microsoft")) {
+ } else if (Name.equals_insensitive("microsoft")) {
*Style = getMicrosoftStyle(Language);
- } else if (Name.equals_lower("none")) {
+ } else if (Name.equals_insensitive("none")) {
*Style = getNoStyle();
+ } else if (Name.equals_insensitive("inheritparentconfig")) {
+ Style->InheritsParentConfig = true;
} else {
return false;
}
@@ -1362,8 +1472,9 @@ bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language,
}
std::error_code parseConfiguration(llvm::MemoryBufferRef Config,
- FormatStyle *Style,
- bool AllowUnknownOptions) {
+ FormatStyle *Style, bool AllowUnknownOptions,
+ llvm::SourceMgr::DiagHandlerTy DiagHandler,
+ void *DiagHandlerCtxt) {
assert(Style);
FormatStyle::LanguageKind Language = Style->Language;
assert(Language != FormatStyle::LK_None);
@@ -1371,7 +1482,8 @@ std::error_code parseConfiguration(llvm::MemoryBufferRef Config,
return make_error_code(ParseError::Error);
Style->StyleSet.Clear();
std::vector<FormatStyle> Styles;
- llvm::yaml::Input Input(Config);
+ llvm::yaml::Input Input(Config, /*Ctxt=*/nullptr, DiagHandler,
+ DiagHandlerCtxt);
// DocumentListTraits<vector<FormatStyle>> uses the context to get default
// values for the fields, keys for which are missing from the configuration.
// Mapping also uses the context to get the language to find the correct
@@ -1659,10 +1771,12 @@ private:
Tok = Tok->Next;
}
}
- if (Style.DerivePointerAlignment)
+ if (Style.DerivePointerAlignment) {
Style.PointerAlignment = countVariableAlignments(AnnotatedLines) <= 0
? FormatStyle::PAS_Left
: FormatStyle::PAS_Right;
+ Style.ReferenceAlignment = FormatStyle::RAS_Pointer;
+ }
if (Style.Standard == FormatStyle::LS_Auto)
Style.Standard = hasCpp03IncompatibleFormat(AnnotatedLines)
? FormatStyle::LS_Latest
@@ -2209,10 +2323,23 @@ static void sortCppIncludes(const FormatStyle &Style,
for (unsigned i = 0, e = Includes.size(); i != e; ++i) {
Indices.push_back(i);
}
- llvm::stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
- return std::tie(Includes[LHSI].Priority, Includes[LHSI].Filename) <
- std::tie(Includes[RHSI].Priority, Includes[RHSI].Filename);
- });
+
+ if (Style.SortIncludes == FormatStyle::SI_CaseInsensitive) {
+ llvm::stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
+ const auto LHSFilenameLower = Includes[LHSI].Filename.lower();
+ const auto RHSFilenameLower = Includes[RHSI].Filename.lower();
+ return std::tie(Includes[LHSI].Priority, LHSFilenameLower,
+ Includes[LHSI].Filename) <
+ std::tie(Includes[RHSI].Priority, RHSFilenameLower,
+ Includes[RHSI].Filename);
+ });
+ } else {
+ llvm::stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
+ return std::tie(Includes[LHSI].Priority, Includes[LHSI].Filename) <
+ std::tie(Includes[RHSI].Priority, Includes[RHSI].Filename);
+ });
+ }
+
// The index of the include on which the cursor will be put after
// sorting/deduplicating.
unsigned CursorIndex;
@@ -2527,7 +2654,7 @@ tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code,
ArrayRef<tooling::Range> Ranges,
StringRef FileName, unsigned *Cursor) {
tooling::Replacements Replaces;
- if (!Style.SortIncludes)
+ if (!Style.SortIncludes || Style.DisableFormat)
return Replaces;
if (isLikelyXml(Code))
return Replaces;
@@ -2702,6 +2829,25 @@ reformat(const FormatStyle &Style, StringRef Code,
if (Expanded.Language == FormatStyle::LK_JavaScript && isMpegTS(Code))
return {tooling::Replacements(), 0};
+ // JSON only needs the formatting passing.
+ if (Style.isJson()) {
+ std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
+ auto Env =
+ std::make_unique<Environment>(Code, FileName, Ranges, FirstStartColumn,
+ NextStartColumn, LastStartColumn);
+ // Perform the actual formatting pass.
+ tooling::Replacements Replaces =
+ Formatter(*Env, Style, Status).process().first;
+ // add a replacement to remove the "x = " from the result.
+ if (!Replaces.add(tooling::Replacement(FileName, 0, 4, ""))) {
+ // apply the reformatting changes and the removal of "x = ".
+ if (applyAllReplacements(Code, Replaces)) {
+ return {Replaces, 0};
+ }
+ }
+ return {tooling::Replacements(), 0};
+ }
+
typedef std::function<std::pair<tooling::Replacements, unsigned>(
const Environment &)>
AnalyzerPass;
@@ -2850,23 +2996,26 @@ const char *StyleOptionHelpDescription =
static FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName) {
if (FileName.endswith(".java"))
return FormatStyle::LK_Java;
- if (FileName.endswith_lower(".js") || FileName.endswith_lower(".mjs") ||
- FileName.endswith_lower(".ts"))
+ if (FileName.endswith_insensitive(".js") ||
+ FileName.endswith_insensitive(".mjs") ||
+ FileName.endswith_insensitive(".ts"))
return FormatStyle::LK_JavaScript; // (module) JavaScript or TypeScript.
if (FileName.endswith(".m") || FileName.endswith(".mm"))
return FormatStyle::LK_ObjC;
- if (FileName.endswith_lower(".proto") ||
- FileName.endswith_lower(".protodevel"))
+ if (FileName.endswith_insensitive(".proto") ||
+ FileName.endswith_insensitive(".protodevel"))
return FormatStyle::LK_Proto;
- if (FileName.endswith_lower(".textpb") ||
- FileName.endswith_lower(".pb.txt") ||
- FileName.endswith_lower(".textproto") ||
- FileName.endswith_lower(".asciipb"))
+ if (FileName.endswith_insensitive(".textpb") ||
+ FileName.endswith_insensitive(".pb.txt") ||
+ FileName.endswith_insensitive(".textproto") ||
+ FileName.endswith_insensitive(".asciipb"))
return FormatStyle::LK_TextProto;
- if (FileName.endswith_lower(".td"))
+ if (FileName.endswith_insensitive(".td"))
return FormatStyle::LK_TableGen;
- if (FileName.endswith_lower(".cs"))
+ if (FileName.endswith_insensitive(".cs"))
return FormatStyle::LK_CSharp;
+ if (FileName.endswith_insensitive(".json"))
+ return FormatStyle::LK_Json;
return FormatStyle::LK_Cpp;
}
@@ -2905,21 +3054,36 @@ llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName,
if (!getPredefinedStyle(FallbackStyleName, Style.Language, &FallbackStyle))
return make_string_error("Invalid fallback style \"" + FallbackStyleName);
+ llvm::SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 1>
+ ChildFormatTextToApply;
+
if (StyleName.startswith("{")) {
// Parse YAML/JSON style from the command line.
- if (std::error_code ec = parseConfiguration(
- llvm::MemoryBufferRef(StyleName, "<command-line>"), &Style,
- AllowUnknownOptions))
+ StringRef Source = "<command-line>";
+ if (std::error_code ec =
+ parseConfiguration(llvm::MemoryBufferRef(StyleName, Source), &Style,
+ AllowUnknownOptions))
return make_string_error("Error parsing -style: " + ec.message());
- return Style;
+ if (Style.InheritsParentConfig)
+ ChildFormatTextToApply.emplace_back(
+ llvm::MemoryBuffer::getMemBuffer(StyleName, Source, false));
+ else
+ return Style;
}
- if (!StyleName.equals_lower("file")) {
+ // If the style inherits the parent configuration it is a command line
+ // configuration, which wants to inherit, so we have to skip the check of the
+ // StyleName.
+ if (!Style.InheritsParentConfig && !StyleName.equals_insensitive("file")) {
if (!getPredefinedStyle(StyleName, Style.Language, &Style))
return make_string_error("Invalid value for -style");
- return Style;
+ if (!Style.InheritsParentConfig)
+ return Style;
}
+ // Reset possible inheritance
+ Style.InheritsParentConfig = false;
+
// Look for .clang-format/_clang-format file in the file's parent directories.
SmallString<128> UnsuitableConfigFiles;
SmallString<128> Path(FileName);
@@ -2930,6 +3094,8 @@ llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName,
FilesToLookFor.push_back(".clang-format");
FilesToLookFor.push_back("_clang-format");
+ auto dropDiagnosticHandler = [](const llvm::SMDiagnostic &, void *) {};
+
for (StringRef Directory = Path; !Directory.empty();
Directory = llvm::sys::path::parent_path(Directory)) {
@@ -2966,7 +3132,36 @@ llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName,
}
LLVM_DEBUG(llvm::dbgs()
<< "Using configuration file " << ConfigFile << "\n");
- return Style;
+
+ if (!Style.InheritsParentConfig) {
+ if (ChildFormatTextToApply.empty())
+ return Style;
+
+ LLVM_DEBUG(llvm::dbgs() << "Applying child configurations\n");
+
+ for (const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) {
+ auto Ec = parseConfiguration(*MemBuf, &Style, AllowUnknownOptions,
+ dropDiagnosticHandler);
+ // It was already correctly parsed.
+ assert(!Ec);
+ static_cast<void>(Ec);
+ }
+
+ return Style;
+ }
+
+ LLVM_DEBUG(llvm::dbgs() << "Inherits parent configuration\n");
+
+ // Reset inheritance of style
+ Style.InheritsParentConfig = false;
+
+ ChildFormatTextToApply.emplace_back(std::move(*Text));
+
+ // Breaking out of the inner loop, since we don't want to parse
+ // .clang-format AND _clang-format, if both exist. Then we continue the
+ // inner loop (parent directories) in search for the parent
+ // configuration.
+ break;
}
}
}
@@ -2974,6 +3169,21 @@ llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName,
return make_string_error("Configuration file(s) do(es) not support " +
getLanguageName(Style.Language) + ": " +
UnsuitableConfigFiles);
+
+ if (!ChildFormatTextToApply.empty()) {
+ assert(ChildFormatTextToApply.size() == 1);
+
+ LLVM_DEBUG(llvm::dbgs()
+ << "Applying child configuration on fallback style\n");
+
+ auto Ec =
+ parseConfiguration(*ChildFormatTextToApply.front(), &FallbackStyle,
+ AllowUnknownOptions, dropDiagnosticHandler);
+ // It was already correctly parsed.
+ assert(!Ec);
+ static_cast<void>(Ec);
+ }
+
return FallbackStyle;
}