// Copyright (C) 2020 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QMLDOMOUTWRITER_P_H #define QMLDOMOUTWRITER_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include "qqmldom_global.h" #include "qqmldom_fwd_p.h" #include "qqmldomattachedinfo_p.h" #include "qqmldomlinewriter_p.h" #include QT_BEGIN_NAMESPACE namespace QQmlJS { namespace Dom { class QMLDOM_EXPORT OutWriterState { public: OutWriterState(const Path &itPath, const DomItem &it, const FileLocations::Tree &fLoc); void closeState(OutWriter &); Path itemCanonicalPath; DomItem item; PendingSourceLocationId fullRegionId; FileLocations::Tree currentMap; QMap pendingRegions; QMap pendingComments; }; class QMLDOM_EXPORT OutWriter { public: int indent = 0; int indenterId = -1; bool indentNextlines = false; bool skipComments = false; LineWriter &lineWriter; Path currentPath; FileLocations::Tree topLocation; QString writtenStr; UpdatedScriptExpression::Tree reformattedScriptExpressions; QList states; explicit OutWriter(LineWriter &lw) : lineWriter(lw), topLocation(FileLocations::createTree(Path())), reformattedScriptExpressions(UpdatedScriptExpression::createTree(Path())) { lineWriter.addInnerSink([this](QStringView s) { writtenStr.append(s); }); indenterId = lineWriter.addTextAddCallback([this](LineWriter &, LineWriter::TextAddType tt) { if (indentNextlines && tt == LineWriter::TextAddType::Normal && QStringView(lineWriter.currentLine()).trimmed().isEmpty()) lineWriter.setLineIndent(indent); return true; }); } OutWriterState &state(int i = 0); int increaseIndent(int level = 1) { int oldIndent = indent; indent += lineWriter.options().formatOptions.indentSize * level; return oldIndent; } int decreaseIndent(int level = 1, int expectedIndent = -1) { indent -= lineWriter.options().formatOptions.indentSize * level; Q_ASSERT(expectedIndent < 0 || expectedIndent == indent); return indent; } void itemStart(const DomItem &it); void itemEnd(const DomItem &it); void regionStart(FileLocationRegion region); void regionEnd(FileLocationRegion regino); quint32 counter() const { return lineWriter.counter(); } OutWriter &writeRegion(FileLocationRegion region, QStringView toWrite); OutWriter &writeRegion(FileLocationRegion region); OutWriter &ensureNewline(int nNewlines = 1) { lineWriter.ensureNewline(nNewlines); return *this; } OutWriter &ensureSpace() { lineWriter.ensureSpace(); return *this; } OutWriter &ensureSpace(QStringView space) { lineWriter.ensureSpace(space); return *this; } OutWriter &newline() { lineWriter.newline(); return *this; } OutWriter &space() { lineWriter.space(); return *this; } OutWriter &write(QStringView v, LineWriter::TextAddType t = LineWriter::TextAddType::Normal) { lineWriter.write(v, t); return *this; } OutWriter &write(QStringView v, SourceLocation *toUpdate) { lineWriter.write(v, toUpdate); return *this; } void flush() { lineWriter.flush(); } void eof(bool ensureNewline = true) { lineWriter.eof(ensureNewline); } int addNewlinesAutospacerCallback(int nLines) { return lineWriter.addNewlinesAutospacerCallback(nLines); } int addTextAddCallback(std::function callback) { return lineWriter.addTextAddCallback(callback); } bool removeTextAddCallback(int i) { return lineWriter.removeTextAddCallback(i); } void addReformattedScriptExpression(const Path &p, const std::shared_ptr &exp) { if (auto updExp = UpdatedScriptExpression::ensure(reformattedScriptExpressions, p, AttachedInfo::PathType::Canonical)) { updExp->info().expr = exp; } } DomItem restoreWrittenFileItem(const DomItem &fileItem); private: DomItem writtenQmlFileItem(const DomItem &fileItem, const Path &filePath); DomItem writtenJsFileItem(const DomItem &fileItem, const Path &filePath); static void logScriptExprUpdateSkipped( const DomItem &exprItem, const Path &exprPath, const std::shared_ptr &formattedExpr); }; } // end namespace Dom } // end namespace QQmlJS QT_END_NAMESPACE #endif // QMLDOMOUTWRITER_P_H