1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25 
26 #include "gtest-creator-printing.h"
27 #include "gtest-std-printing.h"
28 
29 #include "gtest-qt-printing.h"
30 
31 #include <gtest/gtest-printers.h>
32 #include <gmock/gmock-matchers.h>
33 
34 #include <clangcodemodelclientmessages.h>
35 #include <clangcodemodelservermessages.h>
36 #include <clangtools/clangtoolsdiagnostic.h>
37 #include <debugger/analyzer/diagnosticlocation.h>
38 #include <modelnode.h>
39 #include <projectstorage/projectstoragetypes.h>
40 #include <projectstorage/sourcepathcachetypes.h>
41 #include <sqlitesessionchangeset.h>
42 #include <sqlitevalue.h>
43 #include <tooltipinfo.h>
44 #include <utils/fileutils.h>
45 #include <utils/linecolumn.h>
46 #include <variantproperty.h>
47 #include <qmldesigner/designercore/imagecache/imagecachestorageinterface.h>
48 
49 #include <sqlite.h>
50 
PrintTo(const Utf8String & text,::std::ostream * os)51 void PrintTo(const Utf8String &text, ::std::ostream *os)
52 {
53     *os << text;
54 }
55 
56 namespace Utils {
57 
operator <<(std::ostream & out,const LineColumn & lineColumn)58 std::ostream &operator<<(std::ostream &out, const LineColumn &lineColumn)
59 {
60     return out << "(" << lineColumn.line << ", " << lineColumn.column << ")";
61 }
62 namespace {
toText(Utils::Language language)63 const char * toText(Utils::Language language)
64 {
65     using Utils::Language;
66 
67     switch (language) {
68     case Language::C:
69         return "C";
70     case Language::Cxx:
71         return "Cxx";
72     case Language::None:
73         return "None";
74     }
75 
76     return "";
77 }
78 } // namespace
79 
operator <<(std::ostream & out,const Utils::Language & language)80 std::ostream &operator<<(std::ostream &out, const Utils::Language &language)
81 {
82     return out << "Utils::" << toText(language);
83 }
84 
85 namespace {
toText(Utils::LanguageVersion languageVersion)86 const char * toText(Utils::LanguageVersion languageVersion)
87 {
88     using Utils::LanguageVersion;
89 
90     switch (languageVersion) {
91     case LanguageVersion::C11:
92         return "C11";
93     case LanguageVersion::C18:
94         return "C18";
95     case LanguageVersion::C89:
96         return "C89";
97     case LanguageVersion::C99:
98         return "C99";
99     case LanguageVersion::CXX03:
100         return "CXX03";
101     case LanguageVersion::CXX11:
102         return "CXX11";
103     case LanguageVersion::CXX14:
104         return "CXX14";
105     case LanguageVersion::CXX17:
106         return "CXX17";
107     case LanguageVersion::CXX20:
108         return "CXX20";
109     case LanguageVersion::CXX2b:
110         return "CXX2b";
111     case LanguageVersion::CXX98:
112         return "CXX98";
113     case LanguageVersion::None:
114         return "None";
115     }
116 
117     return "";
118 }
119 } // namespace
120 
operator <<(std::ostream & out,const Utils::LanguageVersion & languageVersion)121 std::ostream &operator<<(std::ostream &out, const Utils::LanguageVersion &languageVersion)
122 {
123      return out << "Utils::" << toText(languageVersion);
124 }
125 
126 namespace {
toText(Utils::LanguageExtension extension,std::string prefix={})127 const std::string toText(Utils::LanguageExtension extension, std::string prefix = {})
128 {
129     std::stringstream out;
130     using Utils::LanguageExtension;
131 
132     if (extension == LanguageExtension::None) {
133         out << prefix << "None";
134     } else if (extension == LanguageExtension::All) {
135         out << prefix << "All";
136     } else {
137         std::string split = "";
138         if (extension == LanguageExtension::Gnu) {
139             out << prefix << "Gnu";
140             split = " | ";
141         }
142         if (extension == LanguageExtension::Microsoft) {
143             out << split << prefix << "Microsoft";
144             split = " | ";
145         }
146         if (extension == LanguageExtension::Borland) {
147             out << split << prefix << "Borland";
148             split = " | ";
149         }
150         if (extension == LanguageExtension::OpenMP) {
151             out << split << prefix << "OpenMP";
152             split = " | ";
153         }
154         if (extension == LanguageExtension::ObjectiveC) {
155             out << split << prefix << "ObjectiveC";
156         }
157     }
158 
159     return out.str();
160 }
161 } // namespace
162 
operator <<(std::ostream & out,const Utils::LanguageExtension & languageExtension)163 std::ostream &operator<<(std::ostream &out, const Utils::LanguageExtension &languageExtension)
164 {
165     return out << toText(languageExtension, "Utils::");
166 }
167 
PrintTo(Utils::SmallStringView text,::std::ostream * os)168 void PrintTo(Utils::SmallStringView text, ::std::ostream *os)
169 {
170     *os << "\"" << text << "\"";
171 }
172 
PrintTo(const Utils::SmallString & text,::std::ostream * os)173 void PrintTo(const Utils::SmallString &text, ::std::ostream *os)
174 {
175     *os << "\"" << text << "\"";
176 }
177 
PrintTo(const Utils::PathString & text,::std::ostream * os)178 void PrintTo(const Utils::PathString &text, ::std::ostream *os)
179 {
180     *os << "\"" << text << "\"";
181 }
182 
operator <<(std::ostream & out,const FilePath & filePath)183 std::ostream &operator<<(std::ostream &out, const FilePath &filePath)
184 {
185     return out << filePath.toString();
186 }
187 
188 } // namespace Utils
189 
190 namespace Sqlite {
operator <<(std::ostream & out,const Value & value)191 std::ostream &operator<<(std::ostream &out, const Value &value)
192 {
193     out << "(";
194 
195     switch (value.type()) {
196     case Sqlite::ValueType::Integer:
197         out << value.toInteger();
198         break;
199     case Sqlite::ValueType::Float:
200         out << value.toFloat();
201         break;
202     case Sqlite::ValueType::String:
203         out << "\"" << value.toStringView() << "\"";
204         break;
205     case Sqlite::ValueType::Blob:
206         out << "blob";
207         break;
208     case Sqlite::ValueType::Null:
209         out << "null";
210         break;
211     }
212 
213     return out << ")";
214 }
215 
operator <<(std::ostream & out,const ValueView & value)216 std::ostream &operator<<(std::ostream &out, const ValueView &value)
217 {
218     out << "(";
219 
220     switch (value.type()) {
221     case Sqlite::ValueType::Integer:
222         out << value.toInteger();
223         break;
224     case Sqlite::ValueType::Float:
225         out << value.toFloat();
226         break;
227     case Sqlite::ValueType::String:
228         out << "\"" << value.toStringView() << "\"";
229         break;
230     case Sqlite::ValueType::Blob:
231         out << "blob";
232         break;
233     case Sqlite::ValueType::Null:
234         out << "null";
235         break;
236     }
237 
238     return out << ")";
239 }
240 
241 namespace {
operationText(int operation)242 Utils::SmallStringView operationText(int operation)
243 {
244     switch (operation) {
245     case SQLITE_INSERT:
246         return "INSERT";
247     case SQLITE_UPDATE:
248         return "UPDATE";
249     case SQLITE_DELETE:
250         return "DELETE";
251     }
252 
253     return {};
254 }
255 
operator <<(std::ostream & out,sqlite3_changeset_iter * iter)256 std::ostream &operator<<(std::ostream &out, sqlite3_changeset_iter *iter)
257 {
258     out << "(";
259 
260     const char *tableName = nullptr;
261     int columns = 0;
262     int operation = 0;
263     sqlite3_value *value = nullptr;
264 
265     sqlite3changeset_op(iter, &tableName, &columns, &operation, 0);
266 
267     out << operationText(operation) << " " << tableName << " {";
268 
269     if (operation == SQLITE_UPDATE || operation == SQLITE_DELETE) {
270         out << "Old: [";
271 
272         for (int i = 0; i < columns; i++) {
273             sqlite3changeset_old(iter, i, &value);
274 
275             if (value)
276                 out << " " << sqlite3_value_text(value);
277             else
278                 out << " -";
279         }
280         out << "]";
281     }
282 
283     if (operation == SQLITE_UPDATE)
284         out << ", ";
285 
286     if (operation == SQLITE_UPDATE || operation == SQLITE_INSERT) {
287         out << "New: [";
288         for (int i = 0; i < columns; i++) {
289             sqlite3changeset_new(iter, i, &value);
290 
291             if (value)
292                 out << " " << sqlite3_value_text(value);
293             else
294                 out << " -";
295         }
296         out << "]";
297     }
298 
299     out << "})";
300 
301     return out;
302 }
303 
toText(Operation operation)304 const char *toText(Operation operation)
305 {
306     switch (operation) {
307     case Operation::Invalid:
308         return "Invalid";
309     case Operation::Insert:
310         return "Invalid";
311     case Operation::Update:
312         return "Invalid";
313     case Operation::Delete:
314         return "Invalid";
315     }
316 
317     return "";
318 }
319 
toText(LockingMode lockingMode)320 const char *toText(LockingMode lockingMode)
321 {
322     switch (lockingMode) {
323     case LockingMode::Default:
324         return "Default";
325     case LockingMode::Normal:
326         return "Normal";
327     case LockingMode::Exclusive:
328         return "Exclusive";
329     }
330 
331     return "";
332 }
333 } // namespace
334 
operator <<(std::ostream & out,const SessionChangeSet & changeset)335 std::ostream &operator<<(std::ostream &out, const SessionChangeSet &changeset)
336 {
337     sqlite3_changeset_iter *iter = nullptr;
338     sqlite3changeset_start(&iter, changeset.size(), const_cast<void *>(changeset.data()));
339 
340     out << "ChangeSets([";
341 
342     if (SQLITE_ROW == sqlite3changeset_next(iter)) {
343         out << iter;
344         while (SQLITE_ROW == sqlite3changeset_next(iter))
345             out << ", " << iter;
346     }
347 
348     sqlite3changeset_finalize(iter);
349 
350     out << "])";
351 
352     return out;
353 }
354 
operator <<(std::ostream & out,LockingMode lockingMode)355 std::ostream &operator<<(std::ostream &out, LockingMode lockingMode)
356 {
357     return out << toText(lockingMode);
358 }
359 
operator <<(std::ostream & out,Operation operation)360 std::ostream &operator<<(std::ostream &out, Operation operation)
361 {
362     return out << toText(operation);
363 }
364 
365 namespace SessionChangeSetInternal {
366 namespace {
367 
toText(State state)368 const char *toText(State state)
369 {
370     switch (state) {
371     case State::Invalid:
372         return "Invalid";
373     case State::Row:
374         return "Row";
375     case State::Done:
376         return "Done";
377     }
378 
379     return "";
380 }
381 } // namespace
382 
operator <<(std::ostream & out,SentinelIterator)383 std::ostream &operator<<(std::ostream &out, SentinelIterator)
384 {
385     return out << "sentinel";
386 }
387 
operator <<(std::ostream & out,State state)388 std::ostream &operator<<(std::ostream &out, State state)
389 {
390     return out << toText(state);
391 }
392 
operator <<(std::ostream & out,const Tuple & tuple)393 std::ostream &operator<<(std::ostream &out, const Tuple &tuple)
394 {
395     return out << "(" << tuple.operation << ", " << tuple.columnCount << ")";
396 }
397 
operator <<(std::ostream & out,const ValueViews & valueViews)398 std::ostream &operator<<(std::ostream &out, const ValueViews &valueViews)
399 {
400     return out << "(" << valueViews.newValue << ", " << valueViews.oldValue << ")";
401 }
402 
operator <<(std::ostream & out,const ConstIterator & iterator)403 std::ostream &operator<<(std::ostream &out, const ConstIterator &iterator)
404 {
405     return out << "(" << (*iterator) << ", " << iterator.state() << ")";
406 }
407 
operator <<(std::ostream & out,const ConstTupleIterator & iterator)408 std::ostream &operator<<(std::ostream &out, const ConstTupleIterator &iterator)
409 {
410     auto value = *iterator;
411 
412     return out << "(" << value.newValue << ", " << value.newValue << ")";
413 }
414 
415 } // namespace SessionChangeSetInternal
416 } // namespace Sqlite
417 
418 namespace ClangBackEnd {
419 
operator <<(std::ostream & os,const FollowSymbolResult & result)420 std::ostream &operator<<(std::ostream &os, const FollowSymbolResult &result)
421 {
422     os << "("
423        << result.range
424        << ", " << result.isResultOnlyForFallBack
425        << ")";
426 
427     return os;
428 }
429 
operator <<(std::ostream & os,const FollowSymbolMessage & message)430 std::ostream &operator<<(std::ostream &os, const FollowSymbolMessage &message)
431 {
432       os << "("
433          << message.fileContainer << ", "
434          << message.ticketNumber << ", "
435          << message.result << ", "
436          << ")";
437 
438     return os;
439 }
440 
operator <<(std::ostream & os,const RequestCompletionsMessage & message)441 std::ostream &operator<<(std::ostream &os, const RequestCompletionsMessage &message)
442 {
443     os << "("
444        << message.filePath << ", "
445        << message.line << ", "
446        << message.column << ", "
447        << message.ticketNumber << ", "
448        << message.funcNameStartLine << ", "
449        << message.funcNameStartColumn
450 
451        << ")";
452 
453      return os;
454 }
455 
operator <<(std::ostream & os,const DocumentsOpenedMessage & message)456 std::ostream &operator<<(std::ostream &os, const DocumentsOpenedMessage &message)
457 {
458     os << "DocumentsOpenedMessage("
459        << message.fileContainers << ", "
460        << message.currentEditorFilePath << ", "
461        << message.visibleEditorFilePaths << ")";
462 
463     return os;
464 }
465 
operator <<(std::ostream & os,const EndMessage &)466 std::ostream &operator<<(std::ostream &os, const EndMessage &/*message*/)
467 {
468     return os << "()";
469 }
470 
operator <<(std::ostream & os,const AliveMessage &)471 std::ostream &operator<<(std::ostream &os, const AliveMessage &/*message*/)
472 {
473     return os << "()";
474 }
475 
operator <<(std::ostream & os,const CompletionsMessage & message)476 std::ostream &operator<<(std::ostream &os, const CompletionsMessage &message)
477 {
478     os << "("
479        << message.codeCompletions << ", "
480        << message.ticketNumber
481 
482        << ")";
483 
484     return os;
485 }
486 
operator <<(std::ostream & os,const AnnotationsMessage & message)487 std::ostream &operator<<(std::ostream &os, const AnnotationsMessage &message)
488 {
489     os << "AnnotationsMessage("
490        << message.fileContainer
491        << "," << message.diagnostics.size()
492        << "," << !message.firstHeaderErrorDiagnostic.text.isEmpty()
493        << "," << message.tokenInfos.size()
494        << "," << message.skippedPreprocessorRanges.size()
495        << ")";
496 
497     return os;
498 }
499 
operator <<(std::ostream & os,const ReferencesMessage & message)500 std::ostream &operator<<(std::ostream &os, const ReferencesMessage &message)
501 {
502       os << "("
503          << message.fileContainer << ", "
504          << message.ticketNumber << ", "
505          << message.isLocalVariable << ", "
506          << message.references << ", "
507          << ")";
508 
509     return os;
510 }
511 
operator <<(std::ostream & os,const ToolTipMessage & message)512 std::ostream &operator<<(std::ostream &os, const ToolTipMessage &message)
513 {
514       os << "("
515          << message.fileContainer << ", "
516          << message.ticketNumber << ", "
517          << message.toolTipInfo << ", "
518          << ")";
519 
520     return os;
521 }
522 
operator <<(std::ostream & os,const EchoMessage &)523 std::ostream &operator<<(std::ostream &os, const EchoMessage &/*message*/)
524 {
525      return os << "()";
526 }
527 
operator <<(std::ostream & os,const DocumentsClosedMessage & message)528 std::ostream &operator<<(std::ostream &os, const DocumentsClosedMessage &message)
529 {
530     os << "("
531        << message.fileContainers
532        << ")";
533 
534     return os;
535 }
536 
operator <<(std::ostream & os,const CodeCompletion & message)537 std::ostream &operator<<(std::ostream &os, const CodeCompletion &message)
538 {
539     os << "("
540        << message.text << ", "
541        << message.priority << ", "
542        << message.completionKind << ", "
543        << message.availability << ", "
544        << message.hasParameters
545        << ")";
546 
547     return os;
548 }
549 
operator <<(std::ostream & os,const CodeCompletionChunk & chunk)550 std::ostream &operator<<(std::ostream &os, const CodeCompletionChunk &chunk)
551 {
552     os << "("
553        << chunk.kind << ", "
554        << chunk.text;
555 
556     if (chunk.isOptional)
557         os << ", optional";
558 
559     os << ")";
560 
561     return os;
562 }
563 
severityToText(DiagnosticSeverity severity)564 static const char *severityToText(DiagnosticSeverity severity)
565 {
566     switch (severity) {
567         case DiagnosticSeverity::Ignored: return "Ignored";
568         case DiagnosticSeverity::Note: return "Note";
569         case DiagnosticSeverity::Warning: return "Warning";
570         case DiagnosticSeverity::Error: return "Error";
571         case DiagnosticSeverity::Fatal: return "Fatal";
572     }
573 
574     Q_UNREACHABLE();
575 }
576 
operator <<(std::ostream & os,const DiagnosticContainer & container)577 std::ostream &operator<<(std::ostream &os, const DiagnosticContainer &container)
578 {
579     os << "("
580        << severityToText(container.severity) << ": "
581        << container.text << ", "
582        << container.category << ", "
583        << container.enableOption << ", "
584        << container.location << ", "
585        << container.ranges << ", "
586        << container.fixIts << ", "
587        << container.children << ")";
588 
589     return os;
590 }
591 
operator <<(std::ostream & os,const FileContainer & container)592 std::ostream &operator<<(std::ostream &os, const FileContainer &container)
593 {
594     os << "("
595         << container.filePath << ", "
596         << container.compilationArguments << ", "
597         << container.documentRevision << ", "
598         << container.textCodecName;
599 
600     if (container.hasUnsavedFileContent)
601         os << ", "
602            << container.unsavedFileContent;
603 
604     os << ")";
605 
606     return os;
607 }
608 
operator <<(std::ostream & os,const FixItContainer & container)609 std::ostream &operator<<(std::ostream &os, const FixItContainer &container)
610 {
611     os << "("
612        << container.text << ", "
613        << container.range
614        << ")";
615 
616     return os;
617 }
618 
619 #define RETURN_TEXT_FOR_CASE(enumValue) case HighlightingType::enumValue: return #enumValue
highlightingTypeToCStringLiteral(HighlightingType type)620 static const char *highlightingTypeToCStringLiteral(HighlightingType type)
621 {
622     switch (type) {
623         RETURN_TEXT_FOR_CASE(Invalid);
624         RETURN_TEXT_FOR_CASE(Comment);
625         RETURN_TEXT_FOR_CASE(Keyword);
626         RETURN_TEXT_FOR_CASE(StringLiteral);
627         RETURN_TEXT_FOR_CASE(NumberLiteral);
628         RETURN_TEXT_FOR_CASE(Function);
629         RETURN_TEXT_FOR_CASE(VirtualFunction);
630         RETURN_TEXT_FOR_CASE(Type);
631         RETURN_TEXT_FOR_CASE(LocalVariable);
632         RETURN_TEXT_FOR_CASE(Parameter);
633         RETURN_TEXT_FOR_CASE(GlobalVariable);
634         RETURN_TEXT_FOR_CASE(Field);
635         RETURN_TEXT_FOR_CASE(Enumeration);
636         RETURN_TEXT_FOR_CASE(Operator);
637         RETURN_TEXT_FOR_CASE(Preprocessor);
638         RETURN_TEXT_FOR_CASE(Label);
639         RETURN_TEXT_FOR_CASE(FunctionDefinition);
640         RETURN_TEXT_FOR_CASE(OutputArgument);
641         RETURN_TEXT_FOR_CASE(OverloadedOperator);
642         RETURN_TEXT_FOR_CASE(PreprocessorDefinition);
643         RETURN_TEXT_FOR_CASE(PreprocessorExpansion);
644         RETURN_TEXT_FOR_CASE(PrimitiveType);
645         RETURN_TEXT_FOR_CASE(Punctuation);
646         RETURN_TEXT_FOR_CASE(Declaration);
647         RETURN_TEXT_FOR_CASE(Namespace);
648         RETURN_TEXT_FOR_CASE(Class);
649         RETURN_TEXT_FOR_CASE(Struct);
650         RETURN_TEXT_FOR_CASE(Enum);
651         RETURN_TEXT_FOR_CASE(Union);
652         RETURN_TEXT_FOR_CASE(TypeAlias);
653         RETURN_TEXT_FOR_CASE(Typedef);
654         RETURN_TEXT_FOR_CASE(QtProperty);
655         RETURN_TEXT_FOR_CASE(ObjectiveCClass);
656         RETURN_TEXT_FOR_CASE(ObjectiveCCategory);
657         RETURN_TEXT_FOR_CASE(ObjectiveCProtocol);
658         RETURN_TEXT_FOR_CASE(ObjectiveCInterface);
659         RETURN_TEXT_FOR_CASE(ObjectiveCImplementation);
660         RETURN_TEXT_FOR_CASE(ObjectiveCProperty);
661         RETURN_TEXT_FOR_CASE(ObjectiveCMethod);
662         RETURN_TEXT_FOR_CASE(TemplateTypeParameter);
663         RETURN_TEXT_FOR_CASE(TemplateTemplateParameter);
664         RETURN_TEXT_FOR_CASE(AngleBracketOpen);
665         RETURN_TEXT_FOR_CASE(AngleBracketClose);
666         RETURN_TEXT_FOR_CASE(DoubleAngleBracketClose);
667         RETURN_TEXT_FOR_CASE(TernaryIf);
668         RETURN_TEXT_FOR_CASE(TernaryElse);
669     }
670 
671     return "";
672 }
673 #undef RETURN_TEXT_FOR_CASE
674 
operator <<(std::ostream & os,HighlightingType highlightingType)675 std::ostream &operator<<(std::ostream &os, HighlightingType highlightingType)
676 {
677     return os << highlightingTypeToCStringLiteral(highlightingType);
678 }
679 
operator <<(std::ostream & os,HighlightingTypes types)680 std::ostream &operator<<(std::ostream &os, HighlightingTypes types)
681 {
682     os << "("
683        << types.mainHighlightingType;
684 
685     if (!types.mixinHighlightingTypes.empty())
686        os << ", "<< types.mixinHighlightingTypes;
687 
688     os << ")";
689 
690     return os;
691 }
692 
operator <<(std::ostream & os,const ExtraInfo & extraInfo)693 std::ostream &operator<<(std::ostream &os, const ExtraInfo &extraInfo)
694 {
695     os << "("
696        << extraInfo.token << ", "
697        << extraInfo.typeSpelling << ", "
698        << extraInfo.semanticParentTypeSpelling << ", "
699        << static_cast<uint>(extraInfo.accessSpecifier) << ", "
700        << static_cast<uint>(extraInfo.storageClass) << ", "
701        << extraInfo.identifier << ", "
702        << extraInfo.includeDirectivePath << ", "
703        << extraInfo.declaration << ", "
704        << extraInfo.definition << ", "
705        << extraInfo.signal << ", "
706        << extraInfo.slot
707        << ")";
708     return os;
709 }
710 
operator <<(std::ostream & os,const TokenInfoContainer & container)711 std::ostream &operator<<(std::ostream &os, const TokenInfoContainer &container)
712 {
713     os << "("
714        << container.line << ", "
715        << container.column << ", "
716        << container.length << ", "
717        << container.types << ", "
718        << container.extraInfo << ", "
719        << ")";
720 
721     return os;
722 }
723 
operator <<(std::ostream & os,const UnsavedFilesUpdatedMessage & message)724 std::ostream &operator<<(std::ostream &os, const UnsavedFilesUpdatedMessage &message)
725 {
726     os << "("
727        << message.fileContainers
728        << ")";
729 
730     return os;
731 }
732 
operator <<(std::ostream & os,const RequestAnnotationsMessage & message)733 std::ostream &operator<<(std::ostream &os, const RequestAnnotationsMessage &message)
734 {
735     os << "("
736        << message.fileContainer.filePath << ","
737        << ")";
738 
739     return os;
740 }
741 
operator <<(std::ostream & os,const RequestFollowSymbolMessage & message)742 std::ostream &operator<<(std::ostream &os, const RequestFollowSymbolMessage &message)
743 {
744     os << "("
745        << message.fileContainer << ", "
746        << message.ticketNumber << ", "
747        << message.line << ", "
748        << message.column << ", "
749        << ")";
750 
751      return os;
752 }
753 
operator <<(std::ostream & os,const RequestReferencesMessage & message)754 std::ostream &operator<<(std::ostream &os, const RequestReferencesMessage &message)
755 {
756     os << "("
757        << message.fileContainer << ", "
758        << message.ticketNumber << ", "
759        << message.line << ", "
760        << message.column << ", "
761        << message.local << ", "
762        << ")";
763 
764      return os;
765 }
766 
operator <<(std::ostream & out,const RequestToolTipMessage & message)767 std::ostream &operator<<(std::ostream &out, const RequestToolTipMessage &message)
768 {
769     out << "("
770         << message.fileContainer << ", "
771         << message.ticketNumber << ", "
772         << message.line << ", "
773         << message.column << ", "
774         << ")";
775 
776      return out;
777 }
778 
779 namespace {
780 
operator <<(std::ostream & os,const ToolTipInfo::QdocCategory category)781 std::ostream &operator<<(std::ostream &os, const ToolTipInfo::QdocCategory category)
782 {
783     return os << qdocCategoryToString(category);
784 }
785 } // namespace
786 
operator <<(std::ostream & out,const ToolTipInfo & info)787 std::ostream &operator<<(std::ostream &out, const ToolTipInfo &info)
788 {
789     out << "("
790        << info.text << ", "
791        << info.briefComment << ", "
792        << info.qdocIdCandidates << ", "
793        << info.qdocMark << ", "
794        << info.qdocCategory
795        << info.sizeInBytes << ", "
796        << ")";
797 
798     return out;
799 }
800 
operator <<(std::ostream & os,const SourceLocationContainer & container)801 std::ostream &operator<<(std::ostream &os, const SourceLocationContainer &container)
802 {
803     os << "("
804        << container.filePath << ", "
805        << container.line << ", "
806        << container.column
807        << ")";
808 
809     return os;
810 }
811 
operator <<(std::ostream & os,const SourceRangeContainer & container)812 std::ostream &operator<<(std::ostream &os, const SourceRangeContainer &container)
813 {
814     os << "("
815        << container.start << ", "
816        << container.end
817        << ")";
818 
819     return os;
820 }
821 
operator <<(std::ostream & os,const UnsavedFilesRemovedMessage & message)822 std::ostream &operator<<(std::ostream &os, const UnsavedFilesRemovedMessage &message)
823 {
824     os << "("
825         << message.fileContainers
826         << ")";
827 
828     return os;
829 }
830 
operator <<(std::ostream & os,const DocumentsChangedMessage & message)831 std::ostream &operator<<(std::ostream &os, const DocumentsChangedMessage &message)
832 {
833     os << "DocumentsChangedMessage("
834        << message.fileContainers
835        << ")";
836 
837     return os;
838 }
839 
operator <<(std::ostream & os,const DocumentVisibilityChangedMessage & message)840 std::ostream &operator<<(std::ostream &os, const DocumentVisibilityChangedMessage &message)
841 {
842     os << "("
843        << message.currentEditorFilePath  << ", "
844        << message.visibleEditorFilePaths
845        << ")";
846 
847     return os;
848 }
849 
850 namespace {
symbolKindString(SymbolKind symbolKind)851 const char *symbolKindString(SymbolKind symbolKind)
852 {
853     using ClangBackEnd::SymbolKind;
854 
855     switch (symbolKind) {
856     case SymbolKind::None: return "None";
857     case SymbolKind::Enumeration: return "Enumeration";
858     case SymbolKind::Record: return "Record";
859     case SymbolKind::Function: return "Function";
860     case SymbolKind::Variable: return "Variable";
861     case SymbolKind::Macro: return "Macro";
862     }
863 
864     return "";
865 }
866 
symbolTagString(SymbolTag symbolTag)867 const char *symbolTagString(SymbolTag symbolTag)
868 {
869     using ClangBackEnd::SymbolTag;
870 
871     switch (symbolTag) {
872     case SymbolTag::None: return "None";
873     case SymbolTag::Class: return "Class";
874     case SymbolTag::Struct: return "Struct";
875     case SymbolTag::Union: return "Union";
876     case SymbolTag::MsvcInterface: return "MsvcInterface";
877     }
878 
879     return "";
880 }
881 } // namespace
882 
operator <<(std::ostream & out,SymbolKind symbolKind)883 std::ostream &operator<<(std::ostream &out, SymbolKind symbolKind)
884 {
885     return out << symbolKindString(symbolKind);
886 }
887 
operator <<(std::ostream & out,SymbolTag symbolTag)888 std::ostream &operator<<(std::ostream &out, SymbolTag symbolTag)
889 {
890     return out << symbolTagString(symbolTag);
891 }
892 
operator <<(std::ostream & out,SymbolTags symbolTags)893 std::ostream &operator<<(std::ostream &out, SymbolTags symbolTags)
894 {
895     std::copy(symbolTags.cbegin(), symbolTags.cend(), std::ostream_iterator<SymbolTag>(out, ", "));
896 
897     return out;
898 }
899 
900 } // namespace ClangBackEnd
901 
902 namespace Debugger {
operator <<(std::ostream & out,const DiagnosticLocation & loc)903 std::ostream &operator<<(std::ostream &out, const DiagnosticLocation &loc)
904 {
905     return out << "(" << loc.filePath << ", " << loc.line << ", " << loc.column << ")";
906 }
907 } // namespace Debugger
908 
909 namespace ClangTools {
910 namespace Internal {
operator <<(std::ostream & out,const ExplainingStep & step)911 std::ostream &operator<<(std::ostream &out, const ExplainingStep &step)
912 {
913     return out << "("
914                << step.message << ", "
915                << step.location << ", "
916                << step.ranges << ", "
917                << step.isFixIt
918                << ")";
919 }
920 
operator <<(std::ostream & out,const Diagnostic & diag)921 std::ostream &operator<<(std::ostream &out, const Diagnostic &diag) {
922     return out << "("
923                << diag.name << ", "
924                << diag.description << ", "
925                << diag.category << ", "
926                << diag.type << ", "
927                << diag.location << ", "
928                << diag.explainingSteps << ", "
929                << diag.hasFixits
930                << ")";
931 }
932 } // namespace Internal
933 } // namespace ClangTools
934 
935 namespace QmlDesigner {
936 
operator <<(std::ostream & out,const ModelNode & node)937 std::ostream &operator<<(std::ostream &out, const ModelNode &node)
938 {
939     if (!node.isValid())
940         return out << "(invalid)";
941 
942     return out << "(" << node.id() << ")";
943 }
operator <<(std::ostream & out,const VariantProperty & property)944 std::ostream &operator<<(std::ostream &out, const VariantProperty &property)
945 {
946     if (!property.isValid())
947         return out << "(invalid)";
948 
949     return out << "(" << property.parentModelNode() << ", " << property.name() << ", "
950                << property.value() << ")";
951 }
952 namespace Cache {
953 
operator <<(std::ostream & out,const SourceContext & sourceContext)954 std::ostream &operator<<(std::ostream &out, const SourceContext &sourceContext)
955 {
956     return out << "(" << sourceContext.id << ", " << sourceContext.value << ")";
957 }
958 } // namespace Cache
959 
960 namespace Storage {
961 
962 namespace {
963 
cleanFlags(TypeAccessSemantics accessSemantics)964 TypeAccessSemantics cleanFlags(TypeAccessSemantics accessSemantics)
965 {
966     auto data = static_cast<int>(accessSemantics);
967     data &= ~static_cast<int>(TypeAccessSemantics::IsEnum);
968     return static_cast<TypeAccessSemantics>(data);
969 }
970 
typeAccessSemanticsToString(TypeAccessSemantics accessSemantics)971 const char *typeAccessSemanticsToString(TypeAccessSemantics accessSemantics)
972 {
973     switch (cleanFlags(accessSemantics)) {
974     case TypeAccessSemantics::Invalid:
975         return "Invalid";
976     case TypeAccessSemantics::Reference:
977         return "Reference";
978     case TypeAccessSemantics::Sequence:
979         return "Sequence";
980     case TypeAccessSemantics::Value:
981         return "Value";
982     default:
983         break;
984     }
985 
986     return "";
987 }
988 
operator &(TypeAccessSemantics first,TypeAccessSemantics second)989 bool operator&(TypeAccessSemantics first, TypeAccessSemantics second)
990 {
991     return static_cast<int>(first) & static_cast<int>(second);
992 }
993 
994 } // namespace
995 
typeAccessSemanticsFlagsToString(TypeAccessSemantics accessSemantics)996 static const char *typeAccessSemanticsFlagsToString(TypeAccessSemantics accessSemantics)
997 {
998     if (accessSemantics & TypeAccessSemantics::IsEnum)
999         return "(IsEnum)";
1000 
1001     return "";
1002 }
1003 
operator <<(std::ostream & out,TypeAccessSemantics accessSemantics)1004 std::ostream &operator<<(std::ostream &out, TypeAccessSemantics accessSemantics)
1005 {
1006     return out << typeAccessSemanticsToString(accessSemantics)
1007                << typeAccessSemanticsFlagsToString(accessSemantics);
1008 }
1009 
operator <<(std::ostream & out,VersionNumber versionNumber)1010 std::ostream &operator<<(std::ostream &out, VersionNumber versionNumber)
1011 {
1012     return out << versionNumber.version;
1013 }
1014 
operator <<(std::ostream & out,Version version)1015 std::ostream &operator<<(std::ostream &out, Version version)
1016 {
1017     return out << "(" << version.major << ", " << version.minor << ")";
1018 }
1019 
operator <<(std::ostream & out,const ExportedType & exportedType)1020 std::ostream &operator<<(std::ostream &out, const ExportedType &exportedType)
1021 {
1022     return out << "(\"" << exportedType.name << "\")";
1023 }
1024 
operator <<(std::ostream & out,const ExplicitExportedType & exportedType)1025 std::ostream &operator<<(std::ostream &out, const ExplicitExportedType &exportedType)
1026 {
1027     return out << "(\"" << exportedType.name << "\"" << exportedType.importId << ")";
1028 }
1029 
operator <<(std::ostream & out,const NativeType & nativeType)1030 std::ostream &operator<<(std::ostream &out, const NativeType &nativeType)
1031 {
1032     return out << "(\"" << nativeType.name << "\")";
1033 }
1034 
operator <<(std::ostream & out,const Type & type)1035 std::ostream &operator<<(std::ostream &out, const Type &type)
1036 {
1037     using Utils::operator<<;
1038     return out << "(import: " << type.importId << ", typename: \"" << type.typeName
1039                << "\", prototype: \"" << type.prototype << "\", " << type.accessSemantics
1040                << ", source: " << type.sourceId << ", exports: " << type.exportedTypes
1041                << ", properties: " << type.propertyDeclarations
1042                << ", functions: " << type.functionDeclarations
1043                << ", signals: " << type.signalDeclarations << ")";
1044 }
1045 
operator <<(std::ostream & out,const PropertyDeclaration & propertyDeclaration)1046 std::ostream &operator<<(std::ostream &out, const PropertyDeclaration &propertyDeclaration)
1047 {
1048     using Utils::operator<<;
1049     return out << "(\"" << propertyDeclaration.name << "\", \"" << propertyDeclaration.typeName
1050                << "\", " << propertyDeclaration.traits << ", " << propertyDeclaration.typeId << ")";
1051 }
1052 
operator <<(std::ostream & out,PropertyDeclarationTraits traits)1053 std::ostream &operator<<(std::ostream &out, PropertyDeclarationTraits traits)
1054 {
1055     const char *padding = "";
1056 
1057     out << "(";
1058     if (traits & PropertyDeclarationTraits::IsReadOnly) {
1059         out << "readonly";
1060         padding = ", ";
1061     }
1062 
1063     if (traits & PropertyDeclarationTraits::IsPointer) {
1064         out << padding << "pointer";
1065         padding = ", ";
1066     }
1067 
1068     if (traits & PropertyDeclarationTraits::IsList)
1069         out << padding << "list";
1070 
1071     return out << ")";
1072 }
1073 
operator <<(std::ostream & out,const FunctionDeclaration & functionDeclaration)1074 std::ostream &operator<<(std::ostream &out, const FunctionDeclaration &functionDeclaration)
1075 {
1076     return out << "(\"" << functionDeclaration.name << "\", \"" << functionDeclaration.returnTypeName
1077                << "\", " << functionDeclaration.parameters << ")";
1078 }
1079 
operator <<(std::ostream & out,const ParameterDeclaration & parameter)1080 std::ostream &operator<<(std::ostream &out, const ParameterDeclaration &parameter)
1081 {
1082     return out << "(\"" << parameter.name << "\", \"" << parameter.typeName << "\", "
1083                << parameter.traits << ")";
1084 }
1085 
operator <<(std::ostream & out,const SignalDeclaration & signalDeclaration)1086 std::ostream &operator<<(std::ostream &out, const SignalDeclaration &signalDeclaration)
1087 {
1088     return out << "(\"" << signalDeclaration.name << "\", " << signalDeclaration.parameters << ")";
1089 }
1090 
operator <<(std::ostream & out,const EnumeratorDeclaration & enumeratorDeclaration)1091 std::ostream &operator<<(std::ostream &out, const EnumeratorDeclaration &enumeratorDeclaration)
1092 {
1093     if (enumeratorDeclaration.hasValue) {
1094         return out << "(\"" << enumeratorDeclaration.name << "\", " << enumeratorDeclaration.value
1095                    << ")";
1096     } else {
1097         return out << "(\"" << enumeratorDeclaration.name << ")";
1098     }
1099 }
1100 
operator <<(std::ostream & out,const EnumerationDeclaration & enumerationDeclaration)1101 std::ostream &operator<<(std::ostream &out, const EnumerationDeclaration &enumerationDeclaration)
1102 {
1103     return out << "(\"" << enumerationDeclaration.name << "\", "
1104                << enumerationDeclaration.enumeratorDeclarations << ")";
1105 }
1106 
operator <<(std::ostream & out,const BasicImport & import)1107 std::ostream &operator<<(std::ostream &out, const BasicImport &import)
1108 {
1109     return out << "(" << import.name << ", " << import.version << ")";
1110 }
1111 
operator <<(std::ostream & out,const Import & import)1112 std::ostream &operator<<(std::ostream &out, const Import &import)
1113 {
1114     return out << "(" << import.name << ", " << import.version << ", " << import.sourceId << ", "
1115                << import.importDependencies << ")";
1116 }
1117 
1118 } // namespace Storage
1119 
1120 namespace Internal {
operator <<(std::ostream & out,const ImageCacheStorageImageEntry & entry)1121 std::ostream &operator<<(std::ostream &out, const ImageCacheStorageImageEntry &entry)
1122 {
1123     return out << "(" << entry.image << ", " << entry.hasEntry << ")";
1124 }
1125 
operator <<(std::ostream & out,const ImageCacheStorageIconEntry & entry)1126 std::ostream &operator<<(std::ostream &out, const ImageCacheStorageIconEntry &entry)
1127 {
1128     return out << "(" << entry.icon << ", " << entry.hasEntry << ")";
1129 }
1130 
1131 } // namespace Internal
1132 
1133 } // namespace QmlDesigner
1134