mirror of https://gitlab.com/basile.b/dexed.git
use dastworx to detect main(), fixup #79
without the imports it was not possible to use DMD
This commit is contained in:
parent
44bf535c11
commit
c5e1cf513a
|
@ -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'
|
||||
|
|
|
@ -9,5 +9,5 @@ object _1: TProjectGroup
|
|||
item
|
||||
filename = 'dastworx.ce'
|
||||
end>
|
||||
index = 0
|
||||
index = 2
|
||||
end
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ type
|
|||
|
||||
TIndentationMode = (imSpaces, imTabs);
|
||||
|
||||
THasMain = (mainNo, mainYes, mainDefaultBehavior);
|
||||
|
||||
TCECompiler = (dmd, gdc, ldc);
|
||||
|
||||
// aliased to get a custom prop inspector
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
|
|
Loading…
Reference in New Issue