diff options
6 files changed, 63 insertions, 8 deletions
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index c901d9f68f..62db436ad6 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -579,7 +579,7 @@ void GDScriptParser::parse_program() {  		}  	} -	parse_class_body(); +	parse_class_body(true);  #ifdef TOOLS_ENABLED  	for (Map<int, GDScriptTokenizer::CommentData>::Element *E = tokenizer.get_comments().front(); E; E = E->next()) { @@ -615,9 +615,10 @@ GDScriptParser::ClassNode *GDScriptParser::parse_class() {  	}  	consume(GDScriptTokenizer::Token::COLON, R"(Expected ":" after class declaration.)"); -	consume(GDScriptTokenizer::Token::NEWLINE, R"(Expected newline after class declaration.)"); -	if (!consume(GDScriptTokenizer::Token::INDENT, R"(Expected indented block after class declaration.)")) { +	bool multiline = match(GDScriptTokenizer::Token::NEWLINE); + +	if (multiline && !consume(GDScriptTokenizer::Token::INDENT, R"(Expected indented block after class declaration.)")) {  		current_class = previous_class;  		return n_class;  	} @@ -630,9 +631,11 @@ GDScriptParser::ClassNode *GDScriptParser::parse_class() {  		end_statement("superclass");  	} -	parse_class_body(); +	parse_class_body(multiline); -	consume(GDScriptTokenizer::Token::DEDENT, R"(Missing unindent at the end of the class body.)"); +	if (multiline) { +		consume(GDScriptTokenizer::Token::DEDENT, R"(Missing unindent at the end of the class body.)"); +	}  	current_class = previous_class;  	return n_class; @@ -747,7 +750,7 @@ void GDScriptParser::parse_class_member(T *(GDScriptParser::*p_parse_function)()  	}  } -void GDScriptParser::parse_class_body() { +void GDScriptParser::parse_class_body(bool p_is_multiline) {  	bool class_end = false;  	while (!class_end && !is_at_end()) {  		switch (current.type) { @@ -793,6 +796,9 @@ void GDScriptParser::parse_class_body() {  		if (panic_mode) {  			synchronize();  		} +		if (!p_is_multiline) { +			class_end = true; +		}  	}  } @@ -1358,6 +1364,9 @@ GDScriptParser::SuiteNode *GDScriptParser::parse_suite(const String &p_context,  	int error_count = 0;  	do { +		if (!multiline && previous.type == GDScriptTokenizer::Token::SEMICOLON && check(GDScriptTokenizer::Token::NEWLINE)) { +			break; +		}  		Node *statement = parse_statement();  		if (statement == nullptr) {  			if (error_count++ > 100) { @@ -1398,7 +1407,7 @@ GDScriptParser::SuiteNode *GDScriptParser::parse_suite(const String &p_context,  				break;  		} -	} while (multiline && !check(GDScriptTokenizer::Token::DEDENT) && !lambda_ended && !is_at_end()); +	} while ((multiline || previous.type == GDScriptTokenizer::Token::SEMICOLON) && !check(GDScriptTokenizer::Token::DEDENT) && !lambda_ended && !is_at_end());  	if (multiline) {  		if (!lambda_ended) { diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index a641c1052d..dd7667d291 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -1324,7 +1324,7 @@ private:  	ClassNode *parse_class();  	void parse_class_name();  	void parse_extends(); -	void parse_class_body(); +	void parse_class_body(bool p_is_multiline);  	template <class T>  	void parse_class_member(T *(GDScriptParser::*p_parse_function)(), AnnotationInfo::TargetKind p_target, const String &p_member_kind);  	SignalNode *parse_signal(); diff --git a/modules/gdscript/tests/scripts/parser/features/semicolon_as_terminator.gd b/modules/gdscript/tests/scripts/parser/features/semicolon_as_terminator.gd new file mode 100644 index 0000000000..0f4aebb459 --- /dev/null +++ b/modules/gdscript/tests/scripts/parser/features/semicolon_as_terminator.gd @@ -0,0 +1,22 @@ +#GDTEST_OK + +func test(): +	a(); +	b(); +	c(); +	d(); +	e(); + +func a(): print("a"); + +func b(): print("b1"); print("b2") + +func c(): print("c1"); print("c2"); + +func d(): +	print("d1"); +	print("d2") + +func e(): +	print("e1"); +	print("e2"); diff --git a/modules/gdscript/tests/scripts/parser/features/semicolon_as_terminator.out b/modules/gdscript/tests/scripts/parser/features/semicolon_as_terminator.out new file mode 100644 index 0000000000..387cbd8fc2 --- /dev/null +++ b/modules/gdscript/tests/scripts/parser/features/semicolon_as_terminator.out @@ -0,0 +1,10 @@ +GDTEST_OK +a +b1 +b2 +c1 +c2 +d1 +d2 +e1 +e2 diff --git a/modules/gdscript/tests/scripts/parser/features/single_line_declaration.gd b/modules/gdscript/tests/scripts/parser/features/single_line_declaration.gd new file mode 100644 index 0000000000..650500663b --- /dev/null +++ b/modules/gdscript/tests/scripts/parser/features/single_line_declaration.gd @@ -0,0 +1,11 @@ +#GDTEST_OK + +func test(): C.new().test("Ok"); test2() + +func test2(): print("Ok 2") + +class A: pass + +class B extends RefCounted: pass + +class C extends RefCounted: func test(x): print(x) diff --git a/modules/gdscript/tests/scripts/parser/features/single_line_declaration.out b/modules/gdscript/tests/scripts/parser/features/single_line_declaration.out new file mode 100644 index 0000000000..e021923dc2 --- /dev/null +++ b/modules/gdscript/tests/scripts/parser/features/single_line_declaration.out @@ -0,0 +1,3 @@ +GDTEST_OK +Ok +Ok 2  |