Merge pull request #48804 from EricEzaM/scripting-multi-error-support
Added support for scripts reporting multiple errors to ScriptTextEditor
This commit is contained in:
commit
9b7c963d19
@ -268,6 +268,12 @@ public:
|
|||||||
String message;
|
String message;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ScriptError {
|
||||||
|
int line = -1;
|
||||||
|
int column = -1;
|
||||||
|
String message;
|
||||||
|
};
|
||||||
|
|
||||||
void get_core_type_words(List<String> *p_core_type_words) const;
|
void get_core_type_words(List<String> *p_core_type_words) const;
|
||||||
virtual void get_reserved_words(List<String> *p_words) const = 0;
|
virtual void get_reserved_words(List<String> *p_words) const = 0;
|
||||||
virtual bool is_control_flow_keyword(String p_string) const = 0;
|
virtual bool is_control_flow_keyword(String p_string) const = 0;
|
||||||
@ -276,7 +282,7 @@ public:
|
|||||||
virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const = 0;
|
virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const = 0;
|
||||||
virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) {}
|
virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) {}
|
||||||
virtual bool is_using_templates() { return false; }
|
virtual bool is_using_templates() { return false; }
|
||||||
virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = nullptr, List<Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const = 0;
|
virtual bool validate(const String &p_script, const String &p_path = "", List<String> *r_functions = nullptr, List<ScriptError> *r_errors = nullptr, List<Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const = 0;
|
||||||
virtual String validate_path(const String &p_path) const { return ""; }
|
virtual String validate_path(const String &p_path) const { return ""; }
|
||||||
virtual Script *create_script() const = 0;
|
virtual Script *create_script() const = 0;
|
||||||
virtual bool has_named_classes() const = 0;
|
virtual bool has_named_classes() const = 0;
|
||||||
|
@ -1612,15 +1612,19 @@ void CodeTextEditor::validate_script() {
|
|||||||
idle->start();
|
idle->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeTextEditor::_warning_label_gui_input(const Ref<InputEvent> &p_event) {
|
void CodeTextEditor::_error_button_pressed() {
|
||||||
Ref<InputEventMouseButton> mb = p_event;
|
_set_show_errors_panel(!is_errors_panel_opened);
|
||||||
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
|
_set_show_warnings_panel(false);
|
||||||
_warning_button_pressed();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeTextEditor::_warning_button_pressed() {
|
void CodeTextEditor::_warning_button_pressed() {
|
||||||
_set_show_warnings_panel(!is_warnings_panel_opened);
|
_set_show_warnings_panel(!is_warnings_panel_opened);
|
||||||
|
_set_show_errors_panel(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CodeTextEditor::_set_show_errors_panel(bool p_show) {
|
||||||
|
is_errors_panel_opened = p_show;
|
||||||
|
emit_signal("show_errors_panel", p_show);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeTextEditor::_set_show_warnings_panel(bool p_show) {
|
void CodeTextEditor::_set_show_warnings_panel(bool p_show) {
|
||||||
@ -1653,6 +1657,7 @@ void CodeTextEditor::_notification(int p_what) {
|
|||||||
_update_font();
|
_update_font();
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_ENTER_TREE: {
|
case NOTIFICATION_ENTER_TREE: {
|
||||||
|
error_button->set_icon(get_theme_icon("StatusError", "EditorIcons"));
|
||||||
warning_button->set_icon(get_theme_icon("NodeWarning", "EditorIcons"));
|
warning_button->set_icon(get_theme_icon("NodeWarning", "EditorIcons"));
|
||||||
add_theme_constant_override("separation", 4 * EDSCALE);
|
add_theme_constant_override("separation", 4 * EDSCALE);
|
||||||
} break;
|
} break;
|
||||||
@ -1667,11 +1672,18 @@ void CodeTextEditor::_notification(int p_what) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeTextEditor::set_warning_nb(int p_warning_nb) {
|
void CodeTextEditor::set_error_count(int p_error_count) {
|
||||||
warning_count_label->set_text(itos(p_warning_nb));
|
error_button->set_text(itos(p_error_count));
|
||||||
warning_count_label->set_visible(p_warning_nb > 0);
|
error_button->set_visible(p_error_count > 0);
|
||||||
warning_button->set_visible(p_warning_nb > 0);
|
if (!p_error_count) {
|
||||||
if (!p_warning_nb) {
|
_set_show_errors_panel(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CodeTextEditor::set_warning_count(int p_warning_count) {
|
||||||
|
warning_button->set_text(itos(p_warning_count));
|
||||||
|
warning_button->set_visible(p_warning_count > 0);
|
||||||
|
if (!p_warning_count) {
|
||||||
_set_show_warnings_panel(false);
|
_set_show_warnings_panel(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1738,6 +1750,7 @@ void CodeTextEditor::_bind_methods() {
|
|||||||
|
|
||||||
ADD_SIGNAL(MethodInfo("validate_script"));
|
ADD_SIGNAL(MethodInfo("validate_script"));
|
||||||
ADD_SIGNAL(MethodInfo("load_theme_settings"));
|
ADD_SIGNAL(MethodInfo("load_theme_settings"));
|
||||||
|
ADD_SIGNAL(MethodInfo("show_errors_panel"));
|
||||||
ADD_SIGNAL(MethodInfo("show_warnings_panel"));
|
ADD_SIGNAL(MethodInfo("show_warnings_panel"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1835,6 +1848,22 @@ CodeTextEditor::CodeTextEditor() {
|
|||||||
error->set_mouse_filter(MOUSE_FILTER_STOP);
|
error->set_mouse_filter(MOUSE_FILTER_STOP);
|
||||||
error->connect("gui_input", callable_mp(this, &CodeTextEditor::_error_pressed));
|
error->connect("gui_input", callable_mp(this, &CodeTextEditor::_error_pressed));
|
||||||
|
|
||||||
|
// Errors
|
||||||
|
error_button = memnew(Button);
|
||||||
|
error_button->set_flat(true);
|
||||||
|
status_bar->add_child(error_button);
|
||||||
|
error_button->set_v_size_flags(SIZE_EXPAND | SIZE_SHRINK_CENTER);
|
||||||
|
error_button->set_default_cursor_shape(CURSOR_POINTING_HAND);
|
||||||
|
error_button->connect("pressed", callable_mp(this, &CodeTextEditor::_error_button_pressed));
|
||||||
|
error_button->set_tooltip(TTR("Errors"));
|
||||||
|
|
||||||
|
error_button->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color("error_color", "Editor"));
|
||||||
|
error_button->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font("status_source", "EditorFonts"));
|
||||||
|
error_button->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size("status_source_size", "EditorFonts"));
|
||||||
|
|
||||||
|
is_errors_panel_opened = false;
|
||||||
|
set_error_count(0);
|
||||||
|
|
||||||
// Warnings
|
// Warnings
|
||||||
warning_button = memnew(Button);
|
warning_button = memnew(Button);
|
||||||
warning_button->set_flat(true);
|
warning_button->set_flat(true);
|
||||||
@ -1844,20 +1873,12 @@ CodeTextEditor::CodeTextEditor() {
|
|||||||
warning_button->connect("pressed", callable_mp(this, &CodeTextEditor::_warning_button_pressed));
|
warning_button->connect("pressed", callable_mp(this, &CodeTextEditor::_warning_button_pressed));
|
||||||
warning_button->set_tooltip(TTR("Warnings"));
|
warning_button->set_tooltip(TTR("Warnings"));
|
||||||
|
|
||||||
warning_count_label = memnew(Label);
|
warning_button->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color("warning_color", "Editor"));
|
||||||
status_bar->add_child(warning_count_label);
|
warning_button->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font("status_source", "EditorFonts"));
|
||||||
warning_count_label->set_v_size_flags(SIZE_EXPAND | SIZE_SHRINK_CENTER);
|
warning_button->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size("status_source_size", "EditorFonts"));
|
||||||
warning_count_label->set_align(Label::ALIGN_RIGHT);
|
|
||||||
warning_count_label->set_default_cursor_shape(CURSOR_POINTING_HAND);
|
|
||||||
warning_count_label->set_mouse_filter(MOUSE_FILTER_STOP);
|
|
||||||
warning_count_label->set_tooltip(TTR("Warnings"));
|
|
||||||
warning_count_label->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color("warning_color", "Editor"));
|
|
||||||
warning_count_label->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font("status_source", "EditorFonts"));
|
|
||||||
warning_count_label->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size("status_source_size", "EditorFonts"));
|
|
||||||
warning_count_label->connect("gui_input", callable_mp(this, &CodeTextEditor::_warning_label_gui_input));
|
|
||||||
|
|
||||||
is_warnings_panel_opened = false;
|
is_warnings_panel_opened = false;
|
||||||
set_warning_nb(0);
|
set_warning_count(0);
|
||||||
|
|
||||||
// Line and column
|
// Line and column
|
||||||
line_and_col_txt = memnew(Label);
|
line_and_col_txt = memnew(Label);
|
||||||
|
@ -145,8 +145,8 @@ class CodeTextEditor : public VBoxContainer {
|
|||||||
HBoxContainer *status_bar;
|
HBoxContainer *status_bar;
|
||||||
|
|
||||||
Button *toggle_scripts_button;
|
Button *toggle_scripts_button;
|
||||||
|
Button *error_button;
|
||||||
Button *warning_button;
|
Button *warning_button;
|
||||||
Label *warning_count_label;
|
|
||||||
|
|
||||||
Label *line_and_col_txt;
|
Label *line_and_col_txt;
|
||||||
|
|
||||||
@ -184,8 +184,9 @@ class CodeTextEditor : public VBoxContainer {
|
|||||||
CodeTextEditorCodeCompleteFunc code_complete_func;
|
CodeTextEditorCodeCompleteFunc code_complete_func;
|
||||||
void *code_complete_ud;
|
void *code_complete_ud;
|
||||||
|
|
||||||
void _warning_label_gui_input(const Ref<InputEvent> &p_event);
|
void _error_button_pressed();
|
||||||
void _warning_button_pressed();
|
void _warning_button_pressed();
|
||||||
|
void _set_show_errors_panel(bool p_show);
|
||||||
void _set_show_warnings_panel(bool p_show);
|
void _set_show_warnings_panel(bool p_show);
|
||||||
void _error_pressed(const Ref<InputEvent> &p_event);
|
void _error_pressed(const Ref<InputEvent> &p_event);
|
||||||
|
|
||||||
@ -205,6 +206,7 @@ protected:
|
|||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
bool is_warnings_panel_opened;
|
bool is_warnings_panel_opened;
|
||||||
|
bool is_errors_panel_opened;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void trim_trailing_whitespace();
|
void trim_trailing_whitespace();
|
||||||
@ -238,7 +240,8 @@ public:
|
|||||||
Variant get_edit_state();
|
Variant get_edit_state();
|
||||||
void set_edit_state(const Variant &p_state);
|
void set_edit_state(const Variant &p_state);
|
||||||
|
|
||||||
void set_warning_nb(int p_warning_nb);
|
void set_error_count(int p_error_count);
|
||||||
|
void set_warning_count(int p_warning_count);
|
||||||
|
|
||||||
void update_editor_settings();
|
void update_editor_settings();
|
||||||
void set_error(const String &p_error);
|
void set_error(const String &p_error);
|
||||||
|
@ -109,13 +109,11 @@ ConnectionInfoDialog::ConnectionInfoDialog() {
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Vector<String> ScriptTextEditor::get_functions() {
|
Vector<String> ScriptTextEditor::get_functions() {
|
||||||
String errortxt;
|
|
||||||
int line = -1, col;
|
|
||||||
CodeEdit *te = code_editor->get_text_editor();
|
CodeEdit *te = code_editor->get_text_editor();
|
||||||
String text = te->get_text();
|
String text = te->get_text();
|
||||||
List<String> fnc;
|
List<String> fnc;
|
||||||
|
|
||||||
if (script->get_language()->validate(text, line, col, errortxt, script->get_path(), &fnc)) {
|
if (script->get_language()->validate(text, script->get_path(), &fnc)) {
|
||||||
//if valid rewrite functions to latest
|
//if valid rewrite functions to latest
|
||||||
functions.clear();
|
functions.clear();
|
||||||
for (List<String>::Element *E = fnc.front(); E; E = E->next()) {
|
for (List<String>::Element *E = fnc.front(); E; E = E->next()) {
|
||||||
@ -265,6 +263,10 @@ void ScriptTextEditor::_set_theme_for_script() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScriptTextEditor::_show_errors_panel(bool p_show) {
|
||||||
|
errors_panel->set_visible(p_show);
|
||||||
|
}
|
||||||
|
|
||||||
void ScriptTextEditor::_show_warnings_panel(bool p_show) {
|
void ScriptTextEditor::_show_warnings_panel(bool p_show) {
|
||||||
warnings_panel->set_visible(p_show);
|
warnings_panel->set_visible(p_show);
|
||||||
}
|
}
|
||||||
@ -279,6 +281,12 @@ void ScriptTextEditor::_warning_clicked(Variant p_line) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScriptTextEditor::_error_clicked(Variant p_line) {
|
||||||
|
if (p_line.get_type() == Variant::INT) {
|
||||||
|
code_editor->get_text_editor()->cursor_set_line(p_line.operator int64_t());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ScriptTextEditor::reload_text() {
|
void ScriptTextEditor::reload_text() {
|
||||||
ERR_FAIL_COND(script.is_null());
|
ERR_FAIL_COND(script.is_null());
|
||||||
|
|
||||||
@ -429,23 +437,21 @@ Ref<Texture2D> ScriptTextEditor::get_theme_icon() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ScriptTextEditor::_validate_script() {
|
void ScriptTextEditor::_validate_script() {
|
||||||
String errortxt;
|
|
||||||
int line = -1, col;
|
|
||||||
CodeEdit *te = code_editor->get_text_editor();
|
CodeEdit *te = code_editor->get_text_editor();
|
||||||
|
|
||||||
String text = te->get_text();
|
String text = te->get_text();
|
||||||
List<String> fnc;
|
List<String> fnc;
|
||||||
Set<int> safe_lines;
|
Set<int> safe_lines;
|
||||||
List<ScriptLanguage::Warning> warnings;
|
List<ScriptLanguage::Warning> warnings;
|
||||||
|
List<ScriptLanguage::ScriptError> errors;
|
||||||
|
|
||||||
if (!script->get_language()->validate(text, line, col, errortxt, script->get_path(), &fnc, &warnings, &safe_lines)) {
|
if (!script->get_language()->validate(text, script->get_path(), &fnc, &errors, &warnings, &safe_lines)) {
|
||||||
String error_text = "error(" + itos(line) + "," + itos(col) + "): " + errortxt;
|
String error_text = TTR("Error at ") + "(" + itos(errors[0].line) + "," + itos(errors[0].column) + "): " + errors[0].message;
|
||||||
code_editor->set_error(error_text);
|
code_editor->set_error(error_text);
|
||||||
code_editor->set_error_pos(line - 1, col - 1);
|
code_editor->set_error_pos(errors[0].line - 1, errors[0].column - 1);
|
||||||
script_is_valid = false;
|
script_is_valid = false;
|
||||||
} else {
|
} else {
|
||||||
code_editor->set_error("");
|
code_editor->set_error("");
|
||||||
line = -1;
|
|
||||||
if (!script->is_tool()) {
|
if (!script->is_tool()) {
|
||||||
script->set_source_code(text);
|
script->set_source_code(text);
|
||||||
script->update_exports();
|
script->update_exports();
|
||||||
@ -487,7 +493,8 @@ void ScriptTextEditor::_validate_script() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
code_editor->set_warning_nb(warning_nb);
|
code_editor->set_error_count(errors.size());
|
||||||
|
code_editor->set_warning_count(warning_nb);
|
||||||
|
|
||||||
// Add script warnings.
|
// Add script warnings.
|
||||||
warnings_panel->push_table(3);
|
warnings_panel->push_table(3);
|
||||||
@ -521,11 +528,40 @@ void ScriptTextEditor::_validate_script() {
|
|||||||
}
|
}
|
||||||
warnings_panel->pop(); // Table.
|
warnings_panel->pop(); // Table.
|
||||||
|
|
||||||
line--;
|
errors_panel->clear();
|
||||||
|
errors_panel->push_table(2);
|
||||||
|
for (List<ScriptLanguage::ScriptError>::Element *E = errors.front(); E; E = E->next()) {
|
||||||
|
ScriptLanguage::ScriptError err = E->get();
|
||||||
|
|
||||||
|
errors_panel->push_cell();
|
||||||
|
errors_panel->push_meta(err.line - 1);
|
||||||
|
errors_panel->push_color(warnings_panel->get_theme_color("error_color", "Editor"));
|
||||||
|
errors_panel->add_text(TTR("Line") + " " + itos(err.line) + ":");
|
||||||
|
errors_panel->pop(); // Color.
|
||||||
|
errors_panel->pop(); // Meta goto.
|
||||||
|
errors_panel->pop(); // Cell.
|
||||||
|
|
||||||
|
errors_panel->push_cell();
|
||||||
|
errors_panel->add_text(err.message);
|
||||||
|
errors_panel->pop(); // Cell.
|
||||||
|
}
|
||||||
|
errors_panel->pop(); // Table
|
||||||
|
|
||||||
bool highlight_safe = EDITOR_DEF("text_editor/highlighting/highlight_type_safe_lines", true);
|
bool highlight_safe = EDITOR_DEF("text_editor/highlighting/highlight_type_safe_lines", true);
|
||||||
bool last_is_safe = false;
|
bool last_is_safe = false;
|
||||||
for (int i = 0; i < te->get_line_count(); i++) {
|
for (int i = 0; i < te->get_line_count(); i++) {
|
||||||
te->set_line_background_color(i, (line == i) ? marked_line_color : Color(0, 0, 0, 0));
|
if (errors.is_empty()) {
|
||||||
|
te->set_line_background_color(i, Color(0, 0, 0, 0));
|
||||||
|
} else {
|
||||||
|
for (List<ScriptLanguage::ScriptError>::Element *E = errors.front(); E; E = E->next()) {
|
||||||
|
bool error_line = i == E->get().line - 1;
|
||||||
|
te->set_line_background_color(i, error_line ? marked_line_color : Color(0, 0, 0, 0));
|
||||||
|
if (error_line) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (highlight_safe) {
|
if (highlight_safe) {
|
||||||
if (safe_lines.has(i + 1)) {
|
if (safe_lines.has(i + 1)) {
|
||||||
te->set_line_gutter_item_color(i, line_number_gutter, safe_line_number_color);
|
te->set_line_gutter_item_color(i, line_number_gutter, safe_line_number_color);
|
||||||
@ -537,7 +573,7 @@ void ScriptTextEditor::_validate_script() {
|
|||||||
last_is_safe = false;
|
last_is_safe = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
te->set_line_gutter_item_color(line, 1, default_line_number_color);
|
te->set_line_gutter_item_color(i, 1, default_line_number_color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1675,6 +1711,7 @@ void ScriptTextEditor::_enable_code_editor() {
|
|||||||
editor_box->set_v_size_flags(SIZE_EXPAND_FILL);
|
editor_box->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
|
||||||
editor_box->add_child(code_editor);
|
editor_box->add_child(code_editor);
|
||||||
|
code_editor->connect("show_errors_panel", callable_mp(this, &ScriptTextEditor::_show_errors_panel));
|
||||||
code_editor->connect("show_warnings_panel", callable_mp(this, &ScriptTextEditor::_show_warnings_panel));
|
code_editor->connect("show_warnings_panel", callable_mp(this, &ScriptTextEditor::_show_warnings_panel));
|
||||||
code_editor->connect("validate_script", callable_mp(this, &ScriptTextEditor::_validate_script));
|
code_editor->connect("validate_script", callable_mp(this, &ScriptTextEditor::_validate_script));
|
||||||
code_editor->connect("load_theme_settings", callable_mp(this, &ScriptTextEditor::_load_theme_settings));
|
code_editor->connect("load_theme_settings", callable_mp(this, &ScriptTextEditor::_load_theme_settings));
|
||||||
@ -1695,6 +1732,13 @@ void ScriptTextEditor::_enable_code_editor() {
|
|||||||
"normal_font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size("main_size", "EditorFonts"));
|
"normal_font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size("main_size", "EditorFonts"));
|
||||||
warnings_panel->connect("meta_clicked", callable_mp(this, &ScriptTextEditor::_warning_clicked));
|
warnings_panel->connect("meta_clicked", callable_mp(this, &ScriptTextEditor::_warning_clicked));
|
||||||
|
|
||||||
|
editor_box->add_child(errors_panel);
|
||||||
|
errors_panel->add_theme_font_override(
|
||||||
|
"normal_font", EditorNode::get_singleton()->get_gui_base()->get_theme_font("main", "EditorFonts"));
|
||||||
|
errors_panel->add_theme_font_size_override(
|
||||||
|
"normal_font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size("main_size", "EditorFonts"));
|
||||||
|
errors_panel->connect("meta_clicked", callable_mp(this, &ScriptTextEditor::_error_clicked));
|
||||||
|
|
||||||
add_child(context_menu);
|
add_child(context_menu);
|
||||||
context_menu->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_edit_option));
|
context_menu->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_edit_option));
|
||||||
|
|
||||||
@ -1826,6 +1870,14 @@ ScriptTextEditor::ScriptTextEditor() {
|
|||||||
warnings_panel->set_focus_mode(FOCUS_CLICK);
|
warnings_panel->set_focus_mode(FOCUS_CLICK);
|
||||||
warnings_panel->hide();
|
warnings_panel->hide();
|
||||||
|
|
||||||
|
errors_panel = memnew(RichTextLabel);
|
||||||
|
errors_panel->set_custom_minimum_size(Size2(0, 100 * EDSCALE));
|
||||||
|
errors_panel->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
errors_panel->set_meta_underline(true);
|
||||||
|
errors_panel->set_selection_enabled(true);
|
||||||
|
errors_panel->set_focus_mode(FOCUS_CLICK);
|
||||||
|
errors_panel->hide();
|
||||||
|
|
||||||
update_settings();
|
update_settings();
|
||||||
|
|
||||||
code_editor->get_text_editor()->set_code_hint_draw_below(EditorSettings::get_singleton()->get("text_editor/completion/put_callhint_tooltip_below_current_line"));
|
code_editor->get_text_editor()->set_code_hint_draw_below(EditorSettings::get_singleton()->get("text_editor/completion/put_callhint_tooltip_below_current_line"));
|
||||||
@ -1886,6 +1938,7 @@ ScriptTextEditor::~ScriptTextEditor() {
|
|||||||
if (!editor_enabled) {
|
if (!editor_enabled) {
|
||||||
memdelete(code_editor);
|
memdelete(code_editor);
|
||||||
memdelete(warnings_panel);
|
memdelete(warnings_panel);
|
||||||
|
memdelete(errors_panel);
|
||||||
memdelete(context_menu);
|
memdelete(context_menu);
|
||||||
memdelete(color_panel);
|
memdelete(color_panel);
|
||||||
memdelete(edit_hb);
|
memdelete(edit_hb);
|
||||||
|
@ -55,6 +55,7 @@ class ScriptTextEditor : public ScriptEditorBase {
|
|||||||
|
|
||||||
CodeTextEditor *code_editor = nullptr;
|
CodeTextEditor *code_editor = nullptr;
|
||||||
RichTextLabel *warnings_panel = nullptr;
|
RichTextLabel *warnings_panel = nullptr;
|
||||||
|
RichTextLabel *errors_panel = nullptr;
|
||||||
|
|
||||||
Ref<Script> script;
|
Ref<Script> script;
|
||||||
bool script_is_valid = false;
|
bool script_is_valid = false;
|
||||||
@ -161,7 +162,9 @@ protected:
|
|||||||
|
|
||||||
void _load_theme_settings();
|
void _load_theme_settings();
|
||||||
void _set_theme_for_script();
|
void _set_theme_for_script();
|
||||||
|
void _show_errors_panel(bool p_show);
|
||||||
void _show_warnings_panel(bool p_show);
|
void _show_warnings_panel(bool p_show);
|
||||||
|
void _error_clicked(Variant p_line);
|
||||||
void _warning_clicked(Variant p_line);
|
void _warning_clicked(Variant p_line);
|
||||||
|
|
||||||
void _notification(int p_what);
|
void _notification(int p_what);
|
||||||
|
@ -240,7 +240,7 @@ void ShaderTextEditor::_validate_script() {
|
|||||||
warnings.sort_custom<WarningsComparator>();
|
warnings.sort_custom<WarningsComparator>();
|
||||||
_update_warning_panel();
|
_update_warning_panel();
|
||||||
} else {
|
} else {
|
||||||
set_warning_nb(0);
|
set_warning_count(0);
|
||||||
}
|
}
|
||||||
emit_signal("script_changed");
|
emit_signal("script_changed");
|
||||||
}
|
}
|
||||||
@ -280,7 +280,7 @@ void ShaderTextEditor::_update_warning_panel() {
|
|||||||
}
|
}
|
||||||
warnings_panel->pop(); // Table.
|
warnings_panel->pop(); // Table.
|
||||||
|
|
||||||
set_warning_nb(warning_count);
|
set_warning_count(warning_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderTextEditor::_bind_methods() {
|
void ShaderTextEditor::_bind_methods() {
|
||||||
|
@ -132,7 +132,7 @@ typedef struct {
|
|||||||
godot_bool can_inherit_from_file;
|
godot_bool can_inherit_from_file;
|
||||||
|
|
||||||
godot_string (*get_template_source_code)(godot_pluginscript_language_data *p_data, const godot_string *p_class_name, const godot_string *p_base_class_name);
|
godot_string (*get_template_source_code)(godot_pluginscript_language_data *p_data, const godot_string *p_class_name, const godot_string *p_base_class_name);
|
||||||
godot_bool (*validate)(godot_pluginscript_language_data *p_data, const godot_string *p_script, int *r_line_error, int *r_col_error, godot_string *r_test_error, const godot_string *p_path, godot_packed_string_array *r_functions);
|
godot_bool (*validate)(godot_pluginscript_language_data *p_data, const godot_string *p_script, const godot_string *p_path, godot_packed_string_array *r_functions, godot_array *r_errors); // errors = Array of Dictionary with "line", "column", "message" keys
|
||||||
int (*find_function)(godot_pluginscript_language_data *p_data, const godot_string *p_function, const godot_string *p_code); // Can be nullptr
|
int (*find_function)(godot_pluginscript_language_data *p_data, const godot_string *p_function, const godot_string *p_code); // Can be nullptr
|
||||||
godot_string (*make_function)(godot_pluginscript_language_data *p_data, const godot_string *p_class, const godot_string *p_name, const godot_packed_string_array *p_args);
|
godot_string (*make_function)(godot_pluginscript_language_data *p_data, const godot_string *p_class, const godot_string *p_name, const godot_packed_string_array *p_args);
|
||||||
godot_error (*complete_code)(godot_pluginscript_language_data *p_data, const godot_string *p_code, const godot_string *p_path, godot_object *p_owner, godot_array *r_options, godot_bool *r_force, godot_string *r_call_hint);
|
godot_error (*complete_code)(godot_pluginscript_language_data *p_data, const godot_string *p_code, const godot_string *p_path, godot_object *p_owner, godot_array *r_options, godot_bool *r_force, godot_string *r_call_hint);
|
||||||
|
@ -1035,7 +1035,7 @@ Ref<Script> NativeScriptLanguage::get_template(const String &p_class_name, const
|
|||||||
return Ref<NativeScript>(s);
|
return Ref<NativeScript>(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NativeScriptLanguage::validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions, List<ScriptLanguage::Warning> *r_warnings, Set<int> *r_safe_lines) const {
|
bool NativeScriptLanguage::validate(const String &p_script, const String &p_path, List<String> *r_functions, List<ScriptLanguage::ScriptError> *r_errors, List<ScriptLanguage::Warning> *r_warnings, Set<int> *r_safe_lines) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,7 +317,7 @@ public:
|
|||||||
virtual void get_comment_delimiters(List<String> *p_delimiters) const;
|
virtual void get_comment_delimiters(List<String> *p_delimiters) const;
|
||||||
virtual void get_string_delimiters(List<String> *p_delimiters) const;
|
virtual void get_string_delimiters(List<String> *p_delimiters) const;
|
||||||
virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
|
virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
|
||||||
virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const;
|
virtual bool validate(const String &p_script, const String &p_path, List<String> *r_functions, List<ScriptLanguage::ScriptError> *r_errors = nullptr, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const;
|
||||||
virtual Script *create_script() const;
|
virtual Script *create_script() const;
|
||||||
virtual bool has_named_classes() const;
|
virtual bool has_named_classes() const;
|
||||||
virtual bool supports_builtin_mode() const;
|
virtual bool supports_builtin_mode() const;
|
||||||
|
@ -112,20 +112,29 @@ Ref<Script> PluginScriptLanguage::get_template(const String &p_class_name, const
|
|||||||
return script;
|
return script;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PluginScriptLanguage::validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions, List<ScriptLanguage::Warning> *r_warnings, Set<int> *r_safe_lines) const {
|
bool PluginScriptLanguage::validate(const String &p_script, const String &p_path, List<String> *r_functions, List<ScriptLanguage::ScriptError> *r_errors, List<ScriptLanguage::Warning> *r_warnings, Set<int> *r_safe_lines) const {
|
||||||
PackedStringArray functions;
|
PackedStringArray functions;
|
||||||
|
Array errors;
|
||||||
if (_desc.validate) {
|
if (_desc.validate) {
|
||||||
bool ret = _desc.validate(
|
bool ret = _desc.validate(
|
||||||
_data,
|
_data,
|
||||||
(godot_string *)&p_script,
|
(godot_string *)&p_script,
|
||||||
&r_line_error,
|
|
||||||
&r_col_error,
|
|
||||||
(godot_string *)&r_test_error,
|
|
||||||
(godot_string *)&p_path,
|
(godot_string *)&p_path,
|
||||||
(godot_packed_string_array *)&functions);
|
(godot_packed_string_array *)&functions,
|
||||||
|
(godot_array *)&errors);
|
||||||
for (int i = 0; i < functions.size(); i++) {
|
for (int i = 0; i < functions.size(); i++) {
|
||||||
r_functions->push_back(functions[i]);
|
r_functions->push_back(functions[i]);
|
||||||
}
|
}
|
||||||
|
if (r_errors) {
|
||||||
|
for (int i = 0; i < errors.size(); i++) {
|
||||||
|
Dictionary error = errors[i];
|
||||||
|
ScriptLanguage::ScriptError e;
|
||||||
|
e.line = error["line"];
|
||||||
|
e.column = error["column"];
|
||||||
|
e.message = error["message"];
|
||||||
|
r_errors->push_back(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -75,7 +75,7 @@ public:
|
|||||||
virtual void get_comment_delimiters(List<String> *p_delimiters) const;
|
virtual void get_comment_delimiters(List<String> *p_delimiters) const;
|
||||||
virtual void get_string_delimiters(List<String> *p_delimiters) const;
|
virtual void get_string_delimiters(List<String> *p_delimiters) const;
|
||||||
virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
|
virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
|
||||||
virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = nullptr, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const;
|
virtual bool validate(const String &p_script, const String &p_path = "", List<String> *r_functions = nullptr, List<ScriptLanguage::ScriptError> *r_errors = nullptr, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const;
|
||||||
virtual Script *create_script() const;
|
virtual Script *create_script() const;
|
||||||
virtual bool has_named_classes() const;
|
virtual bool has_named_classes() const;
|
||||||
virtual bool supports_builtin_mode() const;
|
virtual bool supports_builtin_mode() const;
|
||||||
|
@ -447,7 +447,7 @@ public:
|
|||||||
virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
|
virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
|
||||||
virtual bool is_using_templates();
|
virtual bool is_using_templates();
|
||||||
virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script);
|
virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script);
|
||||||
virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = nullptr, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const;
|
virtual bool validate(const String &p_script, const String &p_path = "", List<String> *r_functions = nullptr, List<ScriptLanguage::ScriptError> *r_errors = nullptr, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const;
|
||||||
virtual Script *create_script() const;
|
virtual Script *create_script() const;
|
||||||
virtual bool has_named_classes() const;
|
virtual bool has_named_classes() const;
|
||||||
virtual bool supports_builtin_mode() const;
|
virtual bool supports_builtin_mode() const;
|
||||||
|
@ -131,7 +131,7 @@ static void get_function_names_recursively(const GDScriptParser::ClassNode *p_cl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GDScriptLanguage::validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions, List<ScriptLanguage::Warning> *r_warnings, Set<int> *r_safe_lines) const {
|
bool GDScriptLanguage::validate(const String &p_script, const String &p_path, List<String> *r_functions, List<ScriptLanguage::ScriptError> *r_errors, List<ScriptLanguage::Warning> *r_warnings, Set<int> *r_safe_lines) const {
|
||||||
GDScriptParser parser;
|
GDScriptParser parser;
|
||||||
GDScriptAnalyzer analyzer(&parser);
|
GDScriptAnalyzer analyzer(&parser);
|
||||||
|
|
||||||
@ -156,10 +156,16 @@ bool GDScriptLanguage::validate(const String &p_script, int &r_line_error, int &
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (err) {
|
if (err) {
|
||||||
GDScriptParser::ParserError parse_error = parser.get_errors().front()->get();
|
if (r_errors) {
|
||||||
r_line_error = parse_error.line;
|
for (const List<GDScriptParser::ParserError>::Element *E = parser.get_errors().front(); E; E = E->next()) {
|
||||||
r_col_error = parse_error.column;
|
const GDScriptParser::ParserError &pe = E->get();
|
||||||
r_test_error = parse_error.message;
|
ScriptLanguage::ScriptError e;
|
||||||
|
e.line = pe.line;
|
||||||
|
e.column = pe.column;
|
||||||
|
e.message = pe.message;
|
||||||
|
r_errors->push_back(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
const GDScriptParser::ClassNode *cl = parser.get_tree();
|
const GDScriptParser::ClassNode *cl = parser.get_tree();
|
||||||
@ -2378,7 +2384,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
|
|||||||
r_forced = r_result.size() > 0;
|
r_forced = r_result.size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_forced, String &r_call_hint) {
|
::Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_forced, String &r_call_hint) {
|
||||||
const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\"";
|
const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\"";
|
||||||
|
|
||||||
GDScriptParser parser;
|
GDScriptParser parser;
|
||||||
@ -2929,7 +2935,7 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co
|
|||||||
return ERR_CANT_RESOLVE;
|
return ERR_CANT_RESOLVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol, const String &p_path, Object *p_owner, LookupResult &r_result) {
|
::Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol, const String &p_path, Object *p_owner, LookupResult &r_result) {
|
||||||
//before parsing, try the usual stuff
|
//before parsing, try the usual stuff
|
||||||
if (ClassDB::class_exists(p_symbol)) {
|
if (ClassDB::class_exists(p_symbol)) {
|
||||||
r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS;
|
r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS;
|
||||||
|
@ -455,9 +455,8 @@ public:
|
|||||||
Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const override;
|
Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const override;
|
||||||
bool is_using_templates() override;
|
bool is_using_templates() override;
|
||||||
void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) override;
|
void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) override;
|
||||||
/* TODO */ bool validate(const String &p_script, int &r_line_error, int &r_col_error,
|
/* TODO */ bool validate(const String &p_script, const String &p_path, List<String> *r_functions,
|
||||||
String &r_test_error, const String &p_path, List<String> *r_functions,
|
List<ScriptLanguage::ScriptError> *r_errors = nullptr, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const override {
|
||||||
List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const override {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
String validate_path(const String &p_path) const override;
|
String validate_path(const String &p_path) const override;
|
||||||
|
@ -2276,7 +2276,7 @@ void VisualScriptLanguage::make_template(const String &p_class_name, const Strin
|
|||||||
script->set_instance_base_type(p_base_class_name);
|
script->set_instance_base_type(p_base_class_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VisualScriptLanguage::validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions, List<ScriptLanguage::Warning> *r_warnings, Set<int> *r_safe_lines) const {
|
bool VisualScriptLanguage::validate(const String &p_script, const String &p_path, List<String> *r_functions, List<ScriptLanguage::ScriptError> *r_errors, List<ScriptLanguage::Warning> *r_warnings, Set<int> *r_safe_lines) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -571,7 +571,7 @@ public:
|
|||||||
virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
|
virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
|
||||||
virtual bool is_using_templates();
|
virtual bool is_using_templates();
|
||||||
virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script);
|
virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script);
|
||||||
virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = nullptr, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const;
|
virtual bool validate(const String &p_script, const String &p_path = "", List<String> *r_functions = nullptr, List<ScriptLanguage::ScriptError> *r_errors = nullptr, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const;
|
||||||
virtual Script *create_script() const;
|
virtual Script *create_script() const;
|
||||||
virtual bool has_named_classes() const;
|
virtual bool has_named_classes() const;
|
||||||
virtual bool supports_builtin_mode() const;
|
virtual bool supports_builtin_mode() const;
|
||||||
|
Loading…
Reference in New Issue
Block a user