mirror of https://github.com/buggins/dlangide.git
DCD async access - for #93
This commit is contained in:
parent
d828af306e
commit
4394f834cb
2
dub.json
2
dub.json
|
@ -12,7 +12,7 @@
|
||||||
"stringImportPaths": ["views", "views/res", "views/res/i18n", "views/res/mdpi", "views/res/hdpi"],
|
"stringImportPaths": ["views", "views/res", "views/res/i18n", "views/res/mdpi", "views/res/hdpi"],
|
||||||
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dlangui": "~>0.7.59",
|
"dlangui": "~>0.7.60",
|
||||||
"dcd": "~>0.7.5"
|
"dcd": "~>0.7.5"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ module dlangide.tools.d.dcdinterface;
|
||||||
|
|
||||||
import dlangui.core.logger;
|
import dlangui.core.logger;
|
||||||
import dlangui.core.files;
|
import dlangui.core.files;
|
||||||
|
import dlangui.platforms.common.platform;
|
||||||
import ddebug.common.queue;
|
import ddebug.common.queue;
|
||||||
|
|
||||||
import core.thread;
|
import core.thread;
|
||||||
|
@ -20,13 +21,19 @@ alias DocCommentsResultSet = Tuple!(DCDResult, "result", string[], "docComments"
|
||||||
alias FindDeclarationResultSet = Tuple!(DCDResult, "result", string, "fileName", ulong, "offset");
|
alias FindDeclarationResultSet = Tuple!(DCDResult, "result", string, "fileName", ulong, "offset");
|
||||||
alias ResultSet = Tuple!(DCDResult, "result", dstring[], "output");
|
alias ResultSet = Tuple!(DCDResult, "result", dstring[], "output");
|
||||||
|
|
||||||
|
import server.autocomplete;
|
||||||
|
import common.messages;
|
||||||
|
|
||||||
class DCDTask {
|
class DCDTask {
|
||||||
protected bool _cancelled;
|
protected bool _cancelled;
|
||||||
|
protected CustomEventTarget _guiExecutor;
|
||||||
protected string[] _importPaths;
|
protected string[] _importPaths;
|
||||||
protected string _filename;
|
protected string _filename;
|
||||||
protected string _content;
|
protected string _content;
|
||||||
protected int _index;
|
protected int _index;
|
||||||
this(string[] importPaths, in string filename, in string content, int index) {
|
protected AutocompleteRequest request;
|
||||||
|
this(CustomEventTarget guiExecutor, string[] importPaths, in string filename, in string content, int index) {
|
||||||
|
_guiExecutor = guiExecutor;
|
||||||
_importPaths = importPaths;
|
_importPaths = importPaths;
|
||||||
_filename = filename;
|
_filename = filename;
|
||||||
_content = content;
|
_content = content;
|
||||||
|
@ -34,14 +41,35 @@ class DCDTask {
|
||||||
}
|
}
|
||||||
@property bool cancelled() { return _cancelled; }
|
@property bool cancelled() { return _cancelled; }
|
||||||
void cancel() {
|
void cancel() {
|
||||||
|
synchronized(this) {
|
||||||
_cancelled = true;
|
_cancelled = true;
|
||||||
}
|
}
|
||||||
void execute() {
|
}
|
||||||
|
void createRequest() {
|
||||||
|
request.sourceCode = cast(ubyte[])_content;
|
||||||
|
request.fileName = _filename;
|
||||||
|
request.cursorPosition = _index;
|
||||||
|
}
|
||||||
|
void performRequest() {
|
||||||
// override
|
// override
|
||||||
}
|
}
|
||||||
|
void postResults() {
|
||||||
|
// override
|
||||||
|
}
|
||||||
|
void execute() {
|
||||||
|
if (_cancelled)
|
||||||
|
return;
|
||||||
|
createRequest();
|
||||||
|
performRequest();
|
||||||
|
synchronized(this) {
|
||||||
|
if (_cancelled)
|
||||||
|
return;
|
||||||
|
_guiExecutor.executeInUiThread(&postResults);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Interface to DCD
|
/// Async interface to DCD
|
||||||
class DCDInterface : Thread {
|
class DCDInterface : Thread {
|
||||||
|
|
||||||
import dsymbol.modulecache;
|
import dsymbol.modulecache;
|
||||||
|
@ -51,6 +79,7 @@ class DCDInterface : Thread {
|
||||||
this() {
|
this() {
|
||||||
super(&threadFunc);
|
super(&threadFunc);
|
||||||
_queue = new BlockingQueue!DCDTask();
|
_queue = new BlockingQueue!DCDTask();
|
||||||
|
name = "DCDthread";
|
||||||
start();
|
start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,15 +103,15 @@ class DCDInterface : Thread {
|
||||||
DCDTask task;
|
DCDTask task;
|
||||||
if (!_queue.get(task))
|
if (!_queue.get(task))
|
||||||
break;
|
break;
|
||||||
if (task && !task.cancelled)
|
if (task && !task.cancelled) {
|
||||||
|
Log.d("Execute DCD task");
|
||||||
task.execute();
|
task.execute();
|
||||||
|
Log.d("DCD task execution finished");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Log.d("Exiting DCD tasks thread");
|
Log.d("Exiting DCD tasks thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
import server.autocomplete;
|
|
||||||
import common.messages;
|
|
||||||
|
|
||||||
import dsymbol.modulecache;
|
import dsymbol.modulecache;
|
||||||
|
|
||||||
protected string dumpContext(string content, int pos) {
|
protected string dumpContext(string content, int pos) {
|
||||||
|
@ -98,7 +127,7 @@ class DCDInterface : Thread {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
DocCommentsResultSet getDocComments(in string[] importPaths, in string filename, in string content, int index) {
|
DocCommentsResultSet getDocComments(CustomEventTarget guiExecutor, in string[] importPaths, in string filename, in string content, int index) {
|
||||||
debug(DCD) Log.d("getDocComments: ", dumpContext(content, index));
|
debug(DCD) Log.d("getDocComments: ", dumpContext(content, index));
|
||||||
AutocompleteRequest request;
|
AutocompleteRequest request;
|
||||||
request.sourceCode = cast(ubyte[])content;
|
request.sourceCode = cast(ubyte[])content;
|
||||||
|
@ -119,17 +148,20 @@ class DCDInterface : Thread {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void goToDefinition(in string[] importPaths, in string filename, in string content, int index, void delegate(FindDeclarationResultSet res) callback) {
|
/// DCD go to definition task
|
||||||
|
class GoToDefinitionTask : DCDTask {
|
||||||
|
|
||||||
debug(DCD) Log.d("DCD Context: ", dumpContext(content, index));
|
protected void delegate(FindDeclarationResultSet output) _callback;
|
||||||
AutocompleteRequest request;
|
protected FindDeclarationResultSet result;
|
||||||
request.sourceCode = cast(ubyte[])content;
|
|
||||||
request.fileName = filename;
|
|
||||||
request.cursorPosition = index;
|
|
||||||
|
|
||||||
AutocompleteResponse response = findDeclaration(request, *getModuleCache(importPaths));
|
this(CustomEventTarget guiExecutor, string[] importPaths, in string filename, in string content, int index, void delegate(FindDeclarationResultSet output) callback) {
|
||||||
|
super(guiExecutor, importPaths, filename, content, index);
|
||||||
|
_callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
override void performRequest() {
|
||||||
|
AutocompleteResponse response = findDeclaration(request, *getModuleCache(_importPaths));
|
||||||
|
|
||||||
FindDeclarationResultSet result;
|
|
||||||
result.fileName = response.symbolFilePath;
|
result.fileName = response.symbolFilePath;
|
||||||
result.offset = response.symbolLocation;
|
result.offset = response.symbolLocation;
|
||||||
result.result = DCDResult.SUCCESS;
|
result.result = DCDResult.SUCCESS;
|
||||||
|
@ -139,10 +171,21 @@ class DCDInterface : Thread {
|
||||||
if (result.fileName is null) {
|
if (result.fileName is null) {
|
||||||
result.result = DCDResult.NO_RESULT;
|
result.result = DCDResult.NO_RESULT;
|
||||||
}
|
}
|
||||||
callback(result);
|
}
|
||||||
|
override void postResults() {
|
||||||
|
_callback(result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultSet getCompletions(in string[] importPaths, in string filename, in string content, int index) {
|
DCDTask goToDefinition(CustomEventTarget guiExecutor, string[] importPaths, in string filename, in string content, int index, void delegate(FindDeclarationResultSet res) callback) {
|
||||||
|
|
||||||
|
debug(DCD) Log.d("DCD Context: ", dumpContext(content, index));
|
||||||
|
GoToDefinitionTask task = new GoToDefinitionTask(guiExecutor, importPaths, filename, content, index, callback);
|
||||||
|
_queue.put(task);
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultSet getCompletions(CustomEventTarget guiExecutor, in string[] importPaths, in string filename, in string content, int index) {
|
||||||
|
|
||||||
debug(DCD) Log.d("DCD Context: ", dumpContext(content, index));
|
debug(DCD) Log.d("DCD Context: ", dumpContext(content, index));
|
||||||
ResultSet result;
|
ResultSet result;
|
||||||
|
@ -175,14 +218,12 @@ class DCDInterface : Thread {
|
||||||
protected void delegate(DocCommentsResultSet output) _callback;
|
protected void delegate(DocCommentsResultSet output) _callback;
|
||||||
protected DocCommentsResultSet result;
|
protected DocCommentsResultSet result;
|
||||||
|
|
||||||
this(string[] importPaths, in string filename, in string content, int index, void delegate(DocCommentsResultSet output) callback) {
|
this(CustomEventTarget guiExecutor, string[] importPaths, in string filename, in string content, int index, void delegate(DocCommentsResultSet output) callback) {
|
||||||
super(importPaths, filename, content, index);
|
super(guiExecutor, importPaths, filename, content, index);
|
||||||
_callback = callback;
|
_callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
override void execute() {
|
override void performRequest() {
|
||||||
if (_cancelled)
|
|
||||||
return;
|
|
||||||
AutocompleteRequest request;
|
AutocompleteRequest request;
|
||||||
request.sourceCode = cast(ubyte[])_content;
|
request.sourceCode = cast(ubyte[])_content;
|
||||||
request.fileName = _filename;
|
request.fileName = _filename;
|
||||||
|
@ -198,9 +239,10 @@ class DCDInterface : Thread {
|
||||||
if (result.docComments is null) {
|
if (result.docComments is null) {
|
||||||
result.result = DCDResult.NO_RESULT;
|
result.result = DCDResult.NO_RESULT;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!_cancelled)
|
override void postResults() {
|
||||||
_callback(result);
|
_callback(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,12 +21,16 @@ class DEditorTool : EditorTool
|
||||||
super(frame);
|
super(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~this() {
|
||||||
|
cancelGoToDefinition();
|
||||||
|
}
|
||||||
|
|
||||||
override string[] getDocComments(DSourceEdit editor, TextPosition caretPosition) {
|
override string[] getDocComments(DSourceEdit editor, TextPosition caretPosition) {
|
||||||
string[] importPaths = editor.importPaths();
|
string[] importPaths = editor.importPaths();
|
||||||
|
|
||||||
string content = toUTF8(editor.text);
|
string content = toUTF8(editor.text);
|
||||||
auto byteOffset = caretPositionToByteOffset(content, caretPosition);
|
auto byteOffset = caretPositionToByteOffset(content, caretPosition);
|
||||||
DocCommentsResultSet output = _frame.dcdInterface.getDocComments(importPaths, editor.filename, content, byteOffset);
|
DocCommentsResultSet output = _frame.dcdInterface.getDocComments(editor.window, importPaths, editor.filename, content, byteOffset);
|
||||||
|
|
||||||
switch(output.result) {
|
switch(output.result) {
|
||||||
//TODO: Show dialog
|
//TODO: Show dialog
|
||||||
|
@ -45,14 +49,21 @@ class DEditorTool : EditorTool
|
||||||
|
|
||||||
override void cancelGoToDefinition() {
|
override void cancelGoToDefinition() {
|
||||||
// override it
|
// override it
|
||||||
|
if (_goToDefinitionTask) {
|
||||||
|
_goToDefinitionTask.cancel();
|
||||||
|
_goToDefinitionTask = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DCDTask _goToDefinitionTask;
|
||||||
override void goToDefinition(DSourceEdit editor, TextPosition caretPosition) {
|
override void goToDefinition(DSourceEdit editor, TextPosition caretPosition) {
|
||||||
|
cancelGoToDefinition();
|
||||||
string[] importPaths = editor.importPaths();
|
string[] importPaths = editor.importPaths();
|
||||||
|
|
||||||
string content = toUTF8(editor.text);
|
string content = toUTF8(editor.text);
|
||||||
auto byteOffset = caretPositionToByteOffset(content, caretPosition);
|
auto byteOffset = caretPositionToByteOffset(content, caretPosition);
|
||||||
_frame.dcdInterface.goToDefinition(importPaths, editor.filename, content, byteOffset, delegate(FindDeclarationResultSet output) {
|
|
||||||
|
|
||||||
|
_goToDefinitionTask = _frame.dcdInterface.goToDefinition(editor.window, importPaths, editor.filename, content, byteOffset, delegate(FindDeclarationResultSet output) {
|
||||||
// handle result
|
// handle result
|
||||||
switch(output.result) {
|
switch(output.result) {
|
||||||
//TODO: Show dialog
|
//TODO: Show dialog
|
||||||
|
@ -80,6 +91,7 @@ class DEditorTool : EditorTool
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
_goToDefinitionTask = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -89,7 +101,7 @@ class DEditorTool : EditorTool
|
||||||
|
|
||||||
string content = toUTF8(editor.text);
|
string content = toUTF8(editor.text);
|
||||||
auto byteOffset = caretPositionToByteOffset(content, caretPosition);
|
auto byteOffset = caretPositionToByteOffset(content, caretPosition);
|
||||||
ResultSet output = _frame.dcdInterface.getCompletions(importPaths, editor.filename, content, byteOffset);
|
ResultSet output = _frame.dcdInterface.getCompletions(editor.window, importPaths, editor.filename, content, byteOffset);
|
||||||
switch(output.result) {
|
switch(output.result) {
|
||||||
//TODO: Show dialog
|
//TODO: Show dialog
|
||||||
case DCDResult.FAIL:
|
case DCDResult.FAIL:
|
||||||
|
@ -102,7 +114,10 @@ class DEditorTool : EditorTool
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static int caretPositionToByteOffset(string content, TextPosition caretPosition) {
|
}
|
||||||
|
|
||||||
|
/// convert caret position to byte offset in utf8 content
|
||||||
|
int caretPositionToByteOffset(string content, TextPosition caretPosition) {
|
||||||
auto line = 0;
|
auto line = 0;
|
||||||
auto pos = 0;
|
auto pos = 0;
|
||||||
auto bytes = 0;
|
auto bytes = 0;
|
||||||
|
@ -123,7 +138,8 @@ private:
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TextPosition byteOffsetToCaret(string content, int byteOffset) {
|
/// convert byte offset in utf8 content to caret position
|
||||||
|
TextPosition byteOffsetToCaret(string content, int byteOffset) {
|
||||||
int bytes = 0;
|
int bytes = 0;
|
||||||
int line = 0;
|
int line = 0;
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
@ -147,4 +163,3 @@ private:
|
||||||
}
|
}
|
||||||
return textPos;
|
return textPos;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue