From dad14ec3e4fa4cea4bbf1cf02cf01c0c3add6f4f Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Sat, 12 Jan 2019 16:53:32 +0100 Subject: [PATCH] diagnostics: add -ffixit support for deprecated features Issue directives for IDE/editors to fix the source file. http://clang.llvm.org/docs/UsersManual.html#cmdoption-fdiagnostics-parseable-fixits Do it for deprecated features. For instance: $ cat foo.y %error-verbose %name-prefix = "foo" %name-prefix="bar" %define parser_class_name "Parser" %% exp:; $ LC_ALL=C ./_build/8d/tests/bison -ffixit /tmp/foo.yy /tmp/foo.yy:1.1-14: warning: deprecated directive, use '%define parse.error verbose' [-Wdeprecated] %error-verbose ^^^^^^^^^^^^^^ fix-it:"/tmp/foo.yy":{1:1-1:15}:"%define parse.error verbose" /tmp/foo.yy:3.1-20: warning: deprecated directive, use '%define api.prefix {foo}' [-Wdeprecated] %name-prefix = "foo" ^^^^^^^^^^^^^^^^^^^^ fix-it:"/tmp/foo.yy":{3:1-3:21}:"%define api.prefix {foo}" /tmp/foo.yy:4.1-18: warning: deprecated directive, use '%define api.prefix {bar}' [-Wdeprecated] %name-prefix="bar" ^^^^^^^^^^^^^^^^^^ fix-it:"/tmp/foo.yy":{4:1-4:19}:"%define api.prefix {bar}" /tmp/foo.yy:5.9-25: warning: deprecated directive, use '%define api.parser.class {Parser}' [-Wdeprecated] %define parser_class_name "Parser" ^^^^^^^^^^^^^^^^^ fix-it:"/tmp/foo.yy":{5:9-5:26}:"%define api.parser.class {Parser}" /tmp/foo.yy:5.9-25: error: %define variable 'api.parser.class' is not used %define parser_class_name "Parser" ^^^^^^^^^^^^^^^^^ * src/getargs.h, src/getargs.c (feature_fixit_parsable): New. (feature_types, feature_args): Use it. * src/complain.c (deprecated_directive): Use it. * tests/input.at: Check it. --- src/complain.c | 9 +++++++++ src/getargs.c | 2 ++ src/getargs.h | 7 ++++--- tests/input.at | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/complain.c b/src/complain.c index e96cf276..d20377bb 100644 --- a/src/complain.c +++ b/src/complain.c @@ -30,6 +30,7 @@ #include "files.h" #include "getargs.h" #include "quote.h" +#include "quotearg.h" err_status complaint_status = status_none; @@ -393,6 +394,14 @@ deprecated_directive (location const *loc, char const *old, char const *upd) complain (loc, Wdeprecated, _("deprecated directive: %s, use %s"), quote (old), quote_n (1, upd)); + /* GCC and Clang follow the same pattern. + http://clang.llvm.org/docs/UsersManual.html#cmdoption-fdiagnostics-parseable-fixits */ + if (feature_flag & feature_fixit_parsable) + fprintf (stderr, "fix-it:%s:{%d:%d-%d:%d}:%s\n", + quotearg_n_style (1, c_quoting_style, loc->start.file), + loc->start.line, loc->start.column, + loc->end.line, loc->end.column, + quotearg_n_style (2, c_quoting_style, upd)); } void diff --git a/src/getargs.c b/src/getargs.c index d9672c1f..9874c429 100644 --- a/src/getargs.c +++ b/src/getargs.c @@ -228,6 +228,7 @@ static const char * const feature_args[] = { "none", "caret", "diagnostics-show-caret", + "fixit", "diagnostics-parseable-fixits", "all", 0 }; @@ -236,6 +237,7 @@ static const int feature_types[] = { feature_none, feature_caret, feature_caret, + feature_fixit_parsable, feature_fixit_parsable, feature_all }; diff --git a/src/getargs.h b/src/getargs.h index 2ca2934f..925ef58e 100644 --- a/src/getargs.h +++ b/src/getargs.h @@ -114,9 +114,10 @@ extern int trace_flag; enum feature { - feature_none = 0, /**< No additional feature. */ - feature_caret = 1 << 0, /**< Enhance the output of errors with carets. */ - feature_all = ~0 /**< All above features. */ + feature_none = 0, /**< No additional feature. */ + feature_caret = 1 << 0, /**< Output errors with carets. */ + feature_fixit_parsable = 1 << 1, /**< Issue instructions to fix the sources. */ + feature_all = ~0 /**< All above features. */ }; /** What additional features to use. */ extern int feature_flag; diff --git a/tests/input.at b/tests/input.at index c7042049..d5eec578 100644 --- a/tests/input.at +++ b/tests/input.at @@ -2527,6 +2527,43 @@ input.y:11-6: previous definition input.y:29.1-18: warning: deprecated directive: '%name-prefix "bar"', use '%define api.prefix {bar}' [-Wdeprecated] ]]) +AT_BISON_CHECK([[-ffixit input.y]], [[1]], [[]], +[[input.y:10.1-13: warning: deprecated directive: '%default_prec', use '%default-prec' [-Wdeprecated] +fix-it:"input.y":{10:1-10:14}:"%default-prec" +input.y:11.1-14: warning: deprecated directive: '%error_verbose', use '%define parse.error verbose' [-Wdeprecated] +fix-it:"input.y":{11:1-11:15}:"%define parse.error verbose" +input.y:12.1-10: warning: deprecated directive: '%expect_rr', use '%expect-rr' [-Wdeprecated] +fix-it:"input.y":{12:1-12:11}:"%expect-rr" +input.y:13.1-14: warning: deprecated directive: '%file-prefix =', use '%file-prefix' [-Wdeprecated] +fix-it:"input.y":{13:1-13:15}:"%file-prefix" +input.y:14.1-15.2: warning: deprecated directive: '%file-prefix\n =', use '%file-prefix' [-Wdeprecated] +fix-it:"input.y":{14:1-15:3}:"%file-prefix" +input.y:17.1-19: warning: deprecated directive: '%fixed-output_files', use '%fixed-output-files' [-Wdeprecated] +fix-it:"input.y":{17:1-17:20}:"%fixed-output-files" +input.y:18.1-19: warning: deprecated directive: '%fixed_output-files', use '%fixed-output-files' [-Wdeprecated] +fix-it:"input.y":{18:1-18:20}:"%fixed-output-files" +input.y:20.1-19: warning: deprecated directive: '%name-prefix= "foo"', use '%define api.prefix {foo}' [-Wdeprecated] +fix-it:"input.y":{20:1-20:20}:"%define api.prefix {foo}" +input.y:21.1-16: warning: deprecated directive: '%no-default_prec', use '%no-default-prec' [-Wdeprecated] +fix-it:"input.y":{21:1-21:17}:"%no-default-prec" +input.y:22.1-16: warning: deprecated directive: '%no_default-prec', use '%no-default-prec' [-Wdeprecated] +fix-it:"input.y":{22:1-22:17}:"%no-default-prec" +input.y:23.1-9: warning: deprecated directive: '%no_lines', use '%no-lines' [-Wdeprecated] +fix-it:"input.y":{23:1-23:10}:"%no-lines" +input.y:24.1-9: warning: deprecated directive: '%output =', use '%output' [-Wdeprecated] +fix-it:"input.y":{24:1-24:10}:"%output" +input.y:25.1-12: warning: deprecated directive: '%pure_parser', use '%pure-parser' [-Wdeprecated] +fix-it:"input.y":{25:1-25:13}:"%pure-parser" +input.y:26.1-12: warning: deprecated directive: '%token_table', use '%token-table' [-Wdeprecated] +fix-it:"input.y":{26:1-26:13}:"%token-table" +input.y:27.1-14: warning: deprecated directive: '%error-verbose', use '%define parse.error verbose' [-Wdeprecated] +fix-it:"input.y":{27:1-27:15}:"%define parse.error verbose" +input.y:27-6: error: %define variable 'parse.error' redefined +input.y:11-6: previous definition +input.y:29.1-18: warning: deprecated directive: '%name-prefix "bar"', use '%define api.prefix {bar}' [-Wdeprecated] +fix-it:"input.y":{29:1-29:19}:"%define api.prefix {bar}" +]]) + AT_CLEANUP