2023-10-31 20:26:31 +03:00
|
|
|
/**
|
|
|
|
* @file diagnostic.h
|
|
|
|
*
|
|
|
|
* A list of diagnostics generated during parsing.
|
|
|
|
*/
|
2023-09-27 19:24:48 +03:00
|
|
|
#ifndef PRISM_DIAGNOSTIC_H
|
|
|
|
#define PRISM_DIAGNOSTIC_H
|
2023-06-20 18:53:02 +03:00
|
|
|
|
2023-09-27 19:24:48 +03:00
|
|
|
#include "prism/defines.h"
|
|
|
|
#include "prism/util/pm_list.h"
|
2023-06-20 18:53:02 +03:00
|
|
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdlib.h>
|
2023-09-04 04:27:43 +03:00
|
|
|
#include <assert.h>
|
2023-06-20 18:53:02 +03:00
|
|
|
|
2023-10-31 04:58:48 +03:00
|
|
|
/**
|
2023-10-31 20:26:31 +03:00
|
|
|
* This struct represents a diagnostic generated during parsing.
|
2023-10-31 04:58:48 +03:00
|
|
|
*
|
|
|
|
* @extends pm_list_node_t
|
|
|
|
*/
|
2023-06-20 18:53:02 +03:00
|
|
|
typedef struct {
|
2023-10-31 20:26:31 +03:00
|
|
|
/** The embedded base node. */
|
2023-09-27 19:24:48 +03:00
|
|
|
pm_list_node_t node;
|
2023-10-31 20:26:31 +03:00
|
|
|
|
|
|
|
/** A pointer to the start of the source that generated the diagnostic. */
|
2023-08-29 17:48:20 +03:00
|
|
|
const uint8_t *start;
|
2023-10-31 20:26:31 +03:00
|
|
|
|
|
|
|
/** A pointer to the end of the source that generated the diagnostic. */
|
2023-08-29 17:48:20 +03:00
|
|
|
const uint8_t *end;
|
2023-10-31 20:26:31 +03:00
|
|
|
|
|
|
|
/** The message associated with the diagnostic. */
|
2023-06-20 18:53:02 +03:00
|
|
|
const char *message;
|
2023-09-27 19:24:48 +03:00
|
|
|
} pm_diagnostic_t;
|
2023-06-20 18:53:02 +03:00
|
|
|
|
2023-10-31 18:35:56 +03:00
|
|
|
/**
|
|
|
|
* The diagnostic IDs of all of the diagnostics, used to communicate the types
|
|
|
|
* of errors between the parser and the user.
|
|
|
|
*/
|
2023-09-04 04:27:43 +03:00
|
|
|
typedef enum {
|
2023-09-27 19:24:48 +03:00
|
|
|
PM_ERR_ALIAS_ARGUMENT,
|
|
|
|
PM_ERR_AMPAMPEQ_MULTI_ASSIGN,
|
|
|
|
PM_ERR_ARGUMENT_AFTER_BLOCK,
|
|
|
|
PM_ERR_ARGUMENT_BARE_HASH,
|
|
|
|
PM_ERR_ARGUMENT_BLOCK_MULTI,
|
|
|
|
PM_ERR_ARGUMENT_FORMAL_CLASS,
|
|
|
|
PM_ERR_ARGUMENT_FORMAL_CONSTANT,
|
|
|
|
PM_ERR_ARGUMENT_FORMAL_GLOBAL,
|
|
|
|
PM_ERR_ARGUMENT_FORMAL_IVAR,
|
|
|
|
PM_ERR_ARGUMENT_NO_FORWARDING_AMP,
|
|
|
|
PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES,
|
|
|
|
PM_ERR_ARGUMENT_NO_FORWARDING_STAR,
|
|
|
|
PM_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT,
|
|
|
|
PM_ERR_ARGUMENT_SPLAT_AFTER_SPLAT,
|
|
|
|
PM_ERR_ARGUMENT_TERM_PAREN,
|
|
|
|
PM_ERR_ARGUMENT_UNEXPECTED_BLOCK,
|
|
|
|
PM_ERR_ARRAY_ELEMENT,
|
|
|
|
PM_ERR_ARRAY_EXPRESSION,
|
|
|
|
PM_ERR_ARRAY_EXPRESSION_AFTER_STAR,
|
|
|
|
PM_ERR_ARRAY_SEPARATOR,
|
|
|
|
PM_ERR_ARRAY_TERM,
|
|
|
|
PM_ERR_BEGIN_LONELY_ELSE,
|
|
|
|
PM_ERR_BEGIN_TERM,
|
|
|
|
PM_ERR_BEGIN_UPCASE_BRACE,
|
|
|
|
PM_ERR_BEGIN_UPCASE_TERM,
|
|
|
|
PM_ERR_BEGIN_UPCASE_TOPLEVEL,
|
|
|
|
PM_ERR_BLOCK_PARAM_LOCAL_VARIABLE,
|
|
|
|
PM_ERR_BLOCK_PARAM_PIPE_TERM,
|
|
|
|
PM_ERR_BLOCK_TERM_BRACE,
|
|
|
|
PM_ERR_BLOCK_TERM_END,
|
|
|
|
PM_ERR_CANNOT_PARSE_EXPRESSION,
|
|
|
|
PM_ERR_CANNOT_PARSE_STRING_PART,
|
|
|
|
PM_ERR_CASE_EXPRESSION_AFTER_CASE,
|
|
|
|
PM_ERR_CASE_EXPRESSION_AFTER_WHEN,
|
|
|
|
PM_ERR_CASE_MISSING_CONDITIONS,
|
|
|
|
PM_ERR_CASE_TERM,
|
|
|
|
PM_ERR_CLASS_IN_METHOD,
|
|
|
|
PM_ERR_CLASS_NAME,
|
|
|
|
PM_ERR_CLASS_SUPERCLASS,
|
|
|
|
PM_ERR_CLASS_TERM,
|
2023-09-27 21:24:19 +03:00
|
|
|
PM_ERR_CLASS_UNEXPECTED_END,
|
2023-09-27 19:24:48 +03:00
|
|
|
PM_ERR_CONDITIONAL_ELSIF_PREDICATE,
|
|
|
|
PM_ERR_CONDITIONAL_IF_PREDICATE,
|
|
|
|
PM_ERR_CONDITIONAL_PREDICATE_TERM,
|
|
|
|
PM_ERR_CONDITIONAL_TERM,
|
|
|
|
PM_ERR_CONDITIONAL_TERM_ELSE,
|
|
|
|
PM_ERR_CONDITIONAL_UNLESS_PREDICATE,
|
|
|
|
PM_ERR_CONDITIONAL_UNTIL_PREDICATE,
|
|
|
|
PM_ERR_CONDITIONAL_WHILE_PREDICATE,
|
|
|
|
PM_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT,
|
|
|
|
PM_ERR_DEF_ENDLESS,
|
|
|
|
PM_ERR_DEF_ENDLESS_SETTER,
|
|
|
|
PM_ERR_DEF_NAME,
|
|
|
|
PM_ERR_DEF_NAME_AFTER_RECEIVER,
|
|
|
|
PM_ERR_DEF_PARAMS_TERM,
|
|
|
|
PM_ERR_DEF_PARAMS_TERM_PAREN,
|
|
|
|
PM_ERR_DEF_RECEIVER,
|
|
|
|
PM_ERR_DEF_RECEIVER_TERM,
|
|
|
|
PM_ERR_DEF_TERM,
|
|
|
|
PM_ERR_DEFINED_EXPRESSION,
|
|
|
|
PM_ERR_EMBDOC_TERM,
|
|
|
|
PM_ERR_EMBEXPR_END,
|
|
|
|
PM_ERR_EMBVAR_INVALID,
|
|
|
|
PM_ERR_END_UPCASE_BRACE,
|
|
|
|
PM_ERR_END_UPCASE_TERM,
|
|
|
|
PM_ERR_ESCAPE_INVALID_CONTROL,
|
|
|
|
PM_ERR_ESCAPE_INVALID_CONTROL_REPEAT,
|
|
|
|
PM_ERR_ESCAPE_INVALID_HEXADECIMAL,
|
|
|
|
PM_ERR_ESCAPE_INVALID_META,
|
|
|
|
PM_ERR_ESCAPE_INVALID_META_REPEAT,
|
|
|
|
PM_ERR_ESCAPE_INVALID_UNICODE,
|
|
|
|
PM_ERR_ESCAPE_INVALID_UNICODE_CM_FLAGS,
|
|
|
|
PM_ERR_ESCAPE_INVALID_UNICODE_LITERAL,
|
|
|
|
PM_ERR_ESCAPE_INVALID_UNICODE_LONG,
|
|
|
|
PM_ERR_ESCAPE_INVALID_UNICODE_TERM,
|
|
|
|
PM_ERR_EXPECT_ARGUMENT,
|
|
|
|
PM_ERR_EXPECT_EOL_AFTER_STATEMENT,
|
|
|
|
PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ,
|
|
|
|
PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ,
|
|
|
|
PM_ERR_EXPECT_EXPRESSION_AFTER_COMMA,
|
|
|
|
PM_ERR_EXPECT_EXPRESSION_AFTER_EQUAL,
|
|
|
|
PM_ERR_EXPECT_EXPRESSION_AFTER_LESS_LESS,
|
|
|
|
PM_ERR_EXPECT_EXPRESSION_AFTER_LPAREN,
|
|
|
|
PM_ERR_EXPECT_EXPRESSION_AFTER_QUESTION,
|
|
|
|
PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR,
|
|
|
|
PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT,
|
|
|
|
PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH,
|
|
|
|
PM_ERR_EXPECT_EXPRESSION_AFTER_STAR,
|
|
|
|
PM_ERR_EXPECT_IDENT_REQ_PARAMETER,
|
|
|
|
PM_ERR_EXPECT_LPAREN_REQ_PARAMETER,
|
|
|
|
PM_ERR_EXPECT_RBRACKET,
|
|
|
|
PM_ERR_EXPECT_RPAREN,
|
|
|
|
PM_ERR_EXPECT_RPAREN_AFTER_MULTI,
|
|
|
|
PM_ERR_EXPECT_RPAREN_REQ_PARAMETER,
|
|
|
|
PM_ERR_EXPECT_STRING_CONTENT,
|
|
|
|
PM_ERR_EXPECT_WHEN_DELIMITER,
|
|
|
|
PM_ERR_EXPRESSION_BARE_HASH,
|
|
|
|
PM_ERR_FOR_COLLECTION,
|
|
|
|
PM_ERR_FOR_IN,
|
|
|
|
PM_ERR_FOR_INDEX,
|
|
|
|
PM_ERR_FOR_TERM,
|
|
|
|
PM_ERR_HASH_EXPRESSION_AFTER_LABEL,
|
|
|
|
PM_ERR_HASH_KEY,
|
|
|
|
PM_ERR_HASH_ROCKET,
|
|
|
|
PM_ERR_HASH_TERM,
|
|
|
|
PM_ERR_HASH_VALUE,
|
|
|
|
PM_ERR_HEREDOC_TERM,
|
|
|
|
PM_ERR_INCOMPLETE_QUESTION_MARK,
|
|
|
|
PM_ERR_INCOMPLETE_VARIABLE_CLASS,
|
|
|
|
PM_ERR_INCOMPLETE_VARIABLE_INSTANCE,
|
|
|
|
PM_ERR_INVALID_ENCODING_MAGIC_COMMENT,
|
|
|
|
PM_ERR_INVALID_FLOAT_EXPONENT,
|
|
|
|
PM_ERR_INVALID_NUMBER_BINARY,
|
|
|
|
PM_ERR_INVALID_NUMBER_DECIMAL,
|
|
|
|
PM_ERR_INVALID_NUMBER_HEXADECIMAL,
|
|
|
|
PM_ERR_INVALID_NUMBER_OCTAL,
|
|
|
|
PM_ERR_INVALID_NUMBER_UNDERSCORE,
|
|
|
|
PM_ERR_INVALID_PERCENT,
|
|
|
|
PM_ERR_INVALID_TOKEN,
|
|
|
|
PM_ERR_INVALID_VARIABLE_GLOBAL,
|
|
|
|
PM_ERR_LAMBDA_OPEN,
|
|
|
|
PM_ERR_LAMBDA_TERM_BRACE,
|
|
|
|
PM_ERR_LAMBDA_TERM_END,
|
|
|
|
PM_ERR_LIST_I_LOWER_ELEMENT,
|
|
|
|
PM_ERR_LIST_I_LOWER_TERM,
|
|
|
|
PM_ERR_LIST_I_UPPER_ELEMENT,
|
|
|
|
PM_ERR_LIST_I_UPPER_TERM,
|
|
|
|
PM_ERR_LIST_W_LOWER_ELEMENT,
|
|
|
|
PM_ERR_LIST_W_LOWER_TERM,
|
|
|
|
PM_ERR_LIST_W_UPPER_ELEMENT,
|
|
|
|
PM_ERR_LIST_W_UPPER_TERM,
|
|
|
|
PM_ERR_MALLOC_FAILED,
|
|
|
|
PM_ERR_MODULE_IN_METHOD,
|
|
|
|
PM_ERR_MODULE_NAME,
|
|
|
|
PM_ERR_MODULE_TERM,
|
|
|
|
PM_ERR_MULTI_ASSIGN_MULTI_SPLATS,
|
|
|
|
PM_ERR_NOT_EXPRESSION,
|
|
|
|
PM_ERR_NUMBER_LITERAL_UNDERSCORE,
|
|
|
|
PM_ERR_NUMBERED_PARAMETER_NOT_ALLOWED,
|
|
|
|
PM_ERR_NUMBERED_PARAMETER_OUTER_SCOPE,
|
|
|
|
PM_ERR_OPERATOR_MULTI_ASSIGN,
|
[ruby/prism] Index{Operator,And,Or}WriteNode
Right now, our Call{Operator,And,Or}WriteNode nodes represent two
different concepts:
```ruby
foo.bar += 1
foo[bar] += 1
```
These two statements are different in what they can support. The
former can never have arguments (or an opening_loc or closing_loc).
The former can also never have a block. Also, the former is a
variable method name.
The latter is always going to be []/[]=, it can have any number of
arguments including blocks (`foo[&bar] ||= 1`), and will always
have an opening_loc and closing_loc.
Furthermore, these statements end of having to take different paths
through the various compilers because with the latter you have to
consider the arguments and the block, whereas the former can
perform some additional peephole optimizations since there are
fewer values on the stack.
For these reasons, I'm introducing Index{Operator,And,Or}WriteNode.
These nodes never have a read_name or write_name on them because
they are always []/[]=. They also support blocks, which the previous
write nodes didn't. As a benefit of introducing these nodes, I've
removed the opening_loc, closing_loc, and arguments from the older
write nodes because they will always be null.
For the serialized format, both of these nodes end up being
smaller, and for in-memory we're storing fewer things in general,
so we have savings all around.
I don't love that we are introducing another node that is a call
node since we generally want consumers to only have to handle a
single call, but these nodes are so specific that they would have
to be handled separately anyway since in fact call 2 methods.
https://github.com/ruby/prism/commit/70155db9cd
2023-10-17 18:15:56 +03:00
|
|
|
PM_ERR_OPERATOR_WRITE_ARGUMENTS,
|
2023-09-27 19:24:48 +03:00
|
|
|
PM_ERR_OPERATOR_WRITE_BLOCK,
|
|
|
|
PM_ERR_PARAMETER_ASSOC_SPLAT_MULTI,
|
|
|
|
PM_ERR_PARAMETER_BLOCK_MULTI,
|
|
|
|
PM_ERR_PARAMETER_METHOD_NAME,
|
|
|
|
PM_ERR_PARAMETER_NAME_REPEAT,
|
|
|
|
PM_ERR_PARAMETER_NO_DEFAULT,
|
|
|
|
PM_ERR_PARAMETER_NO_DEFAULT_KW,
|
|
|
|
PM_ERR_PARAMETER_NUMBERED_RESERVED,
|
|
|
|
PM_ERR_PARAMETER_ORDER,
|
|
|
|
PM_ERR_PARAMETER_SPLAT_MULTI,
|
|
|
|
PM_ERR_PARAMETER_STAR,
|
2023-09-27 22:31:49 +03:00
|
|
|
PM_ERR_PARAMETER_UNEXPECTED_FWD,
|
2023-09-27 19:24:48 +03:00
|
|
|
PM_ERR_PARAMETER_WILD_LOOSE_COMMA,
|
|
|
|
PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET,
|
|
|
|
PM_ERR_PATTERN_EXPRESSION_AFTER_HROCKET,
|
|
|
|
PM_ERR_PATTERN_EXPRESSION_AFTER_COMMA,
|
|
|
|
PM_ERR_PATTERN_EXPRESSION_AFTER_IN,
|
|
|
|
PM_ERR_PATTERN_EXPRESSION_AFTER_KEY,
|
|
|
|
PM_ERR_PATTERN_EXPRESSION_AFTER_PAREN,
|
|
|
|
PM_ERR_PATTERN_EXPRESSION_AFTER_PIN,
|
|
|
|
PM_ERR_PATTERN_EXPRESSION_AFTER_PIPE,
|
|
|
|
PM_ERR_PATTERN_EXPRESSION_AFTER_RANGE,
|
|
|
|
PM_ERR_PATTERN_HASH_KEY,
|
|
|
|
PM_ERR_PATTERN_HASH_KEY_LABEL,
|
|
|
|
PM_ERR_PATTERN_IDENT_AFTER_HROCKET,
|
|
|
|
PM_ERR_PATTERN_LABEL_AFTER_COMMA,
|
|
|
|
PM_ERR_PATTERN_REST,
|
|
|
|
PM_ERR_PATTERN_TERM_BRACE,
|
|
|
|
PM_ERR_PATTERN_TERM_BRACKET,
|
|
|
|
PM_ERR_PATTERN_TERM_PAREN,
|
|
|
|
PM_ERR_PIPEPIPEEQ_MULTI_ASSIGN,
|
|
|
|
PM_ERR_REGEXP_TERM,
|
|
|
|
PM_ERR_RESCUE_EXPRESSION,
|
|
|
|
PM_ERR_RESCUE_MODIFIER_VALUE,
|
|
|
|
PM_ERR_RESCUE_TERM,
|
|
|
|
PM_ERR_RESCUE_VARIABLE,
|
|
|
|
PM_ERR_RETURN_INVALID,
|
|
|
|
PM_ERR_STRING_CONCATENATION,
|
|
|
|
PM_ERR_STRING_INTERPOLATED_TERM,
|
|
|
|
PM_ERR_STRING_LITERAL_TERM,
|
|
|
|
PM_ERR_SYMBOL_INVALID,
|
|
|
|
PM_ERR_SYMBOL_TERM_DYNAMIC,
|
|
|
|
PM_ERR_SYMBOL_TERM_INTERPOLATED,
|
|
|
|
PM_ERR_TERNARY_COLON,
|
|
|
|
PM_ERR_TERNARY_EXPRESSION_FALSE,
|
|
|
|
PM_ERR_TERNARY_EXPRESSION_TRUE,
|
|
|
|
PM_ERR_UNARY_RECEIVER_BANG,
|
|
|
|
PM_ERR_UNARY_RECEIVER_MINUS,
|
|
|
|
PM_ERR_UNARY_RECEIVER_PLUS,
|
|
|
|
PM_ERR_UNARY_RECEIVER_TILDE,
|
|
|
|
PM_ERR_UNDEF_ARGUMENT,
|
|
|
|
PM_ERR_UNTIL_TERM,
|
|
|
|
PM_ERR_WHILE_TERM,
|
|
|
|
PM_ERR_WRITE_TARGET_READONLY,
|
|
|
|
PM_ERR_WRITE_TARGET_UNEXPECTED,
|
|
|
|
PM_ERR_XSTRING_TERM,
|
|
|
|
PM_WARN_AMBIGUOUS_FIRST_ARGUMENT_MINUS,
|
|
|
|
PM_WARN_AMBIGUOUS_FIRST_ARGUMENT_PLUS,
|
|
|
|
PM_WARN_AMBIGUOUS_PREFIX_STAR,
|
|
|
|
PM_WARN_AMBIGUOUS_SLASH,
|
2023-10-31 18:35:56 +03:00
|
|
|
|
2023-09-04 04:27:43 +03:00
|
|
|
/* This must be the last member. */
|
2023-09-27 19:24:48 +03:00
|
|
|
PM_DIAGNOSTIC_ID_LEN,
|
|
|
|
} pm_diagnostic_id_t;
|
2023-09-04 04:27:43 +03:00
|
|
|
|
2023-10-31 18:35:56 +03:00
|
|
|
/**
|
|
|
|
* Append a diagnostic to the given list of diagnostics.
|
|
|
|
*
|
|
|
|
* @param list The list to append to.
|
|
|
|
* @param start The start of the diagnostic.
|
|
|
|
* @param end The end of the diagnostic.
|
|
|
|
* @param diag_id The diagnostic ID.
|
|
|
|
* @return Whether the diagnostic was successfully appended.
|
|
|
|
*/
|
2023-09-27 19:24:48 +03:00
|
|
|
bool pm_diagnostic_list_append(pm_list_t *list, const uint8_t *start, const uint8_t *end, pm_diagnostic_id_t diag_id);
|
2023-06-20 18:53:02 +03:00
|
|
|
|
2023-10-31 18:35:56 +03:00
|
|
|
/**
|
|
|
|
* Deallocate the internal state of the given diagnostic list.
|
|
|
|
*
|
|
|
|
* @param list The list to deallocate.
|
|
|
|
*/
|
2023-09-27 19:24:48 +03:00
|
|
|
void pm_diagnostic_list_free(pm_list_t *list);
|
2023-06-20 18:53:02 +03:00
|
|
|
|
|
|
|
#endif
|