diff --git a/changelog/more_json.dd b/changelog/more_json.dd new file mode 100644 index 000000000000..822d63be11f6 --- /dev/null +++ b/changelog/more_json.dd @@ -0,0 +1,37 @@ +Added more information to json output + +Add the following objects were to the json output: +--- +[ + { + "kind" : "compilerInfo", + "binary" : "", + "version" : "", + "supportsIncludeImports" : true + }, + { + "kind" : "buildInfo", + "config": "", + "cwd": "", + "importPaths": [ + "", + "", + //... + ] + }, + // ... + { + "kind": "semantics", + "modules": [ + { + "name": "" + "file": "", + // isRoot is true if the module is going to be taken + // to object code. + "isRoot": true|false, + }, + // ... + ] + } +] +--- diff --git a/src/dmd/dmodule.d b/src/dmd/dmodule.d index bf4480b6622a..8c9b461459ae 100644 --- a/src/dmd/dmodule.d +++ b/src/dmd/dmodule.d @@ -322,6 +322,7 @@ extern (C++) final class Module : Package uint numlines; // number of lines in source file int isDocFile; // if it is a documentation input file, not D source bool isPackageFile; // if it is a package.d + Strings contentImportedFiles; // array of files whose content was imported int needmoduleinfo; /** How many unit tests have been seen so far in this module. Makes it so the diff --git a/src/dmd/expressionsem.d b/src/dmd/expressionsem.d index 5633832a79ef..34471eadf5c8 100644 --- a/src/dmd/expressionsem.d +++ b/src/dmd/expressionsem.d @@ -4282,6 +4282,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return setError(); } + sc._module.contentImportedFiles.push(name); if (global.params.verbose) fprintf(global.stdmsg, "file %.*s\t(%s)\n", cast(int)se.len, se.string, name); if (global.params.moduleDeps !is null) diff --git a/src/dmd/json.d b/src/dmd/json.d index b3dca5489c74..c3e554d86035 100644 --- a/src/dmd/json.d +++ b/src/dmd/json.d @@ -34,6 +34,12 @@ import dmd.mtype; import dmd.root.outbuffer; import dmd.visitor; +version(Windows) { + extern (C) char* getcwd(char* buffer, size_t maxlen); +} else { + import core.sys.posix.unistd : getcwd; +} + private extern (C++) final class ToJsonVisitor : Visitor { alias visit = Visitor.visit; @@ -789,12 +795,70 @@ public: jsonProperties(d); objectEnd(); } + + private void generateCompilerInfo() + { + objectStart(); + property("kind", "compilerInfo"); + property("binary", global.params.argv0); + property("version", global._version); + propertyBool("supportsIncludeImports", true); + objectEnd(); + } + private void generateBuildInfo() + { + objectStart(); + property("kind", "buildInfo"); + property("cwd", getcwd(null, 0)); + property("config", global.inifilename ? global.inifilename : null); + if (global.params.lib) { + property("library", global.params.libname); + } + propertyStart("importPaths"); + arrayStart(); + foreach (importPath; *global.params.imppath) + { + item(importPath); + } + arrayEnd(); + objectEnd(); + } + private void generateSemantics() + { + objectStart(); + property("kind", "semantics"); + propertyStart("modules"); + arrayStart(); + foreach (m; Module.amodules) + { + objectStart(); + if(m.md) + property("name", m.md.toChars()); + property("file", m.srcfile.toChars()); + propertyBool("isRoot", m.isRoot()); + if(m.contentImportedFiles.dim > 0) + { + propertyStart("contentImports"); + arrayStart(); + foreach (file; m.contentImportedFiles) + { + item(file); + } + arrayEnd(); + } + objectEnd(); + } + arrayEnd(); + objectEnd(); + } } extern (C++) void json_generate(OutBuffer* buf, Modules* modules) { scope ToJsonVisitor json = new ToJsonVisitor(buf); json.arrayStart(); + json.generateCompilerInfo(); + json.generateBuildInfo(); for (size_t i = 0; i < modules.dim; i++) { Module m = (*modules)[i]; @@ -802,6 +866,7 @@ extern (C++) void json_generate(OutBuffer* buf, Modules* modules) fprintf(global.stdmsg, "json gen %s\n", m.toChars()); m.accept(json); } + json.generateSemantics(); json.arrayEnd(); json.removeComma(); } diff --git a/src/dmd/module.h b/src/dmd/module.h index 7a40308b8b2d..54f85e7aefdf 100644 --- a/src/dmd/module.h +++ b/src/dmd/module.h @@ -85,6 +85,7 @@ class Module : public Package unsigned numlines; // number of lines in source file int isDocFile; // if it is a documentation input file, not D source bool isPackageFile; // if it is a package.d + Strings contentImportedFiles; // array of files whose content was imported int needmoduleinfo; /** How many unit tests have been seen so far in this module. Makes it so the diff --git a/test/Makefile b/test/Makefile index 10a664bfabec..58c2ad1a9c4a 100644 --- a/test/Makefile +++ b/test/Makefile @@ -203,24 +203,26 @@ fail_compilation_test_results=$(addsuffix .out,$(addprefix $(RESULTS_DIR)/,$(fai all: run_tests -$(RESULTS_DIR)/runnable/%.d.out: runnable/%.d $(RESULTS_DIR)/.created $(RESULTS_DIR)/d_do_test$(EXE) $(DMD) +test_tools: $(RESULTS_DIR)/d_do_test$(EXE) $(RESULTS_DIR)/sanitize_json$(EXE) + +$(RESULTS_DIR)/runnable/%.d.out: runnable/%.d $(RESULTS_DIR)/.created test_tools $(DMD) $(QUIET) $(RESULTS_DIR)/d_do_test $( ${RESULTS_DIR}/compilable/json.out.2 -grep -v "\"file\" : " compilable/extra-files/json.out | grep -v "\"offset\" : " | grep -v "\"deco\" : " > ${RESULTS_DIR}/compilable/json.out.3 +echo SANITIZING JSON... +${RESULTS_DIR}/sanitize_json ${RESULTS_DIR}/compilable/json.out > ${RESULTS_DIR}/compilable/json.out.sanitized +if [ $? -ne 0 ]; then + exit 1; +fi -diff --strip-trailing-cr ${RESULTS_DIR}/compilable/json.out.2 ${RESULTS_DIR}/compilable/json.out.3 +diff --strip-trailing-cr compilable/extra-files/json.out ${RESULTS_DIR}/compilable/json.out.sanitized if [ $? -ne 0 ]; then exit 1; fi -rm ${RESULTS_DIR}/compilable/json.out{.2,.3} +rm ${RESULTS_DIR}/compilable/json.out.sanitized diff --git a/test/compilable/extra-files/json.out b/test/compilable/extra-files/json.out index 02e787f928aa..26704f80822a 100644 --- a/test/compilable/extra-files/json.out +++ b/test/compilable/extra-files/json.out @@ -1,930 +1,976 @@ [ - { - "name" : "json", - "kind" : "module", - "file" : "compilable/json.d", - "members" : [ - { - "name" : "_staticCtor1", - "kind" : "function", - "line" : 8, - "char" : 1, - "storageClass" : [ - "static" - ], - "deco" : "FZv", - "endline" : 8, - "endchar" : 16 - }, - { - "name" : "_staticDtor2", - "kind" : "function", - "line" : 10, - "char" : 1, - "storageClass" : [ - "static" - ], - "deco" : "FZv", - "endline" : 10, - "endchar" : 17 - }, - { - "name" : "myInt", - "kind" : "alias", - "line" : 13, - "char" : 11, - "deco" : "i" - }, - { - "name" : "x", - "kind" : "variable", - "line" : 14, - "char" : 7, - "deco" : "i", - "originalType" : "myInt" - }, - { - "kind" : "template", - "line" : 16, - "char" : 1, - "name" : "Foo", - "parameters" : [ - { - "name" : "T", - "kind" : "type" - } - ], - "members" : [ - { - "name" : "Foo", - "kind" : "struct", - "line" : 16, - "char" : 1, - "members" : [ - { - "name" : "t", - "kind" : "variable", - "line" : 16, - "char" : 19, - "type" : "T" - } - ] - } - ] - }, - { - "kind" : "template", - "line" : 17, - "char" : 1, - "name" : "Bar", - "parameters" : [ - { - "name" : "T", - "kind" : "value", - "deco" : "i" - } - ], - "members" : [ - { - "name" : "Bar", - "kind" : "class", - "line" : 17, - "char" : 1, - "members" : [ - { - "name" : "t", - "kind" : "variable", - "line" : 17, - "char" : 25, - "deco" : "i", - "init" : "T" - } - ] - } - ] - }, - { - "kind" : "template", - "line" : 18, - "char" : 1, - "name" : "Baz", - "parameters" : [ - { - "name" : "T", - "kind" : "tuple" - } - ], - "members" : [ - { - "name" : "Baz", - "kind" : "interface", - "line" : 18, - "char" : 1, - "members" : [ - { - "name" : "t", - "kind" : "function", - "line" : 18, - "char" : 28, - "type" : "const T[0]()" - } - ] - } - ] - }, - { - "kind" : "template", - "line" : 20, - "char" : 1, - "name" : "P", - "parameters" : [ - { - "name" : "T", - "kind" : "alias" - } - ], - "members" : [] - }, - { - "name" : "Bar2", - "kind" : "class", - "line" : 22, - "char" : 1, - "base" : "json.Bar!1.Bar", - "interfaces" : [ - "json.Baz!(int, 2, null).Baz" - ], - "members" : [ - { - "name" : "this", - "kind" : "constructor", - "line" : 23, - "char" : 5, - "deco" : "FZC4json4Bar2", - "originalType" : "()", - "endline" : 23, - "endchar" : 13 - }, - { - "name" : "~this", - "kind" : "destructor", - "line" : 24, - "char" : 5, - "deco" : "FZv", - "endline" : 24, - "endchar" : 14 - }, - { - "name" : "foo", - "kind" : "function", - "line" : 26, - "char" : 12, - "storageClass" : [ - "static" - ], - "deco" : "FNaNbNiNfZv", - "originalType" : "()", - "endline" : 26, - "endchar" : 19 - }, - { - "name" : "baz", - "kind" : "function", - "protection" : "protected", - "line" : 27, - "char" : 32, - "storageClass" : [ - "abstract" - ], - "deco" : "FZS4json__T3FooTiZQh" - }, - { - "name" : "t", - "kind" : "function", - "line" : 28, - "char" : 18, - "storageClass" : [ - "override" - ], - "deco" : "xFZi", - "endline" : 28, - "endchar" : 40, - "overrides" : [ - "json.Baz!(int, 2, null).Baz.t" - ] - }, - { - "name" : "__xdtor", - "kind" : "alias" - } - ] - }, - { - "name" : "Bar3", - "kind" : "class", - "line" : 31, - "char" : 1, - "base" : "json.Bar2", - "members" : [ - { - "name" : "val", - "kind" : "variable", - "protection" : "private", - "line" : 32, - "char" : 17, - "deco" : "i", - "offset" : 32 - }, - { - "name" : "this", - "kind" : "constructor", - "line" : 33, - "char" : 5, - "deco" : "FiZC4json4Bar3", - "originalType" : "(int i)", - "parameters" : [ - { - "name" : "i", - "deco" : "i" - } - ], - "endline" : 33, - "endchar" : 28 - }, - { - "name" : "baz", - "kind" : "function", - "protection" : "protected", - "line" : 35, - "char" : 32, - "storageClass" : [ - "override" - ], - "deco" : "FZS4json__T3FooTiZQh", - "endline" : 35, - "endchar" : 61, - "overrides" : [ - "json.Bar2.baz" - ] - } - ] - }, - { - "name" : "Foo2", - "kind" : "struct", - "line" : 38, - "char" : 1, - "members" : [ - { - "name" : "bar2", - "kind" : "variable", - "line" : 39, - "char" : 10, - "deco" : "C4json4Bar2", - "originalType" : "Bar2", - "offset" : 0 - }, - { - "name" : "U", - "kind" : "union", - "line" : 40, - "char" : 5, - "members" : [ - { - "name" : "s", - "kind" : "variable", - "line" : 42, - "char" : 19, - "deco" : "s", - "offset" : 0 - }, - { - "name" : "i", - "kind" : "variable", - "line" : 43, - "char" : 17, - "deco" : "i", - "offset" : 4 - }, - { - "name" : "o", - "kind" : "variable", - "line" : 45, - "char" : 16, - "deco" : "C6Object", - "originalType" : "Object", - "offset" : 0 - } - ] - } - ] - }, - { - "kind" : "template", - "line" : 49, - "char" : 1, - "name" : "Foo3", - "parameters" : [ - { - "name" : "b", - "kind" : "value", - "deco" : "b" - } - ], - "members" : [ - { - "name" : "Foo3", - "kind" : "struct", - "line" : 49, - "char" : 1, - "members" : [ - { - "name" : "method1", - "kind" : "function", - "line" : 52, - "char" : 14, - "type" : "void()" - }, - { - "name" : "method2", - "kind" : "function", - "line" : 56, - "char" : 14, - "type" : "void()" - }, - { - "name" : "method4", - "kind" : "function", - "line" : 63, - "char" : 10, - "type" : "void()" - } - ] - } - ] - }, - { - "name" : "bar", - "kind" : "function", - "line" : 69, - "char" : 16, - "deco" : "FNeKkC4json4Bar2Zi", - "originalType" : "@trusted myInt(ref uint blah, Bar2 foo = new Bar3(7))", - "parameters" : [ - { - "name" : "blah", - "deco" : "k", - "storageClass" : [ - "ref" - ] - }, - { - "name" : "foo", - "deco" : "C4json4Bar2", - "default" : "new Bar3(7)" - } - ], - "endline" : 72, - "endchar" : 1 - }, - { - "name" : "outer", - "kind" : "function", - "line" : 74, - "char" : 15, - "deco" : "FNbNdZi", - "endline" : 91, - "endchar" : 1 - }, - { - "name" : "imports.jsonimport1", - "kind" : "import", - "line" : 94, - "char" : 8, - "protection" : "private", - "selective" : [ - "target1", - "target2" - ] - }, - { - "name" : "imports.jsonimport2", - "kind" : "import", - "line" : 95, - "char" : 8, - "protection" : "private", - "renamed" : { - "alias1" : "target1", - "alias2" : "target2" - } - }, - { - "name" : "imports.jsonimport3", - "kind" : "import", - "line" : 96, - "char" : 8, - "protection" : "private", - "renamed" : { - "alias3" : "target1", - "alias4" : "target2" + { + "binary": "VALUE_REMOVED_FOR_TEST", + "kind": "compilerInfo", + "supportsIncludeImports": true, + "version": "VALUE_REMOVED_FOR_TEST" + }, + { + "config": "VALUE_REMOVED_FOR_TEST", + "cwd": "VALUE_REMOVED_FOR_TEST", + "importPaths": [ + "compilable", + "..\/..\/druntime\/import", + "..\/..\/phobos" + ], + "kind": "buildInfo" }, - "selective" : [ - "target3" - ] - }, - { - "name" : "imports.jsonimport4", - "kind" : "import", - "line" : 97, - "char" : 8, - "protection" : "private" - }, - { - "name" : "S", - "kind" : "struct", - "line" : 99, - "char" : 1, - "members" : [ - { - "kind" : "template", - "line" : 102, - "char" : 5, - "name" : "this", - "parameters" : [ - { - "name" : "T", - "kind" : "type" - } - ], - "members" : [ - { - "name" : "this", - "kind" : "constructor", - "line" : 102, - "char" : 5, - "type" : "(T t)", - "parameters" : [ - { - "name" : "t", - "type" : "T" - } + { + "file": "VALUE_REMOVED_FOR_TEST", + "kind": "module", + "members": [ + { + "char": 1, + "deco": "VALUE_REMOVED_FOR_TEST", + "endchar": 16, + "endline": 8, + "kind": "function", + "line": 8, + "name": "_staticCtor1", + "storageClass": [ + "static" + ] + }, + { + "char": 1, + "deco": "VALUE_REMOVED_FOR_TEST", + "endchar": 17, + "endline": 10, + "kind": "function", + "line": 10, + "name": "_staticDtor2", + "storageClass": [ + "static" + ] + }, + { + "char": 11, + "deco": "VALUE_REMOVED_FOR_TEST", + "kind": "alias", + "line": 13, + "name": "myInt" + }, + { + "char": 7, + "deco": "VALUE_REMOVED_FOR_TEST", + "kind": "variable", + "line": 14, + "name": "x", + "originalType": "myInt" + }, + { + "char": 1, + "kind": "template", + "line": 16, + "members": [ + { + "char": 1, + "kind": "struct", + "line": 16, + "members": [ + { + "char": 19, + "kind": "variable", + "line": 16, + "name": "t", + "type": "T" + } + ], + "name": "Foo" + } + ], + "name": "Foo", + "parameters": [ + { + "kind": "type", + "name": "T" + } + ] + }, + { + "char": 1, + "kind": "template", + "line": 17, + "members": [ + { + "char": 1, + "kind": "class", + "line": 17, + "members": [ + { + "char": 25, + "deco": "VALUE_REMOVED_FOR_TEST", + "init": "T", + "kind": "variable", + "line": 17, + "name": "t" + } + ], + "name": "Bar" + } + ], + "name": "Bar", + "parameters": [ + { + "deco": "VALUE_REMOVED_FOR_TEST", + "kind": "value", + "name": "T" + } + ] + }, + { + "char": 1, + "kind": "template", + "line": 18, + "members": [ + { + "char": 1, + "kind": "interface", + "line": 18, + "members": [ + { + "char": 28, + "kind": "function", + "line": 18, + "name": "t", + "type": "const T[0]()" + } + ], + "name": "Baz" + } + ], + "name": "Baz", + "parameters": [ + { + "kind": "tuple", + "name": "T" + } + ] + }, + { + "char": 1, + "kind": "template", + "line": 20, + "members": [], + "name": "P", + "parameters": [ + { + "kind": "alias", + "name": "T" + } + ] + }, + { + "base": "json.Bar!1.Bar", + "char": 1, + "interfaces": [ + "json.Baz!(int, 2, null).Baz" + ], + "kind": "class", + "line": 22, + "members": [ + { + "char": 5, + "deco": "VALUE_REMOVED_FOR_TEST", + "endchar": 13, + "endline": 23, + "kind": "constructor", + "line": 23, + "name": "this", + "originalType": "()" + }, + { + "char": 5, + "deco": "VALUE_REMOVED_FOR_TEST", + "endchar": 14, + "endline": 24, + "kind": "destructor", + "line": 24, + "name": "~this" + }, + { + "char": 12, + "deco": "VALUE_REMOVED_FOR_TEST", + "endchar": 19, + "endline": 26, + "kind": "function", + "line": 26, + "name": "foo", + "originalType": "()", + "storageClass": [ + "static" + ] + }, + { + "char": 32, + "deco": "VALUE_REMOVED_FOR_TEST", + "kind": "function", + "line": 27, + "name": "baz", + "protection": "protected", + "storageClass": [ + "abstract" + ] + }, + { + "char": 18, + "deco": "VALUE_REMOVED_FOR_TEST", + "endchar": 40, + "endline": 28, + "kind": "function", + "line": 28, + "name": "t", + "overrides": [ + "json.Baz!(int, 2, null).Baz.t" + ], + "storageClass": [ + "override" + ] + }, + { + "kind": "alias", + "name": "__xdtor" + } + ], + "name": "Bar2" + }, + { + "base": "json.Bar2", + "char": 1, + "kind": "class", + "line": 31, + "members": [ + { + "char": 17, + "deco": "VALUE_REMOVED_FOR_TEST", + "kind": "variable", + "line": 32, + "name": "val", + "offset": 0, + "protection": "private" + }, + { + "char": 5, + "deco": "VALUE_REMOVED_FOR_TEST", + "endchar": 28, + "endline": 33, + "kind": "constructor", + "line": 33, + "name": "this", + "originalType": "(int i)", + "parameters": [ + { + "deco": "VALUE_REMOVED_FOR_TEST", + "name": "i" + } + ] + }, + { + "char": 32, + "deco": "VALUE_REMOVED_FOR_TEST", + "endchar": 61, + "endline": 35, + "kind": "function", + "line": 35, + "name": "baz", + "overrides": [ + "json.Bar2.baz" + ], + "protection": "protected", + "storageClass": [ + "override" + ] + } + ], + "name": "Bar3" + }, + { + "char": 1, + "kind": "struct", + "line": 38, + "members": [ + { + "char": 10, + "deco": "VALUE_REMOVED_FOR_TEST", + "kind": "variable", + "line": 39, + "name": "bar2", + "offset": 0, + "originalType": "Bar2" + }, + { + "char": 5, + "kind": "union", + "line": 40, + "members": [ + { + "char": 19, + "deco": "VALUE_REMOVED_FOR_TEST", + "kind": "variable", + "line": 42, + "name": "s", + "offset": 0 + }, + { + "char": 17, + "deco": "VALUE_REMOVED_FOR_TEST", + "kind": "variable", + "line": 43, + "name": "i", + "offset": 0 + }, + { + "char": 16, + "deco": "VALUE_REMOVED_FOR_TEST", + "kind": "variable", + "line": 45, + "name": "o", + "offset": 0, + "originalType": "Object" + } + ], + "name": "U" + } + ], + "name": "Foo2" + }, + { + "char": 1, + "kind": "template", + "line": 49, + "members": [ + { + "char": 1, + "kind": "struct", + "line": 49, + "members": [ + { + "char": 14, + "kind": "function", + "line": 52, + "name": "method1", + "type": "void()" + }, + { + "char": 14, + "kind": "function", + "line": 56, + "name": "method2", + "type": "void()" + }, + { + "char": 10, + "kind": "function", + "line": 63, + "name": "method4", + "type": "void()" + } + ], + "name": "Foo3" + } + ], + "name": "Foo3", + "parameters": [ + { + "deco": "VALUE_REMOVED_FOR_TEST", + "kind": "value", + "name": "b" + } + ] + }, + { + "char": 16, + "deco": "VALUE_REMOVED_FOR_TEST", + "endchar": 1, + "endline": 72, + "kind": "function", + "line": 69, + "name": "bar", + "originalType": "@trusted myInt(ref uint blah, Bar2 foo = new Bar3(7))", + "parameters": [ + { + "deco": "VALUE_REMOVED_FOR_TEST", + "name": "blah", + "storageClass": [ + "ref" + ] + }, + { + "deco": "VALUE_REMOVED_FOR_TEST", + "default": "new Bar3(7)", + "name": "foo" + } + ] + }, + { + "char": 15, + "deco": "VALUE_REMOVED_FOR_TEST", + "endchar": 1, + "endline": 91, + "kind": "function", + "line": 74, + "name": "outer" + }, + { + "char": 8, + "kind": "import", + "line": 94, + "name": "imports.jsonimport1", + "protection": "private", + "selective": [ + "target1", + "target2" + ] + }, + { + "char": 8, + "kind": "import", + "line": 95, + "name": "imports.jsonimport2", + "protection": "private", + "renamed": { + "alias1": "target1", + "alias2": "target2" + } + }, + { + "char": 8, + "kind": "import", + "line": 96, + "name": "imports.jsonimport3", + "protection": "private", + "renamed": { + "alias3": "target1", + "alias4": "target2" + }, + "selective": [ + "target3" + ] + }, + { + "char": 8, + "kind": "import", + "line": 97, + "name": "imports.jsonimport4", + "protection": "private" + }, + { + "char": 1, + "kind": "struct", + "line": 99, + "members": [ + { + "char": 5, + "kind": "template", + "line": 102, + "members": [ + { + "char": 5, + "endchar": 20, + "endline": 102, + "kind": "constructor", + "line": 102, + "name": "this", + "parameters": [ + { + "name": "t", + "type": "T" + } + ], + "type": "(T t)" + } + ], + "name": "this", + "parameters": [ + { + "kind": "type", + "name": "T" + } + ] + } + ], + "name": "S" + }, + { + "char": 9, + "kind": "template", + "line": 106, + "members": [ + { + "char": 9, + "kind": "struct", + "line": 106, + "members": [], + "name": "S1_9755" + } + ], + "name": "S1_9755", + "parameters": [ + { + "kind": "type", + "name": "T" + } + ], + "protection": "private" + }, + { + "char": 9, + "kind": "template", + "line": 107, + "members": [ + { + "char": 9, + "kind": "struct", + "line": 107, + "members": [], + "name": "S2_9755" + } + ], + "name": "S2_9755", + "parameters": [ + { + "kind": "type", + "name": "T" + } + ], + "protection": "package" + }, + { + "char": 1, + "kind": "class", + "line": 109, + "members": [ + { + "char": 22, + "kind": "template", + "line": 111, + "members": [ + { + "char": 22, + "kind": "class", + "line": 111, + "members": [], + "name": "CI_9755" + } + ], + "name": "CI_9755", + "parameters": [ + { + "kind": "type", + "name": "T" + } + ], + "protection": "protected" + } + ], + "name": "C_9755" + }, + { + "char": 14, + "deco": "VALUE_REMOVED_FOR_TEST", + "init": "Object()", + "kind": "variable", + "line": 115, + "name": "c_10011", + "originalType": "Object", + "storageClass": [ + "const" + ] + }, + { + "baseDeco": "i", + "char": 1, + "kind": "enum", + "line": 118, + "members": [ + { + "char": 5, + "kind": "enum member", + "line": 120, + "name": "unspecified1", + "value": "0" + }, + { + "char": 5, + "kind": "enum member", + "line": 121, + "name": "one", + "value": "2" + }, + { + "char": 5, + "kind": "enum member", + "line": 122, + "name": "two", + "value": "3" + }, + { + "char": 5, + "kind": "enum member", + "line": 123, + "name": "FILE_NOT_FOUND", + "value": "101" + }, + { + "char": 5, + "kind": "enum member", + "line": 124, + "name": "unspecified3", + "value": "102" + }, + { + "char": 5, + "kind": "enum member", + "line": 125, + "name": "unspecified4", + "value": "103" + }, + { + "char": 5, + "kind": "enum member", + "line": 126, + "name": "four", + "value": "4" + } + ], + "name": "Numbers" + }, + { + "char": 1, + "constraint": "T == string", + "kind": "template", + "line": 129, + "members": [], + "name": "IncludeConstraint", + "parameters": [ + { + "kind": "type", + "name": "T" + } + ] + }, + { + "char": 5, + "deco": "VALUE_REMOVED_FOR_TEST", + "file": "VALUE_REMOVED_FOR_TEST", + "init": "1", + "kind": "variable", + "line": 133, + "name": "a0" + }, + { + "char": 5, + "deco": "VALUE_REMOVED_FOR_TEST", + "init": "1", + "kind": "variable", + "line": 133, + "name": "a1" + }, + { + "char": 5, + "deco": "VALUE_REMOVED_FOR_TEST", + "init": "1", + "kind": "variable", + "line": 133, + "name": "a2" + }, + { + "char": 1, + "file": "VALUE_REMOVED_FOR_TEST", + "kind": "template", + "line": 136, + "members": [ + { + "char": 1, + "kind": "alias", + "line": 136, + "name": "Seq", + "type": "T" + } + ], + "name": "Seq", + "parameters": [ + { + "kind": "tuple", + "name": "T" + } + ] + }, + {}, + { + "char": 1, + "file": "VALUE_REMOVED_FOR_TEST", + "kind": "alias", + "line": 140, + "name": "b0" + }, + {}, + { + "char": 1, + "kind": "alias", + "line": 140, + "name": "b1" + }, + {}, + { + "char": 1, + "kind": "alias", + "line": 140, + "name": "b2" + }, + { + "char": 9, + "deco": "VALUE_REMOVED_FOR_TEST", + "endchar": 1, + "endline": 147, + "file": "VALUE_REMOVED_FOR_TEST", + "kind": "function", + "line": 144, + "name": "foo", + "parameters": [ + { + "deco": "VALUE_REMOVED_FOR_TEST", + "name": "a", + "storageClass": [ + "ref", + "return" + ] + } + ] + }, + { + "char": 6, + "deco": "VALUE_REMOVED_FOR_TEST", + "endchar": 1, + "endline": 152, + "kind": "function", + "line": 149, + "name": "foo", + "parameters": [ + { + "deco": "VALUE_REMOVED_FOR_TEST", + "name": "a", + "storageClass": [ + "scope", + "return" + ] + } + ] + }, + { + "char": 10, + "deco": "VALUE_REMOVED_FOR_TEST", + "endchar": 1, + "endline": 157, + "kind": "function", + "line": 154, + "name": "foo", + "parameters": [ + { + "deco": "VALUE_REMOVED_FOR_TEST", + "name": "a", + "storageClass": [ + "scope", + "ref", + "return" + ] + } + ] + }, + { + "char": 1, + "kind": "struct", + "line": 159, + "members": [ + { + "char": 15, + "deco": "VALUE_REMOVED_FOR_TEST", + "endchar": 5, + "endline": 165, + "kind": "function", + "line": 162, + "name": "foo" + }, + { + "char": 11, + "deco": "VALUE_REMOVED_FOR_TEST", + "endchar": 5, + "endline": 170, + "kind": "function", + "line": 167, + "name": "foo2" + }, + { + "char": 15, + "deco": "VALUE_REMOVED_FOR_TEST", + "endchar": 5, + "endline": 175, + "kind": "function", + "line": 172, + "name": "foo3" + }, + { + "char": 7, + "deco": "VALUE_REMOVED_FOR_TEST", + "kind": "variable", + "line": 177, + "name": "p", + "offset": 0, + "storageClass": [ + "@safe" + ] + } + ], + "name": "SafeS" + }, + { + "char": 12, + "deco": "VALUE_REMOVED_FOR_TEST", + "kind": "variable", + "line": 180, + "name": "vlinkageDefault", + "storageClass": [ + "extern" + ] + }, + { + "char": 15, + "deco": "VALUE_REMOVED_FOR_TEST", + "kind": "variable", + "line": 181, + "name": "vlinkageD" + }, + { + "char": 15, + "deco": "VALUE_REMOVED_FOR_TEST", + "kind": "variable", + "line": 182, + "linkage": "c", + "name": "vlinakgeC" + }, + { + "char": 27, + "deco": "VALUE_REMOVED_FOR_TEST", + "kind": "variable", + "line": 183, + "linkage": "cpp", + "name": "vlinkageCpp", + "storageClass": [ + "__gshared" + ] + }, + { + "char": 21, + "deco": "VALUE_REMOVED_FOR_TEST", + "kind": "variable", + "line": 184, + "linkage": "windows", + "name": "vlinkageWindows" + }, + { + "char": 20, + "deco": "VALUE_REMOVED_FOR_TEST", + "kind": "variable", + "line": 185, + "linkage": "pascal", + "name": "vlinkagePascal" + }, + { + "char": 25, + "deco": "VALUE_REMOVED_FOR_TEST", + "kind": "variable", + "line": 186, + "linkage": "objc", + "name": "vlinkageObjc" + }, + { + "char": 12, + "deco": "VALUE_REMOVED_FOR_TEST", + "kind": "function", + "line": 188, + "name": "flinkageDefault", + "storageClass": [ + "extern" + ] + }, + { + "char": 15, + "deco": "VALUE_REMOVED_FOR_TEST", + "kind": "function", + "line": 189, + "name": "flinkageD" + }, + { + "char": 15, + "deco": "VALUE_REMOVED_FOR_TEST", + "kind": "function", + "line": 190, + "linkage": "c", + "name": "linakgeC" + }, + { + "char": 17, + "deco": "VALUE_REMOVED_FOR_TEST", + "kind": "function", + "line": 191, + "linkage": "cpp", + "name": "flinkageCpp" + }, + { + "char": 21, + "deco": "VALUE_REMOVED_FOR_TEST", + "kind": "function", + "line": 192, + "linkage": "windows", + "name": "flinkageWindows" + }, + { + "char": 20, + "deco": "VALUE_REMOVED_FOR_TEST", + "kind": "function", + "line": 193, + "linkage": "pascal", + "name": "flinkagePascal" + }, + { + "char": 25, + "deco": "VALUE_REMOVED_FOR_TEST", + "kind": "function", + "line": 194, + "linkage": "objc", + "name": "flinkageObjc" + } ], - "endline" : 102, - "endchar" : 20 - } - ] - } - ] - }, - { - "kind" : "template", - "protection" : "private", - "line" : 106, - "char" : 9, - "name" : "S1_9755", - "parameters" : [ - { - "name" : "T", - "kind" : "type" - } - ], - "members" : [ - { - "name" : "S1_9755", - "kind" : "struct", - "line" : 106, - "char" : 9, - "members" : [] - } - ] - }, - { - "kind" : "template", - "protection" : "package", - "line" : 107, - "char" : 9, - "name" : "S2_9755", - "parameters" : [ - { - "name" : "T", - "kind" : "type" - } - ], - "members" : [ - { - "name" : "S2_9755", - "kind" : "struct", - "line" : 107, - "char" : 9, - "members" : [] - } - ] - }, - { - "name" : "C_9755", - "kind" : "class", - "line" : 109, - "char" : 1, - "members" : [ - { - "kind" : "template", - "protection" : "protected", - "line" : 111, - "char" : 22, - "name" : "CI_9755", - "parameters" : [ - { - "name" : "T", - "kind" : "type" - } - ], - "members" : [ - { - "name" : "CI_9755", - "kind" : "class", - "line" : 111, - "char" : 22, - "members" : [] - } - ] - } - ] - }, - { - "name" : "c_10011", - "kind" : "variable", - "line" : 115, - "char" : 14, - "storageClass" : [ - "const" - ], - "deco" : "xC6Object", - "originalType" : "Object", - "init" : "Object()" - }, - { - "name" : "Numbers", - "kind" : "enum", - "line" : 118, - "char" : 1, - "baseDeco" : "i", - "members" : [ - { - "name" : "unspecified1", - "kind" : "enum member", - "value" : "0", - "line" : 120, - "char" : 5 - }, - { - "name" : "one", - "kind" : "enum member", - "value" : "2", - "line" : 121, - "char" : 5 - }, - { - "name" : "two", - "kind" : "enum member", - "value" : "3", - "line" : 122, - "char" : 5 - }, - { - "name" : "FILE_NOT_FOUND", - "kind" : "enum member", - "value" : "101", - "line" : 123, - "char" : 5 - }, - { - "name" : "unspecified3", - "kind" : "enum member", - "value" : "102", - "line" : 124, - "char" : 5 - }, - { - "name" : "unspecified4", - "kind" : "enum member", - "value" : "103", - "line" : 125, - "char" : 5 - }, - { - "name" : "four", - "kind" : "enum member", - "value" : "4", - "line" : 126, - "char" : 5 - } - ] - }, - { - "kind" : "template", - "line" : 129, - "char" : 1, - "name" : "IncludeConstraint", - "parameters" : [ - { - "name" : "T", - "kind" : "type" - } - ], - "constraint" : "T == string", - "members" : [] - }, - { - "name" : "a0", - "kind" : "variable", - "file" : "compilable/json.d-mixin-133", - "line" : 133, - "char" : 5, - "deco" : "i", - "init" : "1" - }, - { - "name" : "a1", - "kind" : "variable", - "line" : 133, - "char" : 5, - "deco" : "i", - "init" : "1" - }, - { - "name" : "a2", - "kind" : "variable", - "line" : 133, - "char" : 5, - "deco" : "i", - "init" : "1" - }, - { - "kind" : "template", - "file" : "compilable/json.d", - "line" : 136, - "char" : 1, - "name" : "Seq", - "parameters" : [ - { - "name" : "T", - "kind" : "tuple" - } - ], - "members" : [ - { - "name" : "Seq", - "kind" : "alias", - "line" : 136, - "char" : 1, - "type" : "T" - } - ] - }, - {}, - { - "name" : "b0", - "kind" : "alias", - "file" : "compilable/json.d-mixin-140", - "line" : 140, - "char" : 1 - }, - {}, - { - "name" : "b1", - "kind" : "alias", - "line" : 140, - "char" : 1 - }, - {}, - { - "name" : "b2", - "kind" : "alias", - "line" : 140, - "char" : 1 - }, - { - "name" : "foo", - "kind" : "function", - "file" : "compilable/json.d", - "line" : 144, - "char" : 9, - "deco" : "FNcNfNkKiZi", - "parameters" : [ - { - "name" : "a", - "deco" : "i", - "storageClass" : [ - "ref", - "return" - ] - } - ], - "endline" : 147, - "endchar" : 1 - }, - { - "name" : "foo", - "kind" : "function", - "line" : 149, - "char" : 6, - "deco" : "FNfMNkPiZQd", - "parameters" : [ - { - "name" : "a", - "deco" : "Pi", - "storageClass" : [ - "scope", - "return" - ] - } - ], - "endline" : 152, - "endchar" : 1 - }, - { - "name" : "foo", - "kind" : "function", - "line" : 154, - "char" : 10, - "deco" : "FNcNfMNkKPiZQd", - "parameters" : [ - { - "name" : "a", - "deco" : "Pi", - "storageClass" : [ - "scope", - "ref", - "return" - ] - } - ], - "endline" : 157, - "endchar" : 1 - }, - { - "name" : "SafeS", - "kind" : "struct", - "line" : 159, - "char" : 1, - "members" : [ - { - "name" : "foo", - "kind" : "function", - "line" : 162, - "char" : 15, - "deco" : "FNcNjNfZS4json5SafeS", - "endline" : 165, - "endchar" : 5 - }, - { - "name" : "foo2", - "kind" : "function", - "line" : 167, - "char" : 11, - "deco" : "FNjNfZS4json5SafeS", - "endline" : 170, - "endchar" : 5 - }, - { - "name" : "foo3", - "kind" : "function", - "line" : 172, - "char" : 15, - "deco" : "FNcNjNfZS4json5SafeS", - "endline" : 175, - "endchar" : 5 - }, - { - "name" : "p", - "kind" : "variable", - "line" : 177, - "char" : 7, - "storageClass" : [ - "@safe" - ], - "deco" : "Pi", - "offset" : 0 - } - ] - }, - { - "name" : "vlinkageDefault", - "kind" : "variable", - "line" : 180, - "char" : 12, - "storageClass" : [ - "extern" - ], - "deco" : "i" - }, - { - "name" : "vlinkageD", - "kind" : "variable", - "line" : 181, - "char" : 15, - "deco" : "i" - }, - { - "name" : "vlinakgeC", - "kind" : "variable", - "line" : 182, - "char" : 15, - "linkage" : "c", - "deco" : "i" - }, - { - "name" : "vlinkageCpp", - "kind" : "variable", - "line" : 183, - "char" : 27, - "storageClass" : [ - "__gshared" - ], - "linkage" : "cpp", - "deco" : "i" - }, - { - "name" : "vlinkageWindows", - "kind" : "variable", - "line" : 184, - "char" : 21, - "linkage" : "windows", - "deco" : "i" - }, - { - "name" : "vlinkagePascal", - "kind" : "variable", - "line" : 185, - "char" : 20, - "linkage" : "pascal", - "deco" : "i" - }, - { - "name" : "vlinkageObjc", - "kind" : "variable", - "line" : 186, - "char" : 25, - "linkage" : "objc", - "deco" : "i" - }, - { - "name" : "flinkageDefault", - "kind" : "function", - "line" : 188, - "char" : 12, - "storageClass" : [ - "extern" - ], - "deco" : "FZi" - }, - { - "name" : "flinkageD", - "kind" : "function", - "line" : 189, - "char" : 15, - "deco" : "FZi" - }, - { - "name" : "linakgeC", - "kind" : "function", - "line" : 190, - "char" : 15, - "linkage" : "c", - "deco" : "UZi" - }, - { - "name" : "flinkageCpp", - "kind" : "function", - "line" : 191, - "char" : 17, - "linkage" : "cpp", - "deco" : "RZi" - }, - { - "name" : "flinkageWindows", - "kind" : "function", - "line" : 192, - "char" : 21, - "linkage" : "windows", - "deco" : "WZi" - }, - { - "name" : "flinkagePascal", - "kind" : "function", - "line" : 193, - "char" : 20, - "linkage" : "pascal", - "deco" : "VZi" - }, - { - "name" : "flinkageObjc", - "kind" : "function", - "line" : 194, - "char" : 25, - "linkage" : "objc", - "deco" : "YZi" - } - ] - } -] + "name": "json" + }, + { + "kind": "semantics", + "modules": [ + { + "file": "compilable\/json.d", + "isRoot": true, + "name": "json" + }, + { + "file": "compilable\/imports\/jsonimport1.d", + "isRoot": false, + "name": "imports.jsonimport1" + }, + { + "file": "compilable\/imports\/jsonimport2.d", + "isRoot": false, + "name": "imports.jsonimport2" + }, + { + "file": "compilable\/imports\/jsonimport3.d", + "isRoot": false, + "name": "imports.jsonimport3" + }, + { + "file": "compilable\/imports\/jsonimport4.d", + "isRoot": false, + "name": "imports.jsonimport4" + } + ] + } +] \ No newline at end of file diff --git a/test/sanitize_json.d b/test/sanitize_json.d new file mode 100644 index 000000000000..c2b12ffbaa57 --- /dev/null +++ b/test/sanitize_json.d @@ -0,0 +1,151 @@ +import std.exception : assumeUnique; +import std.string : startsWith, replace; +import std.format : formattedWrite, format; +import std.json; +import std.getopt; +import std.file : readText; +import std.stdio; + +bool keepDeco = false; + +void usage() +{ + writeln("Usage: santize_json [--keep-deco] []"); +} +int main(string[] args) +{ + getopt(args, + "keep-deco", &keepDeco); + args = args[1 .. $]; + if (args.length == 0) + { + usage(); + return 1; + } + string inFilename = args[0]; + File outFile; + if(args.length == 1) + { + outFile = stdout; + } + else if(args.length == 2) + { + outFile = File(args[1], "w"); + } + else + { + writeln("Error: too many command line arguments"); + return 1; + } + + auto json = parseJSON(readText(inFilename)); + sanitize(json.array); + + outFile.write(json.toJSON(true)); + return 0; +} + +void sanitize(JSONValue[] rootArray) +{ + foreach (ref obj; rootArray) + { + auto kind = obj.object["kind"].str; + if (kind == "compilerInfo") + sanitizeCompilerInfo(obj.object); + else if (kind == "buildInfo") + sanitizeBuildInfo(obj.object); + else if(kind == "module") + sanitizeSyntaxNode(obj); + else if(kind == "semantics") + sanitizeSemantics(obj.object); + } +} + +void removeString(JSONValue* value) +{ + assert(value.type == JSON_TYPE.STRING); + *value = JSONValue("VALUE_REMOVED_FOR_TEST"); +} +void removeNumber(JSONValue* value) +{ + assert(value.type == JSON_TYPE.INTEGER || value.type == JSON_TYPE.UINTEGER); + *value = JSONValue(0); +} +void removeStringIfExists(JSONValue* value) +{ + if (value !is null) + removeString(value); +} + +void sanitizeCompilerInfo(ref JSONValue[string] buildInfo) +{ + removeString(&buildInfo["binary"]); + removeString(&buildInfo["version"]); +} +void sanitizeBuildInfo(ref JSONValue[string] buildInfo) +{ + removeString(&buildInfo["cwd"]); + removeStringIfExists("config" in buildInfo); + removeStringIfExists("lib" in buildInfo); + { + auto importPaths = buildInfo["importPaths"].array; + foreach(ref path; importPaths) + { + path = JSONValue(normalizeFile(path.str)); + } + } +} +void sanitizeSyntaxNode(ref JSONValue value) +{ + if (value.type == JSON_TYPE.ARRAY) + { + foreach (ref element; value.array) + { + sanitizeSyntaxNode(element); + } + } + else if(value.type == JSON_TYPE.OBJECT) + { + foreach (name; value.object.byKey) + { + if (name == "file") + removeString(&value.object[name]); + else if (name == "offset") + removeNumber(&value.object[name]); + else if (!keepDeco && name == "deco") + removeString(&value.object[name]); + else + sanitizeSyntaxNode(value.object[name]); + } + } +} + +void sanitizeSemantics(ref JSONValue[string] semantics) +{ + import std.array : appender; + + auto modulesArrayPtr = &semantics["modules"].array(); + auto newModules = appender!(JSONValue[])(); + foreach (ref semanticModuleNode; *modulesArrayPtr) + { + auto semanticModule = semanticModuleNode.object(); + auto moduleName = semanticModule["name"].str; + if(moduleName.startsWith("std.", "core.", "etc.") || moduleName == "object") + { + // remove druntime/phobos modules since they can change for each + // platform + continue; + } + auto fileNode = &semanticModule["file"]; + *fileNode = JSONValue(normalizeFile(fileNode.str)); + newModules.put(JSONValue(semanticModule)); + } + *modulesArrayPtr = newModules.data; +} + +auto normalizeFile(string file) +{ + version(Windows) + return file.replace("\\", "/"); + return file; +}