Skip to content

Commit 7a9ebeb

Browse files
committed
Fix standalone literals and identifier statements
1 parent 9d316f6 commit 7a9ebeb

File tree

3 files changed

+84
-13
lines changed

3 files changed

+84
-13
lines changed

modules/gdscript/gdscript_editor.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5206,6 +5206,29 @@ ::Error GDScriptLanguage::refactor_rename_symbol_code(const String &p_code, cons
52065206
Error signal_err = _refactor_rename_symbol_match_from_class(context, symbol, p_path, base_type.script_path, p_unsaved_scripts_source_code, r_result, RefactorRenameSymbolDefinintionType::REFACTOR_RENAME_SYMBOL_DEFINITION_TYPE_SIGNAL, signal_node);
52075207
REFACTOR_RENAME_RETURN(signal_err);
52085208
} break;
5209+
case GDScriptParser::REFACTOR_RENAME_TYPE_IDENTIFIER: {
5210+
if (context.node->type != GDScriptParser::Node::IDENTIFIER) {
5211+
REFACTOR_RENAME_RETURN(ERR_CANT_RESOLVE);
5212+
}
5213+
5214+
GDScriptParser::DataType base_type;
5215+
if (context.current_class) {
5216+
if (context.type != GDScriptParser::REFACTOR_RENAME_TYPE_SUPER_METHOD) {
5217+
base_type = context.current_class->get_datatype();
5218+
} else {
5219+
base_type = context.current_class->base_type;
5220+
}
5221+
} else {
5222+
REFACTOR_RENAME_RETURN(ERR_CANT_RESOLVE);
5223+
}
5224+
5225+
Error identifier_err = _refactor_rename_symbol_from_base(context, base_type, symbol, p_path, base_type.script_path, p_owner, p_unsaved_scripts_source_code, r_result);
5226+
REFACTOR_RENAME_RETURN(identifier_err);
5227+
} break;
5228+
case GDScriptParser::REFACTOR_RENAME_TYPE_LITERAL: {
5229+
REFACTOR_RENAME_OUTSIDE_GDSCRIPT(REFACTOR_RENAME_SYMBOL_RESULT_LITERAL);
5230+
REFACTOR_RENAME_RETURN(OK);
5231+
} break;
52095232
default: {
52105233
REFACTOR_RENAME_RETURN(ERR_CANT_RESOLVE);
52115234
}

modules/gdscript/gdscript_parser.cpp

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,11 @@ void GDScriptParser::set_last_completion_call_arg(int p_argument) {
395395
completion_call_stack.back()->get().argument = p_argument;
396396
}
397397

398+
bool GDScriptParser::refactor_rename_is_cursor_between_tokens(const GDScriptTokenizer::Token &p_token_start, const GDScriptTokenizer::Token &p_token_end) const {
399+
GDScriptTokenizer::CodeArea enum_code_area(p_token_start.get_code_area().start, p_token_end.get_code_area().end);
400+
return enum_code_area.contains(GDScriptTokenizer::LineColumn(tokenizer->get_cursor_line(), tokenizer->get_cursor_column()));
401+
}
402+
398403
bool GDScriptParser::refactor_rename_does_node_contains_cursor(const GDScriptParser::Node *p_node) const {
399404
ERR_FAIL_NULL_V(p_node, false);
400405
GDScriptTokenizer::CodeArea node_code_area = p_node->get_code_area();
@@ -463,6 +468,19 @@ bool GDScriptParser::refactor_rename_register(GDScriptParser::RefactorRenameType
463468
return true;
464469
}
465470

471+
bool GDScriptParser::refactor_rename_register_if_cursor_is_between_tokens(GDScriptParser::RefactorRenameType p_type, GDScriptParser::Node *p_node, const GDScriptTokenizer::Token &p_token_start, const GDScriptTokenizer::Token &p_token_end) {
472+
if (!is_for_refactor_rename()) {
473+
return false;
474+
}
475+
if (refactor_rename_context.node != nullptr && refactor_rename_context.node->is_owned_by(p_node)) {
476+
return false;
477+
}
478+
if (!refactor_rename_is_cursor_between_tokens(p_token_start, p_token_end)) {
479+
return false;
480+
}
481+
return refactor_rename_register(p_type, p_node, false);
482+
}
483+
466484
bool GDScriptParser::refactor_rename_register_identifier(GDScriptParser::IdentifierNode *p_identifier) {
467485
if (!is_for_refactor_rename()) {
468486
return false;
@@ -1597,9 +1615,11 @@ GDScriptParser::ParameterNode *GDScriptParser::parse_parameter() {
15971615
return nullptr;
15981616
}
15991617

1618+
GDScriptTokenizer::Token token_start = previous;
1619+
16001620
ParameterNode *parameter = alloc_node<ParameterNode>();
16011621
push_owner(parameter);
1602-
refactor_rename_register(REFACTOR_RENAME_TYPE_PARAMETER, parameter);
1622+
refactor_rename_register_if_cursor_is_between_tokens(REFACTOR_RENAME_TYPE_PARAMETER, parameter, previous, current);
16031623
parameter->identifier = parse_identifier();
16041624

16051625
if (match(GDScriptTokenizer::Token::COLON)) {
@@ -1615,13 +1635,16 @@ GDScriptParser::ParameterNode *GDScriptParser::parse_parameter() {
16151635

16161636
if (match(GDScriptTokenizer::Token::EQUAL)) {
16171637
// Default value.
1618-
parameter->initializer = parse_expression(false);
16191638
refactor_rename_register(REFACTOR_RENAME_TYPE_PARAMETER_INITIALIZER, parameter->initializer);
1639+
parameter->initializer = parse_expression(false);
16201640
}
16211641

16221642
complete_extents(parameter);
16231643
pop_owner(parameter);
16241644

1645+
GDScriptTokenizer::Token token_end = previous;
1646+
refactor_rename_register_if_cursor_is_between_tokens(REFACTOR_RENAME_TYPE_PARAMETER, parameter, token_start, token_end);
1647+
16251648
return parameter;
16261649
}
16271650

@@ -1631,11 +1654,7 @@ GDScriptParser::SignalNode *GDScriptParser::parse_signal(bool p_is_static) {
16311654
SignalNode *signal = alloc_node<SignalNode>();
16321655
push_owner(signal);
16331656

1634-
if (is_for_refactor_rename()) {
1635-
if (previous.has_cursor() || current.has_cursor() || !tokenizer->is_past_cursor()) {
1636-
refactor_rename_register(REFACTOR_RENAME_TYPE_SIGNAL, signal, false);
1637-
}
1638-
}
1657+
refactor_rename_register_if_cursor_is_between_tokens(REFACTOR_RENAME_TYPE_SIGNAL, signal, previous, current);
16391658

16401659
if (!consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected signal name after "signal".)")) {
16411660
complete_extents(signal);
@@ -1680,12 +1699,7 @@ GDScriptParser::SignalNode *GDScriptParser::parse_signal(bool p_is_static) {
16801699
end_statement("signal declaration");
16811700

16821701
GDScriptTokenizer::Token signal_end_token = previous;
1683-
if (is_for_refactor_rename()) {
1684-
GDScriptTokenizer::CodeArea enum_code_area(signal_start_token.get_code_area().start, signal_end_token.get_code_area().end);
1685-
if (enum_code_area.contains(GDScriptTokenizer::LineColumn(tokenizer->get_cursor_line(), tokenizer->get_cursor_column()))) {
1686-
refactor_rename_register(REFACTOR_RENAME_TYPE_SIGNAL, signal, false);
1687-
}
1688-
}
1702+
refactor_rename_register_if_cursor_is_between_tokens(REFACTOR_RENAME_TYPE_SIGNAL, signal, signal_start_token, signal_end_token);
16891703

16901704
return signal;
16911705
}
@@ -2115,7 +2129,11 @@ GDScriptParser::SuiteNode *GDScriptParser::parse_suite(const String &p_context,
21152129
if (is_at_end() || (!multiline && previous.type == GDScriptTokenizer::Token::SEMICOLON && check(GDScriptTokenizer::Token::NEWLINE))) {
21162130
break;
21172131
}
2132+
2133+
GDScriptTokenizer::Token statement_start = current;
21182134
Node *statement = parse_statement();
2135+
GDScriptTokenizer::Token statement_end = previous;
2136+
21192137
if (statement == nullptr) {
21202138
if (error_count++ > 100) {
21212139
push_error("Too many statement errors.", suite);
@@ -2125,6 +2143,32 @@ GDScriptParser::SuiteNode *GDScriptParser::parse_suite(const String &p_context,
21252143
}
21262144
suite->statements.push_back(statement);
21272145

2146+
if (is_for_refactor_rename() && refactor_rename_is_cursor_between_tokens(statement_start, statement_end)) {
2147+
if (statement->type == GDScriptParser::Node::IDENTIFIER) {
2148+
// The statement is a naked identifier.
2149+
refactor_rename_register(REFACTOR_RENAME_TYPE_IDENTIFIER, statement, false);
2150+
GDScriptTokenizer::Token before_token = get_token(tokenizer->get_cursor_line(), tokenizer->get_cursor_column() - 1);
2151+
GDScriptTokenizer::Token after_token = get_token(tokenizer->get_cursor_line(), tokenizer->get_cursor_column());
2152+
if (before_token == after_token || statement->get_code_area() == before_token.get_code_area()) {
2153+
refactor_rename_context.token = before_token;
2154+
} else {
2155+
refactor_rename_context.token = after_token;
2156+
}
2157+
} else if (statement->type == GDScriptParser::Node::LITERAL) {
2158+
// The statement is a naked literal.
2159+
refactor_rename_register(REFACTOR_RENAME_TYPE_LITERAL, statement, false);
2160+
GDScriptTokenizer::Token before_token = get_token(tokenizer->get_cursor_line(), tokenizer->get_cursor_column() - 1);
2161+
GDScriptTokenizer::Token after_token = get_token(tokenizer->get_cursor_line(), tokenizer->get_cursor_column());
2162+
if (before_token == after_token || statement->get_code_area() == before_token.get_code_area()) {
2163+
refactor_rename_context.token = before_token;
2164+
} else {
2165+
refactor_rename_context.token = after_token;
2166+
}
2167+
} else if (!refactor_rename_context.node->is_owned_by(statement)) {
2168+
refactor_rename_register(RETACTOR_RENAME_TYPE_STATEMENT, suite, false);
2169+
}
2170+
}
2171+
21282172
// Register locals.
21292173
switch (statement->type) {
21302174
case Node::VARIABLE: {

modules/gdscript/gdscript_parser.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,8 +1741,10 @@ class GDScriptParser {
17411741
REFACTOR_RENAME_TYPE_DICTIONARY, // Dictionary content.
17421742
REFACTOR_RENAME_TYPE_ENUM, // Enum content.
17431743
REFACTOR_RENAME_TYPE_GET_NODE, // Get node with $ notation.
1744+
REFACTOR_RENAME_TYPE_IDENTIFIER, // Rare. Context when it's a naked identifier, nothing else.
17441745
REFACTOR_RENAME_TYPE_INHERIT_TYPE, // Type after extends. Exclude non-viable types (built-ins, enums, void). Includes subtypes using the argument index.
17451746
REFACTOR_RENAME_TYPE_KEYWORD, // Keyword (e.g. class_name).
1747+
REFACTOR_RENAME_TYPE_LITERAL, // Rare. Context when it's a naked literal, nothing else.
17461748
REFACTOR_RENAME_TYPE_LOAD, // For load/preload.
17471749
REFACTOR_RENAME_TYPE_METHOD, // List available methods in scope.
17481750
REFACTOR_RENAME_TYPE_OVERRIDE_METHOD, // Override implementation, also for native virtuals.
@@ -1752,6 +1754,7 @@ class GDScriptParser {
17521754
REFACTOR_RENAME_TYPE_PROPERTY_DECLARATION_OR_TYPE, // Property declaration (get, set) or a type hint.
17531755
REFACTOR_RENAME_TYPE_PROPERTY_METHOD, // Property setter or getter (list available methods).
17541756
REFACTOR_RENAME_TYPE_SIGNAL, // Signal.
1757+
REFACTOR_RENAME_TYPE_STATEMENT, // Inside a statement. Shouldn't come up often, more for debugging purposes.
17551758
REFACTOR_RENAME_TYPE_SUBSCRIPT, // Inside id[|].
17561759
REFACTOR_RENAME_TYPE_SUPER_METHOD, // After super.
17571760
REFACTOR_RENAME_TYPE_TYPE_ATTRIBUTE, // Attribute in type name (Type.|).
@@ -1969,6 +1972,7 @@ class GDScriptParser {
19691972
bool refactor_rename_was_cursor_just_parsed() const;
19701973
bool refactor_rename_is_node_more_specific(const GDScriptParser::Node *p_node) const;
19711974
bool refactor_rename_register(GDScriptParser::RefactorRenameType p_type, GDScriptParser::Node *p_node, bool p_check_for_cursor = true);
1975+
bool refactor_rename_register_if_cursor_is_between_tokens(GDScriptParser::RefactorRenameType p_type, GDScriptParser::Node *p_node, const GDScriptTokenizer::Token &p_start, const GDScriptTokenizer::Token &p_end);
19721976
bool refactor_rename_register_identifier(GDScriptParser::IdentifierNode *p_node);
19731977
bool refactor_rename_register_literal(GDScriptParser::LiteralNode *p_node);
19741978

0 commit comments

Comments
 (0)