use dastworx to detect main(), fixup

without the imports it was not possible to use DMD
This commit is contained in:
Basile Burg 2016-07-02 07:07:03 +02:00
parent 44bf535c11
commit c5e1cf513a
9 changed files with 92 additions and 95 deletions

View File

@ -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'

View File

@ -9,5 +9,5 @@ object _1: TProjectGroup
item
filename = 'dastworx.ce'
end>
index = 0
index = 2
end

View File

@ -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);
}
}

View File

@ -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
}

View File

@ -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);
}

View File

@ -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");
}

View File

@ -27,6 +27,8 @@ type
TIndentationMode = (imSpaces, imTabs);
THasMain = (mainNo, mainYes, mainDefaultBehavior);
TCECompiler = (dmd, gdc, ldc);
// aliased to get a custom prop inspector

View File

@ -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

View File

@ -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}