diff --git a/src/dmd/dmodule.d b/src/dmd/dmodule.d index cacd5a62d4d6..2b208836a578 100644 --- a/src/dmd/dmodule.d +++ b/src/dmd/dmodule.d @@ -723,12 +723,11 @@ extern (C++) final class Module : Package /// syntactic parse Module parse() { - scope diagnosticReporter = new StderrDiagnosticReporter(global.params.useDeprecated); - return parse!ASTCodegen(diagnosticReporter); + return parseModule!ASTCodegen(); } /// ditto - extern (D) Module parse(AST)(DiagnosticReporter diagnosticReporter) + extern (D) Module parseModule(AST)() { @@ -989,13 +988,11 @@ extern (C++) final class Module : Package isHdrFile = true; } { - scope p = new Parser!AST(this, buf, cast(bool) docfile, diagnosticReporter); + scope p = new Parser!AST(this, buf, cast(bool) docfile); p.nextToken(); members = p.parseModule(); md = p.md; numlines = p.scanloc.linnum; - if (p.errors) - ++global.errors; } srcBuffer.destroy(); srcBuffer = null; diff --git a/src/dmd/doc.d b/src/dmd/doc.d index ea79992d4b3f..b15340ae4c6f 100644 --- a/src/dmd/doc.d +++ b/src/dmd/doc.d @@ -5253,8 +5253,8 @@ private void highlightCode3(Scope* sc, ref OutBuffer buf, const(char)* p, const( private void highlightCode2(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t offset) { uint errorsave = global.startGagging(); - scope diagnosticReporter = new StderrDiagnosticReporter(global.params.useDeprecated); - scope Lexer lex = new Lexer(null, cast(char*)buf[].ptr, 0, buf.length - 1, 0, 1, diagnosticReporter); + + scope Lexer lex = new Lexer(null, cast(char*)buf[].ptr, 0, buf.length - 1, 0, 1); OutBuffer res; const(char)* lastp = cast(char*)buf[].ptr; //printf("highlightCode2('%.*s')\n", cast(int)(buf.length - 1), buf[].ptr); diff --git a/src/dmd/dsymbolsem.d b/src/dmd/dsymbolsem.d index 7ebca28482b0..de35732aa6c8 100644 --- a/src/dmd/dsymbolsem.d +++ b/src/dmd/dsymbolsem.d @@ -2090,16 +2090,13 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor const len = buf.length; buf.writeByte(0); const str = buf.extractSlice()[0 .. len]; - scope diagnosticReporter = new StderrDiagnosticReporter(global.params.useDeprecated); - scope p = new Parser!ASTCodegen(cd.loc, sc._module, str, false, diagnosticReporter); + scope p = new Parser!ASTCodegen(cd.loc, sc._module, str, false); p.nextToken(); auto d = p.parseDeclDefs(0); - if (p.errors) - { - assert(global.errors != errors); // should have caught all these cases + if (global.errors != errors) return null; - } + if (p.token.value != TOK.endOfFile) { cd.error("incomplete mixin declaration `%s`", str.ptr); diff --git a/src/dmd/errors.d b/src/dmd/errors.d index 5d868fb24790..ef2600d87edc 100644 --- a/src/dmd/errors.d +++ b/src/dmd/errors.d @@ -24,215 +24,6 @@ import dmd.utils; nothrow: -/// Interface for diagnostic reporting. -abstract class DiagnosticReporter -{ - nothrow: - - /// Returns: the number of errors that occurred during lexing or parsing. - abstract int errorCount(); - - /// Returns: the number of warnings that occurred during lexing or parsing. - abstract int warningCount(); - - /// Returns: the number of deprecations that occurred during lexing or parsing. - abstract int deprecationCount(); - - /** - Reports an error message. - - Params: - loc = Location of error - format = format string for error - ... = format string arguments - */ - final void error(const ref Loc loc, const(char)* format, ...) - { - va_list args; - va_start(args, format); - error(loc, format, args); - va_end(args); - } - - /// ditto - abstract void error(const ref Loc loc, const(char)* format, va_list args); - - /** - Reports additional details about an error message. - - Params: - loc = Location of error - format = format string for supplemental message - ... = format string arguments - */ - final void errorSupplemental(const ref Loc loc, const(char)* format, ...) - { - va_list args; - va_start(args, format); - errorSupplemental(loc, format, args); - va_end(args); - } - - /// ditto - abstract void errorSupplemental(const ref Loc loc, const(char)* format, va_list); - - /** - Reports a warning message. - - Params: - loc = Location of warning - format = format string for warning - ... = format string arguments - */ - final void warning(const ref Loc loc, const(char)* format, ...) - { - va_list args; - va_start(args, format); - warning(loc, format, args); - va_end(args); - } - - /// ditto - abstract void warning(const ref Loc loc, const(char)* format, va_list args); - - /** - Reports additional details about a warning message. - - Params: - loc = Location of warning - format = format string for supplemental message - ... = format string arguments - */ - final void warningSupplemental(const ref Loc loc, const(char)* format, ...) - { - va_list args; - va_start(args, format); - warningSupplemental(loc, format, args); - va_end(args); - } - - /// ditto - abstract void warningSupplemental(const ref Loc loc, const(char)* format, va_list); - - /** - Reports a deprecation message. - - Params: - loc = Location of the deprecation - format = format string for the deprecation - ... = format string arguments - */ - final void deprecation(const ref Loc loc, const(char)* format, ...) - { - va_list args; - va_start(args, format); - deprecation(loc, format, args); - va_end(args); - } - - /// ditto - abstract void deprecation(const ref Loc loc, const(char)* format, va_list args); - - /** - Reports additional details about a deprecation message. - - Params: - loc = Location of deprecation - format = format string for supplemental message - ... = format string arguments - */ - final void deprecationSupplemental(const ref Loc loc, const(char)* format, ...) - { - va_list args; - va_start(args, format); - deprecationSupplemental(loc, format, args); - va_end(args); - } - - /// ditto - abstract void deprecationSupplemental(const ref Loc loc, const(char)* format, va_list); -} - -/** -Diagnostic reporter which prints the diagnostic messages to stderr. - -This is usually the default diagnostic reporter. -*/ -final class StderrDiagnosticReporter : DiagnosticReporter -{ - private const DiagnosticReporting useDeprecated; - - private int errorCount_; - private int warningCount_; - private int deprecationCount_; - - nothrow: - - /** - Initializes this object. - - Params: - useDeprecated = indicates how deprecation diagnostics should be - handled - */ - this(DiagnosticReporting useDeprecated) - { - this.useDeprecated = useDeprecated; - } - - override int errorCount() - { - return errorCount_; - } - - override int warningCount() - { - return warningCount_; - } - - override int deprecationCount() - { - return deprecationCount_; - } - - override void error(const ref Loc loc, const(char)* format, va_list args) - { - verror(loc, format, args); - errorCount_++; - } - - override void errorSupplemental(const ref Loc loc, const(char)* format, va_list args) - { - verrorSupplemental(loc, format, args); - } - - override void warning(const ref Loc loc, const(char)* format, va_list args) - { - vwarning(loc, format, args); - warningCount_++; - } - - override void warningSupplemental(const ref Loc loc, const(char)* format, va_list args) - { - vwarningSupplemental(loc, format, args); - } - - override void deprecation(const ref Loc loc, const(char)* format, va_list args) - { - vdeprecation(loc, format, args); - - if (useDeprecated == DiagnosticReporting.error) - errorCount_++; - else - deprecationCount_++; - } - - override void deprecationSupplemental(const ref Loc loc, const(char)* format, va_list args) - { - vdeprecationSupplemental(loc, format, args); - } -} - /** * Color highlighting to classify messages */ @@ -782,8 +573,7 @@ private void colorHighlightCode(ref OutBuffer buf) ++nested; auto gaggedErrorsSave = global.startGagging(); - scope diagnosticReporter = new StderrDiagnosticReporter(global.params.useDeprecated); - scope Lexer lex = new Lexer(null, cast(char*)buf[].ptr, 0, buf.length - 1, 0, 1, diagnosticReporter); + scope Lexer lex = new Lexer(null, cast(char*)buf[].ptr, 0, buf.length - 1, 0, 1); OutBuffer res; const(char)* lastp = cast(char*)buf[].ptr; //printf("colorHighlightCode('%.*s')\n", cast(int)(buf.length - 1), buf.data); diff --git a/src/dmd/expressionsem.d b/src/dmd/expressionsem.d index c413be8b7684..84d8570bde0d 100644 --- a/src/dmd/expressionsem.d +++ b/src/dmd/expressionsem.d @@ -5662,17 +5662,14 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor uint errors = global.errors; const len = buf.length; const str = buf.extractChars()[0 .. len]; - scope diagnosticReporter = new StderrDiagnosticReporter(global.params.useDeprecated); - scope p = new Parser!ASTCodegen(exp.loc, sc._module, str, false, diagnosticReporter); + scope p = new Parser!ASTCodegen(exp.loc, sc._module, str, false); p.nextToken(); //printf("p.loc.linnum = %d\n", p.loc.linnum); Expression e = p.parseExpression(); - if (p.errors) - { - assert(global.errors != errors); // should have caught all these cases + if (global.errors != errors) return null; - } + if (p.token.value != TOK.endOfFile) { exp.error("incomplete mixin expression `%s`", str.ptr); diff --git a/src/dmd/frontend.d b/src/dmd/frontend.d index 6a772674c7de..6b2aee7b07c9 100644 --- a/src/dmd/frontend.d +++ b/src/dmd/frontend.d @@ -16,13 +16,13 @@ module dmd.frontend; import dmd.astcodegen : ASTCodegen; import dmd.dmodule : Module; -import dmd.errors : DiagnosticReporter; -import dmd.globals : CHECKENABLE; -import dmd.errors : DiagnosticHandler, diagnosticHandler; +import dmd.globals : CHECKENABLE, Loc, DiagnosticReporting; +import dmd.errors : DiagnosticHandler, diagnosticHandler, Classification; import std.range.primitives : isInputRange, ElementType; import std.traits : isNarrowString; import std.typecons : Tuple; +import core.stdc.stdarg; version (Windows) private enum sep = ";", exe = ".exe"; version (Posix) private enum sep = ":", exe = ""; @@ -378,21 +378,12 @@ Parse a module from a string. Params: fileName = file to parse code = text to use instead of opening the file - diagnosticReporter = the diagnostic reporter to use. By default a - diagnostic reporter which prints to stderr will be used Returns: the parsed module object */ Tuple!(Module, "module_", Diagnostics, "diagnostics") parseModule(AST = ASTCodegen)( const(char)[] fileName, - const(char)[] code = null, - DiagnosticReporter diagnosticReporter = defaultDiagnosticReporter -) -in -{ - assert(diagnosticReporter !is null); -} -do + const(char)[] code = null) { import dmd.root.file : File, FileBuffer; @@ -420,7 +411,7 @@ do m.loadSourceBuffer(Loc.initial, readResult); } - m.parse!AST(diagnosticReporter); + m.parseModule!AST(); Diagnostics diagnostics = { errors: global.errors, @@ -475,10 +466,217 @@ string prettyPrint(Module m) return generated.assumeUnique; } -private DiagnosticReporter defaultDiagnosticReporter() +/// Interface for diagnostic reporting. +abstract class DiagnosticReporter { - import dmd.globals : global; - import dmd.errors : StderrDiagnosticReporter; + import dmd.console : Color; + +nothrow: + DiagnosticHandler prevHandler; + + this() + { + prevHandler = diagnosticHandler; + diagnosticHandler = &diagHandler; + } + + ~this() + { + // assumed to be used scoped + diagnosticHandler = prevHandler; + } + + bool diagHandler(const ref Loc loc, Color headerColor, const(char)* header, + const(char)* format, va_list ap, const(char)* p1, const(char)* p2) + { + import core.stdc.string; + + // recover type from header and color + if (strncmp (header, "Error:", 6) == 0) + return error(loc, format, ap, p1, p2); + if (strncmp (header, "Warning:", 8) == 0) + return warning(loc, format, ap, p1, p2); + if (strncmp (header, "Deprecation:", 12) == 0) + return deprecation(loc, format, ap, p1, p2); + + if (cast(Classification)headerColor == Classification.warning) + return warningSupplemental(loc, format, ap, p1, p2); + if (cast(Classification)headerColor == Classification.deprecation) + return deprecationSupplemental(loc, format, ap, p1, p2); + + return errorSupplemental(loc, format, ap, p1, p2); + } + + /// Returns: the number of errors that occurred during lexing or parsing. + abstract int errorCount(); + + /// Returns: the number of warnings that occurred during lexing or parsing. + abstract int warningCount(); + + /// Returns: the number of deprecations that occurred during lexing or parsing. + abstract int deprecationCount(); + + /** + Reports an error message. + + Params: + loc = Location of error + format = format string for error + args = printf-style variadic arguments + p1 = additional message prefix + p2 = additional message prefix + + Returns: false if the message should also be printed to stderr, true otherwise + */ + abstract bool error(const ref Loc loc, const(char)* format, va_list args, const(char)* p1, const(char)* p2); + + /** + Reports additional details about an error message. + + Params: + loc = Location of error + format = format string for supplemental message + args = printf-style variadic arguments + p1 = additional message prefix + p2 = additional message prefix + + Returns: false if the message should also be printed to stderr, true otherwise + */ + abstract bool errorSupplemental(const ref Loc loc, const(char)* format, va_list args, const(char)* p1, const(char)* p2); + + /** + Reports a warning message. + + Params: + loc = Location of warning + format = format string for warning + args = printf-style variadic arguments + p1 = additional message prefix + p2 = additional message prefix + + Returns: false if the message should also be printed to stderr, true otherwise + */ + abstract bool warning(const ref Loc loc, const(char)* format, va_list args, const(char)* p1, const(char)* p2); + + /** + Reports additional details about a warning message. + + Params: + loc = Location of warning + format = format string for supplemental message + args = printf-style variadic arguments + p1 = additional message prefix + p2 = additional message prefix + + Returns: false if the message should also be printed to stderr, true otherwise + */ + abstract bool warningSupplemental(const ref Loc loc, const(char)* format, va_list args, const(char)* p1, const(char)* p2); + + /** + Reports a deprecation message. + + Params: + loc = Location of the deprecation + format = format string for the deprecation + args = printf-style variadic arguments + p1 = additional message prefix + p2 = additional message prefix + + Returns: false if the message should also be printed to stderr, true otherwise + */ + abstract bool deprecation(const ref Loc loc, const(char)* format, va_list args, const(char)* p1, const(char)* p2); + + /** + Reports additional details about a deprecation message. + + Params: + loc = Location of deprecation + format = format string for supplemental message + args = printf-style variadic arguments + p1 = additional message prefix + p2 = additional message prefix + + Returns: false if the message should also be printed to stderr, true otherwise + */ + abstract bool deprecationSupplemental(const ref Loc loc, const(char)* format, va_list args, const(char)* p1, const(char)* p2); +} + +/** +Diagnostic reporter which prints the diagnostic messages to stderr. + +This is usually the default diagnostic reporter. +*/ +final class StderrDiagnosticReporter : DiagnosticReporter +{ + private const DiagnosticReporting useDeprecated; + + private int errorCount_; + private int warningCount_; + private int deprecationCount_; + +nothrow: + + /** + Initializes this object. + + Params: + useDeprecated = indicates how deprecation diagnostics should be + handled + */ + this(DiagnosticReporting useDeprecated) + { + this.useDeprecated = useDeprecated; + } - return new StderrDiagnosticReporter(global.params.useDeprecated); + override int errorCount() + { + return errorCount_; + } + + override int warningCount() + { + return warningCount_; + } + + override int deprecationCount() + { + return deprecationCount_; + } + + override bool error(const ref Loc loc, const(char)* format, va_list args, const(char)* p1, const(char)* p2) + { + errorCount_++; + return false; + } + + override bool errorSupplemental(const ref Loc loc, const(char)* format, va_list args, const(char)* p1, const(char)* p2) + { + return false; + } + + override bool warning(const ref Loc loc, const(char)* format, va_list args, const(char)* p1, const(char)* p2) + { + warningCount_++; + return false; + } + + override bool warningSupplemental(const ref Loc loc, const(char)* format, va_list args, const(char)* p1, const(char)* p2) + { + return false; + } + + override bool deprecation(const ref Loc loc, const(char)* format, va_list args, const(char)* p1, const(char)* p2) + { + if (useDeprecated == DiagnosticReporting.error) + errorCount_++; + else + deprecationCount_++; + return false; + } + + override bool deprecationSupplemental(const ref Loc loc, const(char)* format, va_list args, const(char)* p1, const(char)* p2) + { + return false; + } } + diff --git a/src/dmd/iasmgcc.d b/src/dmd/iasmgcc.d index 246c1166fa8d..56e483f9ddec 100644 --- a/src/dmd/iasmgcc.d +++ b/src/dmd/iasmgcc.d @@ -284,8 +284,7 @@ Ldone: public Statement gccAsmSemantic(GccAsmStatement s, Scope *sc) { //printf("GccAsmStatement.semantic()\n"); - scope diagnosticReporter = new StderrDiagnosticReporter(global.params.useDeprecated); - scope p = new Parser!ASTCodegen(sc._module, ";", false, diagnosticReporter); + scope p = new Parser!ASTCodegen(sc._module, ";", false); // Make a safe copy of the token list before parsing. Token *toklist = null; @@ -302,8 +301,9 @@ public Statement gccAsmSemantic(GccAsmStatement s, Scope *sc) p.scanloc = s.loc; // Parse the gcc asm statement. + const errors = global.errors; s = p.parseGccAsm(s); - if (p.errors) + if (errors != global.errors) return null; s.stc = sc.stc; @@ -370,20 +370,19 @@ unittest // Immitates asmSemantic if version = IN_GCC. static int semanticAsm(Token* tokens) { + const errors = global.errors; scope gas = new GccAsmStatement(Loc.initial, tokens); - scope diagnosticReporter = new StderrDiagnosticReporter(global.params.useDeprecated); - scope p = new Parser!ASTCodegen(null, ";", false, diagnosticReporter); + scope p = new Parser!ASTCodegen(null, ";", false); p.token = *tokens; p.parseGccAsm(gas); - return p.errors; + return global.errors - errors; } // Immitates parseStatement for asm statements. static void parseAsm(string input, bool expectError) { // Generate tokens from input test. - scope diagnosticReporter = new StderrDiagnosticReporter(global.params.useDeprecated); - scope p = new Parser!ASTCodegen(null, input, false, diagnosticReporter); + scope p = new Parser!ASTCodegen(null, input, false); p.nextToken(); Token* toklist = null; diff --git a/src/dmd/lexer.d b/src/dmd/lexer.d index 92f55814fc90..405f1ea8e7fa 100644 --- a/src/dmd/lexer.d +++ b/src/dmd/lexer.d @@ -152,8 +152,7 @@ unittest /* Not much here, just trying things out. */ string text = "int"; // We rely on the implicit null-terminator - scope diagnosticReporter = new StderrDiagnosticReporter(global.params.useDeprecated); - scope Lexer lex1 = new Lexer(null, text.ptr, 0, text.length, 0, 0, diagnosticReporter); + scope Lexer lex1 = new Lexer(null, text.ptr, 0, text.length, 0, 0); TOK tok; tok = lex1.nextToken(); //printf("tok == %s, %d, %d\n", Token::toChars(tok), tok, TOK.int32); @@ -188,8 +187,7 @@ unittest foreach (testcase; testcases) { - scope diagnosticReporter = new StderrDiagnosticReporter(global.params.useDeprecated); - scope Lexer lex2 = new Lexer(null, testcase.ptr, 0, testcase.length-1, 0, 0, diagnosticReporter); + scope Lexer lex2 = new Lexer(null, testcase.ptr, 0, testcase.length-1, 0, 0); TOK tok = lex2.nextToken(); size_t iterations = 1; while ((tok != TOK.endOfFile) && (iterations++ < testcase.length)) @@ -227,7 +225,6 @@ class Lexer int inTokenStringConstant; // can be larger than 1 when in nested q{} strings int lastDocLine; // last line of previous doc comment - DiagnosticReporter diagnosticReporter; Token* tokenFreelist; } @@ -244,18 +241,10 @@ class Lexer * endoffset = the last offset to read into base[] * doDocComment = handle documentation comments * commentToken = comments become TOK.comment's - * diagnosticReporter = the diagnostic reporter to use */ this(const(char)* filename, const(char)* base, size_t begoffset, - size_t endoffset, bool doDocComment, bool commentToken, - DiagnosticReporter diagnosticReporter) pure - in + size_t endoffset, bool doDocComment, bool commentToken) pure { - assert(diagnosticReporter !is null); - } - do - { - this.diagnosticReporter = diagnosticReporter; scanloc = Loc(filename, 1, 1); //printf("Lexer::Lexer(%p,%d)\n",base,length); //printf("lexer.filename = %s\n", filename); @@ -294,12 +283,6 @@ class Lexer } } - /// Returns: `true` if any errors occurred during lexing or parsing. - final bool errors() - { - return diagnosticReporter.errorCount > 0; - } - /// Returns: a newly allocated `Token`. Token* allocateToken() pure nothrow @safe { @@ -1167,25 +1150,19 @@ class Lexer */ private uint escapeSequence() { - return Lexer.escapeSequence(token.loc, diagnosticReporter, p); + return Lexer.escapeSequence(token.loc, p); } /** Parse the given string literal escape sequence into a single character. Params: loc = the location of the current token - handler = the diagnostic reporter object sequence = pointer to string with escape sequence to parse. this is a reference variable that is also used to return the position after the sequence Returns: the escaped sequence as a single character */ - private static dchar escapeSequence(const ref Loc loc, DiagnosticReporter handler, ref const(char)* sequence) - in - { - assert(handler !is null); - } - do + private static dchar escapeSequence(const ref Loc loc, ref const(char)* sequence) { const(char)* p = sequence; // cache sequence reference on stack scope(exit) sequence = p; @@ -1251,20 +1228,20 @@ class Lexer break; if (!ishex(cast(char)c)) { - handler.error(loc, "escape hex sequence has %d hex digits instead of %d", n, ndigits); + .error(loc, "escape hex sequence has %d hex digits instead of %d", n, ndigits); break; } } if (ndigits != 2 && !utf_isValidDchar(v)) { - handler.error(loc, "invalid UTF character \\U%08x", v); + .error(loc, "invalid UTF character \\U%08x", v); v = '?'; // recover with valid UTF character } c = v; } else { - handler.error(loc, "undefined escape hex sequence \\%c%c", sequence[0], c); + .error(loc, "undefined escape hex sequence \\%c%c", sequence[0], c); p++; } break; @@ -1278,7 +1255,7 @@ class Lexer c = HtmlNamedEntity(idstart, p - idstart); if (c == ~0) { - handler.error(loc, "unnamed character entity &%.*s;", cast(int)(p - idstart), idstart); + .error(loc, "unnamed character entity &%.*s;", cast(int)(p - idstart), idstart); c = '?'; } p++; @@ -1286,7 +1263,7 @@ class Lexer default: if (isalpha(*p) || (p != idstart && isdigit(*p))) continue; - handler.error(loc, "unterminated named entity &%.*s;", cast(int)(p - idstart + 1), idstart); + .error(loc, "unterminated named entity &%.*s;", cast(int)(p - idstart + 1), idstart); c = '?'; break; } @@ -1311,11 +1288,11 @@ class Lexer while (++n < 3 && isoctal(cast(char)c)); c = v; if (c > 0xFF) - handler.error(loc, "escape octal sequence \\%03o is larger than \\377", c); + .error(loc, "escape octal sequence \\%03o is larger than \\377", c); } else { - handler.error(loc, "undefined escape sequence \\%c", c); + .error(loc, "undefined escape sequence \\%c", c); p++; } break; @@ -2315,7 +2292,7 @@ class Lexer { va_list args; va_start(args, format); - diagnosticReporter.error(token.loc, format, args); + .verror(token.loc, format, args); va_end(args); } @@ -2323,31 +2300,7 @@ class Lexer { va_list args; va_start(args, format); - diagnosticReporter.error(loc, format, args); - va_end(args); - } - - final void errorSupplemental(const ref Loc loc, const(char)* format, ...) - { - va_list args; - va_start(args, format); - diagnosticReporter.errorSupplemental(loc, format, args); - va_end(args); - } - - final void warning(const ref Loc loc, const(char)* format, ...) - { - va_list args; - va_start(args, format); - diagnosticReporter.warning(loc, format, args); - va_end(args); - } - - final void warningSupplemental(const ref Loc loc, const(char)* format, ...) - { - va_list args; - va_start(args, format); - diagnosticReporter.warningSupplemental(loc, format, args); + .verror(loc, format, args); va_end(args); } @@ -2355,23 +2308,7 @@ class Lexer { va_list args; va_start(args, format); - diagnosticReporter.deprecation(token.loc, format, args); - va_end(args); - } - - final void deprecation(const ref Loc loc, const(char)* format, ...) - { - va_list args; - va_start(args, format); - diagnosticReporter.deprecation(loc, format, args); - va_end(args); - } - - final void deprecationSupplemental(const ref Loc loc, const(char)* format, ...) - { - va_list args; - va_start(args, format); - diagnosticReporter.deprecationSupplemental(loc, format, args); + .vdeprecation(token.loc, format, args); va_end(args); } @@ -2691,23 +2628,18 @@ private: unittest { - static final class AssertDiagnosticReporter : DiagnosticReporter + import dmd.console; + nothrow bool assertDiagnosticHandler(const ref Loc loc, Color headerColor, const(char)* header, + const(char)* format, va_list ap, const(char)* p1, const(char)* p2) { - override int errorCount() { assert(0); } - override int warningCount() { assert(0); } - override int deprecationCount() { assert(0); } - override void error(const ref Loc, const(char)*, va_list) { assert(0); } - override void errorSupplemental(const ref Loc, const(char)*, va_list) { assert(0); } - override void warning(const ref Loc, const(char)*, va_list) { assert(0); } - override void warningSupplemental(const ref Loc, const(char)*, va_list) { assert(0); } - override void deprecation(const ref Loc, const(char)*, va_list) { assert(0); } - override void deprecationSupplemental(const ref Loc, const(char)*, va_list) { assert(0); } + assert(0); } + diagnosticHandler = &assertDiagnosticHandler; + static void test(T)(string sequence, T expected) { - scope assertOnError = new AssertDiagnosticReporter(); auto p = cast(const(char)*)sequence.ptr; - assert(expected == Lexer.escapeSequence(Loc.initial, assertOnError, p)); + assert(expected == Lexer.escapeSequence(Loc.initial, p)); assert(p == sequence.ptr + sequence.length); } @@ -2743,46 +2675,42 @@ unittest test(`"`, '"'); test(`<`, '<'); test(`>`, '>'); + + diagnosticHandler = null; } unittest { - static final class ExpectDiagnosticReporter : DiagnosticReporter - { - string expected; - bool gotError; - - nothrow: + import dmd.console; + string expected; + bool gotError; - this(string expected) { this.expected = expected; } + nothrow bool expectDiagnosticHandler(const ref Loc loc, Color headerColor, const(char)* header, + const(char)* format, va_list ap, const(char)* p1, const(char)* p2) + { + assert(cast(Classification)headerColor == Classification.error); - override int errorCount() { assert(0); } - override int warningCount() { assert(0); } - override int deprecationCount() { assert(0); } + gotError = true; + char[100] buffer = void; + auto actual = buffer[0 .. vsprintf(buffer.ptr, format, ap)]; + assert(expected == actual); + return true; + } - override void error(const ref Loc loc, const(char)* format, va_list args) - { - gotError = true; - char[100] buffer = void; - auto actual = buffer[0 .. vsprintf(buffer.ptr, format, args)]; - assert(expected == actual); - } + diagnosticHandler = &expectDiagnosticHandler; - override void errorSupplemental(const ref Loc, const(char)*, va_list) { assert(0); } - override void warning(const ref Loc, const(char)*, va_list) { assert(0); } - override void warningSupplemental(const ref Loc, const(char)*, va_list) { assert(0); } - override void deprecation(const ref Loc, const(char)*, va_list) { assert(0); } - override void deprecationSupplemental(const ref Loc, const(char)*, va_list) { assert(0); } - } - static void test(string sequence, string expectedError, dchar expectedReturnValue, uint expectedScanLength) + void test(string sequence, string expectedError, dchar expectedReturnValue, uint expectedScanLength) { - scope handler = new ExpectDiagnosticReporter(expectedError); + uint errors = global.errors; + gotError = false; + expected = expectedError; auto p = cast(const(char)*)sequence.ptr; - auto actualReturnValue = Lexer.escapeSequence(Loc.initial, handler, p); - assert(handler.gotError); + auto actualReturnValue = Lexer.escapeSequence(Loc.initial, p); + assert(gotError); assert(expectedReturnValue == actualReturnValue); auto actualScanLength = p - sequence.ptr; assert(expectedScanLength == actualScanLength); + global.errors = errors; } test("c", `undefined escape sequence \c`, 'c', 1); @@ -2814,4 +2742,6 @@ unittest test(""", `unterminated named entity "`, '?', 5); test("400", `escape octal sequence \400 is larger than \377`, 0x100, 3); + + diagnosticHandler = null; } diff --git a/src/dmd/parse.d b/src/dmd/parse.d index 92318bd676ed..69bf70692667 100644 --- a/src/dmd/parse.d +++ b/src/dmd/parse.d @@ -294,10 +294,9 @@ final class Parser(AST) : Lexer * Input: * loc location in source file of mixin */ - extern (D) this(const ref Loc loc, AST.Module _module, const(char)[] input, - bool doDocComment, DiagnosticReporter diagnosticReporter) + extern (D) this(const ref Loc loc, AST.Module _module, const(char)[] input, bool doDocComment) { - super(_module ? _module.srcfile.toChars() : null, input.ptr, 0, input.length, doDocComment, false, diagnosticReporter); + super(_module ? _module.srcfile.toChars() : null, input.ptr, 0, input.length, doDocComment, false); //printf("Parser::Parser()\n"); scanloc = loc; @@ -317,9 +316,9 @@ final class Parser(AST) : Lexer //nextToken(); // start up the scanner } - extern (D) this(AST.Module _module, const(char)[] input, bool doDocComment, DiagnosticReporter diagnosticReporter) + extern (D) this(AST.Module _module, const(char)[] input, bool doDocComment) { - super(_module ? _module.srcfile.toChars() : null, input.ptr, 0, input.length, doDocComment, false, diagnosticReporter); + super(_module ? _module.srcfile.toChars() : null, input.ptr, 0, input.length, doDocComment, false); //printf("Parser::Parser()\n"); mod = _module; diff --git a/src/dmd/statement.d b/src/dmd/statement.d index 409d7ca4d373..7e1986e889a3 100644 --- a/src/dmd/statement.d +++ b/src/dmd/statement.d @@ -815,19 +815,15 @@ extern (C++) final class CompileStatement : Statement const len = buf.length; buf.writeByte(0); const str = buf.extractSlice()[0 .. len]; - scope diagnosticReporter = new StderrDiagnosticReporter(global.params.useDeprecated); - scope p = new Parser!ASTCodegen(loc, sc._module, str, false, diagnosticReporter); + scope p = new Parser!ASTCodegen(loc, sc._module, str, false); p.nextToken(); auto a = new Statements(); while (p.token.value != TOK.endOfFile) { Statement s = p.parseStatement(ParseStatementFlags.semi | ParseStatementFlags.curlyScope); - if (!s || p.errors) - { - assert(!p.errors || global.errors != errors); // make sure we caught all the cases + if (!s || global.errors != errors) return errorStatements(); - } a.push(s); } return a; diff --git a/src/dmd/traits.d b/src/dmd/traits.d index 0257a56c2807..bedbac702e67 100644 --- a/src/dmd/traits.d +++ b/src/dmd/traits.d @@ -1575,14 +1575,12 @@ Expression semanticTraits(TraitsExp e, Scope* sc) const len = buf.length; buf.writeByte(0); const str = buf.extractSlice()[0 .. len]; - scope diagnosticReporter = new StderrDiagnosticReporter(global.params.useDeprecated); - scope p = new Parser!ASTCodegen(e.loc, sc._module, str, false, diagnosticReporter); + scope p = new Parser!ASTCodegen(e.loc, sc._module, str, false); p.nextToken(); //printf("p.loc.linnum = %d\n", p.loc.linnum); o = p.parseTypeOrAssignExp(TOK.endOfFile); - if (p.errors || - p.token.value != TOK.endOfFile) + if (errors != global.errors || p.token.value != TOK.endOfFile) { err = true; break; diff --git a/src/dmd/typesem.d b/src/dmd/typesem.d index 03eee5a6c0cc..ca18a6af7e4e 100644 --- a/src/dmd/typesem.d +++ b/src/dmd/typesem.d @@ -1997,13 +1997,12 @@ RootObject compileTypeMixin(TypeMixin tm, Loc loc, Scope* sc) const len = buf.length; buf.writeByte(0); const str = buf.extractSlice()[0 .. len]; - scope diagnosticReporter = new StderrDiagnosticReporter(global.params.useDeprecated); - scope p = new Parser!ASTCodegen(loc, sc._module, str, false, diagnosticReporter); + scope p = new Parser!ASTCodegen(loc, sc._module, str, false); p.nextToken(); //printf("p.loc.linnum = %d\n", p.loc.linnum); auto o = p.parseTypeOrAssignExp(TOK.endOfFile); - if (p.errors) + if (errors != global.errors) { assert(global.errors != errors); // should have caught all these cases return null; diff --git a/test/dub_package/avg.d b/test/dub_package/avg.d index 3f983406e002..363a391da5cf 100755 --- a/test/dub_package/avg.d +++ b/test/dub_package/avg.d @@ -59,8 +59,7 @@ void main() auto m = new ASTBase.Module(&(fname.dup)[0], id, false, false); auto input = readText(fname); - scope diagnosticReporter = new StderrDiagnosticReporter(global.params.useDeprecated); - scope p = new Parser!ASTBase(m, input, false, diagnosticReporter); + scope p = new Parser!ASTBase(m, input, false); p.nextToken(); m.members = p.parseModule(); diff --git a/test/dub_package/impvisitor.d b/test/dub_package/impvisitor.d index 7a10afe72e6c..b42069430650 100755 --- a/test/dub_package/impvisitor.d +++ b/test/dub_package/impvisitor.d @@ -77,7 +77,6 @@ void main() import std.file; import std.path : buildPath, dirName; - import dmd.errors; import dmd.parse; import dmd.astbase; @@ -109,8 +108,7 @@ void main() auto input = readText(fn); //writeln("Started parsing..."); - scope diagnosticReporter = new StderrDiagnosticReporter(global.params.useDeprecated); - scope p = new Parser!ASTBase(m, input, false, diagnosticReporter); + scope p = new Parser!ASTBase(m, input, false); p.nextToken(); m.members = p.parseModule(); //writeln("Finished parsing. Starting transitive visitor"); diff --git a/test/dub_package/lexer.d b/test/dub_package/lexer.d index 02614fe72945..8d4346ecc6ce 100755 --- a/test/dub_package/lexer.d +++ b/test/dub_package/lexer.d @@ -4,7 +4,6 @@ dependency "dmd" path="../.." +/ void main() { - import dmd.errors; import dmd.globals; import dmd.lexer; import dmd.tokens; @@ -19,8 +18,7 @@ void main() ]; immutable sourceCode = "void test() {} // foobar"; - scope diagnosticReporter = new StderrDiagnosticReporter(global.params.useDeprecated); - scope lexer = new Lexer("test", sourceCode.ptr, 0, sourceCode.length, 0, 0, diagnosticReporter); + scope lexer = new Lexer("test", sourceCode.ptr, 0, sourceCode.length, 0, 0); lexer.nextToken; TOK[] result; diff --git a/test/dub_package/parser.d b/test/dub_package/parser.d index 8c7fa3a45a7a..2c9d7668866c 100755 --- a/test/dub_package/parser.d +++ b/test/dub_package/parser.d @@ -5,11 +5,9 @@ dependency "dmd" path="../.." void main() { import dmd.astbase; - import dmd.errors; import dmd.globals; import dmd.parse; - scope diagnosticReporter = new StderrDiagnosticReporter(global.params.useDeprecated); - scope parser = new Parser!ASTBase(null, null, false, diagnosticReporter); + scope parser = new Parser!ASTBase(null, null, false); assert(parser !is null); } diff --git a/test/unit/lexer/diagnostic_reporter.d b/test/unit/lexer/diagnostic_reporter.d index b35c4c523e82..a5341dc2efa8 100644 --- a/test/unit/lexer/diagnostic_reporter.d +++ b/test/unit/lexer/diagnostic_reporter.d @@ -2,8 +2,7 @@ module lexer.diagnostic_reporter; import core.stdc.stdarg; -import dmd.errors : DiagnosticReporter; -import dmd.globals : Loc; +import dmd.globals : Loc, global, DiagnosticReporting; import support : afterEach, NoopDiagnosticReporter; @@ -20,14 +19,15 @@ unittest { int errorCount; - override void error(const ref Loc, const(char)*, va_list) + override bool error(const ref Loc, const(char)*, va_list, const(char)*, const(char)*) { errorCount++; + return true; } } scope reporter = new ErrorCountingDiagnosticReporter; - lexUntilEndOfFile("/*", reporter); + lexUntilEndOfFile("/*"); assert(reporter.errorCount == 1); } @@ -39,24 +39,26 @@ unittest { int warningCount; - override void warning(const ref Loc, const(char)*, va_list) + override bool warning(const ref Loc, const(char)*, va_list, const(char)*, const(char)*) { warningCount++; + return true; } } + global.params.warnings = DiagnosticReporting.inform; scope reporter = new WarningCountingDiagnosticReporter; - lexUntilEndOfFile(`#foo`, reporter); + lexUntilEndOfFile(`#foo`); assert(reporter.warningCount == 1); } -private void lexUntilEndOfFile(string code, DiagnosticReporter reporter) +private void lexUntilEndOfFile(string code) { import dmd.lexer : Lexer; import dmd.tokens : TOK; - scope lexer = new Lexer("test", code.ptr, 0, code.length, 0, 0, reporter); + scope lexer = new Lexer("test", code.ptr, 0, code.length, 0, 0); lexer.nextToken; while (lexer.nextToken != TOK.endOfFile) {} diff --git a/test/unit/parser/diagnostic_reporter.d b/test/unit/parser/diagnostic_reporter.d index 5f67ad805012..22f832819fb4 100644 --- a/test/unit/parser/diagnostic_reporter.d +++ b/test/unit/parser/diagnostic_reporter.d @@ -3,7 +3,7 @@ module parser.diagnostic_reporter; import core.stdc.stdarg; import dmd.frontend : parseModule; -import dmd.globals : Loc; +import dmd.globals : Loc, global, DiagnosticReporting; import support : afterEach, beforeEach, NoopDiagnosticReporter; @@ -26,9 +26,10 @@ unittest { int errorCount; - override void error(const ref Loc, const(char)*, va_list) + override bool error(const ref Loc, const(char)*, va_list, const(char)*, const(char)*) { errorCount++; + return true; } } @@ -36,7 +37,7 @@ unittest parseModule("test.d", q{ deprecated deprecated module test; - }, reporter); + }); assert(reporter.errorCount == 1); } @@ -48,9 +49,10 @@ unittest { int supplementalCount; - override void errorSupplemental(const ref Loc, const(char)*, va_list) + override bool errorSupplemental(const ref Loc, const(char)*, va_list, const(char)*, const(char)*) { supplementalCount++; + return true; } } @@ -62,7 +64,7 @@ unittest static if (true) {} static else {} } - }, reporter); + }); assert(reporter.supplementalCount == 1); } @@ -74,12 +76,14 @@ unittest { int warningCount; - override void warning(const ref Loc, const(char)*, va_list) + override bool warning(const ref Loc, const(char)*, va_list, const(char)*, const(char)*) { warningCount++; + return true; } } + global.params.warnings = DiagnosticReporting.inform; scope reporter = new WarningCountingDiagnosticReporter; parseModule("test.d", q{ @@ -91,7 +95,7 @@ unittest else assert(4); } - }, reporter); + }); assert(reporter.warningCount == 1); } @@ -103,9 +107,10 @@ unittest { int deprecationCount; - override void deprecation(const ref Loc, const(char)*, va_list) + override bool deprecation(const ref Loc, const(char)*, va_list, const(char)*, const(char)*) { deprecationCount++; + return true; } } @@ -113,7 +118,7 @@ unittest parseModule("test.d", q{ extern (Pascal) void foo(); - }, reporter); + }); assert(reporter.deprecationCount == 1); } diff --git a/test/unit/support.d b/test/unit/support.d index 01f710d17956..b7a28852e5d2 100644 --- a/test/unit/support.d +++ b/test/unit/support.d @@ -1,6 +1,6 @@ module support; -import dmd.errors : DiagnosticReporter; +import dmd.frontend : DiagnosticReporter; /// UDA used to indicate a function should be run before each test. enum beforeEach; @@ -84,10 +84,10 @@ class NoopDiagnosticReporter : DiagnosticReporter override int errorCount() { return 0; } override int warningCount() { return 0; } override int deprecationCount() { return 0; } - override void error(const ref Loc loc, const(char)* format, va_list) {} - override void errorSupplemental(const ref Loc loc, const(char)* format, va_list) {} - override void warning(const ref Loc loc, const(char)* format, va_list) {} - override void warningSupplemental(const ref Loc loc, const(char)* format, va_list) {} - override void deprecation(const ref Loc loc, const(char)* format, va_list) {} - override void deprecationSupplemental(const ref Loc loc, const(char)* format, va_list) {} + override bool error(const ref Loc loc, const(char)* format, va_list, const(char)* p1, const(char)* p2) { return true; } + override bool errorSupplemental(const ref Loc loc, const(char)* format, va_list, const(char)* p1, const(char)* p2) { return true; } + override bool warning(const ref Loc loc, const(char)* format, va_list, const(char)* p1, const(char)* p2) { return true; } + override bool warningSupplemental(const ref Loc loc, const(char)* format, va_list, const(char)* p1, const(char)* p2) { return true; } + override bool deprecation(const ref Loc loc, const(char)* format, va_list, const(char)* p1, const(char)* p2) { return true; } + override bool deprecationSupplemental(const ref Loc loc, const(char)* format, va_list, const(char)* p1, const(char)* p2) { return true; } }