mirror of https://github.com/buggins/dlangide.git
refactoring DCD access - implementing async calls - for #93
This commit is contained in:
parent
d27884a0df
commit
d828af306e
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.58",
|
"dlangui": "~>0.7.59",
|
||||||
"dcd": "~>0.7.5"
|
"dcd": "~>0.7.5"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,13 @@ class DCDInterface : Thread {
|
||||||
_queue = null;
|
_queue = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected ModuleCache * getModuleCache(in string[] importPaths) {
|
||||||
|
// TODO: clear cache if import paths removed or changed
|
||||||
|
// hold several module cache instances - make cache of caches
|
||||||
|
_moduleCache.addImportPaths(importPaths);
|
||||||
|
return &_moduleCache;
|
||||||
|
}
|
||||||
|
|
||||||
void threadFunc() {
|
void threadFunc() {
|
||||||
Log.d("Starting DCD tasks thread");
|
Log.d("Starting DCD tasks thread");
|
||||||
while (!_queue.closed()) {
|
while (!_queue.closed()) {
|
||||||
|
@ -93,13 +100,12 @@ class DCDInterface : Thread {
|
||||||
|
|
||||||
DocCommentsResultSet getDocComments(in string[] importPaths, in string filename, in string content, int index) {
|
DocCommentsResultSet getDocComments(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));
|
||||||
_moduleCache.addImportPaths(importPaths);
|
|
||||||
AutocompleteRequest request;
|
AutocompleteRequest request;
|
||||||
request.sourceCode = cast(ubyte[])content;
|
request.sourceCode = cast(ubyte[])content;
|
||||||
request.fileName = filename;
|
request.fileName = filename;
|
||||||
request.cursorPosition = index;
|
request.cursorPosition = index;
|
||||||
|
|
||||||
AutocompleteResponse response = getDoc(request, _moduleCache);
|
AutocompleteResponse response = getDoc(request, *getModuleCache(importPaths));
|
||||||
|
|
||||||
DocCommentsResultSet result;
|
DocCommentsResultSet result;
|
||||||
result.docComments = response.docComments;
|
result.docComments = response.docComments;
|
||||||
|
@ -113,16 +119,15 @@ class DCDInterface : Thread {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
FindDeclarationResultSet goToDefinition(in string[] importPaths, in string filename, in string content, int index) {
|
void goToDefinition(in string[] importPaths, in string filename, in string content, int index, void delegate(FindDeclarationResultSet res) callback) {
|
||||||
|
|
||||||
debug(DCD) Log.d("DCD Context: ", dumpContext(content, index));
|
debug(DCD) Log.d("DCD Context: ", dumpContext(content, index));
|
||||||
_moduleCache.addImportPaths(importPaths);
|
|
||||||
AutocompleteRequest request;
|
AutocompleteRequest request;
|
||||||
request.sourceCode = cast(ubyte[])content;
|
request.sourceCode = cast(ubyte[])content;
|
||||||
request.fileName = filename;
|
request.fileName = filename;
|
||||||
request.cursorPosition = index;
|
request.cursorPosition = index;
|
||||||
|
|
||||||
AutocompleteResponse response = findDeclaration(request, _moduleCache);
|
AutocompleteResponse response = findDeclaration(request, *getModuleCache(importPaths));
|
||||||
|
|
||||||
FindDeclarationResultSet result;
|
FindDeclarationResultSet result;
|
||||||
result.fileName = response.symbolFilePath;
|
result.fileName = response.symbolFilePath;
|
||||||
|
@ -134,20 +139,19 @@ class DCDInterface : Thread {
|
||||||
if (result.fileName is null) {
|
if (result.fileName is null) {
|
||||||
result.result = DCDResult.NO_RESULT;
|
result.result = DCDResult.NO_RESULT;
|
||||||
}
|
}
|
||||||
return result;
|
callback(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultSet getCompletions(in string[] importPaths, in string filename, in string content, int index) {
|
ResultSet getCompletions(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));
|
||||||
_moduleCache.addImportPaths(importPaths);
|
|
||||||
ResultSet result;
|
ResultSet result;
|
||||||
AutocompleteRequest request;
|
AutocompleteRequest request;
|
||||||
request.sourceCode = cast(ubyte[])content;
|
request.sourceCode = cast(ubyte[])content;
|
||||||
request.fileName = filename;
|
request.fileName = filename;
|
||||||
request.cursorPosition = index;
|
request.cursorPosition = index;
|
||||||
|
|
||||||
AutocompleteResponse response = complete(request, _moduleCache);
|
AutocompleteResponse response = complete(request, *getModuleCache(importPaths));
|
||||||
if(response.completions is null || response.completions.length == 0){
|
if(response.completions is null || response.completions.length == 0){
|
||||||
result.result = DCDResult.NO_RESULT;
|
result.result = DCDResult.NO_RESULT;
|
||||||
return result;
|
return result;
|
||||||
|
@ -167,21 +171,25 @@ class DCDInterface : Thread {
|
||||||
|
|
||||||
/// DCD doc comments task
|
/// DCD doc comments task
|
||||||
class DocCommentsTask : DCDTask {
|
class DocCommentsTask : DCDTask {
|
||||||
this(string[] importPaths, in string filename, in string content, int index) {
|
|
||||||
|
protected void delegate(DocCommentsResultSet output) _callback;
|
||||||
|
protected DocCommentsResultSet result;
|
||||||
|
|
||||||
|
this(string[] importPaths, in string filename, in string content, int index, void delegate(DocCommentsResultSet output) callback) {
|
||||||
super(importPaths, filename, content, index);
|
super(importPaths, filename, content, index);
|
||||||
|
_callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
override void execute() {
|
override void execute() {
|
||||||
if (_cancelled)
|
if (_cancelled)
|
||||||
return;
|
return;
|
||||||
_moduleCache.addImportPaths(_importPaths);
|
|
||||||
AutocompleteRequest request;
|
AutocompleteRequest request;
|
||||||
request.sourceCode = cast(ubyte[])_content;
|
request.sourceCode = cast(ubyte[])_content;
|
||||||
request.fileName = _filename;
|
request.fileName = _filename;
|
||||||
request.cursorPosition = _index;
|
request.cursorPosition = _index;
|
||||||
|
|
||||||
AutocompleteResponse response = getDoc(request, _moduleCache);
|
AutocompleteResponse response = getDoc(request, *getModuleCache(_importPaths));
|
||||||
|
|
||||||
DocCommentsResultSet result;
|
|
||||||
result.docComments = response.docComments;
|
result.docComments = response.docComments;
|
||||||
result.result = DCDResult.SUCCESS;
|
result.result = DCDResult.SUCCESS;
|
||||||
|
|
||||||
|
@ -190,6 +198,9 @@ 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)
|
||||||
|
_callback(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,40 +43,45 @@ class DEditorTool : EditorTool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override bool goToDefinition(DSourceEdit editor, TextPosition caretPosition) {
|
override void cancelGoToDefinition() {
|
||||||
|
// override it
|
||||||
|
}
|
||||||
|
|
||||||
|
override void goToDefinition(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);
|
||||||
FindDeclarationResultSet output = _frame.dcdInterface.goToDefinition(importPaths, editor.filename, content, byteOffset);
|
_frame.dcdInterface.goToDefinition(importPaths, editor.filename, content, byteOffset, delegate(FindDeclarationResultSet output) {
|
||||||
|
// handle result
|
||||||
|
switch(output.result) {
|
||||||
|
//TODO: Show dialog
|
||||||
|
case DCDResult.FAIL:
|
||||||
|
case DCDResult.NO_RESULT:
|
||||||
|
editor.setFocus();
|
||||||
|
break;
|
||||||
|
case DCDResult.SUCCESS:
|
||||||
|
auto fileName = output.fileName;
|
||||||
|
if(fileName.indexOf("stdin") == 0) {
|
||||||
|
Log.d("Declaration is in current file. Jumping to it.");
|
||||||
|
} else {
|
||||||
|
//Must open file first to get the content for finding the correct caret position.
|
||||||
|
if (!_frame.openSourceFile(to!string(fileName)))
|
||||||
|
break;
|
||||||
|
if (_frame.currentEditor.parent)
|
||||||
|
_frame.currentEditor.parent.layout(_frame.currentEditor.parent.pos);
|
||||||
|
content = toUTF8(_frame.currentEditor.text);
|
||||||
|
}
|
||||||
|
auto target = to!int(output.offset);
|
||||||
|
auto destPos = byteOffsetToCaret(content, target);
|
||||||
|
_frame.currentEditor.setCaretPos(destPos.line,destPos.pos, true, true);
|
||||||
|
_frame.currentEditor.setFocus();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
switch(output.result) {
|
|
||||||
//TODO: Show dialog
|
|
||||||
case DCDResult.FAIL:
|
|
||||||
case DCDResult.NO_RESULT:
|
|
||||||
editor.setFocus();
|
|
||||||
return false;
|
|
||||||
case DCDResult.SUCCESS:
|
|
||||||
auto fileName = output.fileName;
|
|
||||||
if(fileName.indexOf("stdin") == 0) {
|
|
||||||
Log.d("Declaration is in current file. Jumping to it.");
|
|
||||||
} else {
|
|
||||||
//Must open file first to get the content for finding the correct caret position.
|
|
||||||
if (!_frame.openSourceFile(to!string(fileName)))
|
|
||||||
return false;
|
|
||||||
if (_frame.currentEditor.parent)
|
|
||||||
_frame.currentEditor.parent.layout(_frame.currentEditor.parent.pos);
|
|
||||||
content = toUTF8(_frame.currentEditor.text);
|
|
||||||
}
|
|
||||||
auto target = to!int(output.offset);
|
|
||||||
auto destPos = byteOffsetToCaret(content, target);
|
|
||||||
_frame.currentEditor.setCaretPos(destPos.line,destPos.pos, true, true);
|
|
||||||
_frame.currentEditor.setFocus();
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override dstring[] getCompletions(DSourceEdit editor, TextPosition caretPosition) {
|
override dstring[] getCompletions(DSourceEdit editor, TextPosition caretPosition) {
|
||||||
|
@ -97,25 +102,28 @@ class DEditorTool : EditorTool
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
int caretPositionToByteOffset(string content, TextPosition caretPosition) {
|
static int caretPositionToByteOffset(string content, TextPosition caretPosition) {
|
||||||
auto line = 0;
|
auto line = 0;
|
||||||
auto pos = 0;
|
auto pos = 0;
|
||||||
auto bytes = 0;
|
auto bytes = 0;
|
||||||
foreach(c; content) {
|
foreach(c; content) {
|
||||||
bytes++;
|
|
||||||
if(c == '\n') {
|
|
||||||
line++;
|
|
||||||
}
|
|
||||||
if(line == caretPosition.line) {
|
if(line == caretPosition.line) {
|
||||||
if(pos == caretPosition.pos)
|
if(pos == caretPosition.pos)
|
||||||
break;
|
break;
|
||||||
pos++;
|
pos++;
|
||||||
|
} else if (line > caretPosition.line) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bytes++;
|
||||||
|
if(c == '\n') {
|
||||||
|
line++;
|
||||||
|
pos = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextPosition byteOffsetToCaret(string content, int byteOffset) {
|
static TextPosition byteOffsetToCaret(string content, int byteOffset) {
|
||||||
int bytes = 0;
|
int bytes = 0;
|
||||||
int line = 0;
|
int line = 0;
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
|
@ -15,7 +15,10 @@ class EditorTool
|
||||||
_frame = frame;
|
_frame = frame;
|
||||||
}
|
}
|
||||||
//Since files might be unsaved, we must send all the text content.
|
//Since files might be unsaved, we must send all the text content.
|
||||||
abstract bool goToDefinition(DSourceEdit editor, TextPosition caretPosition);
|
abstract void goToDefinition(DSourceEdit editor, TextPosition caretPosition);
|
||||||
|
void cancelGoToDefinition() {
|
||||||
|
// override it
|
||||||
|
}
|
||||||
abstract dstring[] getCompletions(DSourceEdit editor, TextPosition caretPosition);
|
abstract dstring[] getCompletions(DSourceEdit editor, TextPosition caretPosition);
|
||||||
abstract string[] getDocComments(DSourceEdit editor, TextPosition caretPosition);
|
abstract string[] getDocComments(DSourceEdit editor, TextPosition caretPosition);
|
||||||
|
|
||||||
|
@ -29,7 +32,7 @@ class DefaultEditorTool : EditorTool
|
||||||
super(frame);
|
super(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
override bool goToDefinition(DSourceEdit editor, TextPosition caretPosition) {
|
override void goToDefinition(DSourceEdit editor, TextPosition caretPosition) {
|
||||||
assert(0); //Go To Definition should not be called for normal files.
|
assert(0); //Go To Definition should not be called for normal files.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue