Parse C# generics and type constraints correctly
This commit is contained in:
parent
9587861662
commit
d339824f15
3 changed files with 100 additions and 4 deletions
2
modules/mono/editor/GodotSharpTools/.gitignore
vendored
Normal file
2
modules/mono/editor/GodotSharpTools/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
# nuget packages
|
||||
packages
|
|
@ -259,6 +259,8 @@ Error ScriptClassParser::_skip_generic_type_params() {
|
|||
if (err)
|
||||
return err;
|
||||
continue;
|
||||
} else if (tk == TK_OP_GREATER) {
|
||||
return OK;
|
||||
} else if (tk != TK_COMMA) {
|
||||
error_str = "Unexpected token: " + get_token_name(tk);
|
||||
error = true;
|
||||
|
@ -312,27 +314,108 @@ Error ScriptClassParser::_parse_class_base(Vector<String> &r_base) {
|
|||
|
||||
Token tk = get_token();
|
||||
|
||||
bool generic = false;
|
||||
if (tk == TK_OP_LESS) {
|
||||
// We don't add it to the base list if it's generic
|
||||
Error err = _skip_generic_type_params();
|
||||
if (err)
|
||||
return err;
|
||||
} else if (tk == TK_COMMA) {
|
||||
// We don't add it to the base list if it's generic
|
||||
generic = true;
|
||||
tk = get_token();
|
||||
}
|
||||
|
||||
if (tk == TK_COMMA) {
|
||||
Error err = _parse_class_base(r_base);
|
||||
if (err)
|
||||
return err;
|
||||
r_base.push_back(name);
|
||||
} else if (tk == TK_IDENTIFIER && String(value) == "where") {
|
||||
Error err = _parse_type_constraints();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// An open curly bracket was parsed by _parse_type_constraints, so we can exit
|
||||
} else if (tk == TK_CURLY_BRACKET_OPEN) {
|
||||
r_base.push_back(name);
|
||||
// we are finished when we hit the open curly bracket
|
||||
} else {
|
||||
error_str = "Unexpected token: " + get_token_name(tk);
|
||||
error = true;
|
||||
return ERR_PARSE_ERROR;
|
||||
}
|
||||
|
||||
if (!generic) {
|
||||
r_base.push_back(name);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Error ScriptClassParser::_parse_type_constraints() {
|
||||
Token tk = get_token();
|
||||
if (tk != TK_IDENTIFIER) {
|
||||
error_str = "Unexpected token: " + get_token_name(tk);
|
||||
error = true;
|
||||
return ERR_PARSE_ERROR;
|
||||
}
|
||||
|
||||
tk = get_token();
|
||||
if (tk != TK_COLON) {
|
||||
error_str = "Unexpected token: " + get_token_name(tk);
|
||||
error = true;
|
||||
return ERR_PARSE_ERROR;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
tk = get_token();
|
||||
if (tk == TK_IDENTIFIER) {
|
||||
if (String(value) == "where") {
|
||||
return _parse_type_constraints();
|
||||
}
|
||||
|
||||
tk = get_token();
|
||||
if (tk == TK_PERIOD) {
|
||||
while (true) {
|
||||
tk = get_token();
|
||||
|
||||
if (tk != TK_IDENTIFIER) {
|
||||
error_str = "Expected " + get_token_name(TK_IDENTIFIER) + ", found: " + get_token_name(tk);
|
||||
error = true;
|
||||
return ERR_PARSE_ERROR;
|
||||
}
|
||||
|
||||
tk = get_token();
|
||||
|
||||
if (tk != TK_PERIOD)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tk == TK_COMMA) {
|
||||
continue;
|
||||
} else if (tk == TK_IDENTIFIER && String(value) == "where") {
|
||||
return _parse_type_constraints();
|
||||
} else if (tk == TK_SYMBOL && String(value) == "(") {
|
||||
tk = get_token();
|
||||
if (tk != TK_SYMBOL || String(value) != ")") {
|
||||
error_str = "Unexpected token: " + get_token_name(tk);
|
||||
error = true;
|
||||
return ERR_PARSE_ERROR;
|
||||
}
|
||||
} else if (tk == TK_OP_LESS) {
|
||||
Error err = _skip_generic_type_params();
|
||||
if (err)
|
||||
return err;
|
||||
} else if (tk == TK_CURLY_BRACKET_OPEN) {
|
||||
return OK;
|
||||
} else {
|
||||
error_str = "Unexpected token: " + get_token_name(tk);
|
||||
error = true;
|
||||
return ERR_PARSE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Error ScriptClassParser::_parse_namespace_name(String &r_name, int &r_curly_stack) {
|
||||
|
||||
Token tk = get_token();
|
||||
|
@ -425,6 +508,16 @@ Error ScriptClassParser::parse(const String &p_code) {
|
|||
Error err = _skip_generic_type_params();
|
||||
if (err)
|
||||
return err;
|
||||
} else if (tk == TK_IDENTIFIER && String(value) == "where") {
|
||||
Error err = _parse_type_constraints();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// An open curly bracket was parsed by _parse_type_constraints, so we can exit
|
||||
curly_stack++;
|
||||
type_curly_stack++;
|
||||
break;
|
||||
} else {
|
||||
error_str = "Unexpected token: " + get_token_name(tk);
|
||||
error = true;
|
||||
|
|
|
@ -65,6 +65,7 @@ private:
|
|||
|
||||
Error _parse_type_full_name(String &r_full_name);
|
||||
Error _parse_class_base(Vector<String> &r_base);
|
||||
Error _parse_type_constraints();
|
||||
Error _parse_namespace_name(String &r_name, int &r_curly_stack);
|
||||
|
||||
public:
|
||||
|
|
Loading…
Reference in a new issue