mirror of https://github.com/buggins/dlangide.git
libdparse integration experiments
This commit is contained in:
parent
e8cd7b882c
commit
be2e3cdc54
|
@ -66,7 +66,7 @@
|
|||
<debuglevel>0</debuglevel>
|
||||
<debugids>DebugInfo DCD</debugids>
|
||||
<versionlevel>0</versionlevel>
|
||||
<versionids>Unicode USE_FREETYPE</versionids>
|
||||
<versionids>Unicode USE_FREETYPE USE_LIBDPARSE</versionids>
|
||||
<dump_source>0</dump_source>
|
||||
<mapverbosity>3</mapverbosity>
|
||||
<createImplib>0</createImplib>
|
||||
|
|
|
@ -73,8 +73,14 @@ class DCDInterface {
|
|||
return output;
|
||||
}
|
||||
|
||||
ResultSet goToDefinition(in string[] importPaths, in string content, int index) {
|
||||
ResultSet goToDefinition(in string[] importPaths, in string filename, in string content, int index) {
|
||||
ResultSet result;
|
||||
|
||||
version(USE_LIBDPARSE) {
|
||||
import dlangide.tools.d.dparser;
|
||||
DParsingService.instance.addImportPaths(importPaths);
|
||||
DParsedModule m = DParsingService.instance.scan(cast(ubyte[])content, filename);
|
||||
}
|
||||
|
||||
debug(DCD) Log.d("DCD Context: ", dumpContext(content, index));
|
||||
|
||||
|
@ -122,7 +128,7 @@ class DCDInterface {
|
|||
return result;
|
||||
}
|
||||
|
||||
ResultSet getCompletions(in string[] importPaths, 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));
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ class DEditorTool : EditorTool
|
|||
string[] importPaths = editor.importPaths();
|
||||
string content = toUTF8(editor.text);
|
||||
auto byteOffset = caretPositionToByteOffset(content, caretPosition);
|
||||
ResultSet output = _dcd.goToDefinition(importPaths, content, byteOffset);
|
||||
ResultSet output = _dcd.goToDefinition(importPaths, editor.filename, content, byteOffset);
|
||||
|
||||
|
||||
switch(output.result) {
|
||||
|
@ -66,7 +66,7 @@ class DEditorTool : EditorTool
|
|||
|
||||
string content = toUTF8(editor.text);
|
||||
auto byteOffset = caretPositionToByteOffset(content, caretPosition);
|
||||
ResultSet output = _dcd.getCompletions(importPaths, content, byteOffset);
|
||||
ResultSet output = _dcd.getCompletions(importPaths, editor.filename, content, byteOffset);
|
||||
switch(output.result) {
|
||||
//TODO: Show dialog
|
||||
case DCDResult.FAIL:
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
module dlangide.tools.d.dparser;
|
||||
|
||||
import dlangui.core.logger;
|
||||
|
||||
import std.d.lexer;
|
||||
import std.d.parser;
|
||||
import std.d.ast;
|
||||
|
@ -14,21 +16,64 @@ class DParsedModule {
|
|||
protected string _moduleFile;
|
||||
protected StringCache* _cache;
|
||||
protected Module _ast;
|
||||
protected string[] _imports;
|
||||
const(Token)[] _tokens;
|
||||
LexerConfig _lexerConfig;
|
||||
|
||||
@property string filename() {
|
||||
return _moduleFile;
|
||||
}
|
||||
@property string filename() { return _moduleFile; }
|
||||
/// module name, e.g. "std.stdio"
|
||||
@property string moduleName() { return _moduleName; }
|
||||
|
||||
this(StringCache* cache, string filename) {
|
||||
_cache = cache;
|
||||
_moduleFile = filename;
|
||||
}
|
||||
|
||||
private static string importDeclToModuleName(IdentifierChain chain) {
|
||||
char[] buf;
|
||||
foreach(token; chain.identifiers) {
|
||||
if (buf.length)
|
||||
buf ~= '.';
|
||||
buf ~= token.text;
|
||||
}
|
||||
return buf.dup;
|
||||
}
|
||||
|
||||
void scanImports(Declaration[] declarations) {
|
||||
foreach(d; declarations) {
|
||||
if (d.importDeclaration) {
|
||||
foreach(imp; d.importDeclaration.singleImports) {
|
||||
addImport(importDeclToModuleName(imp.identifierChain));
|
||||
}
|
||||
} else if (d.declarations) {
|
||||
scanImports(d.declarations);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void msgFunction(string fn, size_t line, size_t col, string msg, bool isError) {
|
||||
debug(DParseErrors) Log.d("parser error: ", fn, "(", line, ":", col, ") : ", isError ? "Error: ": "Warning: ", msg);
|
||||
}
|
||||
|
||||
void parse(ubyte[] sourceCode) {
|
||||
_tokens = getTokensForParser(sourceCode, _lexerConfig, _cache);
|
||||
_ast = parseModule(_tokens, _moduleFile);
|
||||
uint errorCount;
|
||||
uint warningCount;
|
||||
_ast = parseModule(_tokens, _moduleFile, null, &msgFunction, &errorCount, &warningCount);
|
||||
_moduleName = importDeclToModuleName(_ast.moduleDeclaration.moduleName);
|
||||
scanImports(_ast.declarations);
|
||||
|
||||
}
|
||||
|
||||
private void addImport(string m) {
|
||||
foreach(imp; _imports)
|
||||
if (imp.equal(m))
|
||||
return;
|
||||
_imports ~= m;
|
||||
}
|
||||
|
||||
@property string[] imports() {
|
||||
return _imports;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,15 +100,37 @@ class DParsingService {
|
|||
protected DParsedModule[string] _moduleByName;
|
||||
protected DParsedModule[string] _moduleByFile;
|
||||
protected bool[string] _notFoundModules;
|
||||
protected DParsedModule _currentModule; // current module
|
||||
|
||||
this() {
|
||||
_cache = StringCache(16);
|
||||
}
|
||||
|
||||
void scanDeps(DParsedModule m, ref DParsedModule[string]scanned) {
|
||||
foreach(imp; m.imports) {
|
||||
if (imp !in scanned) {
|
||||
DParsedModule impModule = getOrParseModule(imp);
|
||||
scanned[imp] = impModule;
|
||||
if (impModule)
|
||||
scanDeps(impModule, scanned);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DParsedModule scan(ubyte[] sourceCode, string filename) {
|
||||
Log.d("scanning ", filename);
|
||||
destroy(_notFoundModules);
|
||||
DParsedModule res = new DParsedModule(&_cache, filename);
|
||||
res.parse(sourceCode);
|
||||
_currentModule = res;
|
||||
Log.d("moduleName: ", res.moduleName, " imports: ", res.imports);
|
||||
Log.d("deps:");
|
||||
DParsedModule[string] scanned;
|
||||
scanned[res.moduleName] = res;
|
||||
scanDeps(res, scanned);
|
||||
foreach(key, value; scanned) {
|
||||
Log.d(" module ", key, " : ", value ? value.filename : "NOT FOUND");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -77,21 +144,36 @@ class DParsingService {
|
|||
string findModuleFile(string moduleName) {
|
||||
string packagePath = moduleNameToPackagePath(moduleName);
|
||||
foreach(ip; _importPaths) {
|
||||
//Log.d("packagePath: ", packagePath, " importPath: ", ip);
|
||||
string path = buildNormalizedPath(ip, packagePath);
|
||||
if (path.exists && path.isFile)
|
||||
if (path.exists && path.isFile) {
|
||||
//Log.d("found ", path);
|
||||
return path;
|
||||
}
|
||||
string pathImports = path ~ "i";
|
||||
if (pathImports.exists && pathImports.isFile) {
|
||||
//Log.d("found ", pathImports);
|
||||
return pathImports;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
DParsedModule getOrParseModule(string moduleName) {
|
||||
if (_currentModule) {
|
||||
if (moduleName.equal(_currentModule.moduleName))
|
||||
return _currentModule; // module being scanned
|
||||
}
|
||||
if (auto m = moduleName in _moduleByName) {
|
||||
return *m;
|
||||
}
|
||||
if (moduleName in _notFoundModules)
|
||||
if (moduleName in _notFoundModules) {
|
||||
Log.d("module is in not found: ", moduleName);
|
||||
return null; // already listed as not found
|
||||
}
|
||||
string filename = findModuleFile(moduleName);
|
||||
if (!filename) {
|
||||
Log.d("module not found: ", moduleName);
|
||||
_notFoundModules[moduleName] = true;
|
||||
return null;
|
||||
}
|
||||
|
@ -103,12 +185,14 @@ class DParsingService {
|
|||
_moduleByFile[filename] = res;
|
||||
return res;
|
||||
} catch (Exception e) {
|
||||
Log.d("exception while parsing: ", moduleName, " : ", e);
|
||||
_notFoundModules[moduleName] = true;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
void addImportPaths(string[] paths) {
|
||||
void addImportPaths(in string[] paths) {
|
||||
Log.d("addImportPaths: ", paths);
|
||||
foreach(p; paths) {
|
||||
string ap = absolutePath(buildNormalizedPath(p));
|
||||
bool found = false;
|
||||
|
|
|
@ -1 +1 @@
|
|||
// Written in the D programming language.
/**
This app is a Tetris demo for DlangUI library.
Synopsis:
----
dub run dlangui:tetris
----
Copyright: Vadim Lopatin, 2014
License: Boost License 1.0
Authors: Vadim Lopatin, coolreader.org@gmail.com
*/
module main;
import dlangui.all;
import model;
import gui;
/// Required for Windows platform: DMD cannot find WinMain if it's in library
mixin APP_ENTRY_POINT;
/// entry point for dlangui based application
extern (C) int UIAppMain(string[] args) {
//auto power2 = delegate(int X) { return X * X; };
auto power2 = (int X) => X * X;
// embed resources listed in views/resources.list into executable
embeddedResourceList.addResources(embedResourcesFromList!("resources.list")());
// select translation file - for english language
Platform.instance.uiLanguage = "en";
// load theme from file "theme_default.xml"
Platform.instance.uiTheme = "theme_default";
// create window
Window window = Platform.instance.createWindow("DLangUI: Tetris game example"d, null, WindowFlag.Modal);
window.mainWidget = new GameWidget();
window.windowIcon = drawableCache.getImage("dtetris-logo1");
window.show();
// run message loop
return Platform.instance.enterMessageLoop();
}
|
||||
// Written in the D programming language.
/**
This app is a Tetris demo for DlangUI library.
Synopsis:
----
dub run dlangui:tetris
----
Copyright: Vadim Lopatin, 2014
License: Boost License 1.0
Authors: Vadim Lopatin, coolreader.org@gmail.com
*/
module main;
import dlangui.all;
import model;
import gui;
import std.stdio;
/// Required for Windows platform: DMD cannot find WinMain if it's in library
mixin APP_ENTRY_POINT;
/// entry point for dlangui based application
extern (C) int UIAppMain(string[] args) {
//auto power2 = delegate(int X) { return X * X; };
auto power2 = (int X) => X * X;
// embed resources listed in views/resources.list into executable
embeddedResourceList.addResources(embedResourcesFromList!("resources.list")());
// select translation file - for english language
Platform.instance.uiLanguage = "en";
// load theme from file "theme_default.xml"
Platform.instance.uiTheme = "theme_default";
// create window
Window window = Platform.instance.createWindow("DLangUI: Tetris game example"d, null, WindowFlag.Modal);
window.mainWidget = new GameWidget();
window.windowIcon = drawableCache.getImage("dtetris-logo1");
window.show();
// run message loop
return Platform.instance.enterMessageLoop();
}
|
Loading…
Reference in New Issue