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 #pragma once
27 
28 #include "builtineditordocumentparser.h"
29 #include "cppcompletionassistprocessor.h"
30 #include "cppcompletionassistprovider.h"
31 #include "cppmodelmanager.h"
32 #include "cppworkingcopy.h"
33 
34 #include <cplusplus/Icons.h>
35 #include <cplusplus/Symbol.h>
36 #include <cplusplus/TypeOfExpression.h>
37 
38 #include <texteditor/texteditor.h>
39 #include <texteditor/codeassist/genericproposalmodel.h>
40 #include <texteditor/codeassist/assistinterface.h>
41 #include <texteditor/codeassist/iassistprocessor.h>
42 #include <texteditor/snippets/snippetassistcollector.h>
43 
44 
45 #include <QStringList>
46 #include <QVariant>
47 
48 namespace CPlusPlus {
49 class LookupItem;
50 class ClassOrNamespace;
51 class Function;
52 class LookupContext;
53 } // namespace CPlusPlus
54 
55 namespace CppTools {
56 namespace Internal {
57 
58 class CppCompletionAssistInterface;
59 
60 class CppAssistProposalModel : public TextEditor::GenericProposalModel
61 {
62 public:
CppAssistProposalModel()63     CppAssistProposalModel()
64         : TextEditor::GenericProposalModel()
65         , m_typeOfExpression(new CPlusPlus::TypeOfExpression)
66     {
67         m_typeOfExpression->setExpandTemplates(true);
68     }
69 
70     bool isSortable(const QString &prefix) const override;
71     TextEditor::AssistProposalItemInterface *proposalItem(int index) const override;
72 
73     unsigned m_completionOperator = CPlusPlus::T_EOF_SYMBOL;
74     bool m_replaceDotForArrow = false;
75     QSharedPointer<CPlusPlus::TypeOfExpression> m_typeOfExpression;
76 };
77 
78 using CppAssistProposalModelPtr = QSharedPointer<CppAssistProposalModel>;
79 
80 class InternalCompletionAssistProvider : public CppCompletionAssistProvider
81 {
82     Q_OBJECT
83 
84 public:
85     TextEditor::IAssistProcessor *createProcessor() const override;
86 
87     TextEditor::AssistInterface *createAssistInterface(
88         const Utils::FilePath &filePath,
89         const TextEditor::TextEditorWidget *textEditorWidget,
90         const CPlusPlus::LanguageFeatures &languageFeatures,
91         int position,
92         TextEditor::AssistReason reason) const override;
93 };
94 
95 class InternalCppCompletionAssistProcessor : public CppCompletionAssistProcessor
96 {
97 public:
98     InternalCppCompletionAssistProcessor();
99     ~InternalCppCompletionAssistProcessor() override;
100 
101     TextEditor::IAssistProposal *perform(const TextEditor::AssistInterface *interface) override;
102 
103 private:
104     TextEditor::IAssistProposal *createContentProposal();
105     TextEditor::IAssistProposal *createHintProposal(QList<CPlusPlus::Function *> symbols) const;
106     bool accepts() const;
107 
108     int startOfOperator(int positionInDocument, unsigned *kind, bool wantFunctionCall) const;
109     int findStartOfName(int pos = -1) const;
110     int startCompletionHelper();
111     bool tryObjCCompletion();
112     bool objcKeywordsWanted() const;
113     int startCompletionInternal(const QString &fileName,
114                                 int line, int positionInBlock,
115                                 const QString &expression,
116                                 int endOfExpression);
117 
118     void completeObjCMsgSend(CPlusPlus::ClassOrNamespace *binding, bool staticClassAccess);
119     bool completeInclude(const QTextCursor &cursor);
120     void completeInclude(const QString &realPath, const QStringList &suffixes);
121     void completePreprocessor();
122     bool completeConstructorOrFunction(const QList<CPlusPlus::LookupItem> &results,
123                                        int endOfExpression,
124                                        bool toolTipOnly);
125     bool completeMember(const QList<CPlusPlus::LookupItem> &results);
126     bool completeScope(const QList<CPlusPlus::LookupItem> &results);
127     void completeNamespace(CPlusPlus::ClassOrNamespace *binding);
128     void completeClass(CPlusPlus::ClassOrNamespace *b, bool staticLookup = true);
129     void addClassMembersToCompletion(CPlusPlus::Scope *scope, bool staticLookup);
130     enum CompleteQtMethodMode {
131         CompleteQt4Signals,
132         CompleteQt4Slots,
133         CompleteQt5Signals,
134         CompleteQt5Slots,
135     };
136     bool completeQtMethod(const QList<CPlusPlus::LookupItem> &results, CompleteQtMethodMode type);
137     bool completeQtMethodClassName(const QList<CPlusPlus::LookupItem> &results,
138                                    CPlusPlus::Scope *cursorScope);
139     bool globalCompletion(CPlusPlus::Scope *scope);
140 
141     void addKeywordCompletionItem(const QString &text);
142     void addCompletionItem(const QString &text,
143                            const QIcon &icon = QIcon(),
144                            int order = 0,
145                            const QVariant &data = QVariant());
146     void addCompletionItem(CPlusPlus::Symbol *symbol,
147                            int order = 0);
148     void addKeywords();
149     void addMacros(const QString &fileName, const CPlusPlus::Snapshot &snapshot);
150     void addMacros_helper(const CPlusPlus::Snapshot &snapshot,
151                           const QString &fileName,
152                           QSet<QString> *processed,
153                           QSet<QString> *definedMacros);
154 
155     enum {
156         CompleteQt5SignalOrSlotClassNameTrigger = CPlusPlus::T_LAST_TOKEN + 1,
157         CompleteQt5SignalTrigger,
158         CompleteQt5SlotTrigger
159     };
160 
161     QScopedPointer<const CppCompletionAssistInterface> m_interface;
162     CppAssistProposalModelPtr m_model;
163 };
164 
165 class CppCompletionAssistInterface : public TextEditor::AssistInterface
166 {
167 public:
CppCompletionAssistInterface(const Utils::FilePath & filePath,const TextEditor::TextEditorWidget * textEditorWidget,BuiltinEditorDocumentParser::Ptr parser,const CPlusPlus::LanguageFeatures & languageFeatures,int position,TextEditor::AssistReason reason,const WorkingCopy & workingCopy)168     CppCompletionAssistInterface(const Utils::FilePath &filePath,
169                                  const TextEditor::TextEditorWidget *textEditorWidget,
170                                  BuiltinEditorDocumentParser::Ptr parser,
171                                  const CPlusPlus::LanguageFeatures &languageFeatures,
172                                  int position,
173                                  TextEditor::AssistReason reason,
174                                  const WorkingCopy &workingCopy)
175         : TextEditor::AssistInterface(textEditorWidget->document(), position, filePath, reason)
176         , m_parser(parser)
177         , m_gotCppSpecifics(false)
178         , m_workingCopy(workingCopy)
179         , m_languageFeatures(languageFeatures)
180     {}
181 
CppCompletionAssistInterface(const Utils::FilePath & filePath,QTextDocument * textDocument,int position,TextEditor::AssistReason reason,const CPlusPlus::Snapshot & snapshot,const ProjectExplorer::HeaderPaths & headerPaths,const CPlusPlus::LanguageFeatures & features)182     CppCompletionAssistInterface(const Utils::FilePath &filePath,
183                                  QTextDocument *textDocument,
184                                  int position,
185                                  TextEditor::AssistReason reason,
186                                  const CPlusPlus::Snapshot &snapshot,
187                                  const ProjectExplorer::HeaderPaths &headerPaths,
188                                  const CPlusPlus::LanguageFeatures &features)
189         : TextEditor::AssistInterface(textDocument, position, filePath, reason)
190         , m_gotCppSpecifics(true)
191         , m_snapshot(snapshot)
192         , m_headerPaths(headerPaths)
193         , m_languageFeatures(features)
194     {}
195 
snapshot()196     const CPlusPlus::Snapshot &snapshot() const { getCppSpecifics(); return m_snapshot; }
headerPaths()197     const ProjectExplorer::HeaderPaths &headerPaths() const
198     { getCppSpecifics(); return m_headerPaths; }
languageFeatures()199     CPlusPlus::LanguageFeatures languageFeatures() const
200     { getCppSpecifics(); return m_languageFeatures; }
201 
202 private:
203     void getCppSpecifics() const;
204 
205     BuiltinEditorDocumentParser::Ptr m_parser;
206     mutable bool m_gotCppSpecifics;
207     WorkingCopy m_workingCopy;
208     mutable CPlusPlus::Snapshot m_snapshot;
209     mutable ProjectExplorer::HeaderPaths m_headerPaths;
210     mutable CPlusPlus::LanguageFeatures m_languageFeatures;
211 };
212 
213 } // Internal
214 } // CppTools
215 
216 Q_DECLARE_METATYPE(CPlusPlus::Symbol *)
217