Merge pull request #61993 from kdiduk/gdscript-fix-inner-class-on-single-line
Fix inner class parsing when statement after colon is on the same line
This commit is contained in:
commit
5197dc6c9e
2 changed files with 62 additions and 19 deletions
|
@ -82,8 +82,51 @@ void GDScriptParser::_set_end_statement_error(String p_name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GDScriptParser::_enter_indent_block(BlockNode *p_block) {
|
bool GDScriptParser::_enter_indent_block(BlockNode *p_block) {
|
||||||
|
if (!_parse_colon()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tokenizer->get_token() != GDScriptTokenizer::TK_NEWLINE) {
|
||||||
|
// Be more Python-like.
|
||||||
|
IndentLevel current_level = indent_level.back()->get();
|
||||||
|
indent_level.push_back(current_level);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _parse_indent_block_newlines(p_block);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GDScriptParser::_enter_inner_class_indent_block() {
|
||||||
|
if (!_parse_colon()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tokenizer->get_token() != GDScriptTokenizer::TK_NEWLINE) {
|
||||||
|
// Check Python-like one-liner class declaration "class Foo: pass".
|
||||||
|
// Note: only "pass" is allowed on the same line after the colon.
|
||||||
|
if (tokenizer->get_token() != GDScriptTokenizer::TK_CF_PASS) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GDScriptTokenizer::Token token = tokenizer->get_token(1);
|
||||||
|
if (token != GDScriptTokenizer::TK_NEWLINE && token != GDScriptTokenizer::TK_EOF) {
|
||||||
|
int line = tokenizer->get_token_line();
|
||||||
|
int col = tokenizer->get_token_column();
|
||||||
|
String message = "Invalid syntax: unexpected \"";
|
||||||
|
message += GDScriptTokenizer::get_token_name(token);
|
||||||
|
message += "\".";
|
||||||
|
_set_error(message, line, col);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _parse_indent_block_newlines();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GDScriptParser::_parse_colon() {
|
||||||
if (tokenizer->get_token() != GDScriptTokenizer::TK_COLON) {
|
if (tokenizer->get_token() != GDScriptTokenizer::TK_COLON) {
|
||||||
// report location at the previous token (on the previous line)
|
// Report location at the previous token (on the previous line).
|
||||||
int error_line = tokenizer->get_token_line(-1);
|
int error_line = tokenizer->get_token_line(-1);
|
||||||
int error_column = tokenizer->get_token_column(-1);
|
int error_column = tokenizer->get_token_column(-1);
|
||||||
_set_error("':' expected at end of line.", error_line, error_column);
|
_set_error("':' expected at end of line.", error_line, error_column);
|
||||||
|
@ -95,19 +138,12 @@ bool GDScriptParser::_enter_indent_block(BlockNode *p_block) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tokenizer->get_token() != GDScriptTokenizer::TK_NEWLINE) {
|
return true;
|
||||||
// be more python-like
|
}
|
||||||
IndentLevel current_level = indent_level.back()->get();
|
|
||||||
indent_level.push_back(current_level);
|
|
||||||
return true;
|
|
||||||
//_set_error("newline expected after ':'.");
|
|
||||||
//return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
bool GDScriptParser::_parse_indent_block_newlines(BlockNode *p_block) {
|
||||||
while (true) {
|
while (true) {
|
||||||
if (tokenizer->get_token() != GDScriptTokenizer::TK_NEWLINE) {
|
if (tokenizer->get_token(1) == GDScriptTokenizer::TK_EOF) {
|
||||||
return false; //wtf
|
|
||||||
} else if (tokenizer->get_token(1) == GDScriptTokenizer::TK_EOF) {
|
|
||||||
return false;
|
return false;
|
||||||
} else if (tokenizer->get_token(1) != GDScriptTokenizer::TK_NEWLINE) {
|
} else if (tokenizer->get_token(1) != GDScriptTokenizer::TK_NEWLINE) {
|
||||||
int indent = tokenizer->get_token_line_indent();
|
int indent = tokenizer->get_token_line_indent();
|
||||||
|
@ -126,14 +162,13 @@ bool GDScriptParser::_enter_indent_block(BlockNode *p_block) {
|
||||||
indent_level.push_back(new_indent);
|
indent_level.push_back(new_indent);
|
||||||
tokenizer->advance();
|
tokenizer->advance();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} else if (p_block) {
|
} else if (p_block) {
|
||||||
NewLineNode *nl = alloc_node<NewLineNode>();
|
NewLineNode *nl = alloc_node<NewLineNode>();
|
||||||
nl->line = tokenizer->get_token_line();
|
nl->line = tokenizer->get_token_line();
|
||||||
p_block->statements.push_back(nl);
|
p_block->statements.push_back(nl);
|
||||||
}
|
}
|
||||||
|
|
||||||
tokenizer->advance(); // go to next newline
|
tokenizer->advance(); // Go to the next newline.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3840,13 +3875,18 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_enter_indent_block()) {
|
if (!_enter_inner_class_indent_block()) {
|
||||||
_set_error("Indented block expected.");
|
if (!error_set) {
|
||||||
|
_set_error("Indented block or \"pass\" expected.");
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
current_class = newclass;
|
|
||||||
_parse_class(newclass);
|
if (tokenizer->get_token() != GDScriptTokenizer::TK_CF_PASS) {
|
||||||
current_class = p_class;
|
current_class = newclass;
|
||||||
|
_parse_class(newclass);
|
||||||
|
current_class = p_class;
|
||||||
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
/* this is for functions....
|
/* this is for functions....
|
||||||
|
|
|
@ -599,6 +599,9 @@ private:
|
||||||
|
|
||||||
bool _parse_arguments(Node *p_parent, Vector<Node *> &p_args, bool p_static, bool p_can_codecomplete = false, bool p_parsing_constant = false);
|
bool _parse_arguments(Node *p_parent, Vector<Node *> &p_args, bool p_static, bool p_can_codecomplete = false, bool p_parsing_constant = false);
|
||||||
bool _enter_indent_block(BlockNode *p_block = nullptr);
|
bool _enter_indent_block(BlockNode *p_block = nullptr);
|
||||||
|
bool _enter_inner_class_indent_block();
|
||||||
|
bool _parse_colon();
|
||||||
|
bool _parse_indent_block_newlines(BlockNode *p_block = nullptr);
|
||||||
bool _parse_newline();
|
bool _parse_newline();
|
||||||
Node *_parse_expression(Node *p_parent, bool p_static, bool p_allow_assign = false, bool p_parsing_constant = false);
|
Node *_parse_expression(Node *p_parent, bool p_static, bool p_allow_assign = false, bool p_parsing_constant = false);
|
||||||
Node *_reduce_expression(Node *p_node, bool p_to_const = false);
|
Node *_reduce_expression(Node *p_node, bool p_to_const = false);
|
||||||
|
|
Loading…
Reference in a new issue