mirror of https://github.com/buggins/dlangide.git
DCD usage refactoring
This commit is contained in:
parent
06247f3fb2
commit
d27884a0df
|
@ -23,7 +23,7 @@ Currently supported features:
|
|||
|
||||
Source editor features:
|
||||
|
||||
* D language source code syntax highlight (basic)
|
||||
* D language source code, json, dml syntax highlight
|
||||
* Indent / unindent text with Tab and Shift+Tab or Ctrl+\[ and Ctrl+\]
|
||||
* Toggle line or block comments by Ctrl+/ and Ctrl+Shift+/
|
||||
* D source code autocompletion by Ctrl+Space or Ctrl+Shift+G (using DCD)
|
||||
|
|
|
@ -39,6 +39,11 @@ class BlockingQueue(T) {
|
|||
}
|
||||
}
|
||||
|
||||
/// returns true if queue is closed
|
||||
@property bool closed() {
|
||||
return _closed;
|
||||
}
|
||||
|
||||
~this() {
|
||||
// TODO: destroy mutex?
|
||||
close();
|
||||
|
@ -86,7 +91,7 @@ class BlockingQueue(T) {
|
|||
}
|
||||
}
|
||||
|
||||
bool get(ref T value, int timeoutMillis) {
|
||||
bool get(ref T value, int timeoutMillis = 0) {
|
||||
if (_closed)
|
||||
return false;
|
||||
synchronized(_mutex) {
|
||||
|
@ -96,10 +101,14 @@ class BlockingQueue(T) {
|
|||
value = _buffer[_readPos++];
|
||||
return true;
|
||||
}
|
||||
if (timeoutMillis <= 0)
|
||||
_condition.wait(); // no timeout
|
||||
else if (!_condition.wait(dur!"msecs"(timeoutMillis)))
|
||||
return false; // timeout
|
||||
try {
|
||||
if (timeoutMillis <= 0)
|
||||
_condition.wait(); // no timeout
|
||||
else if (!_condition.wait(dur!"msecs"(timeoutMillis)))
|
||||
return false; // timeout
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
if (_readPos < _writePos) {
|
||||
value = _buffer[_readPos++];
|
||||
return true;
|
||||
|
|
|
@ -2,6 +2,9 @@ module dlangide.tools.d.dcdinterface;
|
|||
|
||||
import dlangui.core.logger;
|
||||
import dlangui.core.files;
|
||||
import ddebug.common.queue;
|
||||
|
||||
import core.thread;
|
||||
|
||||
import std.typecons;
|
||||
import std.conv;
|
||||
|
@ -17,9 +20,59 @@ alias DocCommentsResultSet = Tuple!(DCDResult, "result", string[], "docComments"
|
|||
alias FindDeclarationResultSet = Tuple!(DCDResult, "result", string, "fileName", ulong, "offset");
|
||||
alias ResultSet = Tuple!(DCDResult, "result", dstring[], "output");
|
||||
|
||||
class DCDTask {
|
||||
protected bool _cancelled;
|
||||
protected string[] _importPaths;
|
||||
protected string _filename;
|
||||
protected string _content;
|
||||
protected int _index;
|
||||
this(string[] importPaths, in string filename, in string content, int index) {
|
||||
_importPaths = importPaths;
|
||||
_filename = filename;
|
||||
_content = content;
|
||||
_index = index;
|
||||
}
|
||||
@property bool cancelled() { return _cancelled; }
|
||||
void cancel() {
|
||||
_cancelled = true;
|
||||
}
|
||||
void execute() {
|
||||
// override
|
||||
}
|
||||
}
|
||||
|
||||
/// Interface to DCD
|
||||
class DCDInterface : Thread {
|
||||
|
||||
import dsymbol.modulecache;
|
||||
protected ModuleCache _moduleCache = ModuleCache(new ASTAllocator);
|
||||
protected BlockingQueue!DCDTask _queue;
|
||||
|
||||
this() {
|
||||
super(&threadFunc);
|
||||
_queue = new BlockingQueue!DCDTask();
|
||||
start();
|
||||
}
|
||||
|
||||
~this() {
|
||||
_queue.close();
|
||||
join();
|
||||
destroy(_queue);
|
||||
_queue = null;
|
||||
}
|
||||
|
||||
void threadFunc() {
|
||||
Log.d("Starting DCD tasks thread");
|
||||
while (!_queue.closed()) {
|
||||
DCDTask task;
|
||||
if (!_queue.get(task))
|
||||
break;
|
||||
if (task && !task.cancelled)
|
||||
task.execute();
|
||||
}
|
||||
Log.d("Exiting DCD tasks thread");
|
||||
}
|
||||
|
||||
//Interface to DCD
|
||||
class DCDInterface {
|
||||
import server.autocomplete;
|
||||
import common.messages;
|
||||
|
||||
|
@ -38,14 +91,15 @@ class DCDInterface {
|
|||
return "";
|
||||
}
|
||||
|
||||
DocCommentsResultSet getDocComments(in string[] importPaths, in string filename, in string content, int index, ref ModuleCache moduleCache) {
|
||||
DocCommentsResultSet getDocComments(in string[] importPaths, in string filename, in string content, int index) {
|
||||
debug(DCD) Log.d("getDocComments: ", dumpContext(content, index));
|
||||
_moduleCache.addImportPaths(importPaths);
|
||||
AutocompleteRequest request;
|
||||
request.sourceCode = cast(ubyte[])content;
|
||||
request.fileName = filename;
|
||||
request.cursorPosition = index;
|
||||
|
||||
AutocompleteResponse response = getDoc(request,moduleCache);
|
||||
AutocompleteResponse response = getDoc(request, _moduleCache);
|
||||
|
||||
DocCommentsResultSet result;
|
||||
result.docComments = response.docComments;
|
||||
|
@ -59,16 +113,16 @@ class DCDInterface {
|
|||
return result;
|
||||
}
|
||||
|
||||
FindDeclarationResultSet goToDefinition(in string[] importPaths, in string filename, in string content, int index, ref ModuleCache moduleCache) {
|
||||
FindDeclarationResultSet goToDefinition(in string[] importPaths, in string filename, in string content, int index) {
|
||||
|
||||
debug(DCD) Log.d("DCD Context: ", dumpContext(content, index));
|
||||
|
||||
_moduleCache.addImportPaths(importPaths);
|
||||
AutocompleteRequest request;
|
||||
request.sourceCode = cast(ubyte[])content;
|
||||
request.fileName = filename;
|
||||
request.cursorPosition = index;
|
||||
|
||||
AutocompleteResponse response = findDeclaration(request,moduleCache);
|
||||
AutocompleteResponse response = findDeclaration(request, _moduleCache);
|
||||
|
||||
FindDeclarationResultSet result;
|
||||
result.fileName = response.symbolFilePath;
|
||||
|
@ -83,17 +137,17 @@ class DCDInterface {
|
|||
return result;
|
||||
}
|
||||
|
||||
ResultSet getCompletions(in string[] importPaths, in string filename, in string content, int index, ref ModuleCache moduleCache) {
|
||||
ResultSet getCompletions(in string[] importPaths, in string filename, in string content, int index) {
|
||||
|
||||
debug(DCD) Log.d("DCD Context: ", dumpContext(content, index));
|
||||
|
||||
_moduleCache.addImportPaths(importPaths);
|
||||
ResultSet result;
|
||||
AutocompleteRequest request;
|
||||
request.sourceCode = cast(ubyte[])content;
|
||||
request.fileName = filename;
|
||||
request.cursorPosition = index;
|
||||
|
||||
AutocompleteResponse response = complete(request,moduleCache);
|
||||
|
||||
AutocompleteResponse response = complete(request, _moduleCache);
|
||||
if(response.completions is null || response.completions.length == 0){
|
||||
result.result = DCDResult.NO_RESULT;
|
||||
return result;
|
||||
|
@ -109,4 +163,33 @@ class DCDInterface {
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// DCD doc comments task
|
||||
class DocCommentsTask : DCDTask {
|
||||
this(string[] importPaths, in string filename, in string content, int index) {
|
||||
super(importPaths, filename, content, index);
|
||||
}
|
||||
override void execute() {
|
||||
if (_cancelled)
|
||||
return;
|
||||
_moduleCache.addImportPaths(_importPaths);
|
||||
AutocompleteRequest request;
|
||||
request.sourceCode = cast(ubyte[])_content;
|
||||
request.fileName = _filename;
|
||||
request.cursorPosition = _index;
|
||||
|
||||
AutocompleteResponse response = getDoc(request, _moduleCache);
|
||||
|
||||
DocCommentsResultSet result;
|
||||
result.docComments = response.docComments;
|
||||
result.result = DCDResult.SUCCESS;
|
||||
|
||||
debug(DCD) Log.d("DCD doc comments:\n", result.docComments);
|
||||
|
||||
if (result.docComments is null) {
|
||||
result.result = DCDResult.NO_RESULT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,20 +17,16 @@ import std.conv;
|
|||
|
||||
class DEditorTool : EditorTool
|
||||
{
|
||||
|
||||
|
||||
this(IDEFrame frame) {
|
||||
_dcd = new DCDInterface();
|
||||
super(frame);
|
||||
}
|
||||
|
||||
override string[] getDocComments(DSourceEdit editor, TextPosition caretPosition) {
|
||||
string[] importPaths = editor.importPaths();
|
||||
_frame.moduleCache.addImportPaths(importPaths);
|
||||
|
||||
string content = toUTF8(editor.text);
|
||||
auto byteOffset = caretPositionToByteOffset(content, caretPosition);
|
||||
DocCommentsResultSet output = _dcd.getDocComments(importPaths, editor.filename, content, byteOffset, _frame.moduleCache);
|
||||
DocCommentsResultSet output = _frame.dcdInterface.getDocComments(importPaths, editor.filename, content, byteOffset);
|
||||
|
||||
switch(output.result) {
|
||||
//TODO: Show dialog
|
||||
|
@ -49,11 +45,10 @@ class DEditorTool : EditorTool
|
|||
|
||||
override bool goToDefinition(DSourceEdit editor, TextPosition caretPosition) {
|
||||
string[] importPaths = editor.importPaths();
|
||||
_frame.moduleCache.addImportPaths(importPaths);
|
||||
|
||||
string content = toUTF8(editor.text);
|
||||
auto byteOffset = caretPositionToByteOffset(content, caretPosition);
|
||||
FindDeclarationResultSet output = _dcd.goToDefinition(importPaths, editor.filename, content, byteOffset, _frame.moduleCache);
|
||||
FindDeclarationResultSet output = _frame.dcdInterface.goToDefinition(importPaths, editor.filename, content, byteOffset);
|
||||
|
||||
|
||||
switch(output.result) {
|
||||
|
@ -86,11 +81,10 @@ class DEditorTool : EditorTool
|
|||
|
||||
override dstring[] getCompletions(DSourceEdit editor, TextPosition caretPosition) {
|
||||
string[] importPaths = editor.importPaths();
|
||||
_frame.moduleCache.addImportPaths(importPaths);
|
||||
|
||||
string content = toUTF8(editor.text);
|
||||
auto byteOffset = caretPositionToByteOffset(content, caretPosition);
|
||||
ResultSet output = _dcd.getCompletions(importPaths, editor.filename, content, byteOffset, _frame.moduleCache);
|
||||
ResultSet output = _frame.dcdInterface.getCompletions(importPaths, editor.filename, content, byteOffset);
|
||||
switch(output.result) {
|
||||
//TODO: Show dialog
|
||||
case DCDResult.FAIL:
|
||||
|
@ -102,7 +96,6 @@ class DEditorTool : EditorTool
|
|||
}
|
||||
|
||||
private:
|
||||
DCDInterface _dcd;
|
||||
|
||||
int caretPositionToByteOffset(string content, TextPosition caretPosition) {
|
||||
auto line = 0;
|
||||
|
|
|
@ -78,8 +78,13 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
|
|||
TabWidget _tabs;
|
||||
|
||||
///Cache for parsed D files for autocomplete and symbol finding
|
||||
import dsymbol.modulecache;
|
||||
ModuleCache _moduleCache = ModuleCache(new ASTAllocator);
|
||||
import dlangide.tools.d.dcdinterface;
|
||||
private DCDInterface _dcdInterface;
|
||||
@property DCDInterface dcdInterface() {
|
||||
if (!_dcdInterface)
|
||||
_dcdInterface = new DCDInterface();
|
||||
return _dcdInterface;
|
||||
}
|
||||
|
||||
IDESettings _settings;
|
||||
ProgramExecution _execution;
|
||||
|
@ -95,7 +100,13 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
|
|||
applySettings(_settings);
|
||||
}
|
||||
|
||||
@property ref ModuleCache moduleCache() { return _moduleCache; }
|
||||
~this() {
|
||||
if (_dcdInterface) {
|
||||
destroy(_dcdInterface);
|
||||
_dcdInterface = null;
|
||||
}
|
||||
}
|
||||
|
||||
@property DockHost dockHost() { return _dockHost; }
|
||||
@property OutputPanel logPanel() { return _logPanel; }
|
||||
|
||||
|
|
Loading…
Reference in New Issue