2
* Copyright 2014 David Herberth kde@dav1d.de
4
* This library is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Lesser General Public
6
* License as published by the Free Software Foundation; either
7
* version 2.1 of the License, or (at your option) version 3, or any
8
* later version accepted by the membership of KDE e.V. (or its
9
* successor approved by the membership of KDE e.V.), which shall
10
* act as a proxy defined in Section 6 of version 3 of the license.
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
24
#include <QtCore/QFile>
27
char DCDCompletionItemType::toChar(DCDCompletionItemType e)
30
case Invalid: return 0;
31
case Calltip: return 1;
32
case ClassName: return 'c';
33
case InterfaceName: return 'i';
34
case StructName: return 's';
35
case UnionName: return 'u';
36
case VariableName: return 'v';
37
case MemberVariableName: return 'm';
38
case Keyword: return 'k';
39
case FunctionName: return 'f';
40
case EnumName: return 'g';
41
case EnumMember: return 'e';
42
case PackageName: return 'p';
43
case ModuleName: return 'M';
49
DCDCompletionItemType::DCDCompletionItemType DCDCompletionItemType::fromChar(char c)
52
case 0: return Invalid;
53
case 1: return Calltip;
54
case 'c': return ClassName;
55
case 'i': return InterfaceName;
56
case 's': return StructName;
57
case 'u': return UnionName;
58
case 'v': return VariableName;
59
case 'm': return MemberVariableName;
60
case 'k': return Keyword;
61
case 'f': return FunctionName;
62
case 'g': return EnumName;
63
case 'e': return EnumMember;
64
case 'p': return PackageName;
65
case 'M': return ModuleName;
73
DCDCompletionItem::DCDCompletionItem(DCDCompletionItemType::DCDCompletionItemType t, QString s): type(t), name(s)
78
#define RETURN_CACHED_ICON(name) {static QIcon icon(KIcon(name).pixmap(QSize(16, 16))); return icon;}
79
QIcon DCDCompletionItem::icon() const
81
using namespace DCDCompletionItemType;
85
case Calltip: RETURN_CACHED_ICON("code-function")
86
case ClassName: RETURN_CACHED_ICON("code-class")
87
case InterfaceName: RETURN_CACHED_ICON("code-class")
88
case StructName: RETURN_CACHED_ICON("struct")
89
case UnionName: RETURN_CACHED_ICON("union")
90
case VariableName: RETURN_CACHED_ICON("code-variable")
91
case MemberVariableName: RETURN_CACHED_ICON("field")
92
case Keyword: RETURN_CACHED_ICON("field")
93
case FunctionName: RETURN_CACHED_ICON("code-function")
94
case EnumName: RETURN_CACHED_ICON("enum")
95
case EnumMember: RETURN_CACHED_ICON("enum")
96
case PackageName: RETURN_CACHED_ICON("field")
97
case ModuleName: RETURN_CACHED_ICON("field")
103
QString DCDCompletionItem::typeLong() const
105
using namespace DCDCompletionItemType;
108
case Invalid: return "invalid";
109
case Calltip: return "calltip";
110
case ClassName: return "class";
111
case InterfaceName: return "interface";
112
case StructName: return "struct";
113
case UnionName: return "union";
114
case VariableName: return "variable";
115
case MemberVariableName: return "member";
116
case Keyword: return "keyword";
117
case FunctionName: return "function";
118
case EnumName: return "enum";
119
case EnumMember: return "enum member";
120
case PackageName: return "package";
121
case ModuleName: return "module";
128
static const int TIMEOUT_START_SERVER = 200;
129
static const int TIMEOUT_COMPLETE = 200;
130
static const int TIMEOUT_IMPORTPATH = 200;
131
static const int TIMEOUT_SHUTDOWN = 350;
132
static const int TIMEOUT_SHUTDOWN_SERVER = 200;
135
DCD::DCD(int port, const QString& server, const QString& client)
149
return m_sproc.state() == KProcess::Running;
153
bool DCD::startServer()
155
m_sproc.setOutputChannelMode(KProcess::MergedChannels);
156
m_sproc.setProgram(m_server, QStringList(QString("-p%1").arg(m_port)));
158
bool started = m_sproc.waitForStarted(TIMEOUT_START_SERVER);
159
bool finished = m_sproc.waitForFinished(TIMEOUT_START_SERVER);
161
if (!started || finished || m_sproc.state() == KProcess::NotRunning) {
162
kWarning() << "unable to start completion-server:" << m_sproc.exitCode();
163
kWarning() << m_sproc.readAll();
166
kDebug() << "started completion-server";
171
DCDCompletion DCD::complete(QString file, int offset)
174
proc.setOutputChannelMode(KProcess::MergedChannels);
175
proc.setProgram(m_client,
177
<< QString("-p%1").arg(m_port)
178
<< QString("-c%1").arg(offset)
181
int ret = proc.execute(TIMEOUT_COMPLETE);
184
kWarning() << "unable to complete:" << ret;
185
kWarning() << proc.readAll();
186
return DCDCompletion();
189
return processCompletion(proc.readAllStandardOutput());
192
DCDCompletion DCD::complete(QByteArray data, int offset)
195
proc.setOutputChannelMode(KProcess::MergedChannels);
196
proc.setProgram(m_client,
198
<< QString("-p%1").arg(m_port)
199
<< QString("-c%1").arg(offset)
204
proc.closeWriteChannel();
205
if (!proc.waitForFinished(TIMEOUT_COMPLETE)) {
206
kWarning() << "unable to complete: client didn't finish in time";
208
} else if (proc.exitCode() != 0) {
209
kWarning() << "unable to complete:" << proc.exitCode();
210
kWarning() << proc.readAll();
213
return processCompletion(proc.readAllStandardOutput());
216
return DCDCompletion();
219
QString DCD::doc(QByteArray data, int offset)
222
proc.setOutputChannelMode(KProcess::MergedChannels);
223
proc.setProgram(m_client,
225
<< QString("-p%1").arg(m_port)
226
<< QString("-c%1").arg(offset)
232
proc.closeWriteChannel();
233
if (!proc.waitForFinished(TIMEOUT_COMPLETE)) {
234
kWarning() << "unable to lookup documentation: client didn't finish in time";
236
} else if (proc.exitCode() != 0) {
237
kWarning() << "unable to lookup documentation:" << proc.exitCode();
238
kWarning() << proc.readAll();
240
return proc.readAllStandardOutput();
247
DCDCompletion DCD::processCompletion(QString data)
249
DCDCompletion completion;
251
QStringList lines = data.split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
252
if (lines.length() == 0) {
256
QString type = lines.front();
257
if (type == "identifiers") { completion.type = DCDCompletionType::Identifiers; }
258
else if (type == "calltips") { completion.type = DCDCompletionType::Calltips; }
260
kWarning() << "Invalid type:" << type;
265
foreach(QString line, lines) {
266
if (line.trimmed().length() == 0) {
270
QStringList kv = line.split(QRegExp("\\s+"), QString::SkipEmptyParts);
271
if (kv.length() != 2 && completion.type != DCDCompletionType::Calltips) {
272
kWarning() << "invalid completion data:" << kv.length() << completion.type;
276
if (completion.type == DCDCompletionType::Identifiers) {
277
completion.completions.append(DCDCompletionItem(
278
DCDCompletionItemType::fromChar(kv[1].at(0).toAscii()), kv[0]
281
completion.completions.append(DCDCompletionItem(
282
DCDCompletionItemType::Calltip, line
291
void DCD::addImportPath(QString path)
293
addImportPath(QStringList(path));
296
void DCD::addImportPath(QStringList paths)
298
if (paths.isEmpty()) {
302
QStringList arguments = QStringList(QString("-p%1").arg(m_port));
303
foreach(QString path, paths) {
304
if (QFile::exists(path))
305
arguments << QString("-I%1").arg(path);
308
kDebug() << "ARGUMENTS:" << arguments;
311
proc.setOutputChannelMode(KProcess::MergedChannels);
312
proc.setProgram(m_client, arguments);
313
int ret = proc.execute(TIMEOUT_IMPORTPATH);
316
kWarning() << "unable to add importpath(s)" << paths << ":" << ret;
317
kWarning() << proc.readAll();
324
proc.setOutputChannelMode(KProcess::MergedChannels);
325
proc.setProgram(m_client,
327
<< QString("-p%1").arg(m_port)
328
<< QString("--shutdown")
330
int ret = proc.execute(TIMEOUT_SHUTDOWN);
333
kWarning() << "unable to shutdown dcd:" << ret;
334
kWarning() << proc.readAll();
339
bool DCD::stopServer()
341
if (m_sproc.state() == KProcess::Running) {
342
kDebug() << "shutting down dcd";
344
if(!m_sproc.waitForFinished(TIMEOUT_SHUTDOWN_SERVER))
346
if(!m_sproc.waitForFinished(TIMEOUT_SHUTDOWN_SERVER))
b'\\ No newline at end of file'