diff options
author | Dmitrii Akshintsev <dmitrii.akshintsev@qt.io> | 2023-12-05 10:38:43 +0100 |
---|---|---|
committer | Dmitrii Akshintsev <dmitrii.akshintsev@qt.io> | 2024-01-23 20:34:26 +0100 |
commit | bce3842fa0f5a8db4a2ad1104582798eaea81c66 (patch) | |
tree | a735cd6fd758984a4b8b3c1bd947b8ef2a0b4ed0 /tools | |
parent | 15dfa370c4f2c01d2b695f3d9a361a570a60d533 (diff) |
QmlFormat. Minor refactoring of the qmlformat.cpp
Breaking main (qmlformat.cpp) into smaller chunks,
providing better separation of concerns and improving readability
Change-Id: Iadc236d73d3da5e150cdfd41a34baa12d63da6a8
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/qmlformat/qmlformat.cpp | 122 |
1 files changed, 83 insertions, 39 deletions
diff --git a/tools/qmlformat/qmlformat.cpp b/tools/qmlformat/qmlformat.cpp index 326387cd7e..9ef37f7800 100644 --- a/tools/qmlformat/qmlformat.cpp +++ b/tools/qmlformat/qmlformat.cpp @@ -46,45 +46,16 @@ struct Options QStringList errors; }; -bool parseFile(const QString &filename, const Options &options) +// TODO refactor +// Move out to the LineWriterOptions class / helper +static LineWriterOptions composeLwOptions(const Options &options, QStringView code) { - auto envPtr = - DomEnvironment::create(QStringList(), - QQmlJS::Dom::DomEnvironment::Option::SingleThreaded - | QQmlJS::Dom::DomEnvironment::Option::NoDependencies); - DomItem tFile; // place where to store the loaded file - envPtr->loadFile( - FileToLoad::fromFileSystem(envPtr, filename), - [&tFile](Path, const DomItem &, const DomItem &newIt) { - tFile = newIt; // callback called when everything is loaded that receives the loaded - // external file pair (path, oldValue, newValue) - }, - LoadOption::DefaultLoad); - envPtr->loadPendingDependencies(); - DomItem qmlFile = tFile.fileObject(); - std::shared_ptr<QmlFile> qmlFilePtr = qmlFile.ownerAs<QmlFile>(); - if (!qmlFilePtr || !qmlFilePtr->isValid()) { - qmlFile.iterateErrors( - [](const DomItem &, const ErrorMessage &msg) { - errorToQDebug(msg); - return true; - }, - true); - qWarning().noquote() << "Failed to parse" << filename; - return false; - } - - // Turn AST back into source code - if (options.verbose) - qWarning().noquote() << "Dumping" << filename; - LineWriterOptions lwOptions; lwOptions.formatOptions.indentSize = options.indentWidth; lwOptions.formatOptions.useTabs = options.tabs; lwOptions.updateOptions = LineWriterOptions::Update::None; if (options.newline == "native") { // find out current line endings... - QStringView code = qmlFilePtr->code(); int newlineIndex = code.indexOf(QChar(u'\n')); int crIndex = code.indexOf(QChar(u'\r')); if (newlineIndex >= 0) { @@ -109,20 +80,93 @@ bool parseFile(const QString &filename, const Options &options) } else if (options.newline == "unix") { lwOptions.lineEndings = LineWriterOptions::LineEndings::Unix; } else { - qWarning().noquote() << "Unknown line ending type" << options.newline; - return false; + qWarning().noquote() << "Unknown line ending type" << options.newline << ", using default"; } if (options.normalize) lwOptions.attributesSequence = LineWriterOptions::AttributesSequence::Normalize; else lwOptions.attributesSequence = LineWriterOptions::AttributesSequence::Preserve; - WriteOutChecks checks = WriteOutCheck::Default; - if (options.force || qmlFilePtr->code().size() > 32000) - checks = WriteOutCheck::None; lwOptions.objectsSpacing = options.objectsSpacing; lwOptions.functionsSpacing = options.functionsSpacing; + return lwOptions; +} + +static void logParsingErrors(const DomItem &fileItem, const QString &filename) +{ + fileItem.iterateErrors( + [](const DomItem &, const ErrorMessage &msg) { + errorToQDebug(msg); + return true; + }, + true); + qWarning().noquote() << "Failed to parse" << filename; +} + +// TODO +// refactor this workaround. ExternalOWningItem is not recognized as an owning type +// in ownerAs. +static std::shared_ptr<ExternalOwningItem> getFileItemOwner(const DomItem &fileItem) +{ + std::shared_ptr<ExternalOwningItem> filePtr = nullptr; + switch (fileItem.internalKind()) { + case DomType::JsFile: + filePtr = fileItem.ownerAs<JsFile>(); + break; + default: + filePtr = fileItem.ownerAs<QmlFile>(); + break; + } + return filePtr; +} + +// TODO refactor +// Introduce better encapsulation and separation of concerns and move to DOM API +// returns a DomItem corresponding to the loaded file and bool indicating the validity of the file +static std::pair<DomItem, bool> parse(const QString &filename) +{ + auto envPtr = + DomEnvironment::create(QStringList(), + QQmlJS::Dom::DomEnvironment::Option::SingleThreaded + | QQmlJS::Dom::DomEnvironment::Option::NoDependencies); + // placeholder for a node + // containing metadata (ExternalItemInfo) about the loaded file + DomItem fMetadataItem; + envPtr->loadFile( + FileToLoad::fromFileSystem(envPtr, filename), + // callback called when everything is loaded that receives the + // loaded external file pair (path, oldValue, newValue) + [&fMetadataItem](Path, const DomItem &, const DomItem &extItemInfo) { + fMetadataItem = extItemInfo; + }, + LoadOption::DefaultLoad); + auto fItem = fMetadataItem.fileObject(); + auto filePtr = getFileItemOwner(fItem); + return { fItem, filePtr && filePtr->isValid() }; +} + +static bool parseFile(const QString &filename, const Options &options) +{ + const auto [fileItem, validFile] = parse(filename); + if (!validFile) { + logParsingErrors(fileItem, filename); + return false; + } + + // Turn AST back into source code + if (options.verbose) + qWarning().noquote() << "Dumping" << filename; + + const auto code = getFileItemOwner(fileItem)->code(); + auto lwOptions = composeLwOptions(options, code); + WriteOutChecks checks = WriteOutCheck::Default; + //Disable writeOutChecks for some usecases + if (options.force || + code.size() > 32000 || + fileItem.internalKind() == DomType::JsFile) { + checks = WriteOutCheck::None; + } MutableDomItem res; if (options.inplace) { @@ -130,13 +174,13 @@ bool parseFile(const QString &filename, const Options &options) qWarning().noquote() << "Writing to file" << filename; FileWriter fw; const unsigned numberOfBackupFiles = 0; - res = qmlFile.writeOut(filename, numberOfBackupFiles, lwOptions, &fw, checks); + res = fileItem.writeOut(filename, numberOfBackupFiles, lwOptions, &fw, checks); } else { QFile out; out.open(stdout, QIODevice::WriteOnly); LineWriter lw([&out](QStringView s) { out.write(s.toUtf8()); }, filename, lwOptions); OutWriter ow(lw); - res = qmlFile.writeOutForFile(ow, checks); + res = fileItem.writeOutForFile(ow, checks); ow.flush(); } return bool(res); |