1 module support; 2 3 import dmd.frontend : DiagnosticReporter; 4 5 /// UDA used to indicate a function should be run before each test. 6 enum beforeEach; 7 8 /// UDA used to indicate a function should be run after each test. 9 enum afterEach; 10 11 /// Returns: the default import paths, i.e. for Phobos and druntime. 12 string[] defaultImportPaths() 13 { 14 import std.path : buildNormalizedPath, buildPath, dirName; 15 import std.process : environment; 16 17 enum dlangDir = __FILE_FULL_PATH__.dirName.buildNormalizedPath("..", "..", ".."); 18 enum druntimeDir = dlangDir.buildPath("druntime", "import"); 19 enum phobosDir = dlangDir.buildPath("phobos"); 20 21 return [ 22 environment.get("DRUNTIME_PATH", druntimeDir), 23 environment.get("PHOBOS_PATH", phobosDir) 24 ]; 25 } 26 27 /** 28 * Strips indentation and extra newlines in delimited strings. 29 * 30 * This is indented to be used on delimited string literals. It will strip the 31 * indentation and remove the first and the last newlines. 32 * 33 * Params: 34 * str = the delimited string to strip 35 * 36 * Return: the stripped string 37 */ 38 string stripDelimited(string str) 39 { 40 import std..string : chomp, outdent; 41 import dmd.root..string : stripLeadingLineTerminator; 42 43 return str 44 .stripLeadingLineTerminator 45 .outdent 46 .chomp; 47 } 48 49 /** 50 * Returns `true` if the given code compiles. 51 * 52 * This will run the frontend up to, including, the semantic analysis. 53 * 54 * Params: 55 * code = the code to compile 56 * filename = the filename to use when compiling the code 57 * 58 * Returns: `true` if the given code compiles 59 */ 60 bool compiles(string code, string filename = "test.d") 61 { 62 import dmd.globals : global; 63 import std.algorithm : each; 64 65 import dmd.frontend : addImport, fullSemantic, parseModule; 66 67 defaultImportPaths.each!addImport; 68 69 auto t = parseModule(filename, code); 70 71 if (t.diagnostics.hasErrors) 72 return false; 73 74 t.module_.fullSemantic(); 75 76 return global.errors == 0; 77 } 78 79 class NoopDiagnosticReporter : DiagnosticReporter 80 { 81 import core.stdc.stdarg : va_list; 82 import dmd.globals : Loc; 83 84 override int errorCount() { return 0; } 85 override int warningCount() { return 0; } 86 override int deprecationCount() { return 0; } 87 override bool error(const ref Loc loc, const(char)* format, va_list, const(char)* p1, const(char)* p2) { return true; } 88 override bool errorSupplemental(const ref Loc loc, const(char)* format, va_list, const(char)* p1, const(char)* p2) { return true; } 89 override bool warning(const ref Loc loc, const(char)* format, va_list, const(char)* p1, const(char)* p2) { return true; } 90 override bool warningSupplemental(const ref Loc loc, const(char)* format, va_list, const(char)* p1, const(char)* p2) { return true; } 91 override bool deprecation(const ref Loc loc, const(char)* format, va_list, const(char)* p1, const(char)* p2) { return true; } 92 override bool deprecationSupplemental(const ref Loc loc, const(char)* format, va_list, const(char)* p1, const(char)* p2) { return true; } 93 }