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 "clangactivationsequenceprocessor.h"
27 
28 namespace ClangCodeModel {
29 namespace Internal {
30 
31 namespace {
32 
truncateActivationStringByPosition(const QString & activationString,int positionInDocument)33 QString truncateActivationStringByPosition(const QString &activationString,
34                                            int positionInDocument)
35 {
36     if (positionInDocument == 1)
37         return activationString.left(1);
38 
39     if (positionInDocument == 2)
40         return activationString.left(2);
41 
42     return activationString;
43 }
44 
45 }
46 
ActivationSequenceProcessor(const QString & activationString,int positionInDocument,bool wantFunctionCall)47 ActivationSequenceProcessor::ActivationSequenceProcessor(const QString &activationString,
48                                                          int positionInDocument,
49                                                          bool wantFunctionCall)
50     : m_positionInDocument(positionInDocument),
51       m_wantFunctionCall(wantFunctionCall)
52 {
53     extractCharactersBeforePosition(truncateActivationStringByPosition(activationString,
54                                                                        positionInDocument));
55 
56     process();
57 }
58 
completionKind() const59 CPlusPlus::Kind ActivationSequenceProcessor::completionKind() const
60 {
61     return m_completionKind;
62 }
63 
offset() const64 int ActivationSequenceProcessor::offset() const
65 {
66     return m_offset;
67 }
68 
operatorStartPosition() const69 int ActivationSequenceProcessor::operatorStartPosition() const
70 {
71     return m_positionInDocument - m_offset;
72 }
73 
extractCharactersBeforePosition(const QString & activationString)74 void ActivationSequenceProcessor::extractCharactersBeforePosition(const QString &activationString)
75 {
76     if (activationString.size() >= 3) {
77         m_char1 = activationString[0];
78         m_char2 = activationString[1];
79         m_char3 = activationString[2];
80     } else if (activationString.size() == 2) {
81         m_char2 = activationString[0];
82         m_char3 = activationString[1];
83     } else if (activationString.size() == 1) {
84         m_char3 = activationString[0];
85     }
86 }
87 
process()88 void ActivationSequenceProcessor::process()
89 {
90     processDot();
91     processComma();
92     processLeftParen();
93     processLeftBrace();
94     processColonColon();
95     processArrow();
96     processDotStar();
97     processArrowStar();
98     processDoxyGenComment();
99     processAngleStringLiteral();
100     processStringLiteral();
101     processSlash();
102     processPound();
103 }
104 
processDot()105 void ActivationSequenceProcessor::processDot()
106 {
107     if (m_char3 == QLatin1Char('.') && m_char2 != QLatin1Char('.')) {
108         m_completionKind = CPlusPlus::T_DOT;
109         m_offset = 1;
110     }
111 }
112 
processComma()113 void ActivationSequenceProcessor::processComma()
114 {
115     if (m_char3 == QLatin1Char(',') ) {
116         m_completionKind = CPlusPlus::T_COMMA;
117         m_offset = 1;
118     }
119 }
120 
processLeftParen()121 void ActivationSequenceProcessor::processLeftParen()
122 {
123     if (m_char3 == QLatin1Char('(') && m_wantFunctionCall) {
124         m_completionKind = CPlusPlus::T_LPAREN;
125         m_offset = 1;
126     }
127 }
128 
processLeftBrace()129 void ActivationSequenceProcessor::processLeftBrace()
130 {
131     if (m_char3 == QLatin1Char('{') && m_wantFunctionCall) {
132         m_completionKind = CPlusPlus::T_LBRACE;
133         m_offset = 1;
134     }
135 }
136 
processColonColon()137 void ActivationSequenceProcessor::processColonColon()
138 {
139     if (m_char2 == QLatin1Char(':') && m_char3 == QLatin1Char(':')) {
140         m_completionKind = CPlusPlus::T_COLON_COLON;
141         m_offset = 2;
142     }
143 }
144 
processArrow()145 void ActivationSequenceProcessor::processArrow()
146 {
147     if (m_char2 == QLatin1Char('-') && m_char3 == QLatin1Char('>')) {
148         m_completionKind = CPlusPlus::T_ARROW;
149         m_offset = 2;
150     }
151 }
152 
processDotStar()153 void ActivationSequenceProcessor::processDotStar()
154 {
155     if (m_char2 == QLatin1Char('.') && m_char3 == QLatin1Char('*')) {
156         m_completionKind = CPlusPlus::T_DOT_STAR;
157         m_offset = 2;
158     }
159 }
160 
processArrowStar()161 void ActivationSequenceProcessor::processArrowStar()
162 {
163     if (m_char1 == QLatin1Char('-') && m_char2 == QLatin1Char('>') && m_char3 == QLatin1Char('*')) {
164         m_completionKind = CPlusPlus::T_ARROW_STAR;
165         m_offset = 3;
166     }
167 }
168 
processDoxyGenComment()169 void ActivationSequenceProcessor::processDoxyGenComment()
170 {
171     if ((m_char2.isNull() || m_char2.isSpace())
172             && (m_char3 == QLatin1Char('\\') || m_char3 == QLatin1Char('@'))) {
173         m_completionKind = CPlusPlus::T_DOXY_COMMENT;
174         m_offset = 1;
175     }
176 }
177 
processAngleStringLiteral()178 void ActivationSequenceProcessor::processAngleStringLiteral()
179 {
180     if (m_char3 == QLatin1Char('<')) {
181         m_completionKind = CPlusPlus::T_ANGLE_STRING_LITERAL;
182         m_offset = 1;
183     }
184 }
185 
processStringLiteral()186 void ActivationSequenceProcessor::processStringLiteral()
187 {
188     if (m_char3 == QLatin1Char('"')) {
189         m_completionKind = CPlusPlus::T_STRING_LITERAL;
190         m_offset = 1;
191     }
192 }
193 
processSlash()194 void ActivationSequenceProcessor::processSlash()
195 {
196     if (m_char3 == QLatin1Char('/')) {
197         m_completionKind = CPlusPlus::T_SLASH;
198         m_offset = 1;
199     }
200 }
201 
processPound()202 void ActivationSequenceProcessor::processPound()
203 {
204     if (m_char3 == QLatin1Char('#')) {
205         m_completionKind = CPlusPlus::T_POUND;
206         m_offset = 1;
207     }
208 }
209 
210 } // namespace Internal
211 } // namespace ClangCodeModel
212 
213