diff --git a/cedast/build/cedast.coedit b/cedast/build/cedast.coedit index 1516a19b..c029f46c 100644 --- a/cedast/build/cedast.coedit +++ b/cedast/build/cedast.coedit @@ -6,16 +6,31 @@ object CurrentProject: TCENativeProject debugingOptions.codeviewDexts = True messagesOptions.additionalWarnings = True outputOptions.binaryKind = sharedlib - pathsOptions.outputFilename = '..\..\lazproj\cedast.dll' + pathsOptions.outputFilename = '../bin/cedast.so' + end + item + name = 'linux-dbg' + debugingOptions.debug = True + debugingOptions.codeviewDexts = True + messagesOptions.additionalWarnings = True + messagesOptions.tlsInformations = True + outputOptions.binaryKind = obj + pathsOptions.outputFilename = '../bin/cedast.o' + otherOptions.customOptions.Strings = ( + '-fPIC' + ) + postBuildProcess.executable = 'sh' + postBuildProcess.parameters.Strings = ( + '/nux-postbuild.sh' + ) end> Sources.Strings = ( - '..\src\cedast.d' - '..\src\common.d' - '..\src\ast.d' + '../src/cedast.d' + '../src/common.d' + '../src/ast.d' ) - ConfigurationIndex = 0 + ConfigurationIndex = 1 LibraryAliases.Strings = ( - 'libdparse' - 'iz' + '*' ) end diff --git a/cedast/build/nux-postbuild.sh b/cedast/build/nux-postbuild.sh new file mode 100644 index 00000000..ee838ad9 --- /dev/null +++ b/cedast/build/nux-postbuild.sh @@ -0,0 +1 @@ +dmd ../bin/cedast.o /home/basile/Dev/dproj/Iz/lib/iz.a /home/basile/Dev/metad/libs/libdparse.a -of../bin/cedast.so -shared -defaultlib=libphobos2.so diff --git a/cedast/src/ast.d b/cedast/src/ast.d index 1c7530d2..e6017fd5 100644 --- a/cedast/src/ast.d +++ b/cedast/src/ast.d @@ -1,14 +1,21 @@ module ast; import std.d.lexer, std.d.parser, std.d.ast; -import std.json, std.array, std.conv, std.parallelism; +import std.json, std.array, std.conv, std.parallelism, std.concurrency; import iz.enumset, iz.memory; import common; private { - enum AstInfos {ModuleName, ErrorsJson, ErrorsPas, SymsJson, SymsPas} + enum AstInfos + { + ModuleName, + ErrorsJson, ErrorsPas, + SymsJson, SymsPas, + TodosJson, TodosPas + } + alias CachedInfos = EnumSet!(AstInfos, Set8); enum SymbolType @@ -316,7 +323,7 @@ private: ubyte[] todosJson; ubyte[] symsPas; ubyte[] symsJson; - static AstError*[] errors; + __gshared static AstError*[] errors; final static void parserError(string fname, size_t line, size_t col, string msg, bool isErr) { @@ -342,6 +349,7 @@ private: mod = parseModule(getTokensForParser(src, config, &strcache), fname, null, &parserError); if (notif) notif(notifparam); scanned = true; + } public: @@ -359,7 +367,8 @@ public: try src = cast(ubyte[]) read(fname, size_t.max); catch(Exception e){} scanned = false; - task(&taskScan).executeInNewThread; + version(Windows)task(&taskScan).executeInNewThread; + else taskScan; } final void scanBuffer(ubyte[] buffer) @@ -367,7 +376,8 @@ public: resetCachedInfo; src = buffer.dup; scanned = false; - task(&taskScan).executeInNewThread; + version(Windows) task(&taskScan).executeInNewThread; + else taskScan; } @property AstNotification notification(){return notif;} @@ -378,48 +388,50 @@ public: final string moduleName() { - string result; - - if (!scanned) - return result; - if (AstInfos.ModuleName in cachedInfos) - return modName; - - cachedInfos += AstInfos.ModuleName; - if (mod.moduleDeclaration) - foreach(Token t; mod.moduleDeclaration.moduleName.identifiers) - result ~= t.text ~ "."; - - if (result.length) - modName = result[0 .. $-1]; + if (scanned && AstInfos.ModuleName !in cachedInfos) + { + string result; + cachedInfos += AstInfos.ModuleName; + if (mod.moduleDeclaration) + foreach(Token t; mod.moduleDeclaration.moduleName.identifiers) + result ~= t.text ~ "."; + if (result.length) + modName = result[0 .. $-1].idup; + } return modName; } final ubyte[] todoListPas() { - return null; + if (scanned && AstInfos.TodosPas !in cachedInfos) + { + } + return todosPas; } final ubyte[] todoListJson() { - return null; + if (scanned && AstInfos.TodosJson !in cachedInfos) + { + } + return todosJson; } final ubyte[] symbolListPas() { - if (AstInfos.SymsPas !in cachedInfos) + if (scanned && AstInfos.SymsPas !in cachedInfos) { cachedInfos += AstInfos.SymsPas; SymbolListBuilder slb = construct!SymbolListBuilder(mod); scope(exit) destruct(slb); - symsPas = cast(ubyte[]) slb.serializePas(); + symsPas = cast(ubyte[]) slb.serializePas().dup; } return symsPas; } final ubyte[] symbolListJson() { - if (AstInfos.SymsJson !in cachedInfos) + if (scanned && AstInfos.SymsJson !in cachedInfos) { cachedInfos += AstInfos.SymsJson; SymbolListBuilder slb = construct!SymbolListBuilder(mod); diff --git a/cedast/src/cedast.d b/cedast/src/cedast.d index 876c8192..562a8dc6 100644 --- a/cedast/src/cedast.d +++ b/cedast/src/cedast.d @@ -4,11 +4,19 @@ import core.runtime, common, ast; import iz.memory; __gshared Ast[] modules; +__gshared bool init; +void tryInit() +{ + if (init) return; + Runtime.initialize; + init = true; +} extern(C) export AstHandle newAst(void* param, AstNotification clbck) { + version(linux) tryInit; AstHandle result; try { @@ -134,7 +142,7 @@ version(Windows) final switch (ulReason) { case DLL_PROCESS_ATTACH: - Runtime.initialize; + tryInit; g_hInst = hInstance; dll_process_attach( hInstance, true ); break; @@ -155,4 +163,3 @@ version(Windows) return true; } } - diff --git a/cedast/src/common.d b/cedast/src/common.d index fa485ca8..cdb171e3 100644 --- a/cedast/src/common.d +++ b/cedast/src/common.d @@ -1,8 +1,10 @@ module common; +extern(C): + alias AstHandle = ptrdiff_t; -alias AstNotification = extern(C) void function(void* param); +alias AstNotification = void function(void* param); __gshared immutable AstHandle invalidAstHandle = 0; @@ -11,8 +13,3 @@ enum SerializationFormat : byte json, pascal } - -enum logcall = q{ - import std.file; - append("cedast_log.txt", cast(ubyte[])(__PRETTY_FUNCTION__ ~ "\r\n")); -}; diff --git a/src/ce_dast.pas b/src/ce_dast.pas new file mode 100644 index 00000000..34354ba7 --- /dev/null +++ b/src/ce_dast.pas @@ -0,0 +1,74 @@ +unit ce_dast; + +{$I ce_defines.inc} + +interface + +uses + dynlibs, sysutils, ce_common; + +type + + TAstHandle = type NativeInt; + + TAstNotification = procedure(param: Pointer); cdecl; + + {$Z1} + TSerializationFormat = (json, pas); + + // Returns an ID to a D AST. clbsk is the proc called with param when scanning is achieved. + TNewAst = function(param: Pointer; clbck: TAstNotification): TAstHandle; cdecl; + // Deletes the D AST identified by hdl. + TDeleteAst = procedure(hdl: TAstHandle); cdecl; + + // Uses D AST identified by hsdl to parse filename. + TScanFile = procedure(hdl: TAstHandle; filename: PChar); cdecl; + // Uses D AST identified by hsdl to parse the buffer of length len. + TScanBuffer = procedure(hdl: TAstHandle; buffer: PByte; len: NativeUint); cdecl; + + // Returns the name of the module identified by hdl. + TModuleName = function(hdl: TAstHandle): PChar; cdecl; + // Returns the list of the declarations in the module identified by hdl. + TSymbolList = function(hdl: TAstHandle; var len: NativeUint ; fmt: TSerializationFormat): PByte; cdecl; + +var + newAST: TNewAst; + deleteAST: TDeleteAst; + scanFile: TScanFile; + scanBuffer: TScanBuffer; + moduleName: TModuleName; + symbolList: TSymbolList; + dastAvailable: boolean; + + +implementation + +var + dastHdl: TLibHandle = 0; + fname: string; + +initialization + + fname := exeFullName('cedast' + dynExt); + if FileExists(fname) then + dastHdl := LoadLibrary(fname); + if dastHdl <> NilHandle then + begin + newAST := TNewAst(GetProcAddress(dastHdl, 'newAst')); + deleteAST := TDeleteAst(GetProcAddress(dastHdl, 'deleteAst')); + scanFile := TScanFile(GetProcAddress(dastHdl, 'scanFile')); + scanBuffer := TScanBuffer(GetProcAddress(dastHdl, 'scanBuffer')); + moduleName := TModuleName(GetProcAddress(dastHdl, 'moduleName')); + symbolList := TSymbolList(GetProcAddress(dastHdl, 'symbolList')); + // + dastAvailable := assigned(newAST) and assigned(deleteAST) and assigned(scanFile) + and assigned(scanBuffer) and assigned(moduleName) and assigned(symbolList); + end; + +finalization + {$IFDEF RELEASE} + if dastHdl <> NilHandle then + UnloadLibrary(dastHdl); + {$ENDIF} +end. +