generate_diagnostics.cc 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #include <iostream>
  2. #include <tuple>
  3. using namespace std;
  4. namespace {
  5. tuple<string, string> MESSAGES[] = {
  6. // Lexer errors
  7. {"UnicodePointTooLarge", "invalid Unicode codepoint (too large)"},
  8. {"InvalidEscape", "invalid escape character syntax"},
  9. {"IncompleteEscape", "incomplete character syntax"},
  10. {"InvalidHexEscape", "invalid hex escape"},
  11. {"InvalidUnicodeEscape", "invalid Unicode escape"},
  12. {"UnterminatedUnicode", "unterminated Unicode escape"},
  13. {"EscapeEof", "escape sequence meets end of file"},
  14. {"StringEof", "unterminated string meets end of file"},
  15. {"RegexpOptions", "unknown regexp options: {}"},
  16. {"CvarName", "`{}` is not allowed as a class variable name"},
  17. {"IvarName", "`{}` is not allowed as an instance variable name"},
  18. {"TrailingInNumber", "trailing `{}` in number"},
  19. {"EmptyNumeric", "numeric literal without digits"},
  20. {"InvalidOctal", "invalid octal digit"},
  21. {"NoDotDigitLiteral", "no .<digit> floating literal anymore; put 0 before dot"},
  22. {"BareBackslash", "bare backslash only allowed before newline"},
  23. {"Unexpected", "unexpected `{}`"},
  24. {"EmbeddedDocument", "embedded document meets end of file (and they embark on a romantic journey)"},
  25. // Lexer warnings
  26. {"InvalidEscapeUse", "invalid character syntax; use ?{}"},
  27. {"AmbiguousLiteral", "ambiguous first argument; put parentheses or a space even after the operator"},
  28. {"AmbiguousPrefix", "`{}` interpreted as argument prefix"},
  29. // Parser errors
  30. {"NthRefAlias", "cannot define an alias for a back-reference variable"},
  31. {"BeginInMethod", "BEGIN in method"},
  32. {"BackrefAssignment", "cannot assign to a back-reference variable"},
  33. {"InvalidAssignment", "cannot assign to a keyword"},
  34. {"ModuleNameConst", "class or module name must be a constant literal"},
  35. {"UnexpectedToken", "unexpected token {}"},
  36. {"ArgumentConst", "formal argument cannot be a constant"},
  37. {"ArgumentIvar", "formal argument cannot be an instance variable"},
  38. {"ArgumentGvar", "formal argument cannot be a global variable"},
  39. {"ArgumentCvar", "formal argument cannot be a class variable"},
  40. {"DuplicateArgument", "duplicate argument name {}"},
  41. {"EmptySymbol", "empty symbol literal"},
  42. {"OddHash", "odd number of entries for a hash"},
  43. {"SingletonLiteral", "cannot define a singleton method for a literal"},
  44. {"DynamicConst", "dynamic constant assignment"},
  45. {"ConstReassignment", "constant re-assignment"},
  46. {"ModuleInDef", "module definition in method body"},
  47. {"ClassInDef", "class definition in method body"},
  48. {"UnexpectedPercentStr", "{}: unknown type of percent-literal"},
  49. {"BlockAndBlockarg", "both block argument and literal block are passed"},
  50. {"MasgnAsCondition", "multiple assignment in conditional context"},
  51. {"BlockGivenToYield", "block given to yield"},
  52. {"InvalidRegexp", "{}"},
  53. {"InvalidReturn", "Invalid return in class/module body"},
  54. // Parser warnings
  55. {"UselessElse", "else without rescue is useless"},
  56. // Parser errors that are not Ruby errors
  57. {"InvalidEncoding", "literal contains escape sequences incompatible with UTF-8"},
  58. // Rewriter diagnostics
  59. {"InvalidAction", "cannot {}"},
  60. {"Clobbered", "clobbered by: {}"},
  61. // TypedRuby diagnostics
  62. {"NotStaticCpathInGeninst", "Type name in generic instance must be a static constant path"},
  63. };
  64. void generateDclass() {
  65. cout << "// This file is autogenerated by generate_diagnostics.cc\n";
  66. cout << "#ifndef RUBY_PARSER_DIAGNOSTICS\n";
  67. cout << "#define RUBY_PARSER_DIAGNOSTICS\n";
  68. cout << "namespace ruby_parser {\n";
  69. cout << "// DO NOT MODIFY\n";
  70. cout << "enum class dclass {\n";
  71. for (auto [err, _msg] : MESSAGES) {
  72. cout << " " << err << ",\n";
  73. }
  74. cout << "};\n";
  75. cout << "}\n";
  76. cout << "#endif\n";
  77. }
  78. void generateDclassStrings() {
  79. cout << "namespace sorbet {\n";
  80. cout << "namespace parser {\n";
  81. cout << "const char * dclassStrings[] = {\n";
  82. for (auto [_err, msg] : MESSAGES) {
  83. cout << " \"" << msg << "\",\n";
  84. }
  85. cout << "};\n";
  86. cout << "}\n";
  87. cout << "}\n";
  88. }
  89. } // namespace
  90. int main(int argc, char **argv) {
  91. if (argc != 2) {
  92. cout << "Usage: {} (dclass|dclassStrings)\n", (string)argv[0];
  93. return 1;
  94. }
  95. if ((string)argv[1] == "dclass") {
  96. generateDclass();
  97. } else if ((string)argv[1] == "dclassStrings") {
  98. generateDclassStrings();
  99. } else {
  100. cout << "Usage: {} (dclass|dclassStrings)\n", (string)argv[0];
  101. return 1;
  102. }
  103. return 0;
  104. }