diff --git a/dastworx/dastworx.ce b/dastworx/dastworx.ce index 9dabf8fa..8a5ffca2 100644 --- a/dastworx/dastworx.ce +++ b/dastworx/dastworx.ce @@ -11,6 +11,15 @@ object CurrentProject: TCENativeProject ) pathsOptions.outputFilename = '../bin/dastworx' runOptions.options = [poUsePipes, poStderrToOutPut] + end + item + name = 'release' + outputOptions.inlining = True + outputOptions.boundsCheck = offAlways + outputOptions.optimizations = True + outputOptions.release = True + pathsOptions.outputFilename = '../bin/dastworx' + runOptions.options = [poUsePipes, poStderrToOutPut] end> Sources.Strings = ( 'src/main.d' @@ -21,7 +30,7 @@ object CurrentProject: TCENativeProject 'src/common.d' 'src/runnableflags.d' ) - ConfigurationIndex = 0 + ConfigurationIndex = 1 LibraryAliases.Strings = ( 'iz' 'libdparse' diff --git a/dastworx/dastworx.cegrp b/dastworx/dastworx.cegrp index ae71c63d..7e0fcddd 100644 --- a/dastworx/dastworx.cegrp +++ b/dastworx/dastworx.cegrp @@ -9,5 +9,5 @@ object _1: TProjectGroup item filename = 'dastworx.ce' end> - index = 0 + index = 2 end diff --git a/dastworx/src/imports.d b/dastworx/src/imports.d index a757dbf7..4fe4415e 100644 --- a/dastworx/src/imports.d +++ b/dastworx/src/imports.d @@ -36,8 +36,8 @@ private final class ImportLister: ASTVisitor size_t mixinDepth; override void visit(const ConditionalDeclaration decl) - { - const VersionCondition ver = decl.compileCondition.versionCondition; + { + const VersionCondition ver = decl.compileCondition.versionCondition; if (ver is null || !canFind(badVersions, ver.token.text)) decl.accept(this); } @@ -55,23 +55,23 @@ private final class ImportLister: ASTVisitor } override void visit(const(MixinExpression) mix) - { - ++mixinDepth; - mix.accept(this); - --mixinDepth; - } + { + ++mixinDepth; + mix.accept(this); + --mixinDepth; + } override void visit(const PrimaryExpression primary) - { - if (mixinDepth && primary.primary.type.isStringLiteral) - { + { + if (mixinDepth && primary.primary.type.isStringLiteral) + { assert(primary.primary.text.length > 1); size_t startIndex = 1; startIndex += primary.primary.text[0] == 'q'; parseAndVisit!(ImportLister)(primary.primary.text[startIndex..$-1]); - } - primary.accept(this); - } + } + primary.accept(this); + } } diff --git a/dastworx/src/main.d b/dastworx/src/main.d index 842d7f84..adf21e08 100644 --- a/dastworx/src/main.d +++ b/dastworx/src/main.d @@ -1,4 +1,4 @@ -module ceasttools; +module dastworx; import core.memory; @@ -18,6 +18,7 @@ private __gshared Module module_ = void; private __gshared static Appender!(ubyte[]) source; private __gshared RollbackAllocator allocator; private __gshared LexerConfig config; +private __gshared StringCache* cache; private __gshared static Appender!(AstErrors) errors; private __gshared string[] files; @@ -49,8 +50,7 @@ void main(string[] args) files = args[1].splitter(pathSeparator).array; config = LexerConfig("", StringBehavior.source, WhitespaceBehavior.skip); - StringCache cache = StringCache(StringCache.defaultBucketCount); - tokens = getTokensForParser(source.data, config, &cache); + cache = construct!(StringCache)(StringCache.defaultBucketCount); getopt(args, std.getopt.config.passThrough, "d", &deepSymList @@ -77,9 +77,10 @@ void handleSymListOption() void handleTodosOption() { mixin(logCall); - const(Token)[]*[] tokensArray; + lex!true; + const(Token)[][] tokensArray; if (tokens.length) - tokensArray ~= &tokens; + tokensArray ~= tokens; import std.file: exists; if (files.length) @@ -94,7 +95,7 @@ void handleTodosOption() ubyte[] src; foreach(buffer; f.byChunk(4096)) src ~= buffer; - //tokensArray ~= getTokensForParser(src, config, &cache); + tokensArray ~= getTokensForParser(src, config, &cache); f.close; } catch (Exception e) continue; @@ -106,6 +107,7 @@ void handleTodosOption() void handleRunnableFlags() { mixin(logCall); + lex!true; getRunnableFlags(tokens); } @@ -113,6 +115,7 @@ void handleImportsOption() { mixin(logCall); storeAstErrors = false; + lex!false; parseTokens; listImports(module_); } @@ -121,6 +124,7 @@ void handleMainfunOption() { mixin(logCall); storeAstErrors = false; + lex!false; parseTokens; detectMainFun(module_); } @@ -131,6 +135,17 @@ void handleErrors(string fname, size_t line, size_t col, string message, bool er errors ~= construct!(AstError)(cast(ErrorType) err, message, line, col); } +void lex(bool keepComments = false)() +{ + static if (keepComments) + { + DLexer dlx = DLexer(source.data, config, cache); + tokens = dlx.array; + } + else + tokens = getTokensForParser(source.data, config, cache); +} + void parseTokens() { mixin(logCall); @@ -144,6 +159,6 @@ version(devel) version(all) import std.uri; mixin(q{import std.c.time;}); - //TODO: something + // TODO:something } diff --git a/dastworx/src/mainfun.d b/dastworx/src/mainfun.d index 87b4fc5b..9cc4015d 100644 --- a/dastworx/src/mainfun.d +++ b/dastworx/src/mainfun.d @@ -39,8 +39,8 @@ private final class MainFunctionDetector: ASTVisitor } override void visit(const ConditionalDeclaration decl) - { - const VersionCondition ver = decl.compileCondition.versionCondition; + { + const VersionCondition ver = decl.compileCondition.versionCondition; if (ver is null || !canFind(badVersions, ver.token.text)) decl.accept(this); } diff --git a/dastworx/src/todos.d b/dastworx/src/todos.d index 19f69a5d..8d0407e8 100644 --- a/dastworx/src/todos.d +++ b/dastworx/src/todos.d @@ -10,18 +10,17 @@ import private __gshared Appender!string stream; -void getTodos(const(Token)[]*[] tokensArray) +void getTodos(const(Token)[][] tokensArray) { mixin(logCall); stream.reserve(2^^16); - stream.put("object TTodoItems\r items = <"); + stream.put("object TTodoItems\ritems = <"); assert(tokensArray.length); + assert(tokensArray[0].length); foreach(tokens; tokensArray) - //foreach(token; (*tokens).filter!((a) => a.type == tok!"comment")()) - foreach(token; *tokens) - if (token.type == tok!"comment") - token.analyze; - stream.put(">\rend\r\n"); + foreach(token; tokens.filter!((a) => a.type == tok!"comment")) + token.analyze; + stream.put(">\rend\r"); writeln(stream.data); } @@ -111,7 +110,7 @@ private void analyze(const(Token) token) - stream.put("item\r"); + stream.put("\ritem\r"); //stream.put(format("filename = '%s'\r", fname)); stream.put(format("line = '%d'\r", token.line)); stream.put(format("text = '%s'\r", text)); @@ -123,5 +122,5 @@ private void analyze(const(Token) token) stream.put(format("priority = '%s'\r", p)); if (s.length) stream.put(format("status = '%s'\r", s)); - stream.put("end\r"); + stream.put("end"); } diff --git a/src/ce_common.pas b/src/ce_common.pas index 7e52b961..94ef077a 100644 --- a/src/ce_common.pas +++ b/src/ce_common.pas @@ -27,6 +27,8 @@ type TIndentationMode = (imSpaces, imTabs); + THasMain = (mainNo, mainYes, mainDefaultBehavior); + TCECompiler = (dmd, gdc, ldc); // aliased to get a custom prop inspector diff --git a/src/ce_main.pas b/src/ce_main.pas index aa0534cc..c98e7695 100644 --- a/src/ce_main.pas +++ b/src/ce_main.pas @@ -2193,6 +2193,7 @@ var lst: TStringList = nil; firstLineFlags: string = ''; asObj: boolean = false; + hasMain: THasMain; begin result := false; @@ -2261,8 +2262,17 @@ begin dmdproc.Parameters.AddText(fRunnableSw); if lst.isNotNil and (lst.Count <> 0) then dmdproc.Parameters.AddStrings(lst); - if fAppliOpts.detectMain and not fDoc.implementMain then - dmdproc.Parameters.Add('-main'); + if fAppliOpts.detectMain then + begin + hasMain := fDoc.implementMain; + case hasMain of + mainNo: + dmdproc.Parameters.Add('-main'); + mainDefaultBehavior: + if unittest then + dmdproc.Parameters.Add('-main'); + end; + end; if unittest then begin if not fAppliOpts.detectMain then diff --git a/src/ce_synmemo.pas b/src/ce_synmemo.pas index 12020daf..ef249d88 100644 --- a/src/ce_synmemo.pas +++ b/src/ce_synmemo.pas @@ -108,6 +108,7 @@ type TCESynMemo = class(TSynEdit) private fFilename: string; + fDastWorxExename: string; fModified: boolean; fFileDate: double; fCacheLoaded: boolean; @@ -216,7 +217,7 @@ type procedure nextChangedArea; procedure previousChangedArea; procedure copy; - function implementMain: boolean; + function implementMain: THasMain; // function breakPointsCount: integer; function breakPointLine(index: integer): integer; @@ -579,6 +580,8 @@ begin LineHighlightColor.Background := color - $080808; LineHighlightColor.Foreground := clNone; // + fDastWorxExename:= exeFullName('dastworx' + exeExt); + // subjDocNew(TCEMultiDocSubject(fMultiDocSubject), self); end; @@ -1300,74 +1303,33 @@ begin end; end; -function TCESynMemo.implementMain: boolean; - function search(root: TJSONData): boolean; - var - i: integer; - p: TJSONData; - begin - if root.isNil then - exit(false); - root := root.FindPath('members'); - if root.isNil then - exit(false); - for i := 0 to root.Count-1 do - begin - p := root.Items[i].FindPath('kind'); - if p.isNotNil and (p.AsString = 'function') then - begin - p := root.Items[i].FindPath('name'); - if p.isNotNil and (p.AsString = 'main') then - exit(true); - end; - if search(root.Items[i]) then - exit(true); - end; - exit(false); - end; +function TCESynMemo.implementMain: THasMain; var + res: char = '0'; prc: TProcess; - jfn: string; - jdt: string; + src: string; begin - if fileName.fileExists then - save - else - saveTempFile; - jfn := tempFilename + '.json'; + if fDastWorxExename.length = 0 then + exit(mainDefaultBehavior); + src := Lines.Text; prc := TProcess.Create(nil); try - //TODO-crunnables: the main() detector that uses DMD, libman entries must be passd to DMD. - prc.Executable:= 'dmd' + exeExt; - prc.Parameters.Add(fileName); - prc.Parameters.Add('-c'); - prc.Parameters.Add('-o-'); - prc.Parameters.Add('-Xf' + jfn); + prc.Executable:= fDastWorxExename; + prc.Parameters.Add('-m'); + prc.Options := [poUsePipes{$IFDEF WINDOWS}, poNewConsole{$ENDIF}]; + prc.ShowWindow := swoHIDE; prc.Execute; - while prc.Running do Sleep(5); + prc.Input.Write(src[1], src.length); + prc.CloseInput; + while prc.Running do + sleep(1); + prc.Output.Read(res, 1); finally prc.Free; end; - if not jfn.fileExists then - exit(false); - with TMemoryStream.Create do - try - LoadFromFile(jfn); - setLength(jdt, size); - read(jdt[1], size); - finally - free; - DeleteFile(jfn); - end; - with TJSONParser.Create(jdt) do - try - try - result := search(Parse.Items[0]); - except - exit(false); - end; - finally - free; + case res = '1' of + false:result := mainNo; + true: result := mainYes; end; end; {$ENDREGION}