summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/SCsub2
-rw-r--r--modules/assimp/editor_scene_importer_assimp.cpp16
-rw-r--r--modules/assimp/import_utils.h8
-rw-r--r--modules/gdnative/gdnative_library_editor_plugin.cpp1
-rw-r--r--modules/gdscript/doc_classes/@GDScript.xml47
-rw-r--r--modules/gdscript/gdscript.cpp24
-rw-r--r--modules/gdscript/gdscript_compiler.cpp2
-rw-r--r--modules/gdscript/gdscript_editor.cpp11
-rw-r--r--modules/gdscript/gdscript_function.cpp6
-rw-r--r--modules/gdscript/gdscript_functions.cpp22
-rw-r--r--modules/gdscript/gdscript_parser.cpp41
-rw-r--r--modules/gdscript/language_server/gdscript_extend_parser.cpp2
-rw-r--r--modules/gdscript/language_server/gdscript_text_document.cpp2
-rw-r--r--modules/mbedtls/crypto_mbedtls.cpp2
-rwxr-xr-xmodules/mbedtls/stream_peer_mbedtls.cpp5
-rw-r--r--modules/mono/build_scripts/godot_tools_build.py3
-rw-r--r--modules/mono/build_scripts/mono_configure.py11
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotBuildLogger.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotTools.BuildLogger.csproj2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs8
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeClient.cs4
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnection.cs4
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotTools.IdeConnection.csproj2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageComposer.cs4
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageParser.cs6
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs4
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/packages.config4
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/BottomPanel.cs24
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs6
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs6
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/BuildManager.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/BuildTab.cs8
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs8
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs40
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/ExternalEditorId.cs3
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs54
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj17
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs3
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeServer.cs4
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs416
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs117
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs8
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Internals/ScriptClassParser.cs8
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs18
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Utils/User32Dll.cs10
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/packages.config5
-rw-r--r--modules/mono/editor/editor_internal_calls.cpp14
-rw-r--r--modules/mono/editor/script_class_parser.cpp55
-rw-r--r--modules/mono/glue/Managed/Files/StringExtensions.cs44
-rw-r--r--modules/mono/glue/Managed/Managed.csproj2
-rw-r--r--modules/mono/mono_gd/gd_mono.cpp42
-rw-r--r--modules/mono/mono_gd/gd_mono_android.cpp3
-rw-r--r--modules/mono/mono_gd/gd_mono_field.cpp10
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.cpp2
-rw-r--r--modules/recast/navigation_mesh_generator.cpp2
-rw-r--r--modules/visual_script/visual_script_editor.cpp12
-rw-r--r--modules/visual_script/visual_script_nodes.cpp2
59 files changed, 891 insertions, 303 deletions
diff --git a/modules/SCsub b/modules/SCsub
index 42d89d6ce2..dc0420616c 100644
--- a/modules/SCsub
+++ b/modules/SCsub
@@ -16,7 +16,7 @@ for x in env.module_list:
env_modules.Append(CPPDEFINES=["MODULE_" + x.upper() + "_ENABLED"])
SConscript(x + "/SCsub")
-if env.split_modules:
+if env['split_libmodules']:
env.split_lib("modules", env_lib = env_modules)
else:
lib = env_modules.add_library("modules", env.modules_sources)
diff --git a/modules/assimp/editor_scene_importer_assimp.cpp b/modules/assimp/editor_scene_importer_assimp.cpp
index 2cb2a71f1e..752b74b9f2 100644
--- a/modules/assimp/editor_scene_importer_assimp.cpp
+++ b/modules/assimp/editor_scene_importer_assimp.cpp
@@ -364,8 +364,6 @@ EditorSceneImporterAssimp::_generate_scene(const String &p_path, aiScene *scene,
}
} else if (bone != NULL) {
continue;
- } else if (element_assimp_node->mNumMeshes > 0) {
- spatial = memnew(Spatial);
} else {
spatial = memnew(Spatial);
}
@@ -393,16 +391,11 @@ EditorSceneImporterAssimp::_generate_scene(const String &p_path, aiScene *scene,
ERR_FAIL_COND_V_MSG(parent_node == NULL, state.root,
"Parent node invalid even though lookup successful, out of ram?")
- if (parent_node && spatial != state.root) {
+ if (spatial != state.root) {
parent_node->add_child(spatial);
spatial->set_owner(state.root);
- } else if (spatial == state.root) {
+ } else {
// required - think about it root never has a parent yet is valid, anything else without a parent is not valid.
- } else // Safety for instances
- {
- WARN_PRINT(
- "Failed to find parent node instance after lookup, serious warning report to godot with model");
- memdelete(spatial); // this node is broken
}
} else if (spatial != state.root) {
// if the ainode is not in the tree
@@ -477,11 +470,12 @@ EditorSceneImporterAssimp::_generate_scene(const String &p_path, aiScene *scene,
for (Map<const aiNode *, Spatial *>::Element *key_value_pair = state.flat_node_map.front(); key_value_pair; key_value_pair = key_value_pair->next()) {
const aiNode *assimp_node = key_value_pair->key();
Spatial *mesh_template = key_value_pair->value();
- Node *parent_node = mesh_template->get_parent();
ERR_CONTINUE(assimp_node == NULL);
ERR_CONTINUE(mesh_template == NULL);
+ Node *parent_node = mesh_template->get_parent();
+
if (mesh_template == state.root) {
continue;
}
@@ -1009,7 +1003,6 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat
}
}
- const String mesh_name = AssimpUtils::get_assimp_string(ai_mesh->mName);
aiString mat_name;
if (AI_SUCCESS == ai_material->Get(AI_MATKEY_NAME, mat_name)) {
mat->set_name(AssimpUtils::get_assimp_string(mat_name));
@@ -1495,7 +1488,6 @@ void EditorSceneImporterAssimp::_generate_node(
ERR_FAIL_COND(assimp_node == NULL);
state.nodes.push_back(assimp_node);
- String node_name = AssimpUtils::get_assimp_string(assimp_node->mName);
String parent_name = AssimpUtils::get_assimp_string(assimp_node->mParent->mName);
// please note
diff --git a/modules/assimp/import_utils.h b/modules/assimp/import_utils.h
index 8135b352c6..bf7552e7db 100644
--- a/modules/assimp/import_utils.h
+++ b/modules/assimp/import_utils.h
@@ -309,9 +309,7 @@ public:
if (r_found) {
return;
}
- if (r_found == false) {
- find_texture_path(r_p_path, dir, r_path, r_found, "." + exts[i]);
- }
+ find_texture_path(r_p_path, dir, r_path, r_found, "." + exts[i]);
}
}
@@ -322,9 +320,7 @@ public:
static void set_texture_mapping_mode(aiTextureMapMode *map_mode, Ref<ImageTexture> texture) {
ERR_FAIL_COND(texture.is_null());
ERR_FAIL_COND(map_mode == NULL);
- aiTextureMapMode tex_mode = aiTextureMapMode::aiTextureMapMode_Wrap;
-
- tex_mode = map_mode[0];
+ aiTextureMapMode tex_mode = map_mode[0];
int32_t flags = Texture::FLAGS_DEFAULT;
if (tex_mode == aiTextureMapMode_Wrap) {
diff --git a/modules/gdnative/gdnative_library_editor_plugin.cpp b/modules/gdnative/gdnative_library_editor_plugin.cpp
index 5d272a6cdc..5c84222797 100644
--- a/modules/gdnative/gdnative_library_editor_plugin.cpp
+++ b/modules/gdnative/gdnative_library_editor_plugin.cpp
@@ -224,7 +224,6 @@ void GDNativeLibraryEditor::_erase_entry(const String &platform, const String &e
if (List<String>::Element *E = platforms[platform].entries.find(entry)) {
String target = platform + "." + entry;
- Ref<ConfigFile> config = library->get_config_file();
platforms[platform].entries.erase(E);
_set_target_value("entry", target, "");
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml
index d1f52d2422..c4b7e4887e 100644
--- a/modules/gdscript/doc_classes/@GDScript.xml
+++ b/modules/gdscript/doc_classes/@GDScript.xml
@@ -168,14 +168,16 @@
<method name="char">
<return type="String">
</return>
- <argument index="0" name="ascii" type="int">
+ <argument index="0" name="code" type="int">
</argument>
<description>
- Returns a character as a String of the given ASCII code.
+ Returns a character as a String of the given Unicode code point (which is compatible with ASCII code).
[codeblock]
a = char(65) # a is "A"
a = char(65 + 32) # a is "a"
+ a = char(8364) # a is "€"
[/codeblock]
+ This is the inverse of [method ord].
</description>
</method>
<method name="clamp">
@@ -616,9 +618,10 @@
Loads a resource from the filesystem located at [code]path[/code].
[b]Note:[/b] Resource paths can be obtained by right-clicking on a resource in the FileSystem dock and choosing [b]Copy Path[/b].
[codeblock]
- # Load a scene called main located in the root of the project directory
+ # Load a scene called main located in the root of the project directory.
var main = load("res://main.tscn")
[/codeblock]
+ [b]Important:[/b] The path must be absolute, a local path will just return [code]null[/code].
</description>
</method>
<method name="log">
@@ -701,6 +704,13 @@
<argument index="0" name="char" type="String">
</argument>
<description>
+ Returns an integer representing the Unicode code point of the given Unicode character [code]char[/code].
+ [codeblock]
+ a = ord("A") # a is 65
+ a = ord("a") # a is 97
+ a = ord("€") # a is 8364
+ [/codeblock]
+ This is the inverse of [method char].
</description>
</method>
<method name="parse_json">
@@ -786,7 +796,7 @@
Returns a resource from the filesystem that is loaded during script parsing.
[b]Note:[/b] Resource paths can be obtained by right clicking on a resource in the Assets Panel and choosing "Copy Path".
[codeblock]
- # Load a scene called main located in the root of the project directory
+ # Load a scene called main located in the root of the project directory.
var main = preload("res://main.tscn")
[/codeblock]
</description>
@@ -936,7 +946,7 @@
<return type="int">
</return>
<description>
- Returns a random unsigned 32 bit integer. Use remainder to obtain a random value in the interval [code][0, N][/code] (where N is smaller than 2^32 -1).
+ Returns a random unsigned 32 bit integer. Use remainder to obtain a random value in the interval [code][0, N - 1][/code] (where N is smaller than 2^32).
[codeblock]
randi() # Returns random integer between 0 and 2^32 - 1
randi() % 20 # Returns random integer between 0 and 19
@@ -1367,23 +1377,26 @@
You can also use [code]yield[/code] to wait for a function to finish:
[codeblock]
func _ready():
- yield(do_something(), "completed")
- yield(do_something_else(), "completed")
- print("All functions are done!")
-
- func do_something():
- print("Something is done!")
+ yield(countdown(), "completed") # waiting for the countdown() function to complete
+ print('Ready')
- func do_something_else():
- print("Something else is done!")
+ func countdown():
+ yield(get_tree(), "idle_frame") # returns a GDScriptFunctionState object to _ready()
+ print(3)
+ yield(get_tree().create_timer(1.0), "timeout")
+ print(2)
+ yield(get_tree().create_timer(1.0), "timeout")
+ print(1)
+ yield(get_tree().create_timer(1.0), "timeout")
# prints:
- # Something is done!
- # Something else is done!
- # All functions are done!
+ # 3
+ # 2
+ # 1
+ # Ready
[/codeblock]
When yielding on a function, the [code]completed[/code] signal will be emitted automatically when the function returns. It can, therefore, be used as the [code]signal[/code] parameter of the [code]yield[/code] method to resume.
- If you are planning on calling the same function within a loop, you should consider using [code]yield(get_tree(), "idle_frame")[/code] also.
+ In order to yield on a function, the resulting function should also return a [code]GDScriptFunctionState[/code]. Notice [code]yield(get_tree(), "idle_frame")[/code] from the above example.
</description>
</method>
</methods>
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index 563f7e2471..03b51be27f 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -946,18 +946,29 @@ bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) {
{
const Map<StringName, GDScript::MemberInfo>::Element *E = script->member_indices.find(p_name);
if (E) {
- if (E->get().setter) {
+ const GDScript::MemberInfo *member = &E->get();
+ if (member->setter) {
const Variant *val = &p_value;
Variant::CallError err;
- call(E->get().setter, &val, 1, err);
+ call(member->setter, &val, 1, err);
if (err.error == Variant::CallError::CALL_OK) {
return true; //function exists, call was successful
}
} else {
- if (!E->get().data_type.is_type(p_value)) {
- return false; // Type mismatch
+ if (!member->data_type.is_type(p_value)) {
+ // Try conversion
+ Variant::CallError ce;
+ const Variant *value = &p_value;
+ Variant converted = Variant::construct(member->data_type.builtin_type, &value, 1, ce);
+ if (ce.error == Variant::CallError::CALL_OK) {
+ members.write[member->index] = converted;
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ members.write[member->index] = p_value;
}
- members.write[E->get().index] = p_value;
}
return true;
}
@@ -2143,7 +2154,8 @@ GDScriptLanguage::GDScriptLanguage() {
GLOBAL_DEF("debug/gdscript/completion/autocomplete_setters_and_getters", false);
for (int i = 0; i < (int)GDScriptWarning::WARNING_MAX; i++) {
String warning = GDScriptWarning::get_name_from_code((GDScriptWarning::Code)i).to_lower();
- GLOBAL_DEF("debug/gdscript/warnings/" + warning, !warning.begins_with("unsafe_"));
+ bool default_enabled = !warning.begins_with("unsafe_") && i != GDScriptWarning::UNUSED_CLASS_VARIABLE;
+ GLOBAL_DEF("debug/gdscript/warnings/" + warning, default_enabled);
}
#endif // DEBUG_ENABLED
}
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index dea2225e91..7ce19f5adc 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -1144,7 +1144,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
GDScriptDataType assign_type = _gdtype_from_datatype(on->arguments[0]->get_datatype());
- if (assign_type.has_type && !on->arguments[1]->get_datatype().has_type) {
+ if (assign_type.has_type && !on->datatype.has_type) {
// Typed assignment
switch (assign_type.kind) {
case GDScriptDataType::BUILTIN: {
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index 280bc37dc0..97b8dda6d0 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -744,6 +744,14 @@ static bool _guess_expression_type(GDScriptCompletionContext &p_context, const G
r_type.type.kind = GDScriptParser::DataType::BUILTIN;
r_type.type.builtin_type = Variant::ARRAY;
} break;
+ case GDScriptParser::Node::TYPE_CAST: {
+ const GDScriptParser::CastNode *cn = static_cast<const GDScriptParser::CastNode *>(p_expression);
+ GDScriptCompletionIdentifier value;
+ if (_guess_expression_type(p_context, cn->source_node, r_type)) {
+ r_type.type = cn->get_datatype();
+ found = true;
+ }
+ } break;
case GDScriptParser::Node::TYPE_OPERATOR: {
const GDScriptParser::OperatorNode *op = static_cast<const GDScriptParser::OperatorNode *>(p_expression);
switch (op->op) {
@@ -1232,6 +1240,9 @@ static bool _guess_identifier_type(GDScriptCompletionContext &p_context, const S
c.line = last_assign_line;
r_type.assigned_expression = last_assigned_expression;
if (_guess_expression_type(c, last_assigned_expression, r_type)) {
+ if (var_type.has_type) {
+ r_type.type = var_type;
+ }
return true;
}
}
diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp
index 0a01321851..4518a5be4b 100644
--- a/modules/gdscript/gdscript_function.cpp
+++ b/modules/gdscript/gdscript_function.cpp
@@ -764,15 +764,17 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
GET_VARIANT_PTR(dst, 2);
GET_VARIANT_PTR(src, 3);
-#ifdef DEBUG_ENABLED
Variant::Type var_type = (Variant::Type)_code_ptr[ip + 1];
GD_ERR_BREAK(var_type < 0 || var_type >= Variant::VARIANT_MAX);
if (src->get_type() != var_type) {
+#ifdef DEBUG_ENABLED
if (Variant::can_convert_strict(src->get_type(), var_type)) {
+#endif // DEBUG_ENABLED
Variant::CallError ce;
*dst = Variant::construct(var_type, const_cast<const Variant **>(&src), 1, ce);
} else {
+#ifdef DEBUG_ENABLED
err_text = "Trying to assign value of type '" + Variant::get_type_name(src->get_type()) +
"' to a variable of type '" + Variant::get_type_name(var_type) + "'.";
OPCODE_BREAK;
@@ -780,9 +782,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
} else {
#endif // DEBUG_ENABLED
*dst = *src;
-#ifdef DEBUG_ENABLED
}
-#endif // DEBUG_ENABLED
ip += 4;
}
diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp
index bbafef68ed..5c0573be3f 100644
--- a/modules/gdscript/gdscript_functions.cpp
+++ b/modules/gdscript/gdscript_functions.cpp
@@ -1128,25 +1128,11 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
d["@subpath"] = cp;
d["@path"] = p->get_path();
- p = base.ptr();
-
- while (p) {
-
- for (Set<StringName>::Element *E = p->members.front(); E; E = E->next()) {
-
- Variant value;
- if (ins->get(E->get(), value)) {
-
- String k = E->get();
- if (!d.has(k)) {
- d[k] = value;
- }
- }
+ for (Map<StringName, GDScript::MemberInfo>::Element *E = base->member_indices.front(); E; E = E->next()) {
+ if (!d.has(E->key())) {
+ d[E->key()] = ins->members[E->get().index];
}
-
- p = p->_base;
}
-
r_ret = d;
}
}
@@ -1869,7 +1855,7 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
} break;
case TEXT_CHAR: {
- MethodInfo mi("char", PropertyInfo(Variant::INT, "ascii"));
+ MethodInfo mi("char", PropertyInfo(Variant::INT, "code"));
mi.return_val.type = Variant::STRING;
return mi;
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index ef1a282e51..4405393b96 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -8185,7 +8185,9 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
}
#endif // DEBUG_ENABLED
+ bool type_match = check_types;
if (check_types && !_is_type_compatible(lh_type, rh_type)) {
+ type_match = false;
// Try supertype test
if (_is_type_compatible(rh_type, lh_type)) {
_mark_line_as_unsafe(op->line);
@@ -8197,23 +8199,27 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
op->line);
return;
}
- // Replace assignment with implicit conversion
- BuiltInFunctionNode *convert = alloc_node<BuiltInFunctionNode>();
- convert->line = op->line;
- convert->function = GDScriptFunctions::TYPE_CONVERT;
-
- ConstantNode *tgt_type = alloc_node<ConstantNode>();
- tgt_type->line = op->line;
- tgt_type->value = (int)lh_type.builtin_type;
-
- OperatorNode *convert_call = alloc_node<OperatorNode>();
- convert_call->line = op->line;
- convert_call->op = OperatorNode::OP_CALL;
- convert_call->arguments.push_back(convert);
- convert_call->arguments.push_back(op->arguments[1]);
- convert_call->arguments.push_back(tgt_type);
-
- op->arguments.write[1] = convert_call;
+ if (op->op == OperatorNode::OP_ASSIGN) {
+ // Replace assignment with implicit conversion
+ BuiltInFunctionNode *convert = alloc_node<BuiltInFunctionNode>();
+ convert->line = op->line;
+ convert->function = GDScriptFunctions::TYPE_CONVERT;
+
+ ConstantNode *tgt_type = alloc_node<ConstantNode>();
+ tgt_type->line = op->line;
+ tgt_type->value = (int)lh_type.builtin_type;
+
+ OperatorNode *convert_call = alloc_node<OperatorNode>();
+ convert_call->line = op->line;
+ convert_call->op = OperatorNode::OP_CALL;
+ convert_call->arguments.push_back(convert);
+ convert_call->arguments.push_back(op->arguments[1]);
+ convert_call->arguments.push_back(tgt_type);
+
+ op->arguments.write[1] = convert_call;
+
+ type_match = true; // Since we are converting, the type is matching
+ }
#ifdef DEBUG_ENABLED
if (lh_type.builtin_type == Variant::INT && rh_type.builtin_type == Variant::REAL) {
_add_warning(GDScriptWarning::NARROWING_CONVERSION, op->line);
@@ -8226,6 +8232,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
_mark_line_as_unsafe(op->line);
}
#endif // DEBUG_ENABLED
+ op->datatype.has_type = type_match;
} break;
case OperatorNode::OP_CALL:
case OperatorNode::OP_PARENT_CALL: {
diff --git a/modules/gdscript/language_server/gdscript_extend_parser.cpp b/modules/gdscript/language_server/gdscript_extend_parser.cpp
index 6b5c26ec81..d63f786fcb 100644
--- a/modules/gdscript/language_server/gdscript_extend_parser.cpp
+++ b/modules/gdscript/language_server/gdscript_extend_parser.cpp
@@ -115,7 +115,7 @@ void ExtendGDScriptParser::update_document_links(const String &p_code) {
if (tokenizer.get_token() == GDScriptTokenizer::TK_EOF) {
break;
} else if (tokenizer.get_token() == GDScriptTokenizer::TK_CONSTANT) {
- Variant const_val = tokenizer.get_token_constant();
+ const Variant &const_val = tokenizer.get_token_constant();
if (const_val.get_type() == Variant::STRING) {
String path = const_val;
bool exists = fs->file_exists(path);
diff --git a/modules/gdscript/language_server/gdscript_text_document.cpp b/modules/gdscript/language_server/gdscript_text_document.cpp
index b83db718b8..1ca2a50c21 100644
--- a/modules/gdscript/language_server/gdscript_text_document.cpp
+++ b/modules/gdscript/language_server/gdscript_text_document.cpp
@@ -281,8 +281,6 @@ Dictionary GDScriptTextDocument::resolve(const Dictionary &p_params) {
}
Array GDScriptTextDocument::foldingRange(const Dictionary &p_params) {
- Dictionary params = p_params["textDocument"];
- String path = params["uri"];
Array arr;
return arr;
}
diff --git a/modules/mbedtls/crypto_mbedtls.cpp b/modules/mbedtls/crypto_mbedtls.cpp
index 204f4e8905..62912d1459 100644
--- a/modules/mbedtls/crypto_mbedtls.cpp
+++ b/modules/mbedtls/crypto_mbedtls.cpp
@@ -203,8 +203,6 @@ void CryptoMbedTLS::load_default_certificates(String p_path) {
default_certs = memnew(X509CertificateMbedTLS);
ERR_FAIL_COND(default_certs == NULL);
- String certs_path = GLOBAL_DEF("network/ssl/certificates", "");
-
if (p_path != "") {
// Use certs defined in project settings.
default_certs->load(p_path);
diff --git a/modules/mbedtls/stream_peer_mbedtls.cpp b/modules/mbedtls/stream_peer_mbedtls.cpp
index a2e342e219..78e99a3a65 100755
--- a/modules/mbedtls/stream_peer_mbedtls.cpp
+++ b/modules/mbedtls/stream_peer_mbedtls.cpp
@@ -111,7 +111,6 @@ Error StreamPeerMbedTLS::connect_to_stream(Ref<StreamPeer> p_base, bool p_valida
ERR_FAIL_COND_V(p_base.is_null(), ERR_INVALID_PARAMETER);
base = p_base;
- int ret = 0;
int authmode = p_validate_certs ? MBEDTLS_SSL_VERIFY_REQUIRED : MBEDTLS_SSL_VERIFY_NONE;
Error err = ssl_ctx->init_client(MBEDTLS_SSL_TRANSPORT_STREAM, authmode, p_ca_certs);
@@ -122,7 +121,7 @@ Error StreamPeerMbedTLS::connect_to_stream(Ref<StreamPeer> p_base, bool p_valida
status = STATUS_HANDSHAKING;
- if ((ret = _do_handshake()) != OK) {
+ if (_do_handshake() != OK) {
status = STATUS_ERROR_HOSTNAME_MISMATCH;
return FAILED;
}
@@ -143,7 +142,7 @@ Error StreamPeerMbedTLS::accept_stream(Ref<StreamPeer> p_base, Ref<CryptoKey> p_
status = STATUS_HANDSHAKING;
- if ((err = _do_handshake()) != OK) {
+ if (_do_handshake() != OK) {
return FAILED;
}
diff --git a/modules/mono/build_scripts/godot_tools_build.py b/modules/mono/build_scripts/godot_tools_build.py
index 03aaa925f0..6e5273f5e0 100644
--- a/modules/mono/build_scripts/godot_tools_build.py
+++ b/modules/mono/build_scripts/godot_tools_build.py
@@ -82,7 +82,8 @@ def build(env_mono, api_sln_cmd):
target_filenames = [
'GodotTools.dll', 'GodotTools.IdeConnection.dll', 'GodotTools.BuildLogger.dll',
- 'GodotTools.ProjectEditor.dll', 'DotNet.Glob.dll', 'GodotTools.Core.dll'
+ 'GodotTools.ProjectEditor.dll', 'DotNet.Glob.dll', 'GodotTools.Core.dll',
+ 'JetBrains.Annotations.dll', 'Newtonsoft.Json.dll'
]
if env_mono['target'] == 'debug':
diff --git a/modules/mono/build_scripts/mono_configure.py b/modules/mono/build_scripts/mono_configure.py
index 89d56def7d..033c467da9 100644
--- a/modules/mono/build_scripts/mono_configure.py
+++ b/modules/mono/build_scripts/mono_configure.py
@@ -446,18 +446,19 @@ def copy_mono_shared_libs(env, mono_root, target_mono_root_dir):
if not os.path.isdir(target_mono_lib_dir):
os.makedirs(target_mono_lib_dir)
+ lib_file_names = []
if platform == 'osx':
- # TODO: Make sure nothing is missing
- copy(os.path.join(mono_root, 'lib', 'libMonoPosixHelper.dylib'), target_mono_lib_dir)
+ lib_file_names = [lib_name + '.dylib' for lib_name in [
+ 'libmono-btls-shared', 'libmono-native-compat', 'libMonoPosixHelper'
+ ]]
elif is_unix_like(platform):
lib_file_names = [lib_name + '.so' for lib_name in [
'libmono-btls-shared', 'libmono-ee-interp', 'libmono-native', 'libMonoPosixHelper',
'libmono-profiler-aot', 'libmono-profiler-coverage', 'libmono-profiler-log', 'libMonoSupportW'
]]
- for lib_file_name in lib_file_names:
- copy_if_exists(os.path.join(mono_root, 'lib', lib_file_name), target_mono_lib_dir)
-
+ for lib_file_name in lib_file_names:
+ copy_if_exists(os.path.join(mono_root, 'lib', lib_file_name), target_mono_lib_dir)
def pkgconfig_try_find_mono_root(mono_lib_names, sharedlib_ext):
tmpenv = Environment()
diff --git a/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotBuildLogger.cs b/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotBuildLogger.cs
index a0f6f1ff32..6015cb22b6 100644
--- a/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotBuildLogger.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotBuildLogger.cs
@@ -18,7 +18,7 @@ namespace GodotTools.BuildLogger
if (null == Parameters)
throw new LoggerException("Log directory was not set.");
- var parameters = Parameters.Split(new[] {';'});
+ var parameters = Parameters.Split(new[] { ';' });
string logDir = parameters[0];
diff --git a/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotTools.BuildLogger.csproj b/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotTools.BuildLogger.csproj
index dcfdd83831..1eaa36c1aa 100644
--- a/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotTools.BuildLogger.csproj
+++ b/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotTools.BuildLogger.csproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
diff --git a/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj b/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj
index 24c7cb1573..1974220f2f 100644
--- a/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj
+++ b/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
diff --git a/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs b/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs
index 8cd7e76303..b531b6aeee 100644
--- a/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs
@@ -26,7 +26,7 @@ namespace GodotTools.Core
path = path.Replace('\\', '/');
- string[] parts = path.Split(new[] {'/'}, StringSplitOptions.RemoveEmptyEntries);
+ string[] parts = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
path = string.Join(Path.DirectorySeparatorChar.ToString(), parts).Trim();
@@ -44,7 +44,7 @@ namespace GodotTools.Core
public static string CsvEscape(this string value, char delimiter = ',')
{
- bool hasSpecialChar = value.IndexOfAny(new char[] {'\"', '\n', '\r', delimiter}) != -1;
+ bool hasSpecialChar = value.IndexOfAny(new char[] { '\"', '\n', '\r', delimiter }) != -1;
if (hasSpecialChar)
return "\"" + value.Replace("\"", "\"\"") + "\"";
@@ -54,8 +54,8 @@ namespace GodotTools.Core
public static string ToSafeDirName(this string dirName, bool allowDirSeparator)
{
- var invalidChars = new List<string> {":", "*", "?", "\"", "<", ">", "|"};
-
+ var invalidChars = new List<string> { ":", "*", "?", "\"", "<", ">", "|" };
+
if (allowDirSeparator)
{
// Directory separators are allowed, but disallow ".." to avoid going up the filesystem
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeClient.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeClient.cs
index 4f56a8d71b..2bf3b83c75 100644
--- a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeClient.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeClient.cs
@@ -106,7 +106,7 @@ namespace GodotTools.IdeConnection
try
{
Logger.LogInfo("Connecting to Godot Ide Server");
-
+
tcpClient.Connect(IPAddress.Loopback, GodotIdeMetadata.Port);
Logger.LogInfo("Connection open with Godot Ide Server");
@@ -130,7 +130,7 @@ namespace GodotTools.IdeConnection
public void Start()
{
Logger.LogInfo("Starting Godot Ide Client");
-
+
fsWatcher.Changed += OnMetaFileChanged;
fsWatcher.Deleted += OnMetaFileDeleted;
fsWatcher.EnableRaisingEvents = true;
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnection.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnection.cs
index e7e81f175e..6441be8d6e 100644
--- a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnection.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnection.cs
@@ -149,7 +149,7 @@ namespace GodotTools.IdeConnection
public bool WriteMessage(Message message)
{
Logger.LogDebug($"Sending message {message}");
-
+
var messageComposer = new MessageComposer();
messageComposer.AddArgument(message.Id);
@@ -201,7 +201,7 @@ namespace GodotTools.IdeConnection
clientReader?.Dispose();
clientWriter?.Dispose();
- ((IDisposable) tcpClient)?.Dispose();
+ ((IDisposable)tcpClient)?.Dispose();
}
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotTools.IdeConnection.csproj b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotTools.IdeConnection.csproj
index 94e525715b..427a26508f 100644
--- a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotTools.IdeConnection.csproj
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotTools.IdeConnection.csproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageComposer.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageComposer.cs
index 9e4cd6ec1a..30ffe7a06e 100644
--- a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageComposer.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageComposer.cs
@@ -22,14 +22,14 @@ namespace GodotTools.IdeConnection
if (quoted)
{
stringBuilder.Append('"');
-
+
foreach (char @char in argument)
{
if (CharsToEscape.Contains(@char))
stringBuilder.Append('\\');
stringBuilder.Append(@char);
}
-
+
stringBuilder.Append('"');
}
else
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageParser.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageParser.cs
index ed691e481f..4365d69989 100644
--- a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageParser.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageParser.cs
@@ -37,7 +37,7 @@ namespace GodotTools.IdeConnection
while (i < messageLine.Length)
{
@char = messageLine[i];
-
+
if (quoted && @char == '"')
{
i++;
@@ -60,10 +60,10 @@ namespace GodotTools.IdeConnection
{
stringBuilder.Append(@char);
}
-
+
i++;
}
-
+
arguments.Add(stringBuilder.ToString());
stringBuilder.Clear();
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs
index 4f21871f1a..b40d985d51 100644
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs
@@ -26,8 +26,8 @@ namespace GodotTools.ProjectEditor
mainGroup.SetProperty("BaseIntermediateOutputPath", "obj");
GenAssemblyInfoFile(root, dir, CoreApiProjectName,
- new[] {"[assembly: InternalsVisibleTo(\"" + EditorApiProjectName + "\")]"},
- new[] {"System.Runtime.CompilerServices"});
+ new[] { "[assembly: InternalsVisibleTo(\"" + EditorApiProjectName + "\")]" },
+ new[] { "System.Runtime.CompilerServices" });
foreach (var item in compileItems)
{
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/packages.config b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/packages.config
index 13915000e4..2db030f9d8 100644
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/packages.config
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/packages.config
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="DotNet.Glob" version="2.1.1" targetFramework="net45" />
-</packages> \ No newline at end of file
+</packages>
diff --git a/modules/mono/editor/GodotTools/GodotTools/BottomPanel.cs b/modules/mono/editor/GodotTools/GodotTools/BottomPanel.cs
index 44813f962c..4c76d2abf1 100644
--- a/modules/mono/editor/GodotTools/GodotTools/BottomPanel.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/BottomPanel.cs
@@ -34,7 +34,7 @@ namespace GodotTools
for (int i = 0; i < buildTabs.GetChildCount(); i++)
{
- var tab = (BuildTab) buildTabs.GetChild(i);
+ var tab = (BuildTab)buildTabs.GetChild(i);
if (tab == null)
continue;
@@ -120,7 +120,7 @@ namespace GodotTools
if (currentTab < 0 || currentTab >= buildTabs.GetTabCount())
throw new InvalidOperationException("No tab selected");
- var buildTab = (BuildTab) buildTabs.GetChild(currentTab);
+ var buildTab = (BuildTab)buildTabs.GetChild(currentTab);
buildTab.WarningsVisible = pressed;
buildTab.UpdateIssuesList();
}
@@ -132,7 +132,7 @@ namespace GodotTools
if (currentTab < 0 || currentTab >= buildTabs.GetTabCount())
throw new InvalidOperationException("No tab selected");
- var buildTab = (BuildTab) buildTabs.GetChild(currentTab);
+ var buildTab = (BuildTab)buildTabs.GetChild(currentTab);
buildTab.ErrorsVisible = pressed;
buildTab.UpdateIssuesList();
}
@@ -193,7 +193,7 @@ namespace GodotTools
int selectedItem = selectedItems[0];
- var buildTab = (BuildTab) buildTabs.GetTabControl(selectedItem);
+ var buildTab = (BuildTab)buildTabs.GetTabControl(selectedItem);
OS.ShellOpen(Path.Combine(buildTab.BuildInfo.LogsDirPath, BuildManager.MsBuildLogFileName));
}
@@ -249,14 +249,14 @@ namespace GodotTools
var editorBaseControl = editorInterface.GetBaseControl();
- SizeFlagsVertical = (int) SizeFlags.ExpandFill;
+ SizeFlagsVertical = (int)SizeFlags.ExpandFill;
SetAnchorsAndMarginsPreset(LayoutPreset.Wide);
panelTabs = new TabContainer
{
TabAlign = TabContainer.TabAlignEnum.Left,
RectMinSize = new Vector2(0, 228) * EditorScale,
- SizeFlagsVertical = (int) SizeFlags.ExpandFill
+ SizeFlagsVertical = (int)SizeFlags.ExpandFill
};
panelTabs.AddStyleboxOverride("panel", editorBaseControl.GetStylebox("DebuggerPanel", "EditorStyles"));
panelTabs.AddStyleboxOverride("tab_fg", editorBaseControl.GetStylebox("DebuggerTabFG", "EditorStyles"));
@@ -268,11 +268,11 @@ namespace GodotTools
panelBuildsTab = new VBoxContainer
{
Name = "Builds".TTR(),
- SizeFlagsHorizontal = (int) SizeFlags.ExpandFill
+ SizeFlagsHorizontal = (int)SizeFlags.ExpandFill
};
panelTabs.AddChild(panelBuildsTab);
- var toolBarHBox = new HBoxContainer {SizeFlagsHorizontal = (int) SizeFlags.ExpandFill};
+ var toolBarHBox = new HBoxContainer { SizeFlagsHorizontal = (int)SizeFlags.ExpandFill };
panelBuildsTab.AddChild(toolBarHBox);
var buildProjectBtn = new Button
@@ -320,12 +320,12 @@ namespace GodotTools
var hsc = new HSplitContainer
{
- SizeFlagsHorizontal = (int) SizeFlags.ExpandFill,
- SizeFlagsVertical = (int) SizeFlags.ExpandFill
+ SizeFlagsHorizontal = (int)SizeFlags.ExpandFill,
+ SizeFlagsVertical = (int)SizeFlags.ExpandFill
};
panelBuildsTab.AddChild(hsc);
- buildTabsList = new ItemList {SizeFlagsHorizontal = (int) SizeFlags.ExpandFill};
+ buildTabsList = new ItemList { SizeFlagsHorizontal = (int)SizeFlags.ExpandFill };
buildTabsList.Connect("item_selected", this, nameof(_BuildTabsItemSelected));
buildTabsList.Connect("nothing_selected", this, nameof(_BuildTabsNothingSelected));
hsc.AddChild(buildTabsList);
@@ -333,7 +333,7 @@ namespace GodotTools
buildTabs = new TabContainer
{
TabAlign = TabContainer.TabAlignEnum.Left,
- SizeFlagsHorizontal = (int) SizeFlags.ExpandFill,
+ SizeFlagsHorizontal = (int)SizeFlags.ExpandFill,
TabsVisible = false
};
hsc.AddChild(buildTabs);
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs
index da90c960e5..43c96d2e30 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs
@@ -46,7 +46,7 @@ namespace GodotTools.Build
{
if (OS.IsWindows)
{
- return (BuildManager.BuildTool) EditorSettings.GetSetting("mono/builds/build_tool")
+ return (BuildManager.BuildTool)EditorSettings.GetSetting("mono/builds/build_tool")
== BuildManager.BuildTool.MsBuildMono;
}
@@ -55,7 +55,7 @@ namespace GodotTools.Build
}
private static bool PrintBuildOutput =>
- (bool) EditorSettings.GetSetting("mono/builds/print_build_output");
+ (bool)EditorSettings.GetSetting("mono/builds/print_build_output");
private static Process LaunchBuild(string solution, string config, string loggerOutputDir, IEnumerable<string> customProperties = null)
{
@@ -90,7 +90,7 @@ namespace GodotTools.Build
// Needed when running from Developer Command Prompt for VS
RemovePlatformVariable(startInfo.EnvironmentVariables);
- var process = new Process {StartInfo = startInfo};
+ var process = new Process { StartInfo = startInfo };
process.Start();
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
index ad8a6516ab..c3db52aa9e 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
@@ -19,7 +19,7 @@ namespace GodotTools.Build
public static string FindMsBuild()
{
var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings();
- var buildTool = (BuildManager.BuildTool) editorSettings.GetSetting("mono/builds/build_tool");
+ var buildTool = (BuildManager.BuildTool)editorSettings.GetSetting("mono/builds/build_tool");
if (OS.IsWindows)
{
@@ -136,11 +136,11 @@ namespace GodotTools.Build
string vsWherePath = Environment.GetEnvironmentVariable(Internal.GodotIs32Bits() ? "ProgramFiles" : "ProgramFiles(x86)");
vsWherePath += "\\Microsoft Visual Studio\\Installer\\vswhere.exe";
- var vsWhereArgs = new[] {"-latest", "-products", "*", "-requires", "Microsoft.Component.MSBuild"};
+ var vsWhereArgs = new[] { "-latest", "-products", "*", "-requires", "Microsoft.Component.MSBuild" };
var outputArray = new Godot.Collections.Array<string>();
int exitCode = Godot.OS.Execute(vsWherePath, vsWhereArgs,
- blocking: true, output: (Godot.Collections.Array) outputArray);
+ blocking: true, output: (Godot.Collections.Array)outputArray);
if (exitCode != 0)
return string.Empty;
diff --git a/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs b/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs
index 217bf5c144..fa6bf4dafd 100644
--- a/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs
@@ -172,7 +172,7 @@ namespace GodotTools
}
var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings();
- var buildTool = (BuildTool) editorSettings.GetSetting("mono/builds/build_tool");
+ var buildTool = (BuildTool)editorSettings.GetSetting("mono/builds/build_tool");
using (var pr = new EditorProgress("mono_project_debug_build", "Building project solution...", 1))
{
diff --git a/modules/mono/editor/GodotTools/GodotTools/BuildTab.cs b/modules/mono/editor/GodotTools/GodotTools/BuildTab.cs
index 807a20d9a1..727581daab 100644
--- a/modules/mono/editor/GodotTools/GodotTools/BuildTab.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/BuildTab.cs
@@ -113,7 +113,7 @@ namespace GodotTools
throw new IndexOutOfRangeException("Item list index out of range");
// Get correct issue idx from issue list
- int issueIndex = (int) issuesList.GetItemMetadata(idx);
+ int issueIndex = (int)issuesList.GetItemMetadata(idx);
if (idx < 0 || idx >= issues.Count)
throw new IndexOutOfRangeException("Issue index out of range");
@@ -134,7 +134,7 @@ namespace GodotTools
if (file.StartsWith("res://"))
{
- var script = (Script) ResourceLoader.Load(file, typeHint: Internal.CSharpLanguageType);
+ var script = (Script)ResourceLoader.Load(file, typeHint: Internal.CSharpLanguageType);
if (script != null && Internal.ScriptEditorEdit(script, issue.Line, issue.Column))
Internal.EditorNodeShowScriptScreen();
@@ -220,7 +220,7 @@ namespace GodotTools
issuesList.Clear();
- var issue = new BuildIssue {Message = cause, Warning = false};
+ var issue = new BuildIssue { Message = cause, Warning = false };
ErrorCount += 1;
issues.Add(issue);
@@ -250,7 +250,7 @@ namespace GodotTools
{
base._Ready();
- issuesList = new ItemList {SizeFlagsVertical = (int) SizeFlags.ExpandFill};
+ issuesList = new ItemList { SizeFlagsVertical = (int)SizeFlags.ExpandFill };
issuesList.Connect("item_activated", this, nameof(_IssueActivated));
AddChild(issuesList);
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs b/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs
index c021a9051e..174509dc5b 100644
--- a/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs
@@ -26,7 +26,7 @@ namespace GodotTools
public static void AddItem(string projectPath, string itemType, string include)
{
- if (!(bool) GlobalDef("mono/project/auto_update_project", true))
+ if (!(bool)GlobalDef("mono/project/auto_update_project", true))
return;
ProjectUtils.AddItemToProjectChecked(projectPath, itemType, include);
@@ -49,7 +49,7 @@ namespace GodotTools
private static ulong ConvertToTimestamp(this DateTime value)
{
TimeSpan elapsedTime = value - Epoch;
- return (ulong) elapsedTime.TotalSeconds;
+ return (ulong)elapsedTime.TotalSeconds;
}
public static void GenerateScriptsMetadata(string projectPath, string outputPath)
@@ -68,7 +68,7 @@ namespace GodotTools
if (oldDict.TryGetValue(projectIncludeFile, out var oldFileVar))
{
- var oldFileDict = (Dictionary) oldFileVar;
+ var oldFileDict = (Dictionary)oldFileVar;
if (ulong.TryParse(oldFileDict["modified_time"] as string, out ulong storedModifiedTime))
{
@@ -108,7 +108,7 @@ namespace GodotTools
if (classDict.Count == 0)
continue; // Not found
- newDict[projectIncludeFile] = new Dictionary {["modified_time"] = $"{modifiedTime}", ["class"] = classDict};
+ newDict[projectIncludeFile] = new Dictionary { ["modified_time"] = $"{modifiedTime}", ["class"] = classDict };
}
if (newDict.Count > 0)
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
index c7e8ea511a..96cafba87f 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
@@ -39,7 +39,7 @@ namespace GodotTools.Export
private void AddFile(string srcPath, string dstPath, bool remap = false)
{
- AddFile(dstPath, File.ReadAllBytes(srcPath), remap);
+ AddFile(dstPath.Replace("\\", "/"), File.ReadAllBytes(srcPath), remap);
}
public override void _ExportFile(string path, string type, string[] features)
@@ -54,7 +54,7 @@ namespace GodotTools.Export
// TODO What if the source file is not part of the game's C# project
- bool includeScriptsContent = (bool) ProjectSettings.GetSetting("mono/export/include_scripts_content");
+ bool includeScriptsContent = (bool)ProjectSettings.GetSetting("mono/export/include_scripts_content");
if (!includeScriptsContent)
{
@@ -78,7 +78,13 @@ namespace GodotTools.Export
catch (Exception e)
{
maybeLastExportError = e.Message;
- GD.PushError($"Failed to export project: {e.Message}");
+
+ // 'maybeLastExportError' cannot be null or empty if there was an error, so we
+ // must consider the possibility of exceptions being thrown without a message.
+ if (string.IsNullOrEmpty(maybeLastExportError))
+ maybeLastExportError = $"Exception thrown: {e.GetType().Name}";
+
+ GD.PushError($"Failed to export project: {maybeLastExportError}");
Console.Error.WriteLine(e);
// TODO: Do something on error once _ExportBegin supports failing.
}
@@ -114,7 +120,7 @@ namespace GodotTools.Export
var dependencies = new Godot.Collections.Dictionary<string, string>();
- var projectDllName = (string) ProjectSettings.GetSetting("application/config/name");
+ var projectDllName = (string)ProjectSettings.GetSetting("application/config/name");
if (projectDllName.Empty())
{
projectDllName = "UnnamedProject";
@@ -147,7 +153,7 @@ namespace GodotTools.Export
string apiConfig = isDebug ? "Debug" : "Release";
string resAssembliesDir = Path.Combine(GodotSharpDirs.ResAssembliesBaseDir, apiConfig);
- bool assembliesInsidePck = (bool) ProjectSettings.GetSetting("mono/export/export_assemblies_inside_pck") || outputDataDir == null;
+ bool assembliesInsidePck = (bool)ProjectSettings.GetSetting("mono/export/export_assemblies_inside_pck") || outputDataDir == null;
if (!assembliesInsidePck)
{
@@ -174,7 +180,7 @@ namespace GodotTools.Export
// AOT
- if ((bool) ProjectSettings.GetSetting("mono/export/aot/enabled"))
+ if ((bool)ProjectSettings.GetSetting("mono/export/aot/enabled"))
{
AotCompileDependencies(features, platform, isDebug, outputDir, outputDataDir, dependencies);
}
@@ -336,7 +342,7 @@ namespace GodotTools.Export
AotCompileAssembly(platform, isDebug, data, assemblyPath, outputFilePathForThisAbi);
- AddSharedObject(outputFilePathForThisAbi, tags: new[] {abi});
+ AddSharedObject(outputFilePathForThisAbi, tags: new[] { abi });
}
}
else
@@ -377,7 +383,7 @@ namespace GodotTools.Export
string compilerCommand = Path.Combine(monoCrossBin, $"{toolPrefix}{monoExeName}{exeExt}");
- bool fullAot = (bool) ProjectSettings.GetSetting("mono/export/aot/full_aot");
+ bool fullAot = (bool)ProjectSettings.GetSetting("mono/export/aot/full_aot");
string EscapeOption(string option) => option.Contains(',') ? $"\"{option}\"" : option;
string OptionsToString(IEnumerable<string> options) => string.Join(",", options.Select(EscapeOption));
@@ -394,7 +400,7 @@ namespace GodotTools.Export
{
string abi = data["abi"];
- string androidToolchain = (string) ProjectSettings.GetSetting("mono/export/aot/android_toolchain_path");
+ string androidToolchain = (string)ProjectSettings.GetSetting("mono/export/aot/android_toolchain_path");
if (string.IsNullOrEmpty(androidToolchain))
{
@@ -419,13 +425,13 @@ namespace GodotTools.Export
aotOptions.Add("tool-prefix=" + Path.Combine(androidToolchain, "bin", androidToolPrefixes[abi]));
string triple = GetAndroidTriple(abi);
- aotOptions.Add ($"mtriple={triple}");
+ aotOptions.Add($"mtriple={triple}");
}
aotOptions.Add($"outfile={outputFilePath}");
- var extraAotOptions = (string[]) ProjectSettings.GetSetting("mono/export/aot/extra_aot_options");
- var extraOptimizerOptions = (string[]) ProjectSettings.GetSetting("mono/export/aot/extra_optimizer_options");
+ var extraAotOptions = (string[])ProjectSettings.GetSetting("mono/export/aot/extra_aot_options");
+ var extraOptimizerOptions = (string[])ProjectSettings.GetSetting("mono/export/aot/extra_optimizer_options");
if (extraAotOptions.Length > 0)
aotOptions.AddRange(extraAotOptions);
@@ -513,7 +519,7 @@ namespace GodotTools.Export
case OS.Platforms.HTML5:
return "wasm-wasm32";
default:
- throw new NotSupportedException();
+ throw new NotSupportedException($"Platform not supported: {platform}");
}
}
@@ -575,7 +581,7 @@ namespace GodotTools.Export
private static bool PlatformHasTemplateDir(string platform)
{
// OSX export templates are contained in a zip, so we place our custom template inside it and let Godot do the rest.
- return !new[] {OS.Platforms.OSX, OS.Platforms.Android, OS.Platforms.HTML5}.Contains(platform);
+ return !new[] { OS.Platforms.OSX, OS.Platforms.Android, OS.Platforms.HTML5 }.Contains(platform);
}
private static string DeterminePlatformFromFeatures(IEnumerable<string> features)
@@ -623,7 +629,7 @@ namespace GodotTools.Export
/// </summary>
private static bool PlatformRequiresCustomBcl(string platform)
{
- if (new[] {OS.Platforms.Android, OS.Platforms.HTML5}.Contains(platform))
+ if (new[] { OS.Platforms.Android, OS.Platforms.HTML5 }.Contains(platform))
return true;
// The 'net_4_x' BCL is not compatible between Windows and the other platforms.
@@ -655,7 +661,7 @@ namespace GodotTools.Export
case OS.Platforms.HTML5:
return "wasm";
default:
- throw new NotSupportedException();
+ throw new NotSupportedException($"Platform not supported: {platform}");
}
}
@@ -663,7 +669,7 @@ namespace GodotTools.Export
{
get
{
- var appName = (string) ProjectSettings.GetSetting("application/config/name");
+ var appName = (string)ProjectSettings.GetSetting("application/config/name");
string appNameSafe = appName.ToSafeDirName(allowDirSeparator: false);
return $"data_{appNameSafe}";
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/ExternalEditorId.cs b/modules/mono/editor/GodotTools/GodotTools/ExternalEditorId.cs
index 4312ca0230..bb218c2f19 100644
--- a/modules/mono/editor/GodotTools/GodotTools/ExternalEditorId.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/ExternalEditorId.cs
@@ -6,6 +6,7 @@ namespace GodotTools
VisualStudio, // TODO (Windows-only)
VisualStudioForMac, // Mac-only
MonoDevelop,
- VsCode
+ VsCode,
+ Rider
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
index 2a5d3de126..147bc95bb8 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
@@ -6,8 +6,10 @@ using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using GodotTools.Ides;
+using GodotTools.Ides.Rider;
using GodotTools.Internals;
using GodotTools.ProjectEditor;
+using JetBrains.Annotations;
using static GodotTools.Internals.Globals;
using File = GodotTools.Utils.File;
using OS = GodotTools.Utils.OS;
@@ -42,7 +44,7 @@ namespace GodotTools
string resourceDir = ProjectSettings.GlobalizePath("res://");
string path = resourceDir;
- string name = (string) ProjectSettings.GetSetting("application/config/name");
+ string name = (string)ProjectSettings.GetSetting("application/config/name");
if (name.Empty())
name = "UnnamedProject";
@@ -59,7 +61,7 @@ namespace GodotTools
{
Guid = guid,
PathRelativeToSolution = name + ".csproj",
- Configs = new List<string> {"Debug", "Release", "Tools"}
+ Configs = new List<string> { "Debug", "Release", "Tools" }
};
solution.AddNewProject(name, projectInfo);
@@ -108,20 +110,20 @@ namespace GodotTools
private void _RemoveCreateSlnMenuOption()
{
- menuPopup.RemoveItem(menuPopup.GetItemIndex((int) MenuOptions.CreateSln));
+ menuPopup.RemoveItem(menuPopup.GetItemIndex((int)MenuOptions.CreateSln));
bottomPanelBtn.Show();
}
private void _ShowAboutDialog()
{
- bool showOnStart = (bool) editorSettings.GetSetting("mono/editor/show_info_on_start");
+ bool showOnStart = (bool)editorSettings.GetSetting("mono/editor/show_info_on_start");
aboutDialogCheckBox.Pressed = showOnStart;
aboutDialog.PopupCenteredMinsize();
}
private void _ToggleAboutDialogOnStart(bool enabled)
{
- bool showOnStart = (bool) editorSettings.GetSetting("mono/editor/show_info_on_start");
+ bool showOnStart = (bool)editorSettings.GetSetting("mono/editor/show_info_on_start");
if (showOnStart != enabled)
editorSettings.SetSetting("mono/editor/show_info_on_start", enabled);
}
@@ -158,7 +160,7 @@ namespace GodotTools
if (what == NotificationReady)
{
- bool showInfoDialog = (bool) editorSettings.GetSetting("mono/editor/show_info_on_start");
+ bool showInfoDialog = (bool)editorSettings.GetSetting("mono/editor/show_info_on_start");
if (showInfoDialog)
{
aboutDialog.PopupExclusive = true;
@@ -189,9 +191,10 @@ namespace GodotTools
"code", "code-oss", "vscode", "vscode-oss", "visual-studio-code", "visual-studio-code-oss"
};
+ [UsedImplicitly]
public Error OpenInExternalEditor(Script script, int line, int col)
{
- var editor = (ExternalEditorId) editorSettings.GetSetting("mono/editor/external_editor");
+ var editor = (ExternalEditorId)editorSettings.GetSetting("mono/editor/external_editor");
switch (editor)
{
@@ -202,6 +205,12 @@ namespace GodotTools
throw new NotSupportedException();
case ExternalEditorId.VisualStudioForMac:
goto case ExternalEditorId.MonoDevelop;
+ case ExternalEditorId.Rider:
+ {
+ string scriptPath = ProjectSettings.GlobalizePath(script.ResourcePath);
+ RiderPathManager.OpenFile(GodotSharpDirs.ProjectSlnPath, scriptPath, line);
+ return Error.Ok;
+ }
case ExternalEditorId.MonoDevelop:
{
string scriptPath = ProjectSettings.GlobalizePath(script.ResourcePath);
@@ -306,9 +315,10 @@ namespace GodotTools
return Error.Ok;
}
+ [UsedImplicitly]
public bool OverridesExternalEditor()
{
- return (ExternalEditorId) editorSettings.GetSetting("mono/editor/external_editor") != ExternalEditorId.None;
+ return (ExternalEditorId)editorSettings.GetSetting("mono/editor/external_editor") != ExternalEditorId.None;
}
public override bool Build()
@@ -336,7 +346,7 @@ namespace GodotTools
bottomPanelBtn = AddControlToBottomPanel(BottomPanel, "Mono".TTR());
- AddChild(new HotReloadAssemblyWatcher {Name = "HotReloadAssemblyWatcher"});
+ AddChild(new HotReloadAssemblyWatcher { Name = "HotReloadAssemblyWatcher" });
menuPopup = new PopupMenu();
menuPopup.Hide();
@@ -346,7 +356,7 @@ namespace GodotTools
// TODO: Remove or edit this info dialog once Mono support is no longer in alpha
{
- menuPopup.AddItem("About C# support".TTR(), (int) MenuOptions.AboutCSharp);
+ menuPopup.AddItem("About C# support".TTR(), (int)MenuOptions.AboutCSharp);
aboutDialog = new AcceptDialog();
editorBaseControl.AddChild(aboutDialog);
aboutDialog.WindowTitle = "Important: C# support is not feature-complete";
@@ -369,7 +379,7 @@ namespace GodotTools
var aboutLabel = new Label();
aboutHBox.AddChild(aboutLabel);
aboutLabel.RectMinSize = new Vector2(600, 150) * EditorScale;
- aboutLabel.SizeFlagsVertical = (int) Control.SizeFlags.ExpandFill;
+ aboutLabel.SizeFlagsVertical = (int)Control.SizeFlags.ExpandFill;
aboutLabel.Autowrap = true;
aboutLabel.Text =
"C# support in Godot Engine is in late alpha stage and, while already usable, " +
@@ -384,7 +394,7 @@ namespace GodotTools
EditorDef("mono/editor/show_info_on_start", true);
// CheckBox in main container
- aboutDialogCheckBox = new CheckBox {Text = "Show this warning when starting the editor"};
+ aboutDialogCheckBox = new CheckBox { Text = "Show this warning when starting the editor" };
aboutDialogCheckBox.Connect("toggled", this, nameof(_ToggleAboutDialogOnStart));
aboutVBox.AddChild(aboutDialogCheckBox);
}
@@ -397,7 +407,7 @@ namespace GodotTools
else
{
bottomPanelBtn.Hide();
- menuPopup.AddItem("Create C# solution".TTR(), (int) MenuOptions.CreateSln);
+ menuPopup.AddItem("Create C# solution".TTR(), (int)MenuOptions.CreateSln);
}
menuPopup.Connect("id_pressed", this, nameof(_MenuOptionPressed));
@@ -418,19 +428,22 @@ namespace GodotTools
if (OS.IsWindows)
{
- settingsHintStr += $",MonoDevelop:{(int) ExternalEditorId.MonoDevelop}" +
- $",Visual Studio Code:{(int) ExternalEditorId.VsCode}";
+ settingsHintStr += $",MonoDevelop:{(int)ExternalEditorId.MonoDevelop}" +
+ $",Visual Studio Code:{(int)ExternalEditorId.VsCode}" +
+ $",JetBrains Rider:{(int)ExternalEditorId.Rider}";
}
else if (OS.IsOSX)
{
- settingsHintStr += $",Visual Studio:{(int) ExternalEditorId.VisualStudioForMac}" +
- $",MonoDevelop:{(int) ExternalEditorId.MonoDevelop}" +
- $",Visual Studio Code:{(int) ExternalEditorId.VsCode}";
+ settingsHintStr += $",Visual Studio:{(int)ExternalEditorId.VisualStudioForMac}" +
+ $",MonoDevelop:{(int)ExternalEditorId.MonoDevelop}" +
+ $",Visual Studio Code:{(int)ExternalEditorId.VsCode}" +
+ $",JetBrains Rider:{(int)ExternalEditorId.Rider}";
}
else if (OS.IsUnixLike())
{
- settingsHintStr += $",MonoDevelop:{(int) ExternalEditorId.MonoDevelop}" +
- $",Visual Studio Code:{(int) ExternalEditorId.VsCode}";
+ settingsHintStr += $",MonoDevelop:{(int)ExternalEditorId.MonoDevelop}" +
+ $",Visual Studio Code:{(int)ExternalEditorId.VsCode}" +
+ $",JetBrains Rider:{(int)ExternalEditorId.Rider}";
}
editorSettings.AddPropertyInfo(new Godot.Collections.Dictionary
@@ -448,6 +461,7 @@ namespace GodotTools
exportPluginWeak = WeakRef(exportPlugin);
BuildManager.Initialize();
+ RiderPathManager.Initialize();
GodotIdeManager = new GodotIdeManager();
AddChild(GodotIdeManager);
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj b/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj
index fb2cbabc8e..15b9e50a8d 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -30,7 +30,14 @@
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<ItemGroup>
- <Reference Include="Mono.Posix" />
+ <Reference Include="JetBrains.Annotations, Version=2019.1.3.0, Culture=neutral, PublicKeyToken=1010a0d8d6380325">
+ <HintPath>..\packages\JetBrains.Annotations.2019.1.3\lib\net20\JetBrains.Annotations.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed">
+ <HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
<Reference Include="System" />
<Reference Include="GodotSharp">
<HintPath>$(GodotSourceRootPath)/bin/GodotSharp/Api/$(GodotApiConfiguration)/GodotSharp.dll</HintPath>
@@ -47,6 +54,8 @@
<Compile Include="Ides\GodotIdeServer.cs" />
<Compile Include="Ides\MonoDevelop\EditorId.cs" />
<Compile Include="Ides\MonoDevelop\Instance.cs" />
+ <Compile Include="Ides\Rider\RiderPathLocator.cs" />
+ <Compile Include="Ides\Rider\RiderPathManager.cs" />
<Compile Include="Internals\BindingsGenerator.cs" />
<Compile Include="Internals\EditorProgress.cs" />
<Compile Include="Internals\GodotSharpDirs.cs" />
@@ -67,6 +76,7 @@
<Compile Include="BottomPanel.cs" />
<Compile Include="CsProjOperations.cs" />
<Compile Include="Utils\CollectionExtensions.cs" />
+ <Compile Include="Utils\User32Dll.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GodotTools.BuildLogger\GodotTools.BuildLogger.csproj">
@@ -86,5 +96,8 @@
<Name>GodotTools.Core</Name>
</ProjectReference>
</ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project> \ No newline at end of file
diff --git a/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs b/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs
index 0f6f5ffadc..0ed567afd1 100644
--- a/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs
@@ -38,7 +38,7 @@ namespace GodotTools
watchTimer = new Timer
{
OneShot = false,
- WaitTime = (float) EditorDef("mono/assembly_watch_interval_sec", 0.5)
+ WaitTime = (float)EditorDef("mono/assembly_watch_interval_sec", 0.5)
};
watchTimer.Connect("timeout", this, nameof(TimerTimeout));
AddChild(watchTimer);
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs
index f94d6f998c..54f0ffab96 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs
@@ -64,7 +64,7 @@ namespace GodotTools.Ides
private void LaunchIde()
{
- var editor = (ExternalEditorId) GodotSharpEditor.Instance.GetEditorInterface()
+ var editor = (ExternalEditorId)GodotSharpEditor.Instance.GetEditorInterface()
.GetEditorSettings().GetSetting("mono/editor/external_editor");
switch (editor)
@@ -72,6 +72,7 @@ namespace GodotTools.Ides
case ExternalEditorId.None:
case ExternalEditorId.VisualStudio:
case ExternalEditorId.VsCode:
+ case ExternalEditorId.Rider:
throw new NotSupportedException();
case ExternalEditorId.VisualStudioForMac:
goto case ExternalEditorId.MonoDevelop;
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeServer.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeServer.cs
index 309b917c71..72676a8b24 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeServer.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeServer.cs
@@ -45,7 +45,7 @@ namespace GodotTools.Ides
listener = new TcpListener(new IPEndPoint(IPAddress.Loopback, port: 0));
listener.Start();
- int port = ((IPEndPoint) listener.Server.LocalEndPoint).Port;
+ int port = ((IPEndPoint)listener.Server.LocalEndPoint).Port;
using (var metaFileWriter = new StreamWriter(metaFile, Encoding.UTF8))
{
metaFileWriter.WriteLine(port);
@@ -57,7 +57,7 @@ namespace GodotTools.Ides
public void StartServer()
{
- var serverThread = new Thread(RunServerThread) {Name = "Godot Ide Connection Server"};
+ var serverThread = new Thread(RunServerThread) { Name = "Godot Ide Connection Server" };
serverThread.Start();
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs
new file mode 100644
index 0000000000..b752535dcb
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs
@@ -0,0 +1,416 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Godot;
+using JetBrains.Annotations;
+using Microsoft.Win32;
+using Newtonsoft.Json;
+using Directory = System.IO.Directory;
+using Environment = System.Environment;
+using File = System.IO.File;
+using Path = System.IO.Path;
+using OS = GodotTools.Utils.OS;
+
+namespace GodotTools.Ides.Rider
+{
+ /// <summary>
+ /// This code is a modified version of the JetBrains resharper-unity plugin listed under Apache License 2.0 license:
+ /// https://github.com/JetBrains/resharper-unity/blob/master/unity/JetBrains.Rider.Unity.Editor/EditorPlugin/RiderPathLocator.cs
+ /// </summary>
+ public static class RiderPathLocator
+ {
+ public static RiderInfo[] GetAllRiderPaths()
+ {
+ try
+ {
+ if (OS.IsWindows)
+ {
+ return CollectRiderInfosWindows();
+ }
+ if (OS.IsOSX)
+ {
+ return CollectRiderInfosMac();
+ }
+ if (OS.IsUnixLike())
+ {
+ return CollectAllRiderPathsLinux();
+ }
+ throw new Exception("Unexpected OS.");
+ }
+ catch (Exception e)
+ {
+ GD.PushWarning(e.Message);
+ }
+
+ return new RiderInfo[0];
+ }
+
+ private static RiderInfo[] CollectAllRiderPathsLinux()
+ {
+ var installInfos = new List<RiderInfo>();
+ var home = Environment.GetEnvironmentVariable("HOME");
+ if (!string.IsNullOrEmpty(home))
+ {
+ var toolboxRiderRootPath = GetToolboxBaseDir();
+ installInfos.AddRange(CollectPathsFromToolbox(toolboxRiderRootPath, "bin", "rider.sh", false)
+ .Select(a => new RiderInfo(a, true)).ToList());
+
+ //$Home/.local/share/applications/jetbrains-rider.desktop
+ var shortcut = new FileInfo(Path.Combine(home, @".local/share/applications/jetbrains-rider.desktop"));
+
+ if (shortcut.Exists)
+ {
+ var lines = File.ReadAllLines(shortcut.FullName);
+ foreach (var line in lines)
+ {
+ if (!line.StartsWith("Exec=\""))
+ continue;
+ var path = line.Split('"').Where((item, index) => index == 1).SingleOrDefault();
+ if (string.IsNullOrEmpty(path))
+ continue;
+
+ if (installInfos.Any(a => a.Path == path)) // avoid adding similar build as from toolbox
+ continue;
+ installInfos.Add(new RiderInfo(path, false));
+ }
+ }
+ }
+
+ // snap install
+ var snapInstallPath = "/snap/rider/current/bin/rider.sh";
+ if (new FileInfo(snapInstallPath).Exists)
+ installInfos.Add(new RiderInfo(snapInstallPath, false));
+
+ return installInfos.ToArray();
+ }
+
+ private static RiderInfo[] CollectRiderInfosMac()
+ {
+ var installInfos = new List<RiderInfo>();
+ // "/Applications/*Rider*.app"
+ var folder = new DirectoryInfo("/Applications");
+ if (folder.Exists)
+ {
+ installInfos.AddRange(folder.GetDirectories("*Rider*.app")
+ .Select(a => new RiderInfo(a.FullName, false))
+ .ToList());
+ }
+
+ // /Users/user/Library/Application Support/JetBrains/Toolbox/apps/Rider/ch-1/181.3870.267/Rider EAP.app
+ var toolboxRiderRootPath = GetToolboxBaseDir();
+ var paths = CollectPathsFromToolbox(toolboxRiderRootPath, "", "Rider*.app", true)
+ .Select(a => new RiderInfo(a, true));
+ installInfos.AddRange(paths);
+
+ return installInfos.ToArray();
+ }
+
+ private static RiderInfo[] CollectRiderInfosWindows()
+ {
+ var installInfos = new List<RiderInfo>();
+ var toolboxRiderRootPath = GetToolboxBaseDir();
+ var installPathsToolbox = CollectPathsFromToolbox(toolboxRiderRootPath, "bin", "rider64.exe", false).ToList();
+ installInfos.AddRange(installPathsToolbox.Select(a => new RiderInfo(a, true)).ToList());
+
+ var installPaths = new List<string>();
+ const string registryKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
+ CollectPathsFromRegistry(registryKey, installPaths);
+ const string wowRegistryKey = @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall";
+ CollectPathsFromRegistry(wowRegistryKey, installPaths);
+
+ installInfos.AddRange(installPaths.Select(a => new RiderInfo(a, false)).ToList());
+
+ return installInfos.ToArray();
+ }
+
+ private static string GetToolboxBaseDir()
+ {
+ if (OS.IsWindows)
+ {
+ var localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
+ return Path.Combine(localAppData, @"JetBrains\Toolbox\apps\Rider");
+ }
+
+ if (OS.IsOSX)
+ {
+ var home = Environment.GetEnvironmentVariable("HOME");
+ if (!string.IsNullOrEmpty(home))
+ {
+ return Path.Combine(home, @"Library/Application Support/JetBrains/Toolbox/apps/Rider");
+ }
+ }
+
+ if (OS.IsUnixLike())
+ {
+ var home = Environment.GetEnvironmentVariable("HOME");
+ if (!string.IsNullOrEmpty(home))
+ {
+ return Path.Combine(home, @".local/share/JetBrains/Toolbox/apps/Rider");
+ }
+ }
+
+ throw new Exception("Unexpected OS.");
+ }
+
+ internal static ProductInfo GetBuildVersion(string path)
+ {
+ var buildTxtFileInfo = new FileInfo(Path.Combine(path, GetRelativePathToBuildTxt()));
+ var dir = buildTxtFileInfo.DirectoryName;
+ if (!Directory.Exists(dir))
+ return null;
+ var buildVersionFile = new FileInfo(Path.Combine(dir, "product-info.json"));
+ if (!buildVersionFile.Exists)
+ return null;
+ var json = File.ReadAllText(buildVersionFile.FullName);
+ return ProductInfo.GetProductInfo(json);
+ }
+
+ internal static Version GetBuildNumber(string path)
+ {
+ var file = new FileInfo(Path.Combine(path, GetRelativePathToBuildTxt()));
+ if (!file.Exists)
+ return null;
+ var text = File.ReadAllText(file.FullName);
+ if (text.Length <= 3)
+ return null;
+
+ var versionText = text.Substring(3);
+ return Version.TryParse(versionText, out var v) ? v : null;
+ }
+
+ internal static bool IsToolbox(string path)
+ {
+ return path.StartsWith(GetToolboxBaseDir());
+ }
+
+ private static string GetRelativePathToBuildTxt()
+ {
+ if (OS.IsWindows || OS.IsUnixLike())
+ return "../../build.txt";
+ if (OS.IsOSX)
+ return "Contents/Resources/build.txt";
+ throw new Exception("Unknown OS.");
+ }
+
+ private static void CollectPathsFromRegistry(string registryKey, List<string> installPaths)
+ {
+ using (var key = Registry.LocalMachine.OpenSubKey(registryKey))
+ {
+ if (key == null) return;
+ foreach (var subkeyName in key.GetSubKeyNames().Where(a => a.Contains("Rider")))
+ {
+ using (var subkey = key.OpenSubKey(subkeyName))
+ {
+ var folderObject = subkey?.GetValue("InstallLocation");
+ if (folderObject == null) continue;
+ var folder = folderObject.ToString();
+ var possiblePath = Path.Combine(folder, @"bin\rider64.exe");
+ if (File.Exists(possiblePath))
+ installPaths.Add(possiblePath);
+ }
+ }
+ }
+ }
+
+ private static string[] CollectPathsFromToolbox(string toolboxRiderRootPath, string dirName, string searchPattern,
+ bool isMac)
+ {
+ if (!Directory.Exists(toolboxRiderRootPath))
+ return new string[0];
+
+ var channelDirs = Directory.GetDirectories(toolboxRiderRootPath);
+ var paths = channelDirs.SelectMany(channelDir =>
+ {
+ try
+ {
+ // use history.json - last entry stands for the active build https://jetbrains.slack.com/archives/C07KNP99D/p1547807024066500?thread_ts=1547731708.057700&cid=C07KNP99D
+ var historyFile = Path.Combine(channelDir, ".history.json");
+ if (File.Exists(historyFile))
+ {
+ var json = File.ReadAllText(historyFile);
+ var build = ToolboxHistory.GetLatestBuildFromJson(json);
+ if (build != null)
+ {
+ var buildDir = Path.Combine(channelDir, build);
+ var executablePaths = GetExecutablePaths(dirName, searchPattern, isMac, buildDir);
+ if (executablePaths.Any())
+ return executablePaths;
+ }
+ }
+
+ var channelFile = Path.Combine(channelDir, ".channel.settings.json");
+ if (File.Exists(channelFile))
+ {
+ var json = File.ReadAllText(channelFile).Replace("active-application", "active_application");
+ var build = ToolboxInstallData.GetLatestBuildFromJson(json);
+ if (build != null)
+ {
+ var buildDir = Path.Combine(channelDir, build);
+ var executablePaths = GetExecutablePaths(dirName, searchPattern, isMac, buildDir);
+ if (executablePaths.Any())
+ return executablePaths;
+ }
+ }
+
+ // changes in toolbox json files format may brake the logic above, so return all found Rider installations
+ return Directory.GetDirectories(channelDir)
+ .SelectMany(buildDir => GetExecutablePaths(dirName, searchPattern, isMac, buildDir));
+ }
+ catch (Exception e)
+ {
+ // do not write to Debug.Log, just log it.
+ Logger.Warn($"Failed to get RiderPath from {channelDir}", e);
+ }
+
+ return new string[0];
+ })
+ .Where(c => !string.IsNullOrEmpty(c))
+ .ToArray();
+ return paths;
+ }
+
+ private static string[] GetExecutablePaths(string dirName, string searchPattern, bool isMac, string buildDir)
+ {
+ var folder = new DirectoryInfo(Path.Combine(buildDir, dirName));
+ if (!folder.Exists)
+ return new string[0];
+
+ if (!isMac)
+ return new[] { Path.Combine(folder.FullName, searchPattern) }.Where(File.Exists).ToArray();
+ return folder.GetDirectories(searchPattern).Select(f => f.FullName)
+ .Where(Directory.Exists).ToArray();
+ }
+
+ // Disable the "field is never assigned" compiler warning. We never assign it, but Unity does.
+ // Note that Unity disable this warning in the generated C# projects
+#pragma warning disable 0649
+
+ [Serializable]
+ class ToolboxHistory
+ {
+ public List<ItemNode> history;
+
+ public static string GetLatestBuildFromJson(string json)
+ {
+ try
+ {
+ return JsonConvert.DeserializeObject<ToolboxHistory>(json).history.LastOrDefault()?.item.build;
+ }
+ catch (Exception)
+ {
+ Logger.Warn($"Failed to get latest build from json {json}");
+ }
+
+ return null;
+ }
+ }
+
+ [Serializable]
+ class ItemNode
+ {
+ public BuildNode item;
+ }
+
+ [Serializable]
+ class BuildNode
+ {
+ public string build;
+ }
+
+ [Serializable]
+ public class ProductInfo
+ {
+ public string version;
+ public string versionSuffix;
+
+ [CanBeNull]
+ internal static ProductInfo GetProductInfo(string json)
+ {
+ try
+ {
+ var productInfo = JsonConvert.DeserializeObject<ProductInfo>(json);
+ return productInfo;
+ }
+ catch (Exception)
+ {
+ Logger.Warn($"Failed to get version from json {json}");
+ }
+
+ return null;
+ }
+ }
+
+ // ReSharper disable once ClassNeverInstantiated.Global
+ [Serializable]
+ class ToolboxInstallData
+ {
+ // ReSharper disable once InconsistentNaming
+ public ActiveApplication active_application;
+
+ [CanBeNull]
+ public static string GetLatestBuildFromJson(string json)
+ {
+ try
+ {
+ var toolbox = JsonConvert.DeserializeObject<ToolboxInstallData>(json);
+ var builds = toolbox.active_application.builds;
+ if (builds != null && builds.Any())
+ return builds.First();
+ }
+ catch (Exception)
+ {
+ Logger.Warn($"Failed to get latest build from json {json}");
+ }
+
+ return null;
+ }
+ }
+
+ [Serializable]
+ class ActiveApplication
+ {
+ // ReSharper disable once InconsistentNaming
+ public List<string> builds;
+ }
+
+#pragma warning restore 0649
+
+ public struct RiderInfo
+ {
+ public bool IsToolbox;
+ public string Presentation;
+ public Version BuildNumber;
+ public ProductInfo ProductInfo;
+ public string Path;
+
+ public RiderInfo(string path, bool isToolbox)
+ {
+ BuildNumber = GetBuildNumber(path);
+ ProductInfo = GetBuildVersion(path);
+ Path = new FileInfo(path).FullName; // normalize separators
+ var presentation = $"Rider {BuildNumber}";
+
+ if (ProductInfo != null && !string.IsNullOrEmpty(ProductInfo.version))
+ {
+ var suffix = string.IsNullOrEmpty(ProductInfo.versionSuffix) ? "" : $" {ProductInfo.versionSuffix}";
+ presentation = $"Rider {ProductInfo.version}{suffix}";
+ }
+
+ if (isToolbox)
+ presentation += " (JetBrains Toolbox)";
+
+ Presentation = presentation;
+ IsToolbox = isToolbox;
+ }
+ }
+
+ private static class Logger
+ {
+ internal static void Warn(string message, Exception e = null)
+ {
+ throw new Exception(message, e);
+ }
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs
new file mode 100644
index 0000000000..558a242bf9
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs
@@ -0,0 +1,117 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Godot;
+using GodotTools.Internals;
+
+namespace GodotTools.Ides.Rider
+{
+ public static class RiderPathManager
+ {
+ private static readonly string editorPathSettingName = "mono/editor/editor_path_optional";
+
+ private static string GetRiderPathFromSettings()
+ {
+ var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings();
+ if (editorSettings.HasSetting(editorPathSettingName))
+ return (string)editorSettings.GetSetting(editorPathSettingName);
+ return null;
+ }
+
+ public static void Initialize()
+ {
+ var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings();
+ var editor = (ExternalEditorId)editorSettings.GetSetting("mono/editor/external_editor");
+ if (editor == ExternalEditorId.Rider)
+ {
+ if (!editorSettings.HasSetting(editorPathSettingName))
+ {
+ Globals.EditorDef(editorPathSettingName, "Optional");
+ editorSettings.AddPropertyInfo(new Godot.Collections.Dictionary
+ {
+ ["type"] = Variant.Type.String,
+ ["name"] = editorPathSettingName,
+ ["hint"] = PropertyHint.File,
+ ["hint_string"] = ""
+ });
+ }
+
+ var riderPath = (string)editorSettings.GetSetting(editorPathSettingName);
+ if (IsRiderAndExists(riderPath))
+ {
+ Globals.EditorDef(editorPathSettingName, riderPath);
+ return;
+ }
+
+ var paths = RiderPathLocator.GetAllRiderPaths();
+
+ if (!paths.Any())
+ return;
+
+ var newPath = paths.Last().Path;
+ Globals.EditorDef(editorPathSettingName, newPath);
+ editorSettings.SetSetting(editorPathSettingName, newPath);
+ }
+ }
+
+ private static bool IsRider(string path)
+ {
+ if (string.IsNullOrEmpty(path))
+ {
+ return false;
+ }
+
+ var fileInfo = new FileInfo(path);
+ var filename = fileInfo.Name.ToLowerInvariant();
+ return filename.StartsWith("rider", StringComparison.Ordinal);
+ }
+
+ private static string CheckAndUpdatePath(string riderPath)
+ {
+ if (IsRiderAndExists(riderPath))
+ {
+ return riderPath;
+ }
+
+ var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings();
+ var paths = RiderPathLocator.GetAllRiderPaths();
+
+ if (!paths.Any())
+ return null;
+
+ var newPath = paths.Last().Path;
+ editorSettings.SetSetting(editorPathSettingName, newPath);
+ Globals.EditorDef(editorPathSettingName, newPath);
+ return newPath;
+ }
+
+ private static bool IsRiderAndExists(string riderPath)
+ {
+ return !string.IsNullOrEmpty(riderPath) && IsRider(riderPath) && new FileInfo(riderPath).Exists;
+ }
+
+ public static void OpenFile(string slnPath, string scriptPath, int line)
+ {
+ var pathFromSettings = GetRiderPathFromSettings();
+ var path = CheckAndUpdatePath(pathFromSettings);
+
+ var args = new List<string>();
+ args.Add(slnPath);
+ if (line >= 0)
+ {
+ args.Add("--line");
+ args.Add(line.ToString());
+ }
+ args.Add(scriptPath);
+ try
+ {
+ Utils.OS.RunProcess(path, args);
+ }
+ catch (Exception e)
+ {
+ GD.PushError($"Error when trying to run code editor: JetBrains Rider. Exception message: '{e.Message}'");
+ }
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs
index ddf3b829b5..6893bc1974 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs
@@ -33,10 +33,10 @@ namespace GodotTools.Internals
#region Windows-only
public static string DataMonoBinDir => internal_DataMonoBinDir();
#endregion
-
-
+
+
#region Internal
-
+
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_ResDataDir();
[MethodImpl(MethodImplOptions.InternalCall)]
@@ -85,7 +85,7 @@ namespace GodotTools.Internals
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_DataMonoBinDir();
#endregion
-
+
#endregion
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/ScriptClassParser.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/ScriptClassParser.cs
index 2497d276a9..80e45b3a3c 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Internals/ScriptClassParser.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Internals/ScriptClassParser.cs
@@ -39,10 +39,10 @@ namespace GodotTools.Internals
foreach (var classDeclDict in classesArray)
{
classesList.Add(new ClassDecl(
- (string) classDeclDict["name"],
- (string) classDeclDict["namespace"],
- (bool) classDeclDict["nested"],
- (int) classDeclDict["base_count"]
+ (string)classDeclDict["name"],
+ (string)classDeclDict["namespace"],
+ (bool)classDeclDict["nested"],
+ (int)classDeclDict["base_count"]
));
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
index e89ea0c476..279e67b3eb 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
@@ -5,7 +5,6 @@ using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
-using Mono.Unix.Native;
namespace GodotTools.Utils
{
@@ -15,6 +14,9 @@ namespace GodotTools.Utils
[MethodImpl(MethodImplOptions.InternalCall)]
static extern string GetPlatformName();
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ static extern bool UnixFileHasExecutableAccess(string filePath);
+
public static class Names
{
public const string Windows = "Windows";
@@ -75,7 +77,7 @@ namespace GodotTools.Utils
public static bool IsHTML5 => _isHTML5.Value;
private static bool? _isUnixCache;
- private static readonly string[] UnixLikePlatforms = {Names.OSX, Names.X11, Names.Server, Names.Haiku, Names.Android};
+ private static readonly string[] UnixLikePlatforms = { Names.OSX, Names.X11, Names.Server, Names.Haiku, Names.Android };
public static bool IsUnixLike()
{
@@ -105,7 +107,7 @@ namespace GodotTools.Utils
searchDirs.AddRange(pathDirs);
string nameExt = Path.GetExtension(name);
- bool hasPathExt = string.IsNullOrEmpty(nameExt) || windowsExts.Contains(nameExt, StringComparer.OrdinalIgnoreCase);
+ bool hasPathExt = !string.IsNullOrEmpty(nameExt) && windowsExts.Contains(nameExt, StringComparer.OrdinalIgnoreCase);
searchDirs.Add(System.IO.Directory.GetCurrentDirectory()); // last in the list
@@ -113,10 +115,10 @@ namespace GodotTools.Utils
return searchDirs.Select(dir => Path.Combine(dir, name)).FirstOrDefault(File.Exists);
return (from dir in searchDirs
- select Path.Combine(dir, name)
+ select Path.Combine(dir, name)
into path
- from ext in windowsExts
- select path + ext).FirstOrDefault(File.Exists);
+ from ext in windowsExts
+ select path + ext).FirstOrDefault(File.Exists);
}
private static string PathWhichUnix(string name)
@@ -131,7 +133,7 @@ namespace GodotTools.Utils
searchDirs.Add(System.IO.Directory.GetCurrentDirectory()); // last in the list
return searchDirs.Select(dir => Path.Combine(dir, name))
- .FirstOrDefault(path => File.Exists(path) && Syscall.access(path, AccessModes.X_OK) == 0);
+ .FirstOrDefault(path => File.Exists(path) && UnixFileHasExecutableAccess(path));
}
public static void RunProcess(string command, IEnumerable<string> arguments)
@@ -157,6 +159,8 @@ namespace GodotTools.Utils
process.BeginOutputReadLine();
process.BeginErrorReadLine();
+ if (IsWindows && process.Id > 0)
+ User32Dll.AllowSetForegroundWindow(process.Id); // allows application to focus itself
}
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/User32Dll.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/User32Dll.cs
new file mode 100644
index 0000000000..6810a991b3
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools/Utils/User32Dll.cs
@@ -0,0 +1,10 @@
+using System.Runtime.InteropServices;
+
+namespace GodotTools.Utils
+{
+ public static class User32Dll
+ {
+ [DllImport("user32.dll")]
+ public static extern bool AllowSetForegroundWindow(int dwProcessId);
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools/packages.config b/modules/mono/editor/GodotTools/GodotTools/packages.config
new file mode 100644
index 0000000000..dd3de2865a
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools/packages.config
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="JetBrains.Annotations" version="2019.1.3" targetFramework="net45" />
+ <package id="Newtonsoft.Json" version="12.0.3" targetFramework="net45" />
+</packages>
diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp
index 443b4ba841..48a3259a90 100644
--- a/modules/mono/editor/editor_internal_calls.cpp
+++ b/modules/mono/editor/editor_internal_calls.cpp
@@ -30,6 +30,10 @@
#include "editor_internal_calls.h"
+#ifdef UNIX_ENABLED
+#include <unistd.h> // access
+#endif
+
#include "core/os/os.h"
#include "core/version.h"
#include "editor/editor_node.h"
@@ -370,6 +374,15 @@ MonoString *godot_icall_Utils_OS_GetPlatformName() {
return GDMonoMarshal::mono_string_from_godot(os_name);
}
+MonoBoolean godot_icall_Utils_OS_UnixFileHasExecutableAccess(MonoString *p_file_path) {
+#ifdef UNIX_ENABLED
+ String file_path = GDMonoMarshal::mono_string_to_godot(p_file_path);
+ return access(file_path.utf8().get_data(), X_OK) == 0;
+#else
+ ERR_FAIL_V(false);
+#endif
+}
+
void register_editor_internal_calls() {
// GodotSharpDirs
@@ -442,4 +455,5 @@ void register_editor_internal_calls() {
// Utils.OS
mono_add_internal_call("GodotTools.Utils.OS::GetPlatformName", (void *)godot_icall_Utils_OS_GetPlatformName);
+ mono_add_internal_call("GodotTools.Utils.OS::UnixFileHasExecutableAccess", (void *)godot_icall_Utils_OS_UnixFileHasExecutableAccess);
}
diff --git a/modules/mono/editor/script_class_parser.cpp b/modules/mono/editor/script_class_parser.cpp
index dcb0ca5a80..1c3a583601 100644
--- a/modules/mono/editor/script_class_parser.cpp
+++ b/modules/mono/editor/script_class_parser.cpp
@@ -501,12 +501,15 @@ Error ScriptClassParser::parse(const String &p_code) {
int type_curly_stack = 0;
while (!error && tk != TK_EOF) {
- if (tk == TK_IDENTIFIER && String(value) == "class") {
+ String identifier = value;
+ if (tk == TK_IDENTIFIER && (identifier == "class" || identifier == "struct")) {
+ bool is_class = identifier == "class";
+
tk = get_token();
if (tk == TK_IDENTIFIER) {
String name = value;
- int at_level = type_curly_stack;
+ int at_level = curly_stack;
ClassDecl class_decl;
@@ -568,48 +571,22 @@ Error ScriptClassParser::parse(const String &p_code) {
NameDecl name_decl;
name_decl.name = name;
- name_decl.type = NameDecl::CLASS_DECL;
+ name_decl.type = is_class ? NameDecl::CLASS_DECL : NameDecl::STRUCT_DECL;
name_stack[at_level] = name_decl;
- if (!generic) { // no generics, thanks
- classes.push_back(class_decl);
- } else if (OS::get_singleton()->is_stdout_verbose()) {
- String full_name = class_decl.namespace_;
- if (full_name.length())
- full_name += ".";
- full_name += class_decl.name;
- OS::get_singleton()->print("Ignoring generic class declaration: %s\n", class_decl.name.utf8().get_data());
- }
- }
- } else if (tk == TK_IDENTIFIER && String(value) == "struct") {
- String name;
- int at_level = type_curly_stack;
- while (true) {
- tk = get_token();
- if (tk == TK_IDENTIFIER && name.empty()) {
- name = String(value);
- } else if (tk == TK_CURLY_BRACKET_OPEN) {
- if (name.empty()) {
- error_str = "Expected " + get_token_name(TK_IDENTIFIER) + " after keyword 'struct', found " + get_token_name(TK_CURLY_BRACKET_OPEN);
- error = true;
- return ERR_PARSE_ERROR;
+ if (is_class) {
+ if (!generic) { // no generics, thanks
+ classes.push_back(class_decl);
+ } else if (OS::get_singleton()->is_stdout_verbose()) {
+ String full_name = class_decl.namespace_;
+ if (full_name.length())
+ full_name += ".";
+ full_name += class_decl.name;
+ OS::get_singleton()->print("Ignoring generic class declaration: %s\n", full_name.utf8().get_data());
}
-
- curly_stack++;
- type_curly_stack++;
- break;
- } else if (tk == TK_EOF) {
- error_str = "Expected " + get_token_name(TK_CURLY_BRACKET_OPEN) + " after struct decl, found " + get_token_name(TK_EOF);
- error = true;
- return ERR_PARSE_ERROR;
}
}
-
- NameDecl name_decl;
- name_decl.name = name;
- name_decl.type = NameDecl::STRUCT_DECL;
- name_stack[at_level] = name_decl;
- } else if (tk == TK_IDENTIFIER && String(value) == "namespace") {
+ } else if (tk == TK_IDENTIFIER && identifier == "namespace") {
if (type_curly_stack > 0) {
error_str = "Found namespace nested inside type.";
error = true;
diff --git a/modules/mono/glue/Managed/Files/StringExtensions.cs b/modules/mono/glue/Managed/Files/StringExtensions.cs
index 6045c83e95..b926037e5a 100644
--- a/modules/mono/glue/Managed/Files/StringExtensions.cs
+++ b/modules/mono/glue/Managed/Files/StringExtensions.cs
@@ -18,7 +18,7 @@ namespace Godot
int pos = 0;
int slices = 1;
- while ((pos = instance.Find(splitter, pos)) >= 0)
+ while ((pos = instance.Find(splitter, pos, caseSensitive: true)) >= 0)
{
slices++;
pos += splitter.Length;
@@ -229,7 +229,7 @@ namespace Godot
// </summary>
public static int CasecmpTo(this string instance, string to)
{
- return instance.CompareTo(to, true);
+ return instance.CompareTo(to, caseSensitive: true);
}
// <summary>
@@ -322,28 +322,32 @@ namespace Godot
return instance.Substring(pos + 1);
}
- // <summary>
- // Find the first occurrence of a substring, return the starting position of the substring or -1 if not found. Optionally, the initial search index can be passed.
- // </summary>
- public static int Find(this string instance, string what, int from = 0)
+ /// <summary>Find the first occurrence of a substring. Optionally, the search starting position can be passed.</summary>
+ /// <returns>The starting position of the substring, or -1 if not found.</returns>
+ public static int Find(this string instance, string what, int from = 0, bool caseSensitive = true)
{
- return instance.IndexOf(what, StringComparison.OrdinalIgnoreCase);
+ return instance.IndexOf(what, from, caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase);
}
- // <summary>
- // Find the last occurrence of a substring, return the starting position of the substring or -1 if not found. Optionally, the initial search index can be passed.
- // </summary>
- public static int FindLast(this string instance, string what)
+ /// <summary>Find the last occurrence of a substring.</summary>
+ /// <returns>The starting position of the substring, or -1 if not found.</returns>
+ public static int FindLast(this string instance, string what, bool caseSensitive = true)
{
- return instance.LastIndexOf(what, StringComparison.OrdinalIgnoreCase);
+ return instance.FindLast(what, instance.Length - 1, caseSensitive);
}
- // <summary>
- // Find the first occurrence of a substring but search as case-insensitive, return the starting position of the substring or -1 if not found. Optionally, the initial search index can be passed.
- // </summary>
+ /// <summary>Find the last occurrence of a substring specifying the search starting position.</summary>
+ /// <returns>The starting position of the substring, or -1 if not found.</returns>
+ public static int FindLast(this string instance, string what, int from, bool caseSensitive = true)
+ {
+ return instance.LastIndexOf(what, from, caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase);
+ }
+
+ /// <summary>Find the first occurrence of a substring but search as case-insensitive. Optionally, the search starting position can be passed.</summary>
+ /// <returns>The starting position of the substring, or -1 if not found.</returns>
public static int FindN(this string instance, string what, int from = 0)
{
- return instance.IndexOf(what, StringComparison.Ordinal);
+ return instance.IndexOf(what, from, StringComparison.OrdinalIgnoreCase);
}
// <summary>
@@ -502,7 +506,7 @@ namespace Godot
// </summary>
public static bool IsSubsequenceOfI(this string instance, string text)
{
- return instance.IsSubsequenceOf(text, false);
+ return instance.IsSubsequenceOf(text, caseSensitive: false);
}
// <summary>
@@ -662,7 +666,7 @@ namespace Godot
// </summary>
public static bool MatchN(this string instance, string expr)
{
- return instance.ExprMatch(expr, false);
+ return instance.ExprMatch(expr, caseSensitive: false);
}
// <summary>
@@ -692,7 +696,7 @@ namespace Godot
// </summary>
public static int NocasecmpTo(this string instance, string to)
{
- return instance.CompareTo(to, false);
+ return instance.CompareTo(to, caseSensitive: false);
}
// <summary>
@@ -928,7 +932,7 @@ namespace Godot
while (true)
{
- int end = instance.Find(divisor, from);
+ int end = instance.Find(divisor, from, caseSensitive: true);
if (end < 0)
end = len;
if (allowEmpty || end > from)
diff --git a/modules/mono/glue/Managed/Managed.csproj b/modules/mono/glue/Managed/Managed.csproj
index c8eca71199..8bde3b6d22 100644
--- a/modules/mono/glue/Managed/Managed.csproj
+++ b/modules/mono/glue/Managed/Managed.csproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp
index 33ba877352..6cafa6709f 100644
--- a/modules/mono/mono_gd/gd_mono.cpp
+++ b/modules/mono/mono_gd/gd_mono.cpp
@@ -102,33 +102,23 @@ void gd_mono_profiler_init() {
bool profiler_enabled = GLOBAL_DEF("mono/profiler/enabled", false);
if (profiler_enabled) {
mono_profiler_load(profiler_args.utf8());
+ return;
}
-}
-
-#if defined(DEBUG_ENABLED)
-
-bool gd_mono_wait_for_debugger_msecs(uint32_t p_msecs) {
-
- do {
- if (mono_is_debugger_attached())
- return true;
-
- int last_tick = OS::get_singleton()->get_ticks_msec();
-
- OS::get_singleton()->delay_usec((p_msecs < 25 ? p_msecs : 25) * 1000);
- uint32_t tdiff = OS::get_singleton()->get_ticks_msec() - last_tick;
-
- if (tdiff > p_msecs) {
- p_msecs = 0;
- } else {
- p_msecs -= tdiff;
+ const String env_var_name = "MONO_ENV_OPTIONS";
+ if (OS::get_singleton()->has_environment(env_var_name)) {
+ const auto mono_env_ops = OS::get_singleton()->get_environment(env_var_name);
+ // Usually MONO_ENV_OPTIONS looks like: --profile=jb:prof=timeline,ctl=remote,host=127.0.0.1:55467
+ const String prefix = "--profile=";
+ if (mono_env_ops.begins_with(prefix)) {
+ const auto ops = mono_env_ops.substr(prefix.length(), mono_env_ops.length());
+ mono_profiler_load(ops.utf8());
}
- } while (p_msecs > 0);
-
- return mono_is_debugger_attached();
+ }
}
+#if defined(DEBUG_ENABLED)
+
void gd_mono_debug_init() {
mono_debug_init(MONO_DEBUG_FORMAT_MONO);
@@ -356,7 +346,7 @@ void GDMono::initialize() {
}
#endif
-#if !defined(WINDOWS_ENABLED) && !defined(NO_MONO_THREADS_SUSPEND_WORKAROUND)
+#if !defined(NO_MONO_THREADS_SUSPEND_WORKAROUND)
// FIXME: Temporary workaround. See: https://github.com/godotengine/godot/issues/29812
if (!OS::get_singleton()->has_environment("MONO_THREADS_SUSPEND")) {
OS::get_singleton()->set_environment("MONO_THREADS_SUSPEND", "preemptive");
@@ -390,12 +380,6 @@ void GDMono::initialize() {
Error domain_load_err = _load_scripts_domain();
ERR_FAIL_COND_MSG(domain_load_err != OK, "Mono: Failed to load scripts domain.");
-#if defined(DEBUG_ENABLED) && !defined(JAVASCRIPT_ENABLED)
- bool debugger_attached = gd_mono_wait_for_debugger_msecs(500);
- if (!debugger_attached && OS::get_singleton()->is_stdout_verbose())
- print_error("Mono: Debugger wait timeout");
-#endif
-
_register_internal_calls();
print_verbose("Mono: INITIALIZED");
diff --git a/modules/mono/mono_gd/gd_mono_android.cpp b/modules/mono/mono_gd/gd_mono_android.cpp
index 86af8d1812..29ae4856be 100644
--- a/modules/mono/mono_gd/gd_mono_android.cpp
+++ b/modules/mono/mono_gd/gd_mono_android.cpp
@@ -81,7 +81,8 @@ struct ScopedLocalRef {
ScopedLocalRef &operator=(const ScopedLocalRef &) = delete;
ScopedLocalRef(JNIEnv *p_env, T p_local_ref) :
- env(p_env), local_ref(p_local_ref) {
+ env(p_env),
+ local_ref(p_local_ref) {
}
~ScopedLocalRef() {
diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp
index d84359b1ab..56a9bf46a3 100644
--- a/modules/mono/mono_gd/gd_mono_field.cpp
+++ b/modules/mono/mono_gd/gd_mono_field.cpp
@@ -110,8 +110,14 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
} break;
case MONO_TYPE_STRING: {
- MonoString *mono_string = GDMonoMarshal::mono_string_from_godot(p_value);
- mono_field_set_value(p_object, mono_field, mono_string);
+ if (p_value.get_type() == Variant::NIL) {
+ // Otherwise, Variant -> String would return the string "Null"
+ MonoString *mono_string = NULL;
+ mono_field_set_value(p_object, mono_field, mono_string);
+ } else {
+ MonoString *mono_string = GDMonoMarshal::mono_string_from_godot(p_value);
+ mono_field_set_value(p_object, mono_field, mono_string);
+ }
} break;
case MONO_TYPE_VALUETYPE: {
diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp
index f74fe5715c..9f55b31edc 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.cpp
+++ b/modules/mono/mono_gd/gd_mono_marshal.cpp
@@ -374,6 +374,8 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
}
case MONO_TYPE_STRING: {
+ if (p_var->get_type() == Variant::NIL)
+ return NULL; // Otherwise, Variant -> String would return the string "Null"
return (MonoObject *)mono_string_from_godot(p_var->operator String());
} break;
diff --git a/modules/recast/navigation_mesh_generator.cpp b/modules/recast/navigation_mesh_generator.cpp
index 320591cf7c..b668085f90 100644
--- a/modules/recast/navigation_mesh_generator.cpp
+++ b/modules/recast/navigation_mesh_generator.cpp
@@ -62,7 +62,7 @@ void EditorNavigationMeshGenerator::_add_vertex(const Vector3 &p_vec3, Vector<fl
}
void EditorNavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices) {
- int current_vertex_count = 0;
+ int current_vertex_count;
for (int i = 0; i < p_mesh->get_surface_count(); i++) {
current_vertex_count = p_verticies.size() / 3;
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index bf353d287f..13b645732e 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -572,7 +572,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
if (nd_list->is_input_port_editable()) {
has_gnode_text = true;
Button *btn = memnew(Button);
- btn->set_text("Add Input Port");
+ btn->set_text(TTR("Add Input Port"));
hbnc->add_child(btn);
btn->connect("pressed", this, "_add_input_port", varray(E->get()));
}
@@ -581,7 +581,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
hbnc->add_spacer();
has_gnode_text = true;
Button *btn = memnew(Button);
- btn->set_text("Add Output Port");
+ btn->set_text(TTR("Add Output Port"));
hbnc->add_child(btn);
btn->connect("pressed", this, "_add_output_port", varray(E->get()));
}
@@ -4756,7 +4756,7 @@ VisualScriptEditor::VisualScriptEditor() {
HBoxContainer *graph_hbc = graph->get_zoom_hbox();
Label *base_lbl = memnew(Label);
- base_lbl->set_text("Change Base Type: ");
+ base_lbl->set_text(TTR("Change Base Type:") + " ");
graph_hbc->add_child(base_lbl);
base_type_select = memnew(Button);
@@ -4764,18 +4764,19 @@ VisualScriptEditor::VisualScriptEditor() {
graph_hbc->add_child(base_type_select);
Button *add_nds = memnew(Button);
- add_nds->set_text("Add Nodes...");
+ add_nds->set_text(TTR("Add Nodes..."));
graph_hbc->add_child(add_nds);
add_nds->connect("pressed", this, "_add_node_dialog");
Button *fn_btn = memnew(Button);
- fn_btn->set_text("Add Function...");
+ fn_btn->set_text(TTR("Add Function..."));
graph_hbc->add_child(fn_btn);
fn_btn->connect("pressed", this, "_create_function_dialog");
// Add Function Dialog.
VBoxContainer *function_vb = memnew(VBoxContainer);
function_vb->set_v_size_flags(SIZE_EXPAND_FILL);
+ function_vb->set_custom_minimum_size(Size2(450, 300) * EDSCALE);
HBoxContainer *func_name_hbox = memnew(HBoxContainer);
function_vb->add_child(func_name_hbox);
@@ -4810,7 +4811,6 @@ VisualScriptEditor::VisualScriptEditor() {
func_input_scroll->add_child(func_input_vbox);
function_create_dialog = memnew(ConfirmationDialog);
- function_create_dialog->set_custom_minimum_size(Size2(450, 300) * EDSCALE);
function_create_dialog->set_v_size_flags(SIZE_EXPAND_FILL);
function_create_dialog->set_title(TTR("Create Function"));
function_create_dialog->add_child(function_vb);
diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp
index 857d640b43..2a8d67d403 100644
--- a/modules/visual_script/visual_script_nodes.cpp
+++ b/modules/visual_script/visual_script_nodes.cpp
@@ -1290,7 +1290,7 @@ public:
if (!instance->get_variable(variable, p_outputs[0])) {
r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = RTR("VariableGet not found in script: ") + "'" + String(variable) + "'";
- return false;
+ return 0;
}
return 0;
}