Add contains_char() for single-character 'contains' calls.

This commit is contained in:
Lukas Tenbrink 2024-12-05 17:56:08 +01:00
parent eb5103093c
commit b5c31ebb41
61 changed files with 108 additions and 99 deletions

View file

@ -223,7 +223,7 @@ RemoteDebuggerPeer *RemoteDebuggerPeerTCP::create(const String &p_uri) {
String debug_host = p_uri.replace("tcp://", "");
uint16_t debug_port = 6007;
if (debug_host.contains(":")) {
if (debug_host.contains_char(':')) {
int sep_pos = debug_host.rfind_char(':');
debug_port = debug_host.substr(sep_pos + 1).to_int();
debug_host = debug_host.substr(0, sep_pos);

View file

@ -1205,7 +1205,7 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) {
if (F.name.begins_with("_")) {
continue; //hidden property
}
if (F.name.contains("/")) {
if (F.name.contains_char('/')) {
// Ignore properties with '/' (slash) in the name. These are only meant for use in the inspector.
continue;
}

View file

@ -740,7 +740,7 @@ bool FileAccess::store_csv_line(const Vector<String> &p_values, const String &p_
for (int i = 0; i < size; ++i) {
String value = p_values[i];
if (value.contains("\"") || value.contains(p_delim) || value.contains("\n")) {
if (value.contains_char('"') || value.contains(p_delim) || value.contains_char('\n')) {
value = "\"" + value.replace("\"", "\"\"") + "\"";
}
if (i < size - 1) {

View file

@ -71,7 +71,7 @@ void PackedData::add_path(const String &p_pkg_path, const String &p_path, uint64
// Search for directory.
PackedDir *cd = root;
if (simplified_path.contains("/")) { // In a subdirectory.
if (simplified_path.contains_char('/')) { // In a subdirectory.
Vector<String> ds = simplified_path.get_base_dir().split("/");
for (int j = 0; j < ds.size(); j++) {
@ -104,7 +104,7 @@ void PackedData::remove_path(const String &p_path) {
// Search for directory.
PackedDir *cd = root;
if (simplified_path.contains("/")) { // In a subdirectory.
if (simplified_path.contains_char('/')) { // In a subdirectory.
Vector<String> ds = simplified_path.get_base_dir().split("/");
for (int j = 0; j < ds.size(); j++) {

View file

@ -202,7 +202,7 @@ IPAddress::IPAddress(const String &p_string) {
// Wildcard (not a valid IP)
wildcard = true;
} else if (p_string.contains(":")) {
} else if (p_string.contains_char(':')) {
// IPv6
_parse_ipv6(p_string);
valid = true;

View file

@ -1116,7 +1116,7 @@ void ClassDB::bind_integer_constant(const StringName &p_class, const StringName
String enum_name = p_enum;
if (!enum_name.is_empty()) {
if (enum_name.contains(".")) {
if (enum_name.contains_char('.')) {
enum_name = enum_name.get_slicec('.', 1);
}

View file

@ -3314,6 +3314,10 @@ int String::find(const String &p_str, int p_from) const {
return -1; // won't find anything!
}
if (src_len == 1) {
return find_char(p_str[0], p_from); // Optimize with single-char find.
}
const char32_t *src = get_data();
const char32_t *str = p_str.get_data();
@ -3354,6 +3358,10 @@ int String::find(const char *p_str, int p_from) const {
return -1; // won't find anything!
}
if (src_len == 1) {
return find_char(*p_str, p_from); // Optimize with single-char find.
}
const char32_t *src = get_data();
if (src_len == 1) {
@ -4081,7 +4089,7 @@ String String::format(const Variant &values, const String &placeholder) const {
Variant v_val = values_arr[i];
String val = v_val;
if (placeholder.contains("_")) {
if (placeholder.contains_char('_')) {
new_string = new_string.replace(placeholder.replace("_", i_as_str), val);
} else {
new_string = new_string.replace_first(placeholder, val);

View file

@ -432,6 +432,7 @@ public:
_FORCE_INLINE_ bool is_empty() const { return length() == 0; }
_FORCE_INLINE_ bool contains(const char *p_str) const { return find(p_str) != -1; }
_FORCE_INLINE_ bool contains(const String &p_str) const { return find(p_str) != -1; }
_FORCE_INLINE_ bool contains_char(char32_t p_chr) const { return find_char(p_chr) != -1; }
_FORCE_INLINE_ bool containsn(const char *p_str) const { return findn(p_str) != -1; }
_FORCE_INLINE_ bool containsn(const String &p_str) const { return findn(p_str) != -1; }

View file

@ -1961,7 +1961,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
case Variant::FLOAT: {
String s = rtos_fix(p_variant.operator double());
if (s != "inf" && s != "inf_neg" && s != "nan") {
if (!s.contains(".") && !s.contains("e")) {
if (!s.contains_char('.') && !s.contains_char('e')) {
s += ".0";
}
}

View file

@ -949,13 +949,13 @@ String OS_Unix::get_environment(const String &p_var) const {
}
void OS_Unix::set_environment(const String &p_var, const String &p_value) const {
ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains("="), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var));
ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains_char('='), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var));
int err = setenv(p_var.utf8().get_data(), p_value.utf8().get_data(), /* overwrite: */ 1);
ERR_FAIL_COND_MSG(err != 0, vformat("Failed setting environment variable '%s', the system is out of memory.", p_var));
}
void OS_Unix::unset_environment(const String &p_var) const {
ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains("="), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var));
ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains_char('='), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var));
unsetenv(p_var.utf8().get_data());
}

View file

@ -523,7 +523,7 @@ void ConnectDialog::set_dst_node(Node *p_node) {
StringName ConnectDialog::get_dst_method_name() const {
String txt = dst_method->get_text();
if (txt.contains("(")) {
if (txt.contains_char('(')) {
txt = txt.left(txt.find_char('(')).strip_edges();
}
return txt;

View file

@ -359,7 +359,7 @@ Dictionary DebugAdapterParser::req_setBreakpoints(const Dictionary &p_params) co
}
// If path contains \, it's a Windows path, so we need to convert it to /, and make the drive letter uppercase
if (source.path.contains("\\")) {
if (source.path.contains_char('\\')) {
source.path = source.path.replace("\\", "/");
source.path = source.path.substr(0, 1).to_upper() + source.path.substr(1);
}

View file

@ -47,7 +47,7 @@ private:
_FORCE_INLINE_ bool is_valid_path(const String &p_path) const {
// If path contains \, it's a Windows path, so we need to convert it to /, and check as case-insensitive.
if (p_path.contains("\\")) {
if (p_path.contains_char('\\')) {
String project_path = ProjectSettings::get_singleton()->get_resource_path();
String path = p_path.replace("\\", "/");
return path.containsn(project_path);

View file

@ -67,8 +67,8 @@ String DirectoryCreateDialog::_validate_path(const String &p_path) const {
return TTR("Folder name cannot be empty.");
}
}
if (part.contains("\\") || part.contains(":") || part.contains("*") ||
part.contains("|") || part.contains(">") || part.ends_with(".") || part.ends_with(" ")) {
if (part.contains_char('\\') || part.contains_char(':') || part.contains_char('*') ||
part.contains_char('|') || part.contains_char('>') || part.ends_with(".") || part.ends_with(" ")) {
if (is_file) {
return TTR("File name contains invalid characters.");
} else {
@ -101,7 +101,7 @@ void DirectoryCreateDialog::_on_dir_path_changed() {
const String error = _validate_path(path);
if (error.is_empty()) {
if (path.contains("/")) {
if (path.contains_char('/')) {
if (mode == MODE_DIRECTORY) {
validation_panel->set_message(EditorValidationPanel::MSG_ID_DEFAULT, TTR("Using slashes in folder names will create subfolders recursively."), EditorValidationPanel::MSG_OK);
} else {

View file

@ -472,7 +472,7 @@ void EditorFeatureProfileManager::_erase_selected_profile() {
void EditorFeatureProfileManager::_create_new_profile() {
String name = new_profile_name->get_text().strip_edges();
if (!name.is_valid_filename() || name.contains(".")) {
if (!name.is_valid_filename() || name.contains_char('.')) {
EditorNode::get_singleton()->show_warning(TTR("Profile must be a valid filename and must not contain '.'"));
return;
}

View file

@ -384,7 +384,7 @@ void EditorFileSystem::_scan_filesystem() {
FileCache fc;
fc.type = split[1];
if (fc.type.contains("/")) {
if (fc.type.contains_char('/')) {
fc.type = split[1].get_slice("/", 0);
fc.resource_script_class = split[1].get_slice("/", 1);
}

View file

@ -320,7 +320,7 @@ void EditorHelp::_class_desc_select(const String &p_select) {
}
}
if (link.contains(".")) {
if (link.contains_char('.')) {
const int class_end = link.find_char('.');
emit_signal(SNAME("go_to_help"), topic + ":" + link.left(class_end) + ":" + link.substr(class_end + 1));
}
@ -365,7 +365,7 @@ static void _add_type_to_rt(const String &p_type, const String &p_enum, bool p_i
bool is_enum_type = !p_enum.is_empty();
bool is_bitfield = p_is_bitfield && is_enum_type;
bool can_ref = !p_type.contains("*") || is_enum_type;
bool can_ref = !p_type.contains_char('*') || is_enum_type;
String link_t = p_type; // For links in metadata
String display_t; // For display purposes.
@ -2552,7 +2552,7 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt, const C
p_rt->push_meta("@" + link_tag + " " + link_target, underline_mode);
if (link_tag == "member" &&
((!link_target.contains(".") && (p_class == "ProjectSettings" || p_class == "EditorSettings")) ||
((!link_target.contains_char('.') && (p_class == "ProjectSettings" || p_class == "EditorSettings")) ||
link_target.begins_with("ProjectSettings.") || link_target.begins_with("EditorSettings."))) {
// Special formatting for both ProjectSettings and EditorSettings.
String prefix;
@ -3665,7 +3665,7 @@ void EditorHelpBit::_meta_clicked(const String &p_select) {
return;
}
if (link.contains(".")) {
if (link.contains_char('.')) {
const int class_end = link.find_char('.');
_go_to_help(topic + ":" + link.left(class_end) + ":" + link.substr(class_end + 1));
} else {

View file

@ -281,7 +281,7 @@ void EditorProperty::_notification(int p_what) {
} else {
color = get_theme_color(is_read_only() ? SNAME("readonly_color") : SNAME("property_color"));
}
if (label.contains(".")) {
if (label.contains_char('.')) {
// FIXME: Move this to the project settings editor, as this is only used
// for project settings feature tag overrides.
color.a = 0.5;
@ -3177,7 +3177,7 @@ void EditorInspector::update_tree() {
}
// Get the property label's string.
String name_override = (path.contains("/")) ? path.substr(path.rfind_char('/') + 1) : path;
String name_override = (path.contains_char('/')) ? path.substr(path.rfind_char('/') + 1) : path;
String feature_tag;
{
const int dot = name_override.find_char('.');
@ -3326,7 +3326,7 @@ void EditorInspector::update_tree() {
array_element_prefix = class_name_components[0];
editor_inspector_array = memnew(EditorInspectorArray(all_read_only));
String array_label = path.contains("/") ? path.substr(path.rfind_char('/') + 1) : path;
String array_label = path.contains_char('/') ? path.substr(path.rfind_char('/') + 1) : path;
array_label = EditorPropertyNameProcessor::get_singleton()->process_name(property_label_string, property_name_style, p.name, doc_name);
int page = per_array_page.has(array_element_prefix) ? per_array_page[array_element_prefix] : 0;
editor_inspector_array->setup_with_move_element_function(object, array_label, array_element_prefix, page, c, use_folding);

View file

@ -837,7 +837,7 @@ void EditorPropertyLayersGrid::_rename_operation_confirm() {
if (new_name.length() == 0) {
EditorNode::get_singleton()->show_warning(TTR("No name provided."));
return;
} else if (new_name.contains("/") || new_name.contains("\\") || new_name.contains(":")) {
} else if (new_name.contains_char('/') || new_name.contains_char('\\') || new_name.contains_char(':')) {
EditorNode::get_singleton()->show_warning(TTR("Name contains invalid characters."));
return;
}
@ -2873,7 +2873,7 @@ void EditorPropertyNodePath::update_property() {
const Node *target_node = base_node->get_node(p);
ERR_FAIL_NULL(target_node);
if (String(target_node->get_name()).contains("@")) {
if (String(target_node->get_name()).contains_char('@')) {
assign->set_button_icon(Ref<Texture2D>());
assign->set_text(p);
return;

View file

@ -108,7 +108,7 @@ class SectionedInspectorFilter : public Object {
if (pi.name.begins_with(section + "/")) {
pi.name = pi.name.replace_first(section + "/", "");
if (!allow_sub && pi.name.contains("/")) {
if (!allow_sub && pi.name.contains_char('/')) {
continue;
}
p_list->push_back(pi);
@ -247,7 +247,7 @@ void SectionedInspector::update_category_list() {
continue;
}
if (pi.name.contains(":") || pi.name == "script" || pi.name == "resource_name" || pi.name == "resource_path" || pi.name == "resource_local_to_scene" || pi.name.begins_with("_global_script")) {
if (pi.name.contains_char(':') || pi.name == "script" || pi.name == "resource_name" || pi.name == "resource_path" || pi.name == "resource_local_to_scene" || pi.name.begins_with("_global_script")) {
continue;
}

View file

@ -1803,7 +1803,7 @@ void FileSystemDock::_rename_operation_confirm() {
if (new_name.length() == 0) {
EditorNode::get_singleton()->show_warning(TTR("No name provided."));
rename_error = true;
} else if (new_name.contains("/") || new_name.contains("\\") || new_name.contains(":")) {
} else if (new_name.contains_char('/') || new_name.contains_char('\\') || new_name.contains_char(':')) {
EditorNode::get_singleton()->show_warning(TTR("Name contains invalid characters."));
rename_error = true;
} else if (new_name[0] == '.') {
@ -2266,7 +2266,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
test_args.push_back("command -v " + terminal_emulator);
const Error err = OS::get_singleton()->execute("bash", test_args, &pipe);
// Check if a path to the terminal executable exists.
if (err == OK && pipe.contains("/")) {
if (err == OK && pipe.contains_char('/')) {
chosen_terminal_emulator = terminal_emulator;
break;
} else if (err == ERR_CANT_FORK) {

View file

@ -759,7 +759,7 @@ bool SceneTreeEditor::_item_matches_all_terms(TreeItem *p_item, const PackedStri
const String &term = p_terms[i];
// Recognize special filter.
if (term.contains(":") && !term.get_slicec(':', 0).is_empty()) {
if (term.contains_char(':') && !term.get_slicec(':', 0).is_empty()) {
String parameter = term.get_slicec(':', 0);
String argument = term.get_slicec(':', 1);

View file

@ -1808,10 +1808,10 @@ void Collada::_parse_animation(XMLParser &p_parser) {
}
}
if (target.contains("/")) { //transform component
if (target.contains_char('/')) { //transform component
track.target = target.get_slicec('/', 0);
track.param = target.get_slicec('/', 1);
if (track.param.contains(".")) {
if (track.param.contains_char('.')) {
track.component = track.param.get_slice(".", 1).to_upper();
}
track.param = track.param.get_slice(".", 0);

View file

@ -239,7 +239,7 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
List<StringName> anims;
ap->get_animation_list(&anims);
for (const StringName &name : anims) {
if (String(name).contains("/")) {
if (String(name).contains_char('/')) {
continue; // Avoid animation library which may be created by importer dynamically.
}

View file

@ -1068,7 +1068,7 @@ void AnimationNodeBlendTreeEditor::_node_renamed(const String &p_text, Ref<Anima
const String &new_name = p_text;
ERR_FAIL_COND(new_name.is_empty() || new_name.contains(".") || new_name.contains("/"));
ERR_FAIL_COND(new_name.is_empty() || new_name.contains_char('.') || new_name.contains_char('/'));
if (new_name == prev_name) {
return; //nothing to do

View file

@ -470,7 +470,7 @@ void AnimationLibraryEditor::_item_renamed() {
bool restore_text = false;
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
if (String(text).contains("/") || String(text).contains(":") || String(text).contains(",") || String(text).contains("[")) {
if (String(text).contains_char('/') || String(text).contains_char(':') || String(text).contains_char(',') || String(text).contains_char('[')) {
restore_text = true;
} else {
if (ti->get_parent() == tree->get_root()) {

View file

@ -504,7 +504,7 @@ void AnimationPlayerEditor::_animation_rename() {
String selected_name = animation->get_item_text(selected);
// Remove library prefix if present.
if (selected_name.contains("/")) {
if (selected_name.contains_char('/')) {
selected_name = selected_name.get_slice("/", 1);
}
@ -537,7 +537,7 @@ void AnimationPlayerEditor::_animation_remove_confirmed() {
ERR_FAIL_COND(al.is_null());
// For names of form lib_name/anim_name, remove library name prefix.
if (current.contains("/")) {
if (current.contains_char('/')) {
current = current.get_slice("/", 1);
}
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
@ -626,7 +626,7 @@ void AnimationPlayerEditor::_animation_name_edited() {
// Extract library prefix if present.
String new_library_prefix = "";
if (current.contains("/")) {
if (current.contains_char('/')) {
new_library_prefix = current.get_slice("/", 0) + "/";
current = current.get_slice("/", 1);
}
@ -1340,7 +1340,7 @@ void AnimationPlayerEditor::_animation_duplicate() {
break;
}
if (new_name.contains("/")) {
if (new_name.contains_char('/')) {
// Discard library prefix.
new_name = new_name.get_slice("/", 1);
}

View file

@ -1618,7 +1618,7 @@ void AnimationNodeStateMachineEditor::_open_editor(const String &p_name) {
void AnimationNodeStateMachineEditor::_name_edited(const String &p_text) {
const String &new_name = p_text;
ERR_FAIL_COND(new_name.is_empty() || new_name.contains(".") || new_name.contains("/"));
ERR_FAIL_COND(new_name.is_empty() || new_name.contains_char('.') || new_name.contains_char('/'));
if (new_name == prev_name) {
return; // Nothing to do.

View file

@ -113,7 +113,7 @@ void ResourcePreloaderEditor::_item_edited() {
return;
}
if (new_name.is_empty() || new_name.contains("\\") || new_name.contains("/") || preloader->has_resource(new_name)) {
if (new_name.is_empty() || new_name.contains_char('\\') || new_name.contains_char('/') || preloader->has_resource(new_name)) {
s->set_text(0, old_name);
return;
}

View file

@ -183,7 +183,7 @@ void EditorStandardSyntaxHighlighter::_update_cache() {
if (E.usage & PROPERTY_USAGE_CATEGORY || E.usage & PROPERTY_USAGE_GROUP || E.usage & PROPERTY_USAGE_SUBGROUP) {
continue;
}
if (prop_name.contains("/")) {
if (prop_name.contains_char('/')) {
continue;
}
highlighter->add_member_keyword_color(prop_name, member_variable_color);

View file

@ -1636,7 +1636,7 @@ void ScriptTextEditor::_edit_option_toggle_inline_comment() {
script->get_language()->get_comment_delimiters(&comment_delimiters);
for (const String &script_delimiter : comment_delimiters) {
if (!script_delimiter.contains(" ")) {
if (!script_delimiter.contains_char(' ')) {
delimiter = script_delimiter;
break;
}

View file

@ -1677,7 +1677,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
}
// -- \t.func() -> \tsuper.func() Object
if (line.contains("(") && line.contains(".")) {
if (line.contains_char('(') && line.contains_char('.')) {
line = reg_container.reg_super.sub(line, "$1super.$2", true); // TODO, not sure if possible, but for now this broke String text e.g. "Chosen .gitignore" -> "Chosen super.gitignore"
}

View file

@ -834,7 +834,7 @@ void ProjectManager::_set_new_tag_name(const String p_name) {
return;
}
if (p_name.contains(" ")) {
if (p_name.contains_char(' ')) {
tag_error->set_text(TTR("Tag name can't contain spaces."));
return;
}

View file

@ -350,7 +350,7 @@ const char *ProjectList::SIGNAL_PROJECT_ASK_OPEN = "project_ask_open";
// Helpers.
bool ProjectList::project_feature_looks_like_version(const String &p_feature) {
return p_feature.contains(".") && p_feature.substr(0, 3).is_numeric();
return p_feature.contains_char('.') && p_feature.substr(0, 3).is_numeric();
}
// Notifications.
@ -581,7 +581,7 @@ void ProjectList::sort_projects() {
bool item_visible = true;
if (!_search_term.is_empty()) {
String search_path;
if (search_term.contains("/")) {
if (search_term.contains_char('/')) {
// Search path will match the whole path
search_path = item.path;
} else {

View file

@ -268,7 +268,7 @@ void ProjectSettingsEditor::shortcut_input(const Ref<InputEvent> &p_event) {
String ProjectSettingsEditor::_get_setting_name() const {
String name = property_box->get_text().strip_edges();
if (!name.begins_with("_") && !name.contains("/")) {
if (!name.begins_with("_") && !name.contains_char('/')) {
name = "global/" + name;
}
return name;

View file

@ -258,7 +258,7 @@ void PropertySelector::_update_search() {
TreeItem *item = search_options->create_item(category ? category : root);
String desc;
if (mi.name.contains(":")) {
if (mi.name.contains_char(':')) {
desc = mi.name.get_slice(":", 1) + " ";
mi.name = mi.name.get_slice(":", 0);
} else if (mi.return_val.type != Variant::NIL) {
@ -278,7 +278,7 @@ void PropertySelector::_update_search() {
if (arg_itr->type == Variant::NIL) {
desc += ": Variant";
} else if (arg_itr->name.contains(":")) {
} else if (arg_itr->name.contains_char(':')) {
desc += vformat(": %s", arg_itr->name.get_slice(":", 1));
arg_itr->name = arg_itr->name.get_slice(":", 0);
} else {

View file

@ -744,7 +744,7 @@ ScriptLanguage::ScriptTemplate ScriptCreateDialog::_parse_template(const ScriptL
List<String> comment_delimiters;
p_language->get_comment_delimiters(&comment_delimiters);
for (const String &script_delimiter : comment_delimiters) {
if (!script_delimiter.contains(" ")) {
if (!script_delimiter.contains_char(' ')) {
meta_delimiter = script_delimiter;
break;
}

View file

@ -292,7 +292,7 @@ void ShaderCreateDialog::_type_changed(int p_language) {
String extension = "";
if (!path.is_empty()) {
if (path.contains(".")) {
if (path.contains_char('.')) {
extension = path.get_extension();
}
if (extension.length() == 0) {

View file

@ -1290,7 +1290,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
if (N) {
String vm = N->get();
if (!vm.contains("x")) { // invalid parameter format
if (!vm.contains_char('x')) { // invalid parameter format
OS::get_singleton()->print("Invalid resolution '%s', it should be e.g. '1280x720'.\n",
vm.utf8().get_data());
@ -1333,7 +1333,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
if (N) {
String vm = N->get();
if (!vm.contains(",")) { // invalid parameter format
if (!vm.contains_char(',')) { // invalid parameter format
OS::get_singleton()->print("Invalid position '%s', it should be e.g. '80,128'.\n",
vm.utf8().get_data());
@ -1832,7 +1832,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
// 'project.godot' file which will only be available through the network if this is enabled
if (!remotefs.is_empty()) {
int port;
if (remotefs.contains(":")) {
if (remotefs.contains_char(':')) {
port = remotefs.get_slicec(':', 1).to_int();
remotefs = remotefs.get_slicec(':', 0);
} else {
@ -3275,7 +3275,7 @@ Error Main::setup2(bool p_show_boot_logo) {
// Dummy text driver cannot draw any text, making the editor unusable if selected.
continue;
}
if (!text_driver_options.is_empty() && !text_driver_options.contains(",")) {
if (!text_driver_options.is_empty() && !text_driver_options.contains_char(',')) {
// Not the first option; add a comma before it as a separator for the property hint.
text_driver_options += ",";
}

View file

@ -815,7 +815,7 @@ void GDScriptSyntaxHighlighter::_update_cache() {
if (E.usage & PROPERTY_USAGE_CATEGORY || E.usage & PROPERTY_USAGE_GROUP || E.usage & PROPERTY_USAGE_SUBGROUP) {
continue;
}
if (prop_name.contains("/")) {
if (prop_name.contains_char('/')) {
continue;
}
member_keywords[prop_name] = member_variable_color;

View file

@ -1210,7 +1210,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
if (E.usage & (PROPERTY_USAGE_CATEGORY | PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP | PROPERTY_USAGE_INTERNAL)) {
continue;
}
if (E.name.contains("/")) {
if (E.name.contains_char('/')) {
continue;
}
int location = p_recursion_depth + _get_property_location(scr, E.name);
@ -1301,7 +1301,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
if (E.usage & (PROPERTY_USAGE_CATEGORY | PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP | PROPERTY_USAGE_INTERNAL)) {
continue;
}
if (E.name.contains("/")) {
if (E.name.contains_char('/')) {
continue;
}
int location = p_recursion_depth + _get_property_location(type, E.name);
@ -1383,7 +1383,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
if (E.usage & (PROPERTY_USAGE_CATEGORY | PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP | PROPERTY_USAGE_INTERNAL)) {
continue;
}
if (!String(E.name).contains("/")) {
if (!String(E.name).contains_char('/')) {
ScriptLanguage::CodeCompletionOption option(E.name, ScriptLanguage::CODE_COMPLETION_KIND_MEMBER, location);
if (base_type.kind == GDScriptParser::DataType::ENUM) {
// Sort enum members in their declaration order.
@ -2719,7 +2719,7 @@ static bool _guess_method_return_type_from_base(GDScriptParser::CompletionContex
}
static void _find_enumeration_candidates(GDScriptParser::CompletionContext &p_context, const String &p_enum_hint, HashMap<String, ScriptLanguage::CodeCompletionOption> &r_result) {
if (!p_enum_hint.contains(".")) {
if (!p_enum_hint.contains_char('.')) {
// Global constant or in the current class.
StringName current_enum = p_enum_hint;
if (p_context.current_class && p_context.current_class->has_member(current_enum) && p_context.current_class->get_member(current_enum).type == GDScriptParser::ClassNode::Member::ENUM) {
@ -3474,7 +3474,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
for (const MethodInfo &mi : virtual_methods) {
String method_hint = mi.name;
if (method_hint.contains(":")) {
if (method_hint.contains_char(':')) {
method_hint = method_hint.get_slice(":", 0);
}
method_hint += "(";
@ -3484,7 +3484,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
method_hint += ", ";
}
String arg = arg_itr->name;
if (arg.contains(":")) {
if (arg.contains_char(':')) {
arg = arg.substr(0, arg.find_char(':'));
}
method_hint += arg;
@ -3542,7 +3542,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
if (path_needs_quote) {
// Ignore quote_style and just use double quotes for paths with apostrophes.
// Double quotes don't need to be checked because they're not valid in node and property names.
opt = opt.quote(opt.contains("'") ? "\"" : quote_style); // Handle user preference.
opt = opt.quote(opt.contains_char('\'') ? "\"" : quote_style); // Handle user preference.
}
ScriptLanguage::CodeCompletionOption option(opt, ScriptLanguage::CODE_COMPLETION_KIND_NODE_PATH);
options.insert(option.display, option);

View file

@ -4323,7 +4323,7 @@ bool GDScriptParser::export_annotations(AnnotationNode *p_annotation, Node *p_ta
push_error(vformat(R"(Argument %d of annotation "%s" is empty.)", i + 1, p_annotation->name), p_annotation->arguments[i]);
return false;
}
if (arg_string.contains(",")) {
if (arg_string.contains_char(',')) {
push_error(vformat(R"(Argument %d of annotation "%s" contains a comma. Use separate arguments instead.)", i + 1, p_annotation->name), p_annotation->arguments[i]);
return false;
}

View file

@ -67,7 +67,7 @@ lsp::Position GodotPosition::to_lsp(const Vector<String> &p_lines) const {
res.character = column - 1;
String pos_line = p_lines[res.line];
if (pos_line.contains("\t")) {
if (pos_line.contains_char('\t')) {
int tab_size = get_indent_size();
int in_col = 1;

View file

@ -34,7 +34,7 @@ const uint32_t PROP_EDITOR_SCRIPT_VAR = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_S
bool EditorSceneExporterGLTFSettings::_set(const StringName &p_name, const Variant &p_value) {
String name_str = String(p_name);
if (name_str.contains("/")) {
if (name_str.contains_char('/')) {
return _set_extension_setting(name_str, p_value);
}
if (p_name == StringName("image_format")) {
@ -55,7 +55,7 @@ bool EditorSceneExporterGLTFSettings::_set(const StringName &p_name, const Varia
bool EditorSceneExporterGLTFSettings::_get(const StringName &p_name, Variant &r_ret) const {
String name_str = String(p_name);
if (name_str.contains("/")) {
if (name_str.contains_char('/')) {
return _get_extension_setting(name_str, r_ret);
}
if (p_name == StringName("image_format")) {

View file

@ -4078,7 +4078,7 @@ Error GLTFDocument::_parse_images(Ref<GLTFState> p_state, const String &p_base_p
if (uri.begins_with("data:")) { // Embedded data using base64.
data = _parse_base64_uri(uri);
// mimeType is optional, but if we have it defined in the URI, let's use it.
if (mime_type.is_empty() && uri.contains(";")) {
if (mime_type.is_empty() && uri.contains_char(';')) {
// Trim "data:" prefix which is 5 characters long, and end at ";base64".
mime_type = uri.substr(5, uri.find(";base64") - 5);
}

View file

@ -877,7 +877,7 @@ void BindingsGenerator::_append_text_method(StringBuilder &p_output, const TypeI
}
void BindingsGenerator::_append_text_member(StringBuilder &p_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts) {
if (p_link_target.contains("/")) {
if (p_link_target.contains_char('/')) {
// Properties with '/' (slash) in the name are not declared in C#, so there is nothing to reference.
_append_text_undeclared(p_output, p_link_target);
} else if (!p_target_itype || !p_target_itype->is_object_type) {
@ -1158,7 +1158,7 @@ void BindingsGenerator::_append_xml_method(StringBuilder &p_xml_output, const Ty
}
void BindingsGenerator::_append_xml_member(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts) {
if (p_link_target.contains("/")) {
if (p_link_target.contains_char('/')) {
// Properties with '/' (slash) in the name are not declared in C#, so there is nothing to reference.
_append_xml_undeclared(p_xml_output, p_link_target);
} else if (!p_target_itype || !p_target_itype->is_object_type) {
@ -3870,7 +3870,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
continue;
}
if (property.name.contains("/")) {
if (property.name.contains_char('/')) {
// Ignore properties with '/' (slash) in the name. These are only meant for use in the inspector.
continue;
}

View file

@ -443,7 +443,7 @@ void OpenXRCompositionLayer::_get_property_list(List<PropertyInfo> *p_property_l
for (const PropertyInfo &pinfo : extension_properties) {
StringName prop_name = pinfo.name;
if (!String(prop_name).contains("/")) {
if (!String(prop_name).contains_char('/')) {
WARN_PRINT_ONCE(vformat("Discarding OpenXRCompositionLayer property name '%s' from extension because it doesn't contain a '/'."));
continue;
}

View file

@ -97,7 +97,7 @@ FT_Error tvg_svg_in_ot_preset_slot(FT_GlyphSlot p_slot, FT_Bool p_cache, FT_Poin
if (parser->has_attribute("id")) {
const String &gl_name = parser->get_named_attribute_value("id");
if (gl_name.begins_with("glyph")) {
int dot_pos = gl_name.find(".");
int dot_pos = gl_name.find_char('.');
int64_t gl_idx = gl_name.substr(5, (dot_pos > 0) ? dot_pos - 5 : -1).to_int();
if (p_slot->glyph_index != gl_idx) {
parser->skip_section();

View file

@ -97,7 +97,7 @@ FT_Error tvg_svg_in_ot_preset_slot(FT_GlyphSlot p_slot, FT_Bool p_cache, FT_Poin
if (parser->has_attribute("id")) {
const String &gl_name = parser->get_named_attribute_value("id");
if (gl_name.begins_with("glyph")) {
int dot_pos = gl_name.find(".");
int dot_pos = gl_name.find_char('.');
int64_t gl_idx = gl_name.substr(5, (dot_pos > 0) ? dot_pos - 5 : -1).to_int();
if (p_slot->glyph_index != gl_idx) {
parser->skip_section();

View file

@ -349,7 +349,7 @@ String EditorExportPlatformWindows::get_export_option_warning(const EditorExport
PackedStringArray version_array = file_version.split(".", false);
if (version_array.size() != 4 || !version_array[0].is_valid_int() ||
!version_array[1].is_valid_int() || !version_array[2].is_valid_int() ||
!version_array[3].is_valid_int() || file_version.contains("-")) {
!version_array[3].is_valid_int() || file_version.contains_char('-')) {
return TTR("Invalid file version.");
}
}
@ -359,7 +359,7 @@ String EditorExportPlatformWindows::get_export_option_warning(const EditorExport
PackedStringArray version_array = product_version.split(".", false);
if (version_array.size() != 4 || !version_array[0].is_valid_int() ||
!version_array[1].is_valid_int() || !version_array[2].is_valid_int() ||
!version_array[3].is_valid_int() || product_version.contains("-")) {
!version_array[3].is_valid_int() || product_version.contains_char('-')) {
return TTR("Invalid product version.");
}
}

View file

@ -1727,7 +1727,7 @@ String OS_Windows::get_environment(const String &p_var) const {
}
void OS_Windows::set_environment(const String &p_var, const String &p_value) const {
ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains("="), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var));
ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains_char('='), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var));
Char16String var = p_var.utf16();
Char16String value = p_value.utf16();
ERR_FAIL_COND_MSG(var.length() + value.length() + 2 > 32767, vformat("Invalid definition for environment variable '%s', cannot exceed 32767 characters.", p_var));
@ -1735,7 +1735,7 @@ void OS_Windows::set_environment(const String &p_var, const String &p_value) con
}
void OS_Windows::unset_environment(const String &p_var) const {
ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains("="), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var));
ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains_char('='), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var));
SetEnvironmentVariableW((LPCWSTR)(p_var.utf16().get_data()), nullptr); // Null to delete.
}

View file

@ -608,7 +608,7 @@ uint64_t Skeleton3D::get_version() const {
}
int Skeleton3D::add_bone(const String &p_name) {
ERR_FAIL_COND_V_MSG(p_name.is_empty() || p_name.contains(":") || p_name.contains("/"), -1, vformat("Bone name cannot be empty or contain ':' or '/'.", p_name));
ERR_FAIL_COND_V_MSG(p_name.is_empty() || p_name.contains_char(':') || p_name.contains_char('/'), -1, vformat("Bone name cannot be empty or contain ':' or '/'.", p_name));
ERR_FAIL_COND_V_MSG(name_to_bone_index.has(p_name), -1, vformat("Skeleton3D \"%s\" already has a bone with name \"%s\".", to_string(), p_name));
Bone b;

View file

@ -1437,7 +1437,7 @@ void AnimationNodeBlendTree::add_node(const StringName &p_name, Ref<AnimationNod
ERR_FAIL_COND(nodes.has(p_name));
ERR_FAIL_COND(p_node.is_null());
ERR_FAIL_COND(p_name == SceneStringName(output));
ERR_FAIL_COND(String(p_name).contains("/"));
ERR_FAIL_COND(String(p_name).contains_char('/'));
Node n;
n.node = p_node;

View file

@ -294,7 +294,7 @@ StringName AnimationMixer::find_animation_library(const Ref<Animation> &p_animat
Error AnimationMixer::add_animation_library(const StringName &p_name, const Ref<AnimationLibrary> &p_animation_library) {
ERR_FAIL_COND_V(p_animation_library.is_null(), ERR_INVALID_PARAMETER);
#ifdef DEBUG_ENABLED
ERR_FAIL_COND_V_MSG(String(p_name).contains("/") || String(p_name).contains(":") || String(p_name).contains(",") || String(p_name).contains("["), ERR_INVALID_PARAMETER, "Invalid animation name: " + String(p_name) + ".");
ERR_FAIL_COND_V_MSG(String(p_name).contains_char('/') || String(p_name).contains_char(':') || String(p_name).contains_char(',') || String(p_name).contains_char('['), ERR_INVALID_PARAMETER, "Invalid animation name: " + String(p_name) + ".");
#endif
int insert_pos = 0;
@ -356,7 +356,7 @@ void AnimationMixer::rename_animation_library(const StringName &p_name, const St
return;
}
#ifdef DEBUG_ENABLED
ERR_FAIL_COND_MSG(String(p_new_name).contains("/") || String(p_new_name).contains(":") || String(p_new_name).contains(",") || String(p_new_name).contains("["), "Invalid animation library name: " + String(p_new_name) + ".");
ERR_FAIL_COND_MSG(String(p_new_name).contains_char('/') || String(p_new_name).contains_char(':') || String(p_new_name).contains_char(',') || String(p_new_name).contains_char('['), "Invalid animation library name: " + String(p_new_name) + ".");
#endif
bool found = false;

View file

@ -54,7 +54,7 @@ AnimationNodeStateMachineTransition::AdvanceMode AnimationNodeStateMachineTransi
void AnimationNodeStateMachineTransition::set_advance_condition(const StringName &p_condition) {
String cs = p_condition;
ERR_FAIL_COND(cs.contains("/") || cs.contains(":"));
ERR_FAIL_COND(cs.contains_char('/') || cs.contains_char(':'));
advance_condition = p_condition;
if (!cs.is_empty()) {
advance_condition_name = "conditions/" + cs;
@ -1257,7 +1257,7 @@ bool AnimationNodeStateMachine::is_parameter_read_only(const StringName &p_param
void AnimationNodeStateMachine::add_node(const StringName &p_name, Ref<AnimationNode> p_node, const Vector2 &p_position) {
ERR_FAIL_COND(states.has(p_name));
ERR_FAIL_COND(p_node.is_null());
ERR_FAIL_COND(String(p_name).contains("/"));
ERR_FAIL_COND(String(p_name).contains_char('/'));
State state_new;
state_new.node = p_node;
@ -1276,7 +1276,7 @@ void AnimationNodeStateMachine::add_node(const StringName &p_name, Ref<Animation
void AnimationNodeStateMachine::replace_node(const StringName &p_name, Ref<AnimationNode> p_node) {
ERR_FAIL_COND(states.has(p_name) == false);
ERR_FAIL_COND(p_node.is_null());
ERR_FAIL_COND(String(p_name).contains("/"));
ERR_FAIL_COND(String(p_name).contains_char('/'));
{
Ref<AnimationNode> node = states[p_name].node;

View file

@ -325,7 +325,7 @@ bool AnimationNode::add_input(const String &p_name) {
// Root nodes can't add inputs.
ERR_FAIL_COND_V(Object::cast_to<AnimationRootNode>(this) != nullptr, false);
Input input;
ERR_FAIL_COND_V(p_name.contains(".") || p_name.contains("/"), false);
ERR_FAIL_COND_V(p_name.contains_char('.') || p_name.contains_char('/'), false);
input.name = p_name;
inputs.push_back(input);
emit_changed();
@ -340,7 +340,7 @@ void AnimationNode::remove_input(int p_index) {
bool AnimationNode::set_input_name(int p_input, const String &p_name) {
ERR_FAIL_INDEX_V(p_input, inputs.size(), false);
ERR_FAIL_COND_V(p_name.contains(".") || p_name.contains("/"), false);
ERR_FAIL_COND_V(p_name.contains_char('.') || p_name.contains_char('/'), false);
inputs.write[p_input].name = p_name;
emit_changed();
return true;

View file

@ -33,11 +33,11 @@
#include "scene/scene_string_names.h"
bool AnimationLibrary::is_valid_animation_name(const String &p_name) {
return !(p_name.is_empty() || p_name.contains("/") || p_name.contains(":") || p_name.contains(",") || p_name.contains("["));
return !(p_name.is_empty() || p_name.contains_char('/') || p_name.contains_char(':') || p_name.contains_char(',') || p_name.contains_char('['));
}
bool AnimationLibrary::is_valid_library_name(const String &p_name) {
return !(p_name.contains("/") || p_name.contains(":") || p_name.contains(",") || p_name.contains("["));
return !(p_name.contains_char('/') || p_name.contains_char(':') || p_name.contains_char(',') || p_name.contains_char('['));
}
String AnimationLibrary::validate_library_name(const String &p_name) {

View file

@ -37,7 +37,7 @@
bool Theme::_set(const StringName &p_name, const Variant &p_value) {
String sname = p_name;
if (sname.contains("/")) {
if (sname.contains_char('/')) {
String type = sname.get_slicec('/', 1);
String theme_type = sname.get_slicec('/', 0);
String prop_name = sname.get_slicec('/', 2);
@ -69,7 +69,7 @@ bool Theme::_set(const StringName &p_name, const Variant &p_value) {
bool Theme::_get(const StringName &p_name, Variant &r_ret) const {
String sname = p_name;
if (sname.contains("/")) {
if (sname.contains_char('/')) {
String type = sname.get_slicec('/', 1);
String theme_type = sname.get_slicec('/', 0);
String prop_name = sname.get_slicec('/', 2);

View file

@ -4147,7 +4147,7 @@ String VisualShaderNodeOutput::generate_code(Shader::Mode p_mode, VisualShader::
if (ports[idx].mode == shader_mode && ports[idx].shader_type == shader_type) {
if (!p_input_vars[count].is_empty()) {
String s = ports[idx].string;
if (s.contains(":")) {
if (s.contains_char(':')) {
shader_code += " " + s.get_slicec(':', 0) + " = " + p_input_vars[count] + "." + s.get_slicec(':', 1) + ";\n";
} else {
shader_code += " " + s + " = " + p_input_vars[count] + ";\n";

View file

@ -106,11 +106,11 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, const String
if (reading_versions) {
String l = line.strip_edges();
if (!l.is_empty()) {
if (!l.contains("=")) {
if (!l.contains_char('=')) {
base_error = "Missing `=` in '" + l + "'. Version syntax is `version = \"<defines with C escaping>\";`.";
break;
}
if (!l.contains(";")) {
if (!l.contains_char(';')) {
// We don't require a semicolon per se, but it's needed for clang-format to handle things properly.
base_error = "Missing `;` in '" + l + "'. Version syntax is `version = \"<defines with C escaping>\";`.";
break;

View file

@ -181,7 +181,7 @@ static String _mkid(const String &p_id) {
static String f2sp0(float p_float) {
String num = rtos(p_float);
if (!num.contains(".") && !num.contains("e")) {
if (!num.contains_char('.') && !num.contains_char('e')) {
num += ".0";
}
return num;