From c8556aacfaf8973ee4b3baa3fca30af278be7c1e Mon Sep 17 00:00:00 2001 From: Basile Burg Date: Wed, 4 Nov 2015 20:26:49 +0100 Subject: [PATCH] added option to output symlist data as json --- cesyms/cesyms.d | 97 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 81 insertions(+), 16 deletions(-) diff --git a/cesyms/cesyms.d b/cesyms/cesyms.d index 2b37da9d..881cc196 100644 --- a/cesyms/cesyms.d +++ b/cesyms/cesyms.d @@ -1,17 +1,44 @@ +/** +Usage +===== + +- In Coedit: + the program must be located somewhere in the PATH. + +- Elsewhere: + invoke with `[-j] []`. + - `-j`: optional, if set then the program outputs the list (in stdout) in JSON + otherwise in Pascal streaming text format. + - ``: optional, the D module filename, if not set then the program + reads the module from stdin. + - see the source for more information about how to use the output. + It's basically a tree of struct with 3 members: symbol type, name and location. + +- Test in CE as a runnable module: + click `Compile file and run ...` and type either `` or `-j ` in the + input query dialog. Note that this will only work if libdparse is setup in the + library manager. + +*/ module cesyms; -/* -requires a libdparse fix / or comple without -inline, see - -https://issues.dlang.org/show_bug.cgi?id=15272 -*/ - import std.stdio, std.path, std.file, std.array, std.string; +import std.getopt, std.json, std.conv; import dparse.lexer, dparse.ast, dparse.parser; import std.traits; +enum ListFmt +{ + Pascal, + JSON +} + void main(string[] args) { + // format + bool asJson; + getopt(args, std.getopt.config.passThrough,'j', &asJson); + // get either the module from stdin or from first arg string fname; ubyte[] source; @@ -20,12 +47,13 @@ void main(string[] args) foreach(buff; stdin.byChunk(1024)) source ~= buff; } - else + else if (args.length == 2) { - fname = args[1]; + fname = args[$-1]; if (!fname.exists) return; source = cast(ubyte[]) read(fname, size_t.max); } + else return; // load and parse the file auto config = LexerConfig(fname, StringBehavior.source, WhitespaceBehavior.skip); @@ -40,7 +68,7 @@ void main(string[] args) slb.visit(decl); } - version(runnable_module) + version(none) { int level = -1; void print(Symbol * s) @@ -57,10 +85,10 @@ void main(string[] args) } else { - write(slb.serialize); - - } - + if (asJson) write(slb.serializeJson); + else write(slb.serializePascal); + } + slb.destruct; } @@ -151,7 +179,16 @@ struct Symbol subs[i].destruct; } - void serialize(ref Appender!string lfmApp) + void serialize(List)(auto ref List list) + { + static if (is(List == Appender!string)) + serializePascal(list); + else static if (is(List == JSONValue)) + serializeJson(list); + else static assert(0, "serialization kind cannot be deduced from list"); + } + + void serializePascal(ref Appender!string lfmApp) { lfmApp.put("\ritem\r"); @@ -166,6 +203,23 @@ struct Symbol lfmApp.put(">\r"); lfmApp.put("end"); } + + void serializeJson(ref JSONValue json) + { + auto vobj = parseJSON("{}"); + vobj["line"]= JSONValue(line); + vobj["col"] = JSONValue(col); + vobj["name"]= JSONValue(name); + vobj["type"]= JSONValue(to!string(type)); + if (subs.length) + { + auto vsubs = parseJSON("[]"); + foreach(Symbol * sub; subs) + sub.serializeJson(vsubs); + vobj["items"] = vsubs; + } + json.array ~= vobj; + } } //---- @@ -205,7 +259,7 @@ class SymbolListBuilder : ASTVisitor final void resetRoot(){parent = root;} - final string serialize() + final string serializePascal() { Appender!string lfmApp; lfmApp.reserve(count * 64); @@ -218,6 +272,18 @@ class SymbolListBuilder : ASTVisitor return lfmApp.data; } + final string serializeJson() + { + JSONValue result = parseJSON("{}"); + JSONValue vsubs = parseJSON("[]"); + foreach(sym; illFormed) sym.serialize(vsubs); + foreach(sym; root.subs) sym.serialize(vsubs); + result["items"] = vsubs; + version(assert) return result.toPrettyString; + // else: release mode + else return result.toString; + } + /// returns a new symbol if the declarator is based on a Token named "name". final Symbol * addDeclaration(DT)(DT adt) { @@ -382,4 +448,3 @@ class SymbolListBuilder : ASTVisitor } } //---- -