aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/clangformat/clangformatutils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/clangformat/clangformatutils.cpp')
-rw-r--r--src/plugins/clangformat/clangformatutils.cpp259
1 files changed, 186 insertions, 73 deletions
diff --git a/src/plugins/clangformat/clangformatutils.cpp b/src/plugins/clangformat/clangformatutils.cpp
index babe94da24..74c4165a34 100644
--- a/src/plugins/clangformat/clangformatutils.cpp
+++ b/src/plugins/clangformat/clangformatutils.cpp
@@ -26,6 +26,7 @@
#include "clangformatutils.h"
#include "clangformatconstants.h"
+#include "clangformatsettings.h"
#include <coreplugin/icore.h>
#include <cpptools/cppcodestylesettings.h>
@@ -33,6 +34,8 @@
#include <projectexplorer/project.h>
#include <projectexplorer/session.h>
+#include <QCryptographicHash>
+
using namespace clang;
using namespace format;
using namespace llvm;
@@ -42,6 +45,104 @@ using namespace TextEditor;
namespace ClangFormat {
+static clang::format::FormatStyle qtcStyle()
+{
+ clang::format::FormatStyle style = getLLVMStyle();
+ style.Language = FormatStyle::LK_Cpp;
+ style.AccessModifierOffset = -4;
+ style.AlignAfterOpenBracket = FormatStyle::BAS_Align;
+ style.AlignConsecutiveAssignments = false;
+ style.AlignConsecutiveDeclarations = false;
+ style.AlignEscapedNewlines = FormatStyle::ENAS_DontAlign;
+ style.AlignOperands = true;
+ style.AlignTrailingComments = true;
+ style.AllowAllParametersOfDeclarationOnNextLine = true;
+ style.AllowShortBlocksOnASingleLine = false;
+ style.AllowShortCaseLabelsOnASingleLine = false;
+ style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
+ style.AllowShortIfStatementsOnASingleLine = false;
+ style.AllowShortLoopsOnASingleLine = false;
+ style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_None;
+ style.AlwaysBreakBeforeMultilineStrings = false;
+ style.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes;
+ style.BinPackArguments = false;
+ style.BinPackParameters = false;
+ style.BraceWrapping.AfterClass = true;
+ style.BraceWrapping.AfterControlStatement = false;
+ style.BraceWrapping.AfterEnum = false;
+ style.BraceWrapping.AfterFunction = true;
+ style.BraceWrapping.AfterNamespace = false;
+ style.BraceWrapping.AfterObjCDeclaration = false;
+ style.BraceWrapping.AfterStruct = true;
+ style.BraceWrapping.AfterUnion = false;
+ style.BraceWrapping.BeforeCatch = false;
+ style.BraceWrapping.BeforeElse = false;
+ style.BraceWrapping.IndentBraces = false;
+ style.BraceWrapping.SplitEmptyFunction = false;
+ style.BraceWrapping.SplitEmptyRecord = false;
+ style.BraceWrapping.SplitEmptyNamespace = false;
+ style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
+ style.BreakBeforeBraces = FormatStyle::BS_Custom;
+ style.BreakBeforeTernaryOperators = true;
+ style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
+ style.BreakAfterJavaFieldAnnotations = false;
+ style.BreakStringLiterals = true;
+ style.ColumnLimit = 100;
+ style.CommentPragmas = "^ IWYU pragma:";
+ style.CompactNamespaces = false;
+ style.ConstructorInitializerAllOnOneLineOrOnePerLine = false;
+ style.ConstructorInitializerIndentWidth = 4;
+ style.ContinuationIndentWidth = 4;
+ style.Cpp11BracedListStyle = true;
+ style.DerivePointerAlignment = false;
+ style.DisableFormat = false;
+ style.ExperimentalAutoDetectBinPacking = false;
+ style.FixNamespaceComments = true;
+ style.ForEachMacros = {"forever", "foreach", "Q_FOREACH", "BOOST_FOREACH"};
+ style.IncludeStyle.IncludeCategories = {{"^<Q.*", 200}};
+ style.IncludeStyle.IncludeIsMainRegex = "(Test)?$";
+ style.IndentCaseLabels = false;
+ style.IndentWidth = 4;
+ style.IndentWrappedFunctionNames = false;
+ style.JavaScriptQuotes = FormatStyle::JSQS_Leave;
+ style.JavaScriptWrapImports = true;
+ style.KeepEmptyLinesAtTheStartOfBlocks = false;
+ // Do not add QT_BEGIN_NAMESPACE/QT_END_NAMESPACE as this will indent lines in between.
+ style.MacroBlockBegin = "";
+ style.MacroBlockEnd = "";
+ style.MaxEmptyLinesToKeep = 1;
+ style.NamespaceIndentation = FormatStyle::NI_None;
+ style.ObjCBlockIndentWidth = 4;
+ style.ObjCSpaceAfterProperty = false;
+ style.ObjCSpaceBeforeProtocolList = true;
+ style.PenaltyBreakAssignment = 150;
+ style.PenaltyBreakBeforeFirstCallParameter = 300;
+ style.PenaltyBreakComment = 500;
+ style.PenaltyBreakFirstLessLess = 400;
+ style.PenaltyBreakString = 600;
+ style.PenaltyExcessCharacter = 50;
+ style.PenaltyReturnTypeOnItsOwnLine = 300;
+ style.PointerAlignment = FormatStyle::PAS_Right;
+ style.ReflowComments = false;
+ style.SortIncludes = true;
+ style.SortUsingDeclarations = true;
+ style.SpaceAfterCStyleCast = true;
+ style.SpaceAfterTemplateKeyword = false;
+ style.SpaceBeforeAssignmentOperators = true;
+ style.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements;
+ style.SpaceInEmptyParentheses = false;
+ style.SpacesBeforeTrailingComments = 1;
+ style.SpacesInAngles = false;
+ style.SpacesInContainerLiterals = false;
+ style.SpacesInCStyleCastParentheses = false;
+ style.SpacesInParentheses = false;
+ style.SpacesInSquareBrackets = false;
+ style.Standard = FormatStyle::LS_Cpp11;
+ style.TabWidth = 4;
+ style.UseTab = FormatStyle::UT_Never;
+ return style;
+}
+
static void applyTabSettings(clang::format::FormatStyle &style, const TabSettings &settings)
{
style.IndentWidth = static_cast<unsigned>(settings.m_indentSize);
@@ -63,72 +164,86 @@ static void applyTabSettings(clang::format::FormatStyle &style, const TabSetting
}
}
-static void applyCppCodeStyleSettings(clang::format::FormatStyle &style,
- const CppCodeStyleSettings &settings)
+static bool useGlobalOverriddenSettings()
{
- style.IndentCaseLabels = settings.indentSwitchLabels;
- style.AlignOperands = settings.alignAssignments;
- style.NamespaceIndentation = FormatStyle::NI_None;
- if (settings.indentNamespaceBody)
- style.NamespaceIndentation = FormatStyle::NI_All;
+ return ClangFormatSettings::instance().overrideDefaultFile();
+}
- style.BraceWrapping.IndentBraces = false;
- if (settings.indentBlockBraces) {
- if (settings.indentClassBraces && settings.indentEnumBraces
- && settings.indentNamespaceBraces && settings.indentFunctionBraces) {
- style.BraceWrapping.IndentBraces = true;
- } else {
- style.BreakBeforeBraces = FormatStyle::BS_GNU;
- }
- }
+QString currentProjectUniqueId()
+{
+ const Project *project = SessionManager::startupProject();
+ if (!project)
+ return QString();
- if (settings.bindStarToIdentifier || settings.bindStarToRightSpecifier)
- style.PointerAlignment = FormatStyle::PAS_Right;
- else
- style.PointerAlignment = FormatStyle::PAS_Left;
+ return QString::fromUtf8(QCryptographicHash::hash(project->projectFilePath().toString().toUtf8(),
+ QCryptographicHash::Md5)
+ .toHex(0));
+}
+
+static bool useProjectOverriddenSettings()
+{
+ const Project *project = SessionManager::startupProject();
+ return project ? project->namedSettings(Constants::OVERRIDE_FILE_ID).toBool() : false;
+}
- style.AccessModifierOffset = settings.indentAccessSpecifiers
- ? 0
- : - static_cast<int>(style.IndentWidth);
+static Utils::FileName globalPath()
+{
+ return Utils::FileName::fromString(Core::ICore::userResourcePath());
}
static Utils::FileName projectPath()
{
const Project *project = SessionManager::startupProject();
if (project)
- return project->projectDirectory();
+ return globalPath().appendPath("clang-format").appendPath(currentProjectUniqueId());
return Utils::FileName();
}
-static Utils::FileName globalPath()
+static QString findConfig(Utils::FileName fileName)
{
- return Utils::FileName::fromString(Core::ICore::userResourcePath());
+ QDir parentDir(fileName.parentDir().toString());
+ while (!parentDir.exists(Constants::SETTINGS_FILE_NAME)
+ && !parentDir.exists(Constants::SETTINGS_FILE_ALT_NAME)) {
+ if (!parentDir.cdUp())
+ return QString();
+ }
+
+ if (parentDir.exists(Constants::SETTINGS_FILE_NAME))
+ return parentDir.filePath(Constants::SETTINGS_FILE_NAME);
+ return parentDir.filePath(Constants::SETTINGS_FILE_ALT_NAME);
}
-static QString configForFile(Utils::FileName fileName)
+static QString configForFile(Utils::FileName fileName, bool checkForSettings)
{
- Utils::FileName topProjectPath = projectPath();
- if (topProjectPath.isEmpty())
- return QString();
+ QDir overrideDir;
+ if (!checkForSettings || useProjectOverriddenSettings()) {
+ overrideDir = projectPath().toString();
+ if (!overrideDir.isEmpty() && overrideDir.exists(Constants::SETTINGS_FILE_NAME))
+ return overrideDir.filePath(Constants::SETTINGS_FILE_NAME);
+ }
- QDir projectDir(fileName.parentDir().toString());
- while (!projectDir.exists(Constants::SETTINGS_FILE_NAME)
- && !projectDir.exists(Constants::SETTINGS_FILE_ALT_NAME)) {
- if (projectDir.path() == topProjectPath.toString()
- || !Utils::FileName::fromString(projectDir.path()).isChildOf(topProjectPath)
- || !projectDir.cdUp()) {
- return QString();
- }
+ if (!checkForSettings || useGlobalOverriddenSettings()) {
+ overrideDir = globalPath().toString();
+ if (!overrideDir.isEmpty() && overrideDir.exists(Constants::SETTINGS_FILE_NAME))
+ return overrideDir.filePath(Constants::SETTINGS_FILE_NAME);
}
- if (projectDir.exists(Constants::SETTINGS_FILE_NAME))
- return projectDir.filePath(Constants::SETTINGS_FILE_NAME);
- return projectDir.filePath(Constants::SETTINGS_FILE_ALT_NAME);
+ return findConfig(fileName);
+}
+
+QString configForFile(Utils::FileName fileName)
+{
+ return configForFile(fileName, true);
+}
+
+Utils::FileName assumedPathForConfig(const QString &configFile)
+{
+ Utils::FileName fileName = Utils::FileName::fromString(configFile);
+ return fileName.parentDir().appendPath("test.cpp");
}
-static clang::format::FormatStyle constructStyle(bool isGlobal,
- const QByteArray &baseStyle = QByteArray())
+static clang::format::FormatStyle constructStyle(const QByteArray &baseStyle = QByteArray())
{
if (!baseStyle.isEmpty()) {
// Try to get the style for this base style.
@@ -144,21 +259,7 @@ static clang::format::FormatStyle constructStyle(bool isGlobal,
// Fallthrough to the default style.
}
- FormatStyle style = getLLVMStyle();
- style.BreakBeforeBraces = FormatStyle::BS_Custom;
-
- const CppCodeStyleSettings codeStyleSettings = isGlobal
- ? CppCodeStyleSettings::currentGlobalCodeStyle()
- : CppCodeStyleSettings::currentProjectCodeStyle()
- .value_or(CppCodeStyleSettings::currentGlobalCodeStyle());
- const TabSettings tabSettings = isGlobal
- ? CppCodeStyleSettings::currentGlobalTabSettings()
- : CppCodeStyleSettings::currentProjectTabSettings();
-
- applyTabSettings(style, tabSettings);
- applyCppCodeStyleSettings(style, codeStyleSettings);
-
- return style;
+ return qtcStyle();
}
void createStyleFileIfNeeded(bool isGlobal)
@@ -169,9 +270,21 @@ void createStyleFileIfNeeded(bool isGlobal)
if (QFile::exists(configFile))
return;
+ QDir().mkpath(path.parentDir().toString());
+ if (!isGlobal) {
+ const Project *project = SessionManager::startupProject();
+ Utils::FileName possibleProjectConfig = project->rootProjectDirectory().appendPath(
+ Constants::SETTINGS_FILE_NAME);
+ if (possibleProjectConfig.exists()) {
+ // Just copy th .clang-format if current project has one.
+ QFile::copy(possibleProjectConfig.toString(), configFile);
+ return;
+ }
+ }
+
std::fstream newStyleFile(configFile.toStdString(), std::fstream::out);
if (newStyleFile.is_open()) {
- newStyleFile << clang::format::configurationAsText(constructStyle(isGlobal));
+ newStyleFile << clang::format::configurationAsText(constructStyle());
newStyleFile.close();
}
}
@@ -198,17 +311,13 @@ static QByteArray configBaseStyleName(const QString &configFile)
.trimmed();
}
-clang::format::FormatStyle styleForFile(Utils::FileName fileName)
+static clang::format::FormatStyle styleForFile(Utils::FileName fileName, bool checkForSettings)
{
- bool isGlobal = false;
- QString configFile = configForFile(fileName);
- if (configFile.isEmpty()) {
- Utils::FileName path = fileName = globalPath();
- fileName.appendPath(Constants::SAMPLE_FILE_NAME);
- createStyleFileIfNeeded(true);
- configFile = path.appendPath(Constants::SETTINGS_FILE_NAME).toString();
- }
+ QString configFile = configForFile(fileName, checkForSettings);
+ if (configFile.isEmpty())
+ return constructStyle();
+ fileName = assumedPathForConfig(configFile);
Expected<FormatStyle> style = format::getStyle("file",
fileName.toString().toStdString(),
"none");
@@ -219,17 +328,21 @@ clang::format::FormatStyle styleForFile(Utils::FileName fileName)
// do nothing
});
- return constructStyle(isGlobal, configBaseStyleName(configFile));
+ return constructStyle(configBaseStyleName(configFile));
}
-clang::format::FormatStyle currentProjectStyle()
+clang::format::FormatStyle styleForFile(Utils::FileName fileName)
{
- return styleForFile(projectPath().appendPath(Constants::SAMPLE_FILE_NAME));
+ return styleForFile(fileName, true);
}
-clang::format::FormatStyle currentGlobalStyle()
+clang::format::FormatStyle currentProjectStyle()
{
- return styleForFile(globalPath().appendPath(Constants::SAMPLE_FILE_NAME));
+ return styleForFile(projectPath().appendPath(Constants::SAMPLE_FILE_NAME), false);
}
+clang::format::FormatStyle currentGlobalStyle()
+{
+ return styleForFile(globalPath().appendPath(Constants::SAMPLE_FILE_NAME), false);
}
+} // namespace ClangFormat