aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/Qt6AndroidQmlMacros.cmake20
-rw-r--r--src/qml/Qt6QmlMacros.cmake207
-rw-r--r--src/qml/animations/qabstractanimationjob.cpp10
-rw-r--r--src/qml/animations/qabstractanimationjob_p.h2
-rw-r--r--src/qml/common/qqmljsfixedpoolarray_p.h4
-rw-r--r--src/qml/common/qv4compileddata_p.h8
-rw-r--r--src/qml/common/qv4stringtoarrayindex_p.h2
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp8
-rw-r--r--src/qml/compiler/qv4compiler.cpp34
-rw-r--r--src/qml/compiler/qv4compilercontext.cpp14
-rw-r--r--src/qml/compiler/qv4compilerscanfunctions.cpp22
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h2
-rw-r--r--src/qml/debugger/qqmlconfigurabledebugservice_p.h2
-rw-r--r--src/qml/debugger/qqmldebugconnector.cpp2
-rw-r--r--src/qml/doc/snippets/qmltc/tst_qmltc_examples.cpp2
-rw-r--r--src/qml/doc/src/cmake/cmake-properties.qdoc18
-rw-r--r--src/qml/doc/src/cmake/cmake-variables.qdoc2
-rw-r--r--src/qml/doc/src/cmake/qt_add_qml_module.qdoc10
-rw-r--r--src/qml/doc/src/cmake/qt_add_qml_plugin.qdoc2
-rw-r--r--src/qml/doc/src/cmake/qt_deploy_qml_imports.qdoc4
-rw-r--r--src/qml/doc/src/cmake/qt_generate_deploy_qml_app_script.qdoc4
-rw-r--r--src/qml/doc/src/cmake/qt_generate_foreign_qml_types.qdoc11
-rw-r--r--src/qml/doc/src/cmake/qt_import_qml_plugins.qdoc2
-rw-r--r--src/qml/doc/src/cmake/qt_query_qml_module.qdoc2
-rw-r--r--src/qml/doc/src/cmake/qt_target_compile_qml_to_cpp.qdoc2
-rw-r--r--src/qml/doc/src/cmake/qt_target_qml_sources.qdoc2
-rw-r--r--src/qml/doc/src/cppintegration/definetypes.qdoc69
-rw-r--r--src/qml/doc/src/includes/cmake-qml-qt-finalize-target-warning.qdocinc (renamed from src/qml/doc/src/includes/cmake-qml-qt-finalize-target-warning.cmake)3
-rw-r--r--src/qml/doc/src/qmlfunctions.qdoc8
-rw-r--r--src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc16
-rw-r--r--src/qml/doc/src/qmllanguageref/modules/identifiedmodules.qdoc12
-rw-r--r--src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc2
-rw-r--r--src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc8
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/directoryimports.qdoc5
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/imports.qdoc16
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc1
-rw-r--r--src/qml/doc/src/qmllanguageref/typesystem/valuetypes.qdoc86
-rw-r--r--src/qml/doc/src/qmltypereference.qdoc5
-rw-r--r--src/qml/doc/src/qtqml.qdoc37
-rw-r--r--src/qml/jit/qv4baselinejit_p.h2
-rw-r--r--src/qml/jsapi/qjsengine.cpp2
-rw-r--r--src/qml/jsapi/qjsmanagedvalue.cpp6
-rw-r--r--src/qml/jsapi/qjsvalue.cpp14
-rw-r--r--src/qml/jsruntime/qv4argumentsobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4arraybuffer_p.h5
-rw-r--r--src/qml/jsruntime/qv4arrayiterator_p.h2
-rw-r--r--src/qml/jsruntime/qv4compilationunitmapper.cpp11
-rw-r--r--src/qml/jsruntime/qv4compilationunitmapper_p.h1
-rw-r--r--src/qml/jsruntime/qv4context_p.h4
-rw-r--r--src/qml/jsruntime/qv4dataview_p.h2
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4engine.cpp65
-rw-r--r--src/qml/jsruntime/qv4engine_p.h13
-rw-r--r--src/qml/jsruntime/qv4errorobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4errorobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4executableallocator.cpp2
-rw-r--r--src/qml/jsruntime/qv4executableallocator_p.h4
-rw-r--r--src/qml/jsruntime/qv4executablecompilationunit.cpp22
-rw-r--r--src/qml/jsruntime/qv4function.cpp4
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp23
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4generatorobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4globalobject.cpp14
-rw-r--r--src/qml/jsruntime/qv4identifiertable.cpp8
-rw-r--r--src/qml/jsruntime/qv4jsonobject.cpp43
-rw-r--r--src/qml/jsruntime/qv4mapiterator_p.h2
-rw-r--r--src/qml/jsruntime/qv4memberdata_p.h2
-rw-r--r--src/qml/jsruntime/qv4module.cpp2
-rw-r--r--src/qml/jsruntime/qv4object.cpp2
-rw-r--r--src/qml/jsruntime/qv4persistent_p.h2
-rw-r--r--src/qml/jsruntime/qv4profiling.cpp2
-rw-r--r--src/qml/jsruntime/qv4promiseobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4propertykey.cpp2
-rw-r--r--src/qml/jsruntime/qv4qmlcontext_p.h4
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp110
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper_p.h62
-rw-r--r--src/qml/jsruntime/qv4reflect.cpp5
-rw-r--r--src/qml/jsruntime/qv4regexp.cpp12
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp18
-rw-r--r--src/qml/jsruntime/qv4regexpobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp17
-rw-r--r--src/qml/jsruntime/qv4scopedvalue_p.h6
-rw-r--r--src/qml/jsruntime/qv4setiterator_p.h2
-rw-r--r--src/qml/jsruntime/qv4stringiterator.cpp2
-rw-r--r--src/qml/jsruntime/qv4stringiterator_p.h2
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp58
-rw-r--r--src/qml/jsruntime/qv4stringobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4symbol_p.h2
-rw-r--r--src/qml/jsruntime/qv4typedarray_p.h2
-rw-r--r--src/qml/jsruntime/qv4urlobject.cpp16
-rw-r--r--src/qml/jsruntime/qv4urlobject_p.h4
-rw-r--r--src/qml/memory/qv4mm.cpp4
-rw-r--r--src/qml/parser/qqmljs.g12
-rw-r--r--src/qml/parser/qqmljsast_p.h2
-rw-r--r--src/qml/parser/qqmljslexer.cpp2
-rw-r--r--src/qml/qml/ftw/qbipointer_p.h5
-rw-r--r--src/qml/qml/ftw/qhashedstring_p.h10
-rw-r--r--src/qml/qml/ftw/qstringhash_p.h4
-rw-r--r--src/qml/qml/qqml.cpp16
-rw-r--r--src/qml/qml/qqmlapplicationengine.cpp4
-rw-r--r--src/qml/qml/qqmlbinding.cpp2
-rw-r--r--src/qml/qml/qqmlbinding_p.h8
-rw-r--r--src/qml/qml/qqmlcomponent.cpp44
-rw-r--r--src/qml/qml/qqmlcomponent.h2
-rw-r--r--src/qml/qml/qqmlcontext.cpp2
-rw-r--r--src/qml/qml/qqmlcontext_p.h2
-rw-r--r--src/qml/qml/qqmlcustomparser.cpp65
-rw-r--r--src/qml/qml/qqmlcustomparser_p.h2
-rw-r--r--src/qml/qml/qqmldata_p.h4
-rw-r--r--src/qml/qml/qqmldatablob.cpp14
-rw-r--r--src/qml/qml/qqmlengine.cpp2
-rw-r--r--src/qml/qml/qqmlerror.cpp4
-rw-r--r--src/qml/qml/qqmlextensionplugin.cpp23
-rw-r--r--src/qml/qml/qqmlfile.cpp101
-rw-r--r--src/qml/qml/qqmlimport.cpp94
-rw-r--r--src/qml/qml/qqmlincubator.cpp15
-rw-r--r--src/qml/qml/qqmlirloader.cpp10
-rw-r--r--src/qml/qml/qqmljavascriptexpression.cpp2
-rw-r--r--src/qml/qml/qqmllist.h6
-rw-r--r--src/qml/qml/qqmllocale.cpp16
-rw-r--r--src/qml/qml/qqmllocale_p.h2
-rw-r--r--src/qml/qml/qqmlmetatype.cpp17
-rw-r--r--src/qml/qml/qqmlmetatypedata.cpp14
-rw-r--r--src/qml/qml/qqmlnotifier.cpp4
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp24
-rw-r--r--src/qml/qml/qqmlopenmetaobject.cpp22
-rw-r--r--src/qml/qml/qqmlpluginimporter.cpp10
-rw-r--r--src/qml/qml/qqmlproperty.cpp89
-rw-r--r--src/qml/qml/qqmlproperty.h2
-rw-r--r--src/qml/qml/qqmlpropertybinding.cpp8
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp53
-rw-r--r--src/qml/qml/qqmlpropertycache_p.h18
-rw-r--r--src/qml/qml/qqmlpropertycachecreator.cpp6
-rw-r--r--src/qml/qml/qqmlpropertycachecreator_p.h27
-rw-r--r--src/qml/qml/qqmlpropertycachevector_p.h4
-rw-r--r--src/qml/qml/qqmlpropertydata_p.h1
-rw-r--r--src/qml/qml/qqmlpropertyresolver.cpp2
-rw-r--r--src/qml/qml/qqmlpropertyvalidator_p.h3
-rw-r--r--src/qml/qml/qqmlproxymetaobject.cpp8
-rw-r--r--src/qml/qml/qqmlscriptblob.cpp4
-rw-r--r--src/qml/qml/qqmlscriptdata.cpp4
-rw-r--r--src/qml/qml/qqmlscriptstring.cpp2
-rw-r--r--src/qml/qml/qqmltype.cpp22
-rw-r--r--src/qml/qml/qqmltypecompiler.cpp34
-rw-r--r--src/qml/qml/qqmltypecompiler_p.h2
-rw-r--r--src/qml/qml/qqmltypedata.cpp20
-rw-r--r--src/qml/qml/qqmltypeloader.cpp10
-rw-r--r--src/qml/qml/qqmltypemodule.cpp4
-rw-r--r--src/qml/qml/qqmltypenamecache.cpp4
-rw-r--r--src/qml/qml/qqmlvaluetype.cpp34
-rw-r--r--src/qml/qml/qqmlvaluetype_p.h38
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp36
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp11
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp37
-rw-r--r--src/qml/qmldirparser/qqmldirparser.cpp6
-rw-r--r--src/qml/qmldirparser/qqmlimportresolver.cpp4
-rw-r--r--src/qml/types/qqmlbind.cpp13
-rw-r--r--src/qml/types/qqmlconnections.cpp32
-rw-r--r--src/qml/util/qqmlpropertymap.cpp2
159 files changed, 1475 insertions, 904 deletions
diff --git a/src/qml/Qt6AndroidQmlMacros.cmake b/src/qml/Qt6AndroidQmlMacros.cmake
index 5284c3e71c..787b358975 100644
--- a/src/qml/Qt6AndroidQmlMacros.cmake
+++ b/src/qml/Qt6AndroidQmlMacros.cmake
@@ -26,18 +26,16 @@ function(_qt_internal_generate_android_qml_deployment_settings out_var target)
get_target_property(target_source_dir ${target} SOURCE_DIR)
# QML import paths
- if(NOT "${QT_QML_OUTPUT_DIRECTORY}" STREQUAL "")
- # Need to prepend the default qml module output directory to take precedence
- # over other qml import paths.
- get_target_property(native_qml_import_paths "${target}" _qt_native_qml_import_paths)
- if(native_qml_import_paths)
- list(PREPEND native_qml_import_paths "${QT_QML_OUTPUT_DIRECTORY}")
- else()
- set(native_qml_import_paths "${QT_QML_OUTPUT_DIRECTORY}")
- endif()
- set_property(TARGET "${target}" PROPERTY
- "_qt_native_qml_import_paths" "${native_qml_import_paths}")
+ _qt_internal_collect_target_qml_import_paths(qml_import_paths ${target})
+ get_target_property(native_qml_import_paths "${target}" _qt_native_qml_import_paths)
+ if(native_qml_import_paths)
+ list(PREPEND native_qml_import_paths "${qml_import_paths}")
+ else()
+ set(native_qml_import_paths "${qml_import_paths}")
endif()
+ list(REMOVE_DUPLICATES native_qml_import_paths)
+ set_property(TARGET "${target}" PROPERTY
+ _qt_native_qml_import_paths "${native_qml_import_paths}")
_qt_internal_add_android_deployment_multi_value_property(${out_var} "qml-import-paths"
${target} "_qt_native_qml_import_paths")
diff --git a/src/qml/Qt6QmlMacros.cmake b/src/qml/Qt6QmlMacros.cmake
index 20b8101103..f307c1f4be 100644
--- a/src/qml/Qt6QmlMacros.cmake
+++ b/src/qml/Qt6QmlMacros.cmake
@@ -715,16 +715,18 @@ macro(_qt_internal_genex_getoption var target property)
set(${var} "$<BOOL:$<TARGET_PROPERTY:${target},${property}>>")
endmacro()
+# Gets the Qt import paths, prepends -I, appends the values to the given import_paths_var output
+# variable.
function(_qt_internal_extend_qml_import_paths import_paths_var)
set(local_var ${${import_paths_var}})
- # prepend extra import path which is a current module's build dir: we need
- # this to ensure correct importing of QML modules when having a prefix-build
- # with QLibraryInfo::path(QLibraryInfo::QmlImportsPath) pointing to the
- # install location
- if(QT_BUILDING_QT AND QT_WILL_INSTALL)
- list(PREPEND local_var -I "${QT_BUILD_DIR}/${INSTALL_QMLDIR}")
- endif()
+ _qt_internal_get_main_qt_qml_import_paths(qt_import_paths)
+
+ # Append the paths instead of prepending them, to ensure Qt import paths are searched after
+ # any target or build dir specific import paths.
+ foreach(import_path IN LISTS qt_import_paths)
+ list(APPEND local_var -I "${import_path}")
+ endforeach()
set(${import_paths_var} ${local_var} PARENT_SCOPE)
endfunction()
@@ -780,9 +782,11 @@ function(_qt_internal_target_enable_qmllint target)
_qt_internal_extend_qml_import_paths(import_args)
+ _qt_internal_get_tool_wrapper_script_path(tool_wrapper)
set(cmd
- ${QT_TOOL_COMMAND_WRAPPER_PATH}
- ${QT_CMAKE_EXPORT_NAMESPACE}::qmllint
+ ${tool_wrapper}
+ $<TARGET_FILE:${QT_CMAKE_EXPORT_NAMESPACE}::qmllint>
+ --bare
${import_args}
${qrc_args}
${qmllint_files}
@@ -918,8 +922,10 @@ function(_qt_internal_target_enable_qmlcachegen target output_targets_var qmlcac
if(CMAKE_GENERATOR STREQUAL "Ninja Multi-Config" AND CMAKE_VERSION VERSION_GREATER_EQUAL "3.20")
set(qmlcachegen "$<COMMAND_CONFIG:${qmlcachegen}>")
endif()
+
+ _qt_internal_get_tool_wrapper_script_path(tool_wrapper)
set(cmd
- ${QT_TOOL_COMMAND_WRAPPER_PATH}
+ ${tool_wrapper}
${qmlcachegen}
--resource-name "${qmlcache_resource_name}"
${qrc_resource_args}
@@ -1342,12 +1348,14 @@ function(_qt_internal_target_enable_qmltc target)
set(compiled_cpp "${target_binary_dir}/.qmltc/${target}/${file_name}.cpp")
get_filename_component(out_dir ${compiled_header} DIRECTORY)
+ _qt_internal_get_tool_wrapper_script_path(tool_wrapper)
add_custom_command(
OUTPUT ${compiled_header} ${compiled_cpp}
COMMAND ${CMAKE_COMMAND} -E make_directory ${out_dir}
COMMAND
- ${QT_TOOL_COMMAND_WRAPPER_PATH}
+ ${tool_wrapper}
${qmltc_executable}
+ --bare
--header "${compiled_header}"
--impl "${compiled_cpp}"
${common_args}
@@ -1598,12 +1606,18 @@ function(qt6_add_qml_plugin target)
)
endif()
+ get_target_property(install_rpath ${target} INSTALL_RPATH)
# Ignore any CMAKE_INSTALL_RPATH and set a better default RPATH on platforms
# that support it, if allowed. Projects will often set CMAKE_INSTALL_RPATH
# for executables or backing libraries, but forget about plugins. Because
# the path for QML plugins depends on their URI, it is unlikely that
# CMAKE_INSTALL_RPATH would ever be intended for use with QML plugins.
- if(NOT WIN32 AND NOT QT_NO_QML_PLUGIN_RPATH)
+ #
+ # Avoid setting INSTALL_RPATH if it was set before. This is mostly
+ # applicable for the Qml plugins built in Qt tree, that got INSTALL_RPATH
+ # from the qt_internal_add_plugin function, but also can be the case for the
+ # user Qml plugins created manually.
+ if(NOT WIN32 AND NOT QT_NO_QML_PLUGIN_RPATH AND NOT install_rpath)
# Construct a relative path from a default install location (assumed to
# be qml/target-path) to ${CMAKE_INSTALL_LIBDIR}. This would be
# applicable for Apple too (although unusual) if this is a bare install
@@ -1690,13 +1704,13 @@ function(qt6_add_qml_plugin target)
string(APPEND qt_qml_plugin_outro "} // namespace ${arg_NAMESPACE}")
endif()
- string(APPEND qt_qml_plugin_intro "extern void ${register_types_function_name}();\nQ_GHS_KEEP_REFERENCE(${register_types_function_name});")
+ string(APPEND qt_qml_plugin_intro "extern void ${register_types_function_name}();\nQ_GHS_KEEP_REFERENCE(${register_types_function_name})")
# Indenting here is deliberately different so as to make the generated
# file have sensible indenting
set(qt_qml_plugin_constructor_content
"volatile auto registration = &${register_types_function_name};
- Q_UNUSED(registration);"
+ Q_UNUSED(registration)"
)
set(generated_cpp_file
@@ -2040,6 +2054,12 @@ function(qt6_target_qml_sources target)
get_source_file_property(qml_file_singleton ${qml_file_src} QT_QML_SINGLETON_TYPE)
get_source_file_property(qml_file_internal ${qml_file_src} QT_QML_INTERNAL_TYPE)
+ if (qml_file_singleton AND qml_file_internal)
+ message(FATAL_ERROR
+ "${qml_file_src} is marked as both internal and as a "
+ "singleton, but singletons cannot be internal!")
+ endif()
+
if (NOT qml_file_versions)
set(qml_file_versions ${qml_module_files_versions})
endif()
@@ -2095,12 +2115,15 @@ function(qt6_target_qml_sources target)
else()
set(qmlcachegen_cmd "${qmlcachegen}")
endif()
+
+ _qt_internal_get_tool_wrapper_script_path(tool_wrapper)
add_custom_command(
OUTPUT ${compiled_file}
COMMAND ${CMAKE_COMMAND} -E make_directory ${out_dir}
COMMAND
- ${QT_TOOL_COMMAND_WRAPPER_PATH}
+ ${tool_wrapper}
${qmlcachegen_cmd}
+ --bare
--resource-path "${file_resource_path}"
${cachegen_args}
-o "${compiled_file}"
@@ -2226,9 +2249,19 @@ function(qt6_generate_foreign_qml_types source_target destination_qml_target)
message(FATAL_ERROR "Need target metatypes.json file")
endif()
+ get_target_property(automoc_enabled ${destination_qml_target} AUTOMOC)
+ if(NOT automoc_enabled)
+ message(FATAL_ERROR "qt6_generate_foreign_qml_types requires AUTOMOC to be enabled "
+ "on target '${destination_qml_target}'.")
+ endif()
+
set(registration_files_base ${source_target}_${destination_qml_target})
- set(additional_sources ${registration_files_base}.cpp ${registration_files_base}.h)
+ set(additional_sources
+ "${CMAKE_CURRENT_BINARY_DIR}/${registration_files_base}.cpp"
+ "${CMAKE_CURRENT_BINARY_DIR}/${registration_files_base}.h"
+ )
+ _qt_internal_get_tool_wrapper_script_path(tool_wrapper)
add_custom_command(
OUTPUT
${additional_sources}
@@ -2237,7 +2270,7 @@ function(qt6_generate_foreign_qml_types source_target destination_qml_target)
${target_metatypes_json_file}
${QT_CMAKE_EXPORT_NAMESPACE}::qmltyperegistrar
COMMAND
- ${QT_TOOL_COMMAND_WRAPPER_PATH}
+ ${tool_wrapper}
$<TARGET_FILE:${QT_CMAKE_EXPORT_NAMESPACE}::qmltyperegistrar>
"--extract"
-o ${registration_files_base}
@@ -2247,7 +2280,6 @@ function(qt6_generate_foreign_qml_types source_target destination_qml_target)
)
target_sources(${destination_qml_target} PRIVATE ${additional_sources})
- qt6_wrap_cpp(${additional_sources} TARGET ${destination_qml_target})
endfunction()
if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
@@ -2399,6 +2431,11 @@ function(_qt_internal_qml_type_registration target)
if (TARGET ${target}Private)
list(APPEND cmd_args --private-includes)
+ else()
+ string(REGEX MATCH "Private$" privateSuffix ${target})
+ if (privateSuffix)
+ list(APPEND cmd_args --private-includes)
+ endif()
endif()
get_target_property(target_metatypes_json_file ${target} INTERFACE_QT_META_TYPES_BUILD_FILE)
@@ -2428,6 +2465,7 @@ function(_qt_internal_qml_type_registration target)
)
endif()
+ _qt_internal_get_tool_wrapper_script_path(tool_wrapper)
add_custom_command(
OUTPUT
${type_registration_cpp_file}
@@ -2438,7 +2476,7 @@ function(_qt_internal_qml_type_registration target)
${QT_CMAKE_EXPORT_NAMESPACE}::qmltyperegistrar
"$<$<BOOL:${genex_list}>:${genex_list}>"
COMMAND
- ${QT_TOOL_COMMAND_WRAPPER_PATH}
+ ${tool_wrapper}
$<TARGET_FILE:${QT_CMAKE_EXPORT_NAMESPACE}::qmltyperegistrar>
${cmd_args}
-o ${type_registration_cpp_file}
@@ -2540,6 +2578,84 @@ if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
endfunction()
endif()
+# Get Qt provided QML import paths.
+# The appending order is important. Build dirs are preferred over install dirs.
+function(_qt_internal_get_main_qt_qml_import_paths out_var)
+ set(qml_import_paths "")
+
+ # When building a qml module as part of a prefix Qt build that is not yet installed, add an
+ # extra import path which is the current module's build dir: we need
+ # this to ensure correct importing of QML modules when having a prefix-build
+ # with QLibraryInfo::path(QLibraryInfo::QmlImportsPath) pointing to the
+ # install location.
+ if(QT_BUILDING_QT AND QT_WILL_INSTALL)
+ set(build_dir_import_path "${QT_BUILD_DIR}/${INSTALL_QMLDIR}")
+ if(IS_DIRECTORY "${build_dir_import_path}")
+ list(APPEND qml_import_paths "${build_dir_import_path}")
+ endif()
+ endif()
+
+ # We could have multiple additional installation prefixes: one per Qt repository (conan).
+ # Or just extra ones, that might be needed during cross-compilation or example building.
+ # Add those that have a "qml" subdirectory.
+ # The additional prefixes have priority over the main Qt prefix, so they come first.
+ if(NOT "${_qt_additional_packages_prefix_paths}" STREQUAL "")
+ __qt_internal_prefix_paths_to_roots(
+ additional_root_paths "${_qt_additional_packages_prefix_paths}")
+ foreach(root IN ITEMS ${additional_root_paths})
+ set(candidate "${root}/${QT6_INSTALL_QML}")
+ if(IS_DIRECTORY "${candidate}")
+ list(APPEND qml_import_paths "${candidate}")
+ endif()
+ endforeach()
+ endif()
+
+ # Add the main Qt "<prefix>/qml" import path.
+ if(QT6_INSTALL_PREFIX)
+ set(main_import_path "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_QML}")
+ if(IS_DIRECTORY "${main_import_path}")
+ list(APPEND qml_import_paths "${main_import_path}")
+ endif()
+ endif()
+
+ set(${out_var} "${qml_import_paths}" PARENT_SCOPE)
+endfunction()
+
+function(_qt_internal_collect_target_qml_import_paths out_var target)
+ set(qml_import_paths "")
+ # Get custom import paths provided during qt_add_qml_module call.
+ get_target_property(qml_import_path ${target} QT_QML_IMPORT_PATH)
+ if(qml_import_path)
+ list(APPEND qml_import_paths ${qml_import_path})
+ endif()
+
+ # Facilitate self-import so we can find the qmldir file
+ get_target_property(module_out_dir ${target} QT_QML_MODULE_OUTPUT_DIRECTORY)
+ if(module_out_dir)
+ list(APPEND qml_import_paths "${module_out_dir}")
+ endif()
+
+ # Find qmldir files we copied to the build directory
+ if(NOT "${QT_QML_OUTPUT_DIRECTORY}" STREQUAL "")
+ if(EXISTS "${QT_QML_OUTPUT_DIRECTORY}")
+ list(APPEND qml_import_paths "${QT_QML_OUTPUT_DIRECTORY}")
+ endif()
+ else()
+ list(APPEND qml_import_paths "${CMAKE_CURRENT_BINARY_DIR}")
+ endif()
+
+ set(${out_var} "${qml_import_paths}" PARENT_SCOPE)
+endfunction()
+
+function(_qt_internal_collect_qml_import_paths out_var target)
+ _qt_internal_collect_target_qml_import_paths(qml_import_paths ${target})
+
+ # Add the Qt import paths last.
+ _qt_internal_get_main_qt_qml_import_paths(qt_main_import_paths)
+ list(APPEND qml_import_paths ${qt_main_import_paths})
+
+ set(${out_var} "${qml_import_paths}" PARENT_SCOPE)
+endfunction()
function(_qt_internal_scan_qml_imports target imports_file_var when_to_scan)
if(NOT "${ARGN}" STREQUAL "")
@@ -2577,29 +2693,6 @@ but this file does not exist. Possible reasons include:
")
endif()
- # Find QML import paths.
- if("${_qt_additional_packages_prefix_paths}" STREQUAL "")
- # We have one installation prefix for all Qt modules. Add the "<prefix>/qml" directory.
- set(qml_import_paths "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_QML}")
- else()
- # We have multiple installation prefixes: one per Qt repository (conan). Add those that have
- # a "qml" subdirectory.
- set(qml_import_paths)
- foreach(root IN ITEMS ${QT6_INSTALL_PREFIX} ${_qt_additional_packages_prefix_paths})
- set(candidate "${root}/${QT6_INSTALL_QML}")
- if(IS_DIRECTORY "${candidate}")
- list(APPEND qml_import_paths "${candidate}")
- endif()
- endforeach()
- endif()
-
- # Construct the -importPath arguments.
- set(import_path_arguments)
- foreach(path IN LISTS qml_import_paths)
- list(APPEND import_path_arguments -importPath ${path})
- endforeach()
-
- # Run qmlimportscanner to generate the cmake file that records the import entries
get_target_property(target_source_dir ${target} SOURCE_DIR)
get_target_property(target_binary_dir ${target} BINARY_DIR)
set(out_dir "${target_binary_dir}/.qt_plugins")
@@ -2611,28 +2704,18 @@ but this file does not exist. Possible reasons include:
-rootPath "${target_source_dir}"
-cmake-output
-output-file "${imports_file}"
- ${import_path_arguments}
)
- get_target_property(qml_import_path ${target} QT_QML_IMPORT_PATH)
- if (qml_import_path)
- list(APPEND cmd_args ${qml_import_path})
- endif()
+ _qt_internal_collect_qml_import_paths(qml_import_paths ${target})
+ list(REMOVE_DUPLICATES qml_import_paths)
- # Facilitate self-import so we can find the qmldir file
- get_target_property(module_out_dir ${target} QT_QML_MODULE_OUTPUT_DIRECTORY)
- if(module_out_dir)
- list(APPEND cmd_args "${module_out_dir}")
- endif()
+ # Construct the -importPath arguments.
+ set(import_path_arguments)
+ foreach(path IN LISTS qml_import_paths)
+ list(APPEND import_path_arguments -importPath ${path})
+ endforeach()
- # Find qmldir files we copied to the build directory
- if(NOT "${QT_QML_OUTPUT_DIRECTORY}" STREQUAL "")
- if(EXISTS "${QT_QML_OUTPUT_DIRECTORY}")
- list(APPEND cmd_args "${QT_QML_OUTPUT_DIRECTORY}")
- endif()
- else()
- list(APPEND cmd_args "${CMAKE_CURRENT_BINARY_DIR}")
- endif()
+ list(APPEND cmd_args ${import_path_arguments})
# All of the module's .qml files will be listed in one of the generated
# .qrc files, so there's no need to list the files individually. We provide
@@ -2653,8 +2736,10 @@ but this file does not exist. Possible reasons include:
set(cmd_args "@${rsp_file}")
endif()
- set(import_scanner_args ${QT_TOOL_COMMAND_WRAPPER_PATH} ${tool_path} ${cmd_args})
+ _qt_internal_get_tool_wrapper_script_path(tool_wrapper)
+ set(import_scanner_args ${tool_wrapper} ${tool_path} ${cmd_args})
+ # Run qmlimportscanner to generate the cmake file that records the import entries
if(scan_at_build_time)
add_custom_command(
OUTPUT "${imports_file}"
diff --git a/src/qml/animations/qabstractanimationjob.cpp b/src/qml/animations/qabstractanimationjob.cpp
index 196fe7ed4a..7bb2af476c 100644
--- a/src/qml/animations/qabstractanimationjob.cpp
+++ b/src/qml/animations/qabstractanimationjob.cpp
@@ -48,11 +48,11 @@ void QQmlAnimationTimer::unsetJobTimer(QAbstractAnimationJob *animation)
QQmlAnimationTimer::~QQmlAnimationTimer()
{
- for (const auto &animation : qAsConst(animations))
+ for (const auto &animation : std::as_const(animations))
unsetJobTimer(animation);
- for (const auto &animation : qAsConst(animationsToStart))
+ for (const auto &animation : std::as_const(animationsToStart))
unsetJobTimer(animation);
- for (const auto &animation : qAsConst(runningPauseAnimations))
+ for (const auto &animation : std::as_const(runningPauseAnimations))
unsetJobTimer(animation);
}
@@ -93,7 +93,7 @@ void QQmlAnimationTimer::updateAnimationsTime(qint64 delta)
//when the CPU load is high
if (delta) {
insideTick = true;
- for (currentAnimationIdx = 0; currentAnimationIdx < animations.count(); ++currentAnimationIdx) {
+ for (currentAnimationIdx = 0; currentAnimationIdx < animations.size(); ++currentAnimationIdx) {
QAbstractAnimationJob *animation = animations.at(currentAnimationIdx);
int elapsed = animation->m_totalCurrentTime
+ (animation->direction() == QAbstractAnimationJob::Forward ? delta : -delta);
@@ -101,7 +101,7 @@ void QQmlAnimationTimer::updateAnimationsTime(qint64 delta)
}
if (animationTickDump()) {
qDebug() << "***** Dumping Animation Tree ***** ( tick:" << lastTick << "delta:" << delta << ")";
- for (int i = 0; i < animations.count(); ++i)
+ for (int i = 0; i < animations.size(); ++i)
qDebug() << animations.at(i);
}
insideTick = false;
diff --git a/src/qml/animations/qabstractanimationjob_p.h b/src/qml/animations/qabstractanimationjob_p.h
index a933f49be3..6330b01bb1 100644
--- a/src/qml/animations/qabstractanimationjob_p.h
+++ b/src/qml/animations/qabstractanimationjob_p.h
@@ -193,7 +193,7 @@ public:
void updateAnimationsTime(qint64 timeStep) override;
//useful for profiling/debugging
- int runningAnimationCount() override { return animations.count(); }
+ int runningAnimationCount() override { return animations.size(); }
bool hasStartAnimationPending() const { return startAnimationPending; }
diff --git a/src/qml/common/qqmljsfixedpoolarray_p.h b/src/qml/common/qqmljsfixedpoolarray_p.h
index 16f60c002e..e946b1ecfd 100644
--- a/src/qml/common/qqmljsfixedpoolarray_p.h
+++ b/src/qml/common/qqmljsfixedpoolarray_p.h
@@ -44,7 +44,7 @@ public:
void allocate(MemoryPool *pool, const QVector<T> &vector)
{
- count = vector.count();
+ count = vector.size();
data = reinterpret_cast<T*>(pool->allocate(count * sizeof(T)));
if (QTypeInfo<T>::isComplex) {
@@ -58,7 +58,7 @@ public:
template <typename Container>
void allocate(MemoryPool *pool, const Container &container)
{
- count = container.count();
+ count = container.size();
data = reinterpret_cast<T*>(pool->allocate(count * sizeof(T)));
typename Container::ConstIterator it = container.constBegin();
for (int i = 0; i < count; ++i)
diff --git a/src/qml/common/qv4compileddata_p.h b/src/qml/common/qv4compileddata_p.h
index 2edb73f7b0..23c75d705f 100644
--- a/src/qml/common/qv4compileddata_p.h
+++ b/src/qml/common/qv4compileddata_p.h
@@ -222,7 +222,7 @@ struct String
qint32_le size;
static int calculateSize(const QString &str) {
- return (sizeof(String) + (str.length() + 1) * sizeof(quint16) + 7) & ~0x7;
+ return (sizeof(String) + (str.size() + 1) * sizeof(quint16) + 7) & ~0x7;
}
};
@@ -578,7 +578,7 @@ struct Binding
static QString escapedString(const QString &string)
{
QString tmp = QLatin1String("\"");
- for (int i = 0; i < string.length(); ++i) {
+ for (int i = 0; i < string.size(); ++i) {
const QChar &c = string.at(i);
switch (c.unicode()) {
case 0x08:
@@ -1047,8 +1047,8 @@ public:
InlineComponentIterator inlineComponentsEnd() const {return InlineComponentIterator(this, nInlineComponents);}
typedef TableIterator<RequiredPropertyExtraData, Object, &Object::requiredPropertyExtraDataAt> RequiredPropertyExtraDataIterator;
- RequiredPropertyExtraDataIterator requiredPropertyExtraDataBegin() const {return RequiredPropertyExtraDataIterator(this, 0); };
- RequiredPropertyExtraDataIterator requiredPropertyExtraDataEnd() const {return RequiredPropertyExtraDataIterator(this, nRequiredPropertyExtraData); };
+ RequiredPropertyExtraDataIterator requiredPropertyExtraDataBegin() const {return RequiredPropertyExtraDataIterator(this, 0); }
+ RequiredPropertyExtraDataIterator requiredPropertyExtraDataEnd() const {return RequiredPropertyExtraDataIterator(this, nRequiredPropertyExtraData); }
int namedObjectsInComponentCount() const { return nNamedObjectsInComponent; }
// ---
diff --git a/src/qml/common/qv4stringtoarrayindex_p.h b/src/qml/common/qv4stringtoarrayindex_p.h
index ba5642a27d..fc71ca7072 100644
--- a/src/qml/common/qv4stringtoarrayindex_p.h
+++ b/src/qml/common/qv4stringtoarrayindex_p.h
@@ -52,7 +52,7 @@ uint stringToArrayIndex(const T *ch, const T *end)
inline uint stringToArrayIndex(const QString &str)
{
- return stringToArrayIndex(str.constData(), str.constData() + str.length());
+ return stringToArrayIndex(str.constData(), str.constData() + str.size());
}
} // namespace QV4
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index 5beeda930f..92b1d897e3 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -1391,7 +1391,7 @@ bool IRBuilder::resolveQualifiedId(QQmlJS::AST::UiQualifiedId **nameToResolve, O
// If it's a namespace, prepend the qualifier and we'll resolve it later to the correct type.
QString currentName = qualifiedIdElement->name.toString();
if (qualifiedIdElement->next) {
- for (const QV4::CompiledData::Import* import : qAsConst(_imports))
+ for (const QV4::CompiledData::Import* import : std::as_const(_imports))
if (import->qualifierIndex != emptyStringIndex
&& stringAt(import->qualifierIndex) == currentName) {
qualifiedIdElement = qualifiedIdElement->next;
@@ -1522,7 +1522,7 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen
jsUnit = createdUnit = output.jsGenerator.generateUnit();
// enable flag if we encountered pragma Singleton
- for (Pragma *p : qAsConst(output.pragmas)) {
+ for (Pragma *p : std::as_const(output.pragmas)) {
switch (p->type) {
case Pragma::Singleton:
createdUnit->flags |= Unit::IsSingleton;
@@ -1579,7 +1579,7 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen
const unsigned int objectOffset = sizeof(QV4::CompiledData::QmlUnit) + importSize;
uint nextOffset = objectOffset + objectOffsetTableSize;
- for (Object *o : qAsConst(output.objects)) {
+ for (Object *o : std::as_const(output.objects)) {
objectOffsets.insert(o, nextOffset);
nextOffset += QV4::CompiledData::Object::calculateSizeExcludingSignalsAndEnums(o->functionCount(), o->propertyCount(), o->aliasCount(), o->enumCount(), o->signalCount(), o->bindingCount(), o->namedObjectsInComponent.size(), o->inlineComponentCount(), o->requiredPropertyExtraDataCount());
@@ -1607,7 +1607,7 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen
// write imports
char *importPtr = data + qmlUnit->offsetToImports;
- for (const QV4::CompiledData::Import *imp : qAsConst(output.imports)) {
+ for (const QV4::CompiledData::Import *imp : std::as_const(output.imports)) {
QV4::CompiledData::Import *importToWrite = reinterpret_cast<QV4::CompiledData::Import*>(importPtr);
*importToWrite = *imp;
importPtr += sizeof(QV4::CompiledData::Import);
diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp
index c0026aba1f..bab1f026c3 100644
--- a/src/qml/compiler/qv4compiler.cpp
+++ b/src/qml/compiler/qv4compiler.cpp
@@ -74,8 +74,8 @@ void QV4::Compiler::StringTableGenerator::serialize(CompiledData::Unit *unit)
QV4::CompiledData::String *s = reinterpret_cast<QV4::CompiledData::String *>(stringData);
Q_ASSERT(reinterpret_cast<uintptr_t>(s) % alignof(QV4::CompiledData::String) == 0);
- Q_ASSERT(qstr.length() >= 0);
- s->size = qstr.length();
+ Q_ASSERT(qstr.size() >= 0);
+ s->size = qstr.size();
ushort *uc = reinterpret_cast<ushort *>(reinterpret_cast<char *>(s) + sizeof(*s));
qToLittleEndian<ushort>(qstr.constData(), s->size, uc);
@@ -209,7 +209,7 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit(GeneratorO
{
registerString(module->fileName);
registerString(module->finalUrl);
- for (Context *f : qAsConst(module->functions)) {
+ for (Context *f : std::as_const(module->functions)) {
registerString(f->name);
registerString(f->returnType);
for (int i = 0; i < f->arguments.size(); ++i) {
@@ -219,7 +219,7 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit(GeneratorO
for (int i = 0; i < f->locals.size(); ++i)
registerString(f->locals.at(i));
}
- for (Context *c : qAsConst(module->blocks)) {
+ for (Context *c : std::as_const(module->blocks)) {
for (int i = 0; i < c->locals.size(); ++i)
registerString(c->locals.at(i));
}
@@ -290,7 +290,7 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit(GeneratorO
}
CompiledData::Lookup *lookupsToWrite = reinterpret_cast<CompiledData::Lookup*>(dataPtr + unit->offsetToLookupTable);
- for (const CompiledData::Lookup &l : qAsConst(lookups))
+ for (const CompiledData::Lookup &l : std::as_const(lookups))
*lookupsToWrite++ = l;
CompiledData::RegExp *regexpTable = reinterpret_cast<CompiledData::RegExp *>(dataPtr + unit->offsetToRegexpTable);
@@ -313,12 +313,12 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit(GeneratorO
// write js classes and js class lookup table
quint32_le *jsClassOffsetTable = reinterpret_cast<quint32_le *>(dataPtr + unit->offsetToJSClassTable);
- for (int i = 0; i < jsClassOffsets.count(); ++i)
+ for (int i = 0; i < jsClassOffsets.size(); ++i)
jsClassOffsetTable[i] = jsClassDataOffset + jsClassOffsets.at(i);
}
- if (translations.count()) {
- memcpy(dataPtr + unit->offsetToTranslationTable, translations.constData(), translations.count() * sizeof(CompiledData::TranslationData));
+ if (translations.size()) {
+ memcpy(dataPtr + unit->offsetToTranslationTable, translations.constData(), translations.size() * sizeof(CompiledData::TranslationData));
}
{
@@ -588,7 +588,7 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp
unit.offsetToBlockTable = nextOffset;
nextOffset += unit.blockTableSize * sizeof(uint);
- unit.lookupTableSize = lookups.count();
+ unit.lookupTableSize = lookups.size();
unit.offsetToLookupTable = nextOffset;
nextOffset += unit.lookupTableSize * sizeof(CompiledData::Lookup);
@@ -603,7 +603,7 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp
unit.offsetToConstantTable = nextOffset;
nextOffset += unit.constantTableSize * sizeof(ReturnedValue);
- unit.jsClassTableSize = jsClassOffsets.count();
+ unit.jsClassTableSize = jsClassOffsets.size();
unit.offsetToJSClassTable = nextOffset;
nextOffset += unit.jsClassTableSize * sizeof(uint);
@@ -612,7 +612,7 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp
nextOffset = static_cast<quint32>(roundUpToMultipleOf(8, nextOffset));
- unit.translationTableSize = translations.count();
+ unit.translationTableSize = translations.size();
unit.offsetToTranslationTable = nextOffset;
nextOffset += unit.translationTableSize * sizeof(CompiledData::TranslationData);
@@ -625,16 +625,16 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp
nextOffset = static_cast<quint32>(roundUpToMultipleOf(8, nextOffset));
};
- reserveExportTable(module->localExportEntries.count(), &unit.localExportEntryTableSize, &unit.offsetToLocalExportEntryTable);
- reserveExportTable(module->indirectExportEntries.count(), &unit.indirectExportEntryTableSize, &unit.offsetToIndirectExportEntryTable);
- reserveExportTable(module->starExportEntries.count(), &unit.starExportEntryTableSize, &unit.offsetToStarExportEntryTable);
+ reserveExportTable(module->localExportEntries.size(), &unit.localExportEntryTableSize, &unit.offsetToLocalExportEntryTable);
+ reserveExportTable(module->indirectExportEntries.size(), &unit.indirectExportEntryTableSize, &unit.offsetToIndirectExportEntryTable);
+ reserveExportTable(module->starExportEntries.size(), &unit.starExportEntryTableSize, &unit.offsetToStarExportEntryTable);
- unit.importEntryTableSize = module->importEntries.count();
+ unit.importEntryTableSize = module->importEntries.size();
unit.offsetToImportEntryTable = nextOffset;
nextOffset += unit.importEntryTableSize * sizeof(CompiledData::ImportEntry);
nextOffset = static_cast<quint32>(roundUpToMultipleOf(8, nextOffset));
- unit.moduleRequestTableSize = module->moduleRequests.count();
+ unit.moduleRequestTableSize = module->moduleRequests.size();
unit.offsetToModuleRequestTable = nextOffset;
nextOffset += unit.moduleRequestTableSize * sizeof(uint);
nextOffset = static_cast<quint32>(roundUpToMultipleOf(8, nextOffset));
@@ -696,7 +696,7 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp
if (showStats) {
qDebug() << "Generated JS unit that is" << unit.unitSize << "bytes contains:";
qDebug() << " " << functionSize << "bytes for non-code function data for" << unit.functionTableSize << "functions";
- qDebug() << " " << translations.count() * sizeof(CompiledData::TranslationData) << "bytes for" << translations.count() << "translations";
+ qDebug() << " " << translations.size() * sizeof(CompiledData::TranslationData) << "bytes for" << translations.size() << "translations";
}
return unit;
diff --git a/src/qml/compiler/qv4compilercontext.cpp b/src/qml/compiler/qv4compilercontext.cpp
index cb32f9ad43..1d4b0bde17 100644
--- a/src/qml/compiler/qv4compilercontext.cpp
+++ b/src/qml/compiler/qv4compilercontext.cpp
@@ -147,7 +147,7 @@ Context::ResolvedName Context::resolveName(const QString &name, const QQmlJS::So
return result;
if (c->contextType == ContextType::ESModule) {
- for (int i = 0; i < c->importEntries.count(); ++i) {
+ for (int i = 0; i < c->importEntries.size(); ++i) {
if (c->importEntries.at(i).localName == name) {
result.index = i;
result.type = ResolvedName::Import;
@@ -180,7 +180,7 @@ void Context::emitBlockHeader(Codegen *codegen)
if (requiresExecutionContext) {
if (blockIndex < 0) {
codegen->module()->blocks.append(this);
- blockIndex = codegen->module()->blocks.count() - 1;
+ blockIndex = codegen->module()->blocks.size() - 1;
}
if (contextType == ContextType::Global) {
@@ -272,7 +272,7 @@ void Context::emitBlockHeader(Codegen *codegen)
codegen->referenceForName(QStringLiteral("arguments"), false).storeConsumeAccumulator();
}
- for (const Context::Member &member : qAsConst(members)) {
+ for (const Context::Member &member : std::as_const(members)) {
if (member.function) {
const int function = codegen->defineFunction(member.function->name.toString(), member.function, member.function->formals, member.function->body);
codegen->loadClosure(function);
@@ -360,8 +360,8 @@ void Context::setupFunctionIndices(Moth::BytecodeGenerator *bytecodeGenerator)
break;
}
- sizeOfLocalTemporalDeadZone = localsInTDZ.count();
- for (auto &member: qAsConst(localsInTDZ)) {
+ sizeOfLocalTemporalDeadZone = localsInTDZ.size();
+ for (auto &member: std::as_const(localsInTDZ)) {
member->index = locals.size();
locals.append(member.key());
}
@@ -375,9 +375,9 @@ void Context::setupFunctionIndices(Moth::BytecodeGenerator *bytecodeGenerator)
}
}
- sizeOfRegisterTemporalDeadZone = registersInTDZ.count();
+ sizeOfRegisterTemporalDeadZone = registersInTDZ.size();
firstTemporalDeadZoneRegister = bytecodeGenerator->currentRegister();
- for (auto &member: qAsConst(registersInTDZ))
+ for (auto &member: std::as_const(registersInTDZ))
member->index = bytecodeGenerator->newRegister();
nRegisters = bytecodeGenerator->currentRegister() - registerOffset;
diff --git a/src/qml/compiler/qv4compilerscanfunctions.cpp b/src/qml/compiler/qv4compilerscanfunctions.cpp
index 29bc3918ea..157d2896aa 100644
--- a/src/qml/compiler/qv4compilerscanfunctions.cpp
+++ b/src/qml/compiler/qv4compilerscanfunctions.cpp
@@ -308,7 +308,7 @@ bool ScanFunctions::visit(PatternElement *ast)
declarationLocation.length = ast->lastSourceLocation().end() - declarationLocation.offset;
}
- for (const auto &name : qAsConst(names)) {
+ for (const auto &name : std::as_const(names)) {
if (_context->isStrict && (name.id == QLatin1String("eval") || name.id == QLatin1String("arguments")))
_cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Variable name may not be eval or arguments in strict mode"));
checkName(QStringView(name.id), ast->identifierToken);
@@ -721,7 +721,7 @@ void ScanFunctions::calcEscapingVariables()
{
Module *m = _cg->_module;
- for (Context *inner : qAsConst(m->contextMap)) {
+ for (Context *inner : std::as_const(m->contextMap)) {
if (inner->usesArgumentsObject != Context::ArgumentsObjectUsed)
continue;
if (inner->contextType != ContextType::Block && !inner->isArrowFunction)
@@ -733,7 +733,7 @@ void ScanFunctions::calcEscapingVariables()
c->usesArgumentsObject = Context::ArgumentsObjectUsed;
inner->usesArgumentsObject = Context::ArgumentsObjectNotUsed;
}
- for (Context *inner : qAsConst(m->contextMap)) {
+ for (Context *inner : std::as_const(m->contextMap)) {
if (!inner->parent || inner->usesArgumentsObject == Context::ArgumentsObjectUnknown)
inner->usesArgumentsObject = Context::ArgumentsObjectNotUsed;
if (inner->usesArgumentsObject == Context::ArgumentsObjectUsed) {
@@ -746,7 +746,7 @@ void ScanFunctions::calcEscapingVariables()
}
}
- for (Context *c : qAsConst(m->contextMap)) {
+ for (Context *c : std::as_const(m->contextMap)) {
if (c->contextType != ContextType::ESModule)
continue;
for (const auto &entry: c->exportEntries) {
@@ -757,8 +757,8 @@ void ScanFunctions::calcEscapingVariables()
break;
}
- for (Context *inner : qAsConst(m->contextMap)) {
- for (const QString &var : qAsConst(inner->usedVariables)) {
+ for (Context *inner : std::as_const(m->contextMap)) {
+ for (const QString &var : std::as_const(inner->usedVariables)) {
Context *c = inner;
while (c) {
Context *current = c;
@@ -820,7 +820,7 @@ void ScanFunctions::calcEscapingVariables()
c->innerFunctionAccessesThis |= innerFunctionAccessesThis;
}
}
- for (Context *c : qAsConst(m->contextMap)) {
+ for (Context *c : std::as_const(m->contextMap)) {
if (c->innerFunctionAccessesThis) {
// add an escaping 'this' variable
c->addLocalVar(QStringLiteral("this"), Context::VariableDefinition, VariableScope::Let);
@@ -846,7 +846,7 @@ void ScanFunctions::calcEscapingVariables()
c->requiresExecutionContext = true;
c->argumentsCanEscape = true;
} else {
- for (const auto &m : qAsConst(c->members)) {
+ for (const auto &m : std::as_const(c->members)) {
if (m.isLexicallyScoped()) {
c->requiresExecutionContext = true;
break;
@@ -861,13 +861,13 @@ void ScanFunctions::calcEscapingVariables()
mIt->canEscape = true;
}
const QLatin1String exprForOn("expression for on");
- if (c->contextType == ContextType::Binding && c->name.length() > exprForOn.size() &&
+ if (c->contextType == ContextType::Binding && c->name.size() > exprForOn.size() &&
c->name.startsWith(exprForOn) && c->name.at(exprForOn.size()).isUpper())
// we don't really need this for bindings, but we do for signal handlers, and in this case,
// we don't know if the code is a signal handler or not.
c->requiresExecutionContext = true;
if (c->allVarsEscape) {
- for (const auto &m : qAsConst(c->members))
+ for (const auto &m : std::as_const(c->members))
m.canEscape = true;
}
}
@@ -875,7 +875,7 @@ void ScanFunctions::calcEscapingVariables()
static const bool showEscapingVars = qEnvironmentVariableIsSet("QV4_SHOW_ESCAPING_VARS");
if (showEscapingVars) {
qDebug() << "==== escaping variables ====";
- for (Context *c : qAsConst(m->contextMap)) {
+ for (Context *c : std::as_const(m->contextMap)) {
qDebug() << "Context" << c << c->name << "requiresExecutionContext" << c->requiresExecutionContext << "isStrict" << c->isStrict;
qDebug() << " isArrowFunction" << c->isArrowFunction << "innerFunctionAccessesThis" << c->innerFunctionAccessesThis;
qDebug() << " parent:" << c->parent;
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index c7fdec1a4d..75408fd348 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -503,7 +503,7 @@ void dumpBytecode(const char *bytecode, int len, int nLocals, int nFormals, int
const QVector<CompiledData::CodeOffsetToLine> &lineNumberMapping = QVector<CompiledData::CodeOffsetToLine>());
inline void dumpBytecode(const QByteArray &bytecode, int nLocals, int nFormals, int startLine = 1,
const QVector<CompiledData::CodeOffsetToLine> &lineNumberMapping = QVector<CompiledData::CodeOffsetToLine>()) {
- dumpBytecode(bytecode.constData(), bytecode.length(), nLocals, nFormals, startLine, lineNumberMapping);
+ dumpBytecode(bytecode.constData(), bytecode.size(), nLocals, nFormals, startLine, lineNumberMapping);
}
union Instr
diff --git a/src/qml/debugger/qqmlconfigurabledebugservice_p.h b/src/qml/debugger/qqmlconfigurabledebugservice_p.h
index 8451f4e800..ce911c5baf 100644
--- a/src/qml/debugger/qqmlconfigurabledebugservice_p.h
+++ b/src/qml/debugger/qqmlconfigurabledebugservice_p.h
@@ -37,7 +37,7 @@ protected:
{
QMutexLocker lock(&m_configMutex);
m_waitingForConfiguration = false;
- for (QJSEngine *engine : qAsConst(m_waitingEngines))
+ for (QJSEngine *engine : std::as_const(m_waitingEngines))
Q_EMIT Base::attachedToEngine(engine);
m_waitingEngines.clear();
}
diff --git a/src/qml/debugger/qqmldebugconnector.cpp b/src/qml/debugger/qqmldebugconnector.cpp
index add0396228..0b66a29e18 100644
--- a/src/qml/debugger/qqmldebugconnector.cpp
+++ b/src/qml/debugger/qqmldebugconnector.cpp
@@ -95,7 +95,7 @@ QQmlDebugConnector *QQmlDebugConnector::instance()
int connectorEnd = params->arguments.indexOf(QLatin1Char(','), connectorBegin);
if (connectorEnd == -1)
- connectorEnd = params->arguments.length();
+ connectorEnd = params->arguments.size();
params->instance = loadQQmlDebugConnector(params->arguments.mid(
connectorBegin,
diff --git a/src/qml/doc/snippets/qmltc/tst_qmltc_examples.cpp b/src/qml/doc/snippets/qmltc/tst_qmltc_examples.cpp
index c933adfcaf..f82b9f6d39 100644
--- a/src/qml/doc/snippets/qmltc/tst_qmltc_examples.cpp
+++ b/src/qml/doc/snippets/qmltc/tst_qmltc_examples.cpp
@@ -162,7 +162,7 @@ void tst_qmltc_examples::helloWorld()
QVERIFY(!documentationCode.isEmpty());
auto begin = generatedCode.cbegin();
- for (const QString &existingString : qAsConst(documentationCode)) {
+ for (const QString &existingString : std::as_const(documentationCode)) {
auto pos = std::find(begin, generatedCode.cend(), existingString);
QVERIFY2(pos != generatedCode.cend(), qPrintable(u"Could not find: " + existingString));
begin = std::next(pos);
diff --git a/src/qml/doc/src/cmake/cmake-properties.qdoc b/src/qml/doc/src/cmake/cmake-properties.qdoc
index 0b8d2c9367..98858ca6d1 100644
--- a/src/qml/doc/src/cmake/cmake-properties.qdoc
+++ b/src/qml/doc/src/cmake/cmake-properties.qdoc
@@ -13,7 +13,7 @@ CMake source file properties:
/*!
-\page cmake-source-file-property-QT_QML_INTERNAL_TYPE.html
+\page cmake-source-file-property-qt-qml-internal-type.html
\ingroup cmake-source-file-properties-qtqml
\title QT_QML_INTERNAL_TYPE
@@ -30,7 +30,7 @@ Set this property to \c TRUE to indicate that the \c{.qml} file provides an inte
/*!
-\page cmake-source-file-property-QT_QML_SINGLETON_TYPE.html
+\page cmake-source-file-property-qt-qml-singleton-type.html
\ingroup cmake-source-file-properties-qtqml
\title QT_QML_SINGLETON_TYPE
@@ -53,7 +53,7 @@ how to set the \c QT_QML_SINGLETON_TYPE property.
/*!
-\page cmake-source-file-property-QT_QML_SKIP_CACHEGEN.html
+\page cmake-source-file-property-qt-qml-skip-cachegen.html
\ingroup cmake-source-file-properties-qtqml
\title QT_QML_SKIP_CACHEGEN
@@ -72,7 +72,7 @@ The file will still be added to the \c target as a resource in uncompiled form
/*!
-\page cmake-source-file-property-QT_QML_SKIP_QMLDIR_ENTRY.html
+\page cmake-source-file-property-qt-qml-skip-qmldir-entry.html
\ingroup cmake-source-file-properties-qtqml
\title QT_QML_SKIP_QMLDIR_ENTRY
@@ -91,7 +91,7 @@ the \c{.qml} file from being added as a type to the QML module's typeinfo file
/*!
-\page cmake-source-file-property-QT_QML_SKIP_QMLLINT.html
+\page cmake-source-file-property-qt-qml-skip-qmllint.html
\ingroup cmake-source-file-properties-qtqml
\title QT_QML_SKIP_QMLLINT
@@ -109,7 +109,7 @@ Set this property to \c TRUE to prevent the file from being included in
/*!
-\page cmake-source-file-property-QT_QML_SOURCE_TYPENAME.html
+\page cmake-source-file-property-qt-qml-source-typename.html
\ingroup cmake-source-file-properties-qtqml
\title QT_QML_SOURCE_TYPENAME
@@ -126,7 +126,7 @@ Use this property to override the \c QML type name provided by this file.
/*!
-\page cmake-source-file-property-QT_QML_SOURCE_VERSIONS.html
+\page cmake-source-file-property-qt-qml-source-versions.html
\ingroup cmake-source-file-properties-qtqml
\title QT_QML_SOURCE_VERSIONS
@@ -145,7 +145,7 @@ version after the \c{.0} release, specify those versions using this property.
/*!
-\page cmake-source-file-property-QT_QMLTC_FILE_BASENAME.html
+\page cmake-source-file-property-qt-qmltc-file-basename.html
\ingroup cmake-source-file-properties-qtqml
\title QT_QMLTC_FILE_BASENAME
@@ -163,7 +163,7 @@ conflicting file names.
*/
/*!
-\page cmake-source-file-property-QT_QML_SKIP_TYPE_COMPILER.html
+\page cmake-source-file-property-qt-qml-skip-type-compiler.html
\ingroup cmake-source-file-properties-qtqml
\title QT_QML_SKIP_TYPE_COMPILER
diff --git a/src/qml/doc/src/cmake/cmake-variables.qdoc b/src/qml/doc/src/cmake/cmake-variables.qdoc
index 15f73f074e..574b24e970 100644
--- a/src/qml/doc/src/cmake/cmake-variables.qdoc
+++ b/src/qml/doc/src/cmake/cmake-variables.qdoc
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
-\page cmake-variable-QT_QML_OUTPUT_DIRECTORY.html
+\page cmake-variable-qt-qml-output-directory.html
\ingroup cmake-variables-qtqml
\title QT_QML_OUTPUT_DIRECTORY
diff --git a/src/qml/doc/src/cmake/qt_add_qml_module.qdoc b/src/qml/doc/src/cmake/qt_add_qml_module.qdoc
index 20c343a1bd..e20876fede 100644
--- a/src/qml/doc/src/cmake/qt_add_qml_module.qdoc
+++ b/src/qml/doc/src/cmake/qt_add_qml_module.qdoc
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
-\page qt_add_qml_module.html
+\page qt-add-qml-module.html
\ingroup cmake-commands-qtqml
\title qt_add_qml_module
@@ -364,8 +364,12 @@ been created. When \c NO_CREATE_PLUGIN_TARGET is given, \c PLUGIN_TARGET must
also be provided to explicitly name the plugin target.
Every QML module must define a \c URI. It should be specified in dotted URI
-notation, such as \c{QtQuick.Layouts}. It must not contain anything other than
-alphanumeric or dot characters. Other QML modules may use this name in
+notation, such as \c{QtQuick.Layouts}. Each segment must be a well-formed
+ECMAScript Identifier Name. This means, for example, the segments
+must not start with a number and they must not contain \e{-} (minus)
+characters. As the \c URI will be translated into directory names, you
+should restrict it to alphanumeric characters of the latin alphabet,
+underscores, and dots. Other QML modules may use this name in
\l{qtqml-syntax-imports.html}{import statements} to import the module. The
\c URI will be used in the \c module line of the generated
\l{Module Definition qmldir Files}{qmldir} file. The \c URI is also used to
diff --git a/src/qml/doc/src/cmake/qt_add_qml_plugin.qdoc b/src/qml/doc/src/cmake/qt_add_qml_plugin.qdoc
index cb98406a9d..2ce744559c 100644
--- a/src/qml/doc/src/cmake/qt_add_qml_plugin.qdoc
+++ b/src/qml/doc/src/cmake/qt_add_qml_plugin.qdoc
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
-\page qt_add_qml_plugin.html
+\page qt-add-qml-plugin.html
\ingroup cmake-commands-qtqml
\title qt_add_qml_plugin
diff --git a/src/qml/doc/src/cmake/qt_deploy_qml_imports.qdoc b/src/qml/doc/src/cmake/qt_deploy_qml_imports.qdoc
index 92da84733e..cc3c61863c 100644
--- a/src/qml/doc/src/cmake/qt_deploy_qml_imports.qdoc
+++ b/src/qml/doc/src/cmake/qt_deploy_qml_imports.qdoc
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
-\page qt_deploy_qml_imports.html
+\page qt-deploy-qml-imports.html
\ingroup cmake-commands-qtqml
\title qt_deploy_qml_imports
@@ -18,7 +18,7 @@ project.
\preliminarycmakecommand
-\include cmake-qml-qt-finalize-target-warning.cmake
+\include cmake-qml-qt-finalize-target-warning.qdocinc
\section1 Synopsis
diff --git a/src/qml/doc/src/cmake/qt_generate_deploy_qml_app_script.qdoc b/src/qml/doc/src/cmake/qt_generate_deploy_qml_app_script.qdoc
index 493a4fc029..fc78baddcd 100644
--- a/src/qml/doc/src/cmake/qt_generate_deploy_qml_app_script.qdoc
+++ b/src/qml/doc/src/cmake/qt_generate_deploy_qml_app_script.qdoc
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
-\page qt_generate_deploy_qml_app_script.html
+\page qt-generate-deploy-qml-app-script.html
\ingroup cmake-commands-qtqml
\title qt_generate_deploy_qml_app_script
@@ -15,7 +15,7 @@
\cmakecommandsince 6.3
\preliminarycmakecommand
-\include cmake-qml-qt-finalize-target-warning.cmake
+\include cmake-qml-qt-finalize-target-warning.qdocinc
\section1 Synopsis
diff --git a/src/qml/doc/src/cmake/qt_generate_foreign_qml_types.qdoc b/src/qml/doc/src/cmake/qt_generate_foreign_qml_types.qdoc
index 856f0fe2b1..9bd412d36d 100644
--- a/src/qml/doc/src/cmake/qt_generate_foreign_qml_types.qdoc
+++ b/src/qml/doc/src/cmake/qt_generate_foreign_qml_types.qdoc
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
-\page qt_generate_foreign_qml_types.html
+\page qt-generate-foreign-qml-types.html
\ingroup cmake-commands-qtqml
\title qt_generate_foreign_qml_types
@@ -67,4 +67,13 @@ the \c QML_ELEMENT macro).
The effect is equivalent to using \c QML_FOREIGN with custom structs in the QML library to expose
the types.
+
+\note In order to implement custom behavior, such as exposing an existing
+singleton instance with its own life cycle to QML, you should add custom types
+to your QML library (mylib_declarative in the above example). In turn, you
+should omit the \l QML_ELEMENT and similar macros from the original C++ classes
+so that qt_generate_foreign_qml_types() does not generate more QML integration
+structs for them. The QML macros, as well as any singleton factory functions,
+can be added to the structs that contain the \l QML_FOREIGN.
+
*/
diff --git a/src/qml/doc/src/cmake/qt_import_qml_plugins.qdoc b/src/qml/doc/src/cmake/qt_import_qml_plugins.qdoc
index b45e47ce55..8d6b32f903 100644
--- a/src/qml/doc/src/cmake/qt_import_qml_plugins.qdoc
+++ b/src/qml/doc/src/cmake/qt_import_qml_plugins.qdoc
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
-\page qt_import_qml_plugins.html
+\page qt-import-qml-plugins.html
\ingroup cmake-commands-qtqml
\title qt_import_qml_plugins
diff --git a/src/qml/doc/src/cmake/qt_query_qml_module.qdoc b/src/qml/doc/src/cmake/qt_query_qml_module.qdoc
index 50996745c8..44d0a7f8da 100644
--- a/src/qml/doc/src/cmake/qt_query_qml_module.qdoc
+++ b/src/qml/doc/src/cmake/qt_query_qml_module.qdoc
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
-\page qt_query_qml_module.html
+\page qt-query-qml-module.html
\ingroup cmake-commands-qtqml
\title qt_query_qml_module
diff --git a/src/qml/doc/src/cmake/qt_target_compile_qml_to_cpp.qdoc b/src/qml/doc/src/cmake/qt_target_compile_qml_to_cpp.qdoc
index d989c80fcf..0ef6e421ed 100644
--- a/src/qml/doc/src/cmake/qt_target_compile_qml_to_cpp.qdoc
+++ b/src/qml/doc/src/cmake/qt_target_compile_qml_to_cpp.qdoc
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
-\page qt_target_compile_qml_to_cpp.html
+\page qt-target-compile-qml-to-cpp.html
\ingroup cmake-commands-qtqml
\title qt_target_compile_qml_to_cpp
diff --git a/src/qml/doc/src/cmake/qt_target_qml_sources.qdoc b/src/qml/doc/src/cmake/qt_target_qml_sources.qdoc
index 126c9767a0..35854d4b95 100644
--- a/src/qml/doc/src/cmake/qt_target_qml_sources.qdoc
+++ b/src/qml/doc/src/cmake/qt_target_qml_sources.qdoc
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
-\page qt_target_qml_sources.html
+\page qt-target-qml-sources.html
\ingroup cmake-commands-qtqml
\title qt_target_qml_sources
diff --git a/src/qml/doc/src/cppintegration/definetypes.qdoc b/src/qml/doc/src/cppintegration/definetypes.qdoc
index 5799fda87e..ac1c751bf2 100644
--- a/src/qml/doc/src/cppintegration/definetypes.qdoc
+++ b/src/qml/doc/src/cppintegration/definetypes.qdoc
@@ -77,15 +77,18 @@ Types to QML} explains, the properties, methods and signals of any
QObject-derived class are accessible from QML code.
To register a QObject-derived class as an instantiable QML object type, add
-\c QML_ELEMENT or \c QML_NAMED_ELEMENT(<name>) to the class declaration and
+\c QML_ELEMENT or \c QML_NAMED_ELEMENT(<name>) to the class declaration. You
+also need to make adjustments in the build system. For qmake, add
\c {CONFIG += qmltypes}, a \c {QML_IMPORT_NAME}, and a
-\c QML_IMPORT_MAJOR_VERSION to your project file. This will register the class
-into the type namespace under the given major version, using either the class
-name or an explicitly given name as QML type name. The minor version(s) will
-be derived from any revisions attached to properties, methods, or signals. The
-default minor version is \c 0. You can explicitly restrict the type to be
-available only from specific minor versions by adding the
-\c QML_ADDED_IN_MINOR_VERSION() macro to the class declaration. Clients can
+\c QML_IMPORT_MAJOR_VERSION to your project file. For CMake, the file containing
+the class should be part of a target set-up with
+\l{qt_add_qml_module}{qt_add_qml_module()}.
+This will register the class into the type namespace under the given major version,
+using either the class name or an explicitly given name as QML type name. The
+minor version(s) will be derived from any revisions attached to properties,
+methods, or signals. The default minor version is \c 0. You can explicitly
+restrict the type to be available only from specific minor versions by adding
+the \c QML_ADDED_IN_MINOR_VERSION() macro to the class declaration. Clients can
import suitable versions of the namespace in order to use the type.
For example, suppose there is a \c Message class with \c author and
@@ -107,26 +110,52 @@ This type can be registered by adding an appropriate type namespace and version
number to the project file. For example, to make the type available in the
\c com.mycompany.messaging namespace with version 1.0:
-\code
-CONFIG += qmltypes
-QML_IMPORT_NAME = com.mycompany.messaging
-QML_IMPORT_MAJOR_VERSION = 1
-\endcode
+\if defined(onlinedocs)
+ \tab {build-qt-app}{tab-cmake}{CMake}{selected}
+ \tab {build-qt-app}{tab-qmake}{qmake}{}
+ \tabcontent {tab-cmake}
+ \else
+ \section3 Using CMake
+\endif
+ \badcode
+ qt_add_qml_module(messaging
+ URI com.mycompany.messaging
+ VERSION 1.0
+ SOURCES
+ message.cpp message.h
+ )
+ \endcode
+\if defined(onlinedocs)
+ \endtabcontent
+ \tabcontent {tab-qmake}
+\else
+ \section3 Using QMake
+\endif
+ \code
+ CONFIG += qmltypes
+ QML_IMPORT_NAME = com.mycompany.messaging
+ QML_IMPORT_MAJOR_VERSION = 1
+ \endcode
+
+ If the header the class is declared in is not accessible from your project's
+ include path, you may have to amend the include path so that the generated
+ registration code can be compiled.
+
+ \code
+ INCLUDEPATH += com/mycompany/messaging
+ \endcode
+\if defined(onlinedocs)
+ \endtabcontent
+\endif
-If the header the class is declared in is not accessible from your project's
-include path, you may have to amend the include path so that the generated
-registration code can be compiled:
-\code
-INCLUDEPATH += com/mycompany/messaging
-\endcode
The type can be used in an \l{qtqml-syntax-basics.html#object-declarations}
{object declaration} from QML, and its properties can be read and written to,
as per the example below:
\qml
-import com.mycompany.messaging 1.0
+import com.mycompany.messaging
Message {
author: "Amelie"
diff --git a/src/qml/doc/src/includes/cmake-qml-qt-finalize-target-warning.cmake b/src/qml/doc/src/includes/cmake-qml-qt-finalize-target-warning.qdocinc
index d3c7383d2e..9152726398 100644
--- a/src/qml/doc/src/includes/cmake-qml-qt-finalize-target-warning.cmake
+++ b/src/qml/doc/src/includes/cmake-qml-qt-finalize-target-warning.qdocinc
@@ -1,3 +1,6 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
\warning If you are using a CMake version lower than 3.19, make sure that you
pass the \c MANUAL_FINALIZATION option to
\l{qt_add_executable}{qt6_add_executable()}, and then call
diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc
index 89b52131d9..005bd0be94 100644
--- a/src/qml/doc/src/qmlfunctions.qdoc
+++ b/src/qml/doc/src/qmlfunctions.qdoc
@@ -173,7 +173,9 @@
\c{T *create(QQmlEngine *, QJSEngine *)} when the type is first accessed.
If both do exist and are accessible, the default constructor is preferred.
If there is no default constructor and no factory function the singleton is
- inaccessible.
+ inaccessible. The QML engine generally assumes ownership of the singleton and
+ will delete it when the engine itself is destroyed. You can prevent this by
+ calling QJSEngine::setObjectOwnership() on the singleton.
In order to declare a default-constructible class as singleton, all you have
to do is add \l QML_SINGLETON:
@@ -260,7 +262,7 @@
// Initialize this using myObject where you would previously
// call qmlRegisterSingletonInstance().
- static MySingleton *s_singletonInstance = nullptr;
+ inline static MySingleton *s_singletonInstance = nullptr;
static MySingleton *create(QQmlEngine *, QJSEngine *engine)
{
@@ -284,7 +286,7 @@
}
private:
- static QJSEngine *s_engine = nullptr;
+ inline static QJSEngine *s_engine = nullptr;
};
\endcode
diff --git a/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc b/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc
index 80dabe45b9..58e2027e1c 100644
--- a/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc
+++ b/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc
@@ -29,8 +29,12 @@ The type name has the following requirements:
This document is then automatically recognized by the engine as a definition of
a QML type. Additionally, a type defined in this manner is automatically made
-available to other QML files within the same directory as the engine searches
-within the immediate directory when resolving QML type names.
+available to other QML files within the same local directory as the engine
+searches within the immediate directory when resolving QML type names.
+
+\note The QML engine does not automatically search remote directories this way.
+You have to add a qmldir file if your documents are loaded over the network. See
+\l{Importing QML Document Directories}.
\section2 Custom QML Type Definition
@@ -251,14 +255,14 @@ The same declaration can also be given for C++-defined types. See
\section2 ComponentBehavior
With this pragma you can restrict components defined in this file to only
-create objects within the context of the same file. This holds for inline
+create objects within their original context. This holds for inline
components as well as Component elements explicitly or implicitly created
-as properties. If a component is bound to a file context, you can safely
+as properties. If a component is bound to its context, you can safely
use IDs from the rest of the file within the component. Otherwise, the
engine and the QML tooling cannot know in advance what type, if any, such
IDs will resolve to at run time.
-In order to bind the components to the file scope specify the \c{Bound}
+In order to bind the components to their context specify the \c{Bound}
argument:
\qml
@@ -268,7 +272,7 @@ pragma ComponentBehavior: Bound
The default is \c{Unbound}. You can also specify it explicitly. In a
future version of Qt the default will change to \c{Bound}.
-Delegate components bound to the file context don't receive their own
+Delegate components bound to their context don't receive their own
private contexts on instantiation. This means that model data can only
be passed via \l{Required Properties}{required properties} in this case.
Passing model data via context properties will not work. This concerns
diff --git a/src/qml/doc/src/qmllanguageref/modules/identifiedmodules.qdoc b/src/qml/doc/src/qmllanguageref/modules/identifiedmodules.qdoc
index 6e8751af70..93461f1ed7 100644
--- a/src/qml/doc/src/qmllanguageref/modules/identifiedmodules.qdoc
+++ b/src/qml/doc/src/qmllanguageref/modules/identifiedmodules.qdoc
@@ -20,6 +20,12 @@ Identified modules must be installed into the
\l{qtqml-syntax-imports.html#qml-import-path}{import path} in order to be found
by the QML engine.
+Syntactically, each dot-separated segment of the URI must be a well-formed
+ECMAScript Identifier Name. This means, for example, the segments must not start
+with a number and they must not contain \e{-} (minus) characters. As the URI
+will be translated into directory names, you should restrict it to alphanumeric
+characters of the latin alphabet, underscores, and dots.
+
\section1 Locally Installed Identified Modules
A directory of QML and/or C++ files can be shared as an identified module if it
@@ -147,7 +153,6 @@ An identified module has several restrictions upon it:
\li the module must register its types into the module identifier type
namespace
\li the module may not register types into any other module's namespace
-\li clients must specify a version when importing the module
\endlist
For example, if an identified module is installed into
@@ -164,10 +169,9 @@ module com.example.CustomUi
\endcode
Clients will then be able to import the above module with the following import
-statement (assuming that the module registers types into version 1.0 of its
-namespace):
+statement:
\qml
-import com.example.CustomUi 1.0
+import com.example.CustomUi
\endqml
*/
diff --git a/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc b/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc
index c6d5e1446b..ac82d8136e 100644
--- a/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc
+++ b/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc
@@ -419,7 +419,7 @@ documentation on this, no further action is needed. qmltyperegistrar will
automatically generate the \c .qmltypes files.
Example:
-If your module is in \c /tmp/imports/My/Module, a file caled \c plugins.qmltypes
+If your module is in \c /tmp/imports/My/Module, a file called \c plugins.qmltypes
should be generated alongside the actual plugin binary.
Add the line
diff --git a/src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc b/src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc
index c37fb81401..fca702a278 100644
--- a/src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc
+++ b/src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc
@@ -38,6 +38,14 @@ plugins. Library plugins should limit themselves to registering types, as
any manipulation of the engine's root context may cause conflicts or other
issues in the library user's code.
+\note When using the CMake \l qt_add_qml_module API, a plugin will be generated
+automatically for you. It will take care of type registration.
+You only need to write a custom plugin if you have special
+requirements, such as registering custom image
+providers. In that case, pass
+\l{NO_GENERATE_PLUGIN_SOURCE} to the \c qt_add_qml_module
+call to disable the generation of the default plugin.
+
The linker might erroneously remove the generated type registration
function as an optimization. You can prevent that by declaring a synthetic
volatile pointer to the function somewhere in your code. If your module is
diff --git a/src/qml/doc/src/qmllanguageref/syntax/directoryimports.qdoc b/src/qml/doc/src/qmllanguageref/syntax/directoryimports.qdoc
index 37298c8caf..7126033431 100644
--- a/src/qml/doc/src/qmllanguageref/syntax/directoryimports.qdoc
+++ b/src/qml/doc/src/qmllanguageref/syntax/directoryimports.qdoc
@@ -85,6 +85,11 @@ a file system path.
A directory of QML files can also be imported from a remote location if the
directory contains a directory listing \c qmldir file.
+\note This also holds for the implicit import of the directory a QML document
+resides in. If your QML documents are loaded from a remote location, you need
+to add qmldir files even if they don't contain any explicit directory import
+statements. Otherwise your QML documents won't see each other.
+
For example, if the \c myapp directory in the previous example was hosted at
"http://www.my-example-server.com", and the \c mycomponents directory
contained a \c qmldir file defined as follows:
diff --git a/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc b/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc
index a6158b14af..6e6088049c 100644
--- a/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc
+++ b/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc
@@ -12,12 +12,10 @@ resources and component directories are used within a QML document. The types
which may be used within a document depends on which modules, resources and
directories are imported by the document.
-\section2 Import Types
-
There are three different types of imports. Each import type has a slightly
different syntax, and different semantics apply to different import types.
-\section3 Module (Namespace) Imports
+\section2 Module (Namespace) Imports
The most common type of import is a module import. Clients can import
\l{qtqml-modules-identifiedmodules.html}{QML modules} which register QML object
@@ -112,7 +110,7 @@ Rectangle {
In this case, the engine will emit an error and refuse to load the file.
-\section4 C++ Module Imports
+\section3 C++ Module Imports
Usually, C++ types are declared using the QML_ELEMENT and QML_NAMED_ELEMENT()
macros and registered via the build system using QML_IMPORT_NAME and
@@ -122,7 +120,7 @@ module that can be imported to access the types.
This is most common in client applications which define their own QML object
types in C++.
-\section4 Importing into a Qualified Local Namespace
+\section3 Importing into a Qualified Local Namespace
The \c import statement may optionally use the \c as keyword to specify that
the types should be imported into a particular document-local namespace. If a
@@ -172,7 +170,7 @@ way that multiple modules can be imported into the global namespace. For example
\snippet qml/imports/merged-named-imports.qml imports
-\section3 Directory Imports
+\section2 Directory Imports
A directory which contains QML documents may also be imported directly in a
QML document. This provides a simple way for QML types to be segmented into
@@ -198,7 +196,7 @@ section about \l{Importing into a Qualified Local Namespace}.
For more information about directory imports, please see the in-depth
documentation about \l{qtqml-syntax-directoryimports.html}{directory imports}.
-\section3 JavaScript Resource Imports
+\section2 JavaScript Resource Imports
JavaScript resources may be imported directly in a QML document. Every
JavaScript resource must have an identifier by which it is accessed.
@@ -211,7 +209,7 @@ import "<JavaScriptFile>" as <Identifier>
Note that the \c <Identifier> must be unique within a QML document, unlike the
local namespace qualifier which can be applied to module imports.
-\section4 JavaScript Resources from Modules
+\section3 JavaScript Resources from Modules
Javascript files can be provided by modules, by adding identifier
definitions to the \c qmldir file which specifies the module.
@@ -254,7 +252,7 @@ Item {
}
\endqml
-\section4 Further Information
+\section3 Further Information
For more information about JavaScript resources, please see the documentation
about \l{qtqml-javascript-resources.html}
diff --git a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
index bbc5aae0f0..60e90217f4 100644
--- a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
+++ b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
@@ -32,6 +32,7 @@ The set of QML object-type attribute types is as follows:
These attributes are discussed in detail below.
\section2 The \e id Attribute
+\keyword QML.id
Every QML object type has exactly one \e id attribute. This attribute is
provided by the language itself, and cannot be redefined or overridden by any
diff --git a/src/qml/doc/src/qmllanguageref/typesystem/valuetypes.qdoc b/src/qml/doc/src/qmllanguageref/typesystem/valuetypes.qdoc
index ef10620422..e497d5d5c8 100644
--- a/src/qml/doc/src/qmllanguageref/typesystem/valuetypes.qdoc
+++ b/src/qml/doc/src/qmllanguageref/typesystem/valuetypes.qdoc
@@ -40,7 +40,7 @@ the client to import the module which provides them.
All of the value types listed below may be used as a \c property type in a QML
document, with the following exceptions:
\list
- \li \c list must be used in conjunction with a QML object type
+ \li \c list must be used in conjunction with an object or value type as element
\li \c enumeration cannot be used directly as the enumeration must be defined by a registered QML object type
\endlist
@@ -285,16 +285,7 @@ property is only invoked when the property is reassigned to a different object v
The \c list type refers to a list of QML objects or values.
- A list value can be accessed in a similar way to a JavaScript array:
-
- \list
- \li Values are assigned using the \c[] square bracket syntax with comma-separated values
- \li The \c length property provides the number of items in the list
- \li Values in the list are accessed using the \c [index] syntax
- \endlist
-
- Values can be dynamically added to the list by using the \c push method,
- as if it were a JavaScript Array
+ Properties of type \c list are empty by default.
A \c list can store QML objects or \l{QML Value Types}{value type} values.
@@ -311,7 +302,7 @@ property is only invoked when the property is reassigned to a different object v
can be assigned to and used as follows:
\qml
- import QtQuick 2.0
+ import QtQuick
Item {
width: 100; height: 100
@@ -335,7 +326,7 @@ property is only invoked when the property is reassigned to a different object v
If the list only contains one object, the square brackets may be omitted:
\qml
- import QtQuick 2.0
+ import QtQuick
Item {
width: 100; height: 100
@@ -343,17 +334,38 @@ property is only invoked when the property is reassigned to a different object v
}
\endqml
- Objects and values in a list can be replaced with the \c{[]} operator, just
- like entries of JavaScript arrays. You can also use \c{push()} to append
- entries, or you can set the \c length property of the list to truncate or
- extend it. You can not automatically extend the list by assigning to an
- index currently out of range, though. Furthermore, if you insert \c null
- values into a list of objects, those are converted to \c nullptr entries in
+ You can also declare your own list properties in QML:
+
+ \qml
+ import QtQml
+
+ QtObject {
+ property list<int> intList: [1, 2, 3, 4]
+ property list<QtObject> objectList
+ }
+ \endqml
+
+ Lists can be used much like JavaScript arrays. For example:
+
+ \list
+ \li Values are assigned using the \c[] square bracket syntax with comma-separated values
+ \li The \c length property provides the number of items in the list
+ \li Values in the list are accessed using the \c [index] syntax
+ \li You can use \c{push()} to append entries
+ \li You can set the \c length property of the list to truncate or extend it.
+ \endlist
+
+ However, you can \e{not} automatically extend the list by assigning to an
+ index currently out of range. Furthermore, if you insert \c null values
+ into a list of objects, those are converted to \c nullptr entries in
the underlying QQmlListProperty.
- A list of value types is different from a JavaScript array in one important
- aspect: Growing it by setting its length does not produce undefined entries,
- but rather default-constructed instances of the value type.
+ A list of value types is different from a JavaScript array in one further
+ important aspect: Growing it by setting its length does not produce undefined
+ entries, but rather default-constructed instances of the value type.
+
+ Similarly, growing a list of object types this way produces null entries,
+ rather than undefined entries.
This value type is provided by the QML language.
@@ -461,6 +473,36 @@ property is only invoked when the property is reassigned to a different object v
*/
/*!
+ \qmlvaluetype variant
+ \ingroup qmlvaluetypes
+ \brief a generic property type.
+
+ The \c variant type is the same as the \c var type. Use \c var instead.
+
+ \sa {QML Value Types}
+*/
+
+/*!
+ \qmlvaluetype void
+ \ingroup qmlvaluetypes
+ \brief The empty value type.
+
+ The \c void type is exclusively used to type-annotate JavaScript functions
+ returning \c undefined. For example:
+
+ \qml
+ function doThings() : void { console.log("hello") }
+ \endqml
+
+ This is to help tooling analyze calls to such functions and compile them and
+ their callers to C++.
+
+ You cannot declare \c void properties in QML.
+
+ \sa {QML Value Types}
+*/
+
+/*!
\qmlvaluetype enumeration
\ingroup qmlvaluetypes
\brief a named enumeration value.
diff --git a/src/qml/doc/src/qmltypereference.qdoc b/src/qml/doc/src/qmltypereference.qdoc
index a89f89f9f7..da9d08d4e6 100644
--- a/src/qml/doc/src/qmltypereference.qdoc
+++ b/src/qml/doc/src/qmltypereference.qdoc
@@ -60,8 +60,7 @@ provided:
/*!
\qmlvaluetype date
-\ingroup qtqmlvaluetypes
-\ingroup qtquickvaluetypes
+\ingroup qmlvaluetypes
\brief a date value.
The \c date type refers to a date value, including the time of the day.
@@ -130,7 +129,7 @@ is automatically converted into a QPointF value.
\qmlvaluetype size
\ingroup qtqmlvaluetypes
\ingroup qtquickvaluetypes
-\brief a value with width and height attributes
+\brief a value with width and height attributes.
The \c size type refers to a value with has \c width and \c height attributes.
diff --git a/src/qml/doc/src/qtqml.qdoc b/src/qml/doc/src/qtqml.qdoc
index 9d0a0e67a8..2da6a8c9e0 100644
--- a/src/qml/doc/src/qtqml.qdoc
+++ b/src/qml/doc/src/qtqml.qdoc
@@ -128,6 +128,20 @@ the QML code to interact with C++ code.
\endlist
\endomit
+\section1 Licenses and Attributions
+
+Qt QML is available under commercial licenses from \l{The Qt Company}.
+In addition, it is available under free software licenses. Since Qt 5.4,
+these free software licenses are
+\l{GNU Lesser General Public License, version 3}, or
+the \l{GNU General Public License, version 2}.
+See \l{Qt Licensing} for further details.
+
+Furthermore Qt QML in Qt \QtVersion may contain third party
+modules under following permissive licenses:
+
+\generatelist{groupsbymodule attributions-qtqml}
+
\section1 Related Articles and Guides
Further information for writing QML applications:
@@ -146,30 +160,11 @@ Further information for writing QML applications:
results
\endlist
-\section1 Examples
-
-\list
- \li \l {Qt QML Examples} {Examples}
-\endlist
-
-\section2 Reference
+\section1 Reference
\list
\li \l {Qt QML C++ Classes} {C++ Classes}
\li \l {Qt QML QML Types} {QML Types}
+ \li \l {Qt QML Examples} {Examples}
\endlist
-
-\section1 Licenses and Attributions
-
-Qt QML is available under commercial licenses from \l{The Qt Company}.
-In addition, it is available under free software licenses. Since Qt 5.4,
-these free software licenses are
-\l{GNU Lesser General Public License, version 3}, or
-the \l{GNU General Public License, version 2}.
-See \l{Qt Licensing} for further details.
-
-Furthermore Qt QML in Qt \QtVersion may contain third party
-modules under following permissive licenses:
-
-\generatelist{groupsbymodule attributions-qtqml}
*/
diff --git a/src/qml/jit/qv4baselinejit_p.h b/src/qml/jit/qv4baselinejit_p.h
index 99cdcaa0fc..537a493127 100644
--- a/src/qml/jit/qv4baselinejit_p.h
+++ b/src/qml/jit/qv4baselinejit_p.h
@@ -34,7 +34,7 @@ class BaselineJIT final: public Moth::ByteCodeHandler
{
public:
BaselineJIT(QV4::Function *);
- virtual ~BaselineJIT() Q_DECL_OVERRIDE;
+ ~BaselineJIT() override;
void generate();
diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp
index f82c2cba26..7363703544 100644
--- a/src/qml/jsapi/qjsengine.cpp
+++ b/src/qml/jsapi/qjsengine.cpp
@@ -829,7 +829,7 @@ static bool convertString(const QString &string, QMetaType metaType, void *ptr)
{
// have a string based value without engine. Do conversion manually
if (metaType == QMetaType::fromType<bool>()) {
- *reinterpret_cast<bool*>(ptr) = string.length() != 0;
+ *reinterpret_cast<bool*>(ptr) = string.size() != 0;
return true;
}
if (metaType == QMetaType::fromType<QString>()) {
diff --git a/src/qml/jsapi/qjsmanagedvalue.cpp b/src/qml/jsapi/qjsmanagedvalue.cpp
index 8b2f367304..0bb01f1835 100644
--- a/src/qml/jsapi/qjsmanagedvalue.cpp
+++ b/src/qml/jsapi/qjsmanagedvalue.cpp
@@ -958,7 +958,7 @@ QJSValue QJSManagedValue::call(const QJSValueList &arguments) const
QV4::ExecutionEngine *engine = f->engine();
QV4::Scope scope(engine);
- QV4::JSCallArguments jsCallData(scope, arguments.length());
+ QV4::JSCallArguments jsCallData(scope, arguments.size());
*jsCallData.thisObject = engine->globalObject;
int i = 0;
for (const QJSValue &arg : arguments) {
@@ -997,7 +997,7 @@ QJSValue QJSManagedValue::callWithInstance(const QJSValue &instance,
}
QV4::Scope scope(engine);
- QV4::JSCallArguments jsCallData(scope, arguments.length());
+ QV4::JSCallArguments jsCallData(scope, arguments.size());
*jsCallData.thisObject = QJSValuePrivate::convertToReturnedValue(engine, instance);
int i = 0;
for (const QJSValue &arg : arguments) {
@@ -1030,7 +1030,7 @@ QJSValue QJSManagedValue::callAsConstructor(const QJSValueList &arguments) const
QV4::ExecutionEngine *engine = f->engine();
QV4::Scope scope(engine);
- QV4::JSCallArguments jsCallData(scope, arguments.length());
+ QV4::JSCallArguments jsCallData(scope, arguments.size());
int i = 0;
for (const QJSValue &arg : arguments) {
if (Q_UNLIKELY(!QJSValuePrivate::checkEngine(engine, arg))) {
diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp
index 388cc1a21a..ea0381e886 100644
--- a/src/qml/jsapi/qjsvalue.cpp
+++ b/src/qml/jsapi/qjsvalue.cpp
@@ -106,6 +106,16 @@
integers.append(jsArray.property(i).toInt());
}
\endcode
+
+ \section2 Converting to JSON
+
+ It's possible to convert a QJSValue to a JSON type. For example,
+ to convert to an array, use \l QJSEngine::fromScriptValue():
+
+ \code
+ const QJsonValue jsonValue = engine.fromScriptValue<QJsonValue>(jsValue);
+ const QJsonArray jsonArray = jsonValue.toArray();
+ \endcode
*/
/*!
@@ -490,7 +500,7 @@ double QJSValue::toNumber() const
bool QJSValue::toBool() const
{
if (const QString *string = QJSValuePrivate::asQString(this))
- return string->length() > 0;
+ return string->size() > 0;
return caughtResult<bool>(this, &QV4::Value::toBoolean);
}
@@ -664,7 +674,7 @@ QJSValue QJSValue::call(const QJSValueList &args) const
Q_ASSERT(engine);
Scope scope(engine);
- JSCallArguments jsCallData(scope, args.length());
+ JSCallArguments jsCallData(scope, args.size());
*jsCallData.thisObject = engine->globalObject;
for (int i = 0; i < args.size(); ++i) {
if (!QJSValuePrivate::checkEngine(engine, args.at(i))) {
diff --git a/src/qml/jsruntime/qv4argumentsobject_p.h b/src/qml/jsruntime/qv4argumentsobject_p.h
index 4edfe2a763..dc17ea4e54 100644
--- a/src/qml/jsruntime/qv4argumentsobject_p.h
+++ b/src/qml/jsruntime/qv4argumentsobject_p.h
@@ -30,7 +30,7 @@ namespace Heap {
Member(class, NoMark, quint64, mapped)
DECLARE_HEAP_OBJECT(ArgumentsObject, Object) {
- DECLARE_MARKOBJECTS(ArgumentsObject);
+ DECLARE_MARKOBJECTS(ArgumentsObject)
enum {
LengthPropertyIndex = 0,
SymbolIteratorPropertyIndex = 1,
diff --git a/src/qml/jsruntime/qv4arraybuffer_p.h b/src/qml/jsruntime/qv4arraybuffer_p.h
index cc322b3f01..b955618cbe 100644
--- a/src/qml/jsruntime/qv4arraybuffer_p.h
+++ b/src/qml/jsruntime/qv4arraybuffer_p.h
@@ -60,7 +60,10 @@ private:
return *reinterpret_cast<QArrayDataPointer<char> *>(&arrayDataPointerStorage);
}
- std::aligned_storage_t<sizeof(QArrayDataPointer<char>), alignof(QArrayDataPointer<char>)>
+ template <typename T>
+ struct storage_t { alignas(T) unsigned char data[sizeof(T)]; };
+
+ storage_t<QArrayDataPointer<char>>
arrayDataPointerStorage;
bool isShared;
};
diff --git a/src/qml/jsruntime/qv4arrayiterator_p.h b/src/qml/jsruntime/qv4arrayiterator_p.h
index 2682dc79d0..ff00f99bea 100644
--- a/src/qml/jsruntime/qv4arrayiterator_p.h
+++ b/src/qml/jsruntime/qv4arrayiterator_p.h
@@ -33,7 +33,7 @@ namespace Heap {
Member(class, NoMark, quint32, nextIndex)
DECLARE_HEAP_OBJECT(ArrayIteratorObject, Object) {
- DECLARE_MARKOBJECTS(ArrayIteratorObject);
+ DECLARE_MARKOBJECTS(ArrayIteratorObject)
void init(Object *obj, QV4::ExecutionEngine *engine)
{
Object::init();
diff --git a/src/qml/jsruntime/qv4compilationunitmapper.cpp b/src/qml/jsruntime/qv4compilationunitmapper.cpp
index 0479b8b8f1..61b0f1d497 100644
--- a/src/qml/jsruntime/qv4compilationunitmapper.cpp
+++ b/src/qml/jsruntime/qv4compilationunitmapper.cpp
@@ -29,6 +29,11 @@ public:
s_staticUnits.insert(file, staticUnit);
}
+ void remove(const QString &file)
+ {
+ s_staticUnits.remove(file);
+ }
+
private:
QMutexLocker<QMutex> m_lock;
@@ -69,4 +74,10 @@ CompiledData::Unit *CompilationUnitMapper::get(
return data;
}
+void CompilationUnitMapper::invalidate(const QString &cacheFilePath)
+{
+ StaticUnitCache cache;
+ cache.remove(cacheFilePath);
+}
+
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4compilationunitmapper_p.h b/src/qml/jsruntime/qv4compilationunitmapper_p.h
index 0d3ec4eeee..07952be62c 100644
--- a/src/qml/jsruntime/qv4compilationunitmapper_p.h
+++ b/src/qml/jsruntime/qv4compilationunitmapper_p.h
@@ -33,6 +33,7 @@ public:
CompiledData::Unit *get(
const QString &cacheFilePath, const QDateTime &sourceTimeStamp, QString *errorString);
+ static void invalidate(const QString &cacheFilePath);
private:
CompiledData::Unit *open(
diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h
index 66f06ff96a..82a9472223 100644
--- a/src/qml/jsruntime/qv4context_p.h
+++ b/src/qml/jsruntime/qv4context_p.h
@@ -29,7 +29,7 @@ namespace Heap {
Member(class, Pointer, Object *, activation)
DECLARE_HEAP_OBJECT(ExecutionContext, Base) {
- DECLARE_MARKOBJECTS(ExecutionContext);
+ DECLARE_MARKOBJECTS(ExecutionContext)
enum ContextType {
Type_GlobalContext = 0x1,
@@ -68,7 +68,7 @@ Q_STATIC_ASSERT(offsetof(ExecutionContextData, activation) == offsetof(Execution
Member(class, ValueArray, ValueArray, locals)
DECLARE_HEAP_OBJECT(CallContext, ExecutionContext) {
- DECLARE_MARKOBJECTS(CallContext);
+ DECLARE_MARKOBJECTS(CallContext)
void init()
{
diff --git a/src/qml/jsruntime/qv4dataview_p.h b/src/qml/jsruntime/qv4dataview_p.h
index 73f31d8f8c..ab2e1e589a 100644
--- a/src/qml/jsruntime/qv4dataview_p.h
+++ b/src/qml/jsruntime/qv4dataview_p.h
@@ -33,7 +33,7 @@ struct DataViewCtor : FunctionObject {
Member(class, NoMark, uint, byteOffset)
DECLARE_HEAP_OBJECT(DataView, Object) {
- DECLARE_MARKOBJECTS(DataView);
+ DECLARE_MARKOBJECTS(DataView)
void init() { Object::init(); }
};
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp
index 769b8c161a..1fb6d92183 100644
--- a/src/qml/jsruntime/qv4dateobject.cpp
+++ b/src/qml/jsruntime/qv4dateobject.cpp
@@ -343,7 +343,7 @@ static inline double ParseString(const QString &s, double localTZA)
};
const QChar *ch = s.constData();
- const QChar *end = ch + s.length();
+ const QChar *end = ch + s.size();
uint format = Year;
int current = 0;
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 17cea99fd8..30924dd76d 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -324,6 +324,9 @@ void ExecutionEngine::initializeStaticMembers()
#elif defined(Q_OS_ANDROID)
// In experiments, it started crashing at 1059.
s_maxCallDepth = 1000;
+#elif defined(Q_OS_WIN)
+ // We've seen crashes around 750.
+ s_maxCallDepth = 640;
#else
s_maxCallDepth = 1234;
#endif
@@ -391,12 +394,15 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
}
}
+ // We allocate guard pages around our stacks.
+ const size_t guardPages = 2 * WTF::pageSize();
+
memoryManager = new QV4::MemoryManager(this);
// reserve space for the JS stack
// we allow it to grow to a bit more than m_maxJSStackSize, as we can overshoot due to ScopedValues
// allocated outside of JIT'ed methods.
*jsStack = WTF::PageAllocation::allocate(
- s_maxJSStackSize + 256*1024, WTF::OSAllocator::JSVMStackPages,
+ s_maxJSStackSize + 256*1024 + guardPages, WTF::OSAllocator::JSVMStackPages,
/* writable */ true, /* executable */ false, /* includesGuardPages */ true);
jsStackBase = (Value *)jsStack->base();
#ifdef V4_USE_VALGRIND
@@ -405,9 +411,9 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
jsStackTop = jsStackBase;
- *gcStack = WTF::PageAllocation::allocate(s_maxGCStackSize, WTF::OSAllocator::JSVMStackPages,
- /* writable */ true, /* executable */ false,
- /* includesGuardPages */ true);
+ *gcStack = WTF::PageAllocation::allocate(
+ s_maxGCStackSize + guardPages, WTF::OSAllocator::JSVMStackPages,
+ /* writable */ true, /* executable */ false, /* includesGuardPages */ true);
exceptionValue = jsAlloca(1);
*exceptionValue = Encode::undefined();
@@ -949,13 +955,13 @@ Heap::Object *ExecutionEngine::newObject(Heap::InternalClass *internalClass)
Heap::String *ExecutionEngine::newString(const QString &s)
{
- return memoryManager->allocWithStringData<String>(s.length() * sizeof(QChar), s);
+ return memoryManager->allocWithStringData<String>(s.size() * sizeof(QChar), s);
}
Heap::String *ExecutionEngine::newIdentifier(const QString &text)
{
Scope scope(this);
- ScopedString s(scope, memoryManager->allocWithStringData<String>(text.length() * sizeof(QChar), text));
+ ScopedString s(scope, memoryManager->allocWithStringData<String>(text.size() * sizeof(QChar), text));
s->toPropertyKey();
return s->d();
}
@@ -1511,6 +1517,12 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMet
if (metaType == QMetaType::fromType<bool>())
return QVariant(value.toBoolean());
+ if (metaType == QMetaType::fromType<double>())
+ return QVariant(value.toNumber());
+
+ if (metaType == QMetaType::fromType<float>())
+ return QVariant(float(value.toNumber()));
+
if (metaType == QMetaType::fromType<QJsonValue>())
return QVariant::fromValue(QV4::JsonObject::toJsonValue(value));
@@ -1842,23 +1854,17 @@ QV4::ReturnedValue ExecutionEngine::fromData(
// directly against QList<QObject*>?
const QList<QObject *> &list = *(const QList<QObject *>*)ptr;
QV4::ScopedArrayObject a(scope, newArrayObject());
- a->arrayReserve(list.count());
+ a->arrayReserve(list.size());
QV4::ScopedValue v(scope);
- for (int ii = 0; ii < list.count(); ++ii)
+ for (int ii = 0; ii < list.size(); ++ii)
a->arrayPut(ii, (v = QV4::QObjectWrapper::wrap(this, list.at(ii))));
- a->setArrayLengthUnchecked(list.count());
+ a->setArrayLengthUnchecked(list.size());
return a.asReturnedValue();
} else if (auto flags = metaType.flags(); flags & QMetaType::PointerToQObject) {
- QV4::ReturnedValue ret = QV4::QObjectWrapper::wrap(this, *reinterpret_cast<QObject* const *>(ptr));
- if (!flags.testFlag(QMetaType::IsConst))
- return ret;
- QV4::ScopedValue v(scope, ret);
- if (auto obj = v->as<Object>()) {
- obj->setInternalClass(obj->internalClass()->cryopreserved());
- return obj->asReturnedValue();
- } else {
- return ret;
- }
+ if (flags.testFlag(QMetaType::IsConst))
+ return QV4::QObjectWrapper::wrapConst(this, *reinterpret_cast<QObject* const *>(ptr));
+ else
+ return QV4::QObjectWrapper::wrap(this, *reinterpret_cast<QObject* const *>(ptr));
}
bool succeeded = false;
@@ -1981,6 +1987,25 @@ int ExecutionEngine::maxGCStackSize() const
return s_maxGCStackSize;
}
+/*!
+ \internal
+ Returns \a length converted to int if its safe to
+ pass to \c Scope::alloc.
+ Otherwise it throws a RangeError, and returns 0.
+ */
+int ExecutionEngine::safeForAllocLength(qint64 len64)
+{
+ if (len64 < 0ll || len64 > qint64(std::numeric_limits<int>::max())) {
+ throwRangeError(QStringLiteral("Invalid array length."));
+ return 0;
+ }
+ if (len64 > qint64(this->jsStackLimit - this->jsStackTop)) {
+ throwRangeError(QStringLiteral("Array too large for apply()."));
+ return 0;
+ }
+ return len64;
+}
+
ReturnedValue ExecutionEngine::global()
{
return globalObject->asReturnedValue();
@@ -2252,7 +2277,7 @@ int ExecutionEngine::consoleCountHelper(const QString &file, quint16 line, quint
void ExecutionEngine::setExtensionData(int index, Deletable *data)
{
- if (m_extensionData.count() <= index)
+ if (m_extensionData.size() <= index)
m_extensionData.resize(index + 1);
if (m_extensionData.at(index))
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index d00495eff0..c6b97273e3 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -650,6 +650,7 @@ public:
int maxGCStackSize() const;
bool checkStackLimits();
+ int safeForAllocLength(qint64 len64);
bool canJIT(Function *f = nullptr)
{
@@ -702,7 +703,7 @@ public:
void setExtensionData(int, Deletable *);
Deletable *extensionData(int index) const
{
- if (index < m_extensionData.count())
+ if (index < m_extensionData.size())
return m_extensionData[index];
else
return nullptr;
@@ -736,6 +737,9 @@ public:
QV4::ExecutionContext *ctxt, int argc, const QV4::Value *argv);
private:
+ template<int Frames>
+ friend struct ExecutionEngineCallDepthRecorder;
+
QV4::ReturnedValue fromData(QMetaType type, const void *ptr, const QVariant *variant = nullptr);
static void initializeStaticMembers();
@@ -772,12 +776,15 @@ private:
#define CHECK_STACK_LIMITS(v4) if ((v4)->checkStackLimits()) return Encode::undefined(); \
ExecutionEngineCallDepthRecorder _executionEngineCallDepthRecorder(v4);
+template<int Frames = 1>
struct ExecutionEngineCallDepthRecorder
{
ExecutionEngine *ee;
- ExecutionEngineCallDepthRecorder(ExecutionEngine *e): ee(e) { ++ee->callDepth; }
- ~ExecutionEngineCallDepthRecorder() { --ee->callDepth; }
+ ExecutionEngineCallDepthRecorder(ExecutionEngine *e): ee(e) { ee->callDepth += Frames; }
+ ~ExecutionEngineCallDepthRecorder() { ee->callDepth -= Frames; }
+
+ bool hasOverflow() const { return ee->callDepth >= ExecutionEngine::s_maxCallDepth; }
};
inline bool ExecutionEngine::checkStackLimits()
diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp
index f3adadc887..eb449ba293 100644
--- a/src/qml/jsruntime/qv4errorobject.cpp
+++ b/src/qml/jsruntime/qv4errorobject.cpp
@@ -120,7 +120,7 @@ ReturnedValue ErrorObject::method_get_stack(const FunctionObject *b, const Value
return v4->throwTypeError();
if (!This->d()->stack) {
QString trace;
- for (int i = 0; i < This->d()->stackTrace->count(); ++i) {
+ for (int i = 0; i < This->d()->stackTrace->size(); ++i) {
if (i > 0)
trace += QLatin1Char('\n');
const StackFrame &frame = This->d()->stackTrace->at(i);
diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h
index c8ebe11f30..3d9069b587 100644
--- a/src/qml/jsruntime/qv4errorobject_p.h
+++ b/src/qml/jsruntime/qv4errorobject_p.h
@@ -31,7 +31,7 @@ namespace Heap {
Member(class, Pointer, String *, stack)
DECLARE_HEAP_OBJECT(ErrorObject, Object) {
- DECLARE_MARKOBJECTS(ErrorObject);
+ DECLARE_MARKOBJECTS(ErrorObject)
enum ErrorType {
Error,
EvalError,
diff --git a/src/qml/jsruntime/qv4executableallocator.cpp b/src/qml/jsruntime/qv4executableallocator.cpp
index f8b005e914..5a63230858 100644
--- a/src/qml/jsruntime/qv4executableallocator.cpp
+++ b/src/qml/jsruntime/qv4executableallocator.cpp
@@ -125,7 +125,7 @@ ExecutableAllocator::ExecutableAllocator()
ExecutableAllocator::~ExecutableAllocator()
{
- for (ChunkOfPages *chunk : qAsConst(chunks)) {
+ for (ChunkOfPages *chunk : std::as_const(chunks)) {
for (Allocation *allocation = chunk->firstAllocation; allocation; allocation = allocation->next)
if (!allocation->free)
allocation->invalidate();
diff --git a/src/qml/jsruntime/qv4executableallocator_p.h b/src/qml/jsruntime/qv4executableallocator_p.h
index d6551599e7..7fd8a10cdb 100644
--- a/src/qml/jsruntime/qv4executableallocator_p.h
+++ b/src/qml/jsruntime/qv4executableallocator_p.h
@@ -79,8 +79,8 @@ public:
};
// for debugging / unit-testing
- int freeAllocationCount() const { return freeAllocations.count(); }
- int chunkCount() const { return chunks.count(); }
+ int freeAllocationCount() const { return freeAllocations.size(); }
+ int chunkCount() const { return chunks.size(); }
struct ChunkOfPages
{
diff --git a/src/qml/jsruntime/qv4executablecompilationunit.cpp b/src/qml/jsruntime/qv4executablecompilationunit.cpp
index 3fe031501f..2affa4f6dd 100644
--- a/src/qml/jsruntime/qv4executablecompilationunit.cpp
+++ b/src/qml/jsruntime/qv4executablecompilationunit.cpp
@@ -297,7 +297,7 @@ void ExecutableCompilationUnit::unlink()
delete [] runtimeLookups;
runtimeLookups = nullptr;
- for (QV4::Function *f : qAsConst(runtimeFunctions))
+ for (QV4::Function *f : std::as_const(runtimeFunctions))
f->destroy();
runtimeFunctions.clear();
@@ -325,14 +325,14 @@ void ExecutableCompilationUnit::markObjects(QV4::MarkStack *markStack)
if (runtimeClasses[i])
runtimeClasses[i]->mark(markStack);
}
- for (QV4::Function *f : qAsConst(runtimeFunctions))
+ for (QV4::Function *f : std::as_const(runtimeFunctions))
if (f && f->internalClass)
f->internalClass->mark(markStack);
- for (QV4::Heap::InternalClass *c : qAsConst(runtimeBlocks))
+ for (QV4::Heap::InternalClass *c : std::as_const(runtimeBlocks))
if (c)
c->mark(markStack);
- for (QV4::Heap::Object *o : qAsConst(templateObjects))
+ for (QV4::Heap::Object *o : std::as_const(templateObjects))
if (o)
o->mark(markStack);
@@ -819,8 +819,14 @@ bool ExecutableCompilationUnit::saveToDisk(const QUrl &unitUrl, QString *errorSt
return CompiledData::SaveableUnitPointer(unitData()).saveToDisk<char>(
[&unitUrl, errorString](const char *data, quint32 size) {
- return CompiledData::SaveableUnitPointer::writeDataToFile(localCacheFilePath(unitUrl), data,
- size, errorString);
+ const QString cachePath = localCacheFilePath(unitUrl);
+ if (CompiledData::SaveableUnitPointer::writeDataToFile(
+ cachePath, data, size, errorString)) {
+ CompilationUnitMapper::invalidate(cachePath);
+ return true;
+ }
+
+ return false;
});
}
@@ -832,7 +838,7 @@ bool ExecutableCompilationUnit::saveToDisk(const QUrl &unitUrl, QString *errorSt
bool ResolvedTypeReferenceMap::addToHash(
QCryptographicHash *hash, QHash<quintptr, QByteArray> *checksums) const
{
- std::vector<int> keys (count());
+ std::vector<int> keys (size());
int i = 0;
for (auto it = constBegin(), end = constEnd(); it != end; ++it) {
keys[i] = it.key();
@@ -864,7 +870,7 @@ QString ExecutableCompilationUnit::bindingValueAsString(const CompiledData::Bind
// This code must match that in the qsTr() implementation
const QString &path = fileName();
int lastSlash = path.lastIndexOf(QLatin1Char('/'));
- QStringView context = (lastSlash > -1) ? QStringView{path}.mid(lastSlash + 1, path.length() - lastSlash - 5)
+ QStringView context = (lastSlash > -1) ? QStringView{path}.mid(lastSlash + 1, path.size() - lastSlash - 5)
: QStringView();
QByteArray contextUtf8 = context.toUtf8();
QByteArray comment = stringAt(translation.commentIndex).toUtf8();
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
index 1be093f0a4..f756575ea8 100644
--- a/src/qml/jsruntime/qv4function.cpp
+++ b/src/qml/jsruntime/qv4function.cpp
@@ -111,7 +111,7 @@ Function::Function(ExecutionEngine *engine, const QQmlPrivate::AOTCompiledFuncti
, aotFunction(aotFunction)
{
internalClass = engine->internalClasses(EngineBase::Class_CallContext);
- nFormals = aotFunction->argumentTypes.length();
+ nFormals = aotFunction->argumentTypes.size();
}
Function::~Function()
@@ -127,7 +127,7 @@ void Function::updateInternalClass(ExecutionEngine *engine, const QList<QByteArr
QStringList parameterNames;
// Resolve duplicate parameter names:
- for (int i = 0, ei = parameters.count(); i != ei; ++i) {
+ for (int i = 0, ei = parameters.size(); i != ei; ++i) {
const QByteArray &param = parameters.at(i);
int duplicate = -1;
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index 186535cb82..b38c29a6c5 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -351,36 +351,31 @@ ReturnedValue FunctionPrototype::method_apply(const QV4::FunctionObject *b, cons
if (!arr)
return v4->throwTypeError();
- const qint64 len64 = arr->getLength();
- if (len64 < 0ll || len64 > qint64(std::numeric_limits<int>::max()))
- return v4->throwRangeError(QStringLiteral("Invalid array length."));
- if (len64 > qint64(v4->jsStackLimit - v4->jsStackTop))
- return v4->throwRangeError(QStringLiteral("Array too large for apply()."));
-
- const uint len = uint(len64);
-
Scope scope(v4);
+ const int len = v4->safeForAllocLength(arr->getLength());
+ CHECK_EXCEPTION();
+
Value *arguments = scope.alloc<Scope::Uninitialized>(len);
if (len) {
if (ArgumentsObject::isNonStrictArgumentsObject(arr) && !arr->cast<ArgumentsObject>()->fullyCreated()) {
QV4::ArgumentsObject *a = arr->cast<ArgumentsObject>();
- int l = qMin(len, (uint)a->d()->context->argc());
+ int l = qMin(len, a->d()->context->argc());
memcpy(arguments, a->d()->context->args(), l*sizeof(Value));
- for (quint32 i = l; i < len; ++i)
+ for (int i = l; i < len; ++i)
arguments[i] = Value::undefinedValue();
} else if (arr->arrayType() == Heap::ArrayData::Simple && !arr->protoHasArray()) {
auto sad = static_cast<Heap::SimpleArrayData *>(arr->arrayData());
- uint alen = sad ? sad->values.size : 0;
+ int alen = sad ? sad->values.size : 0;
if (alen > len)
alen = len;
- for (uint i = 0; i < alen; ++i)
+ for (int i = 0; i < alen; ++i)
arguments[i] = sad->data(i);
- for (quint32 i = alen; i < len; ++i)
+ for (int i = alen; i < len; ++i)
arguments[i] = Value::undefinedValue();
} else {
// need to init the arguments array, as the get() calls below can have side effects
memset(arguments, 0, len*sizeof(Value));
- for (quint32 i = 0; i < len; ++i)
+ for (int i = 0; i < len; ++i)
arguments[i] = arr->get(i);
}
}
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index b42c55f5a8..e32fce28ba 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -40,7 +40,7 @@ namespace Heap {
Member(class, NoMark, bool, canBeTailCalled)
DECLARE_HEAP_OBJECT(FunctionObject, Object) {
- DECLARE_MARKOBJECTS(FunctionObject);
+ DECLARE_MARKOBJECTS(FunctionObject)
enum {
Index_ProtoConstructor = 0,
Index_Prototype = 0,
@@ -125,7 +125,7 @@ struct DefaultClassConstructorFunction : FunctionObject
Member(class, Pointer, MemberData *, boundArgs)
DECLARE_HEAP_OBJECT(BoundFunction, FunctionObject) {
- DECLARE_MARKOBJECTS(BoundFunction);
+ DECLARE_MARKOBJECTS(BoundFunction)
void init(QV4::ExecutionContext *scope, QV4::FunctionObject *target, const Value &boundThis, QV4::MemberData *boundArgs);
};
diff --git a/src/qml/jsruntime/qv4generatorobject_p.h b/src/qml/jsruntime/qv4generatorobject_p.h
index 4a84bec748..55ccc133aa 100644
--- a/src/qml/jsruntime/qv4generatorobject_p.h
+++ b/src/qml/jsruntime/qv4generatorobject_p.h
@@ -57,7 +57,7 @@ struct GeneratorPrototype : FunctionObject {
Member(class, Pointer, ArrayObject *, jsFrame)
DECLARE_HEAP_OBJECT(GeneratorObject, Object) {
- DECLARE_MARKOBJECTS(GeneratorObject);
+ DECLARE_MARKOBJECTS(GeneratorObject)
};
}
diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp
index 0112347053..7ea90a2ddd 100644
--- a/src/qml/jsruntime/qv4globalobject.cpp
+++ b/src/qml/jsruntime/qv4globalobject.cpp
@@ -32,7 +32,7 @@ static QString escape(const QString &input)
{
QString output;
output.reserve(input.size() * 3);
- const int length = input.length();
+ const int length = input.size();
for (int i = 0; i < length; ++i) {
ushort uc = input.at(i).unicode();
if (uc < 0x100) {
@@ -63,9 +63,9 @@ static QString escape(const QString &input)
static QString unescape(const QString &input)
{
QString result;
- result.reserve(input.length());
+ result.reserve(input.size());
int i = 0;
- const int length = input.length();
+ const int length = input.size();
while (i < length) {
QChar c = input.at(i++);
if ((c == u'%') && (i + 1 < length)) {
@@ -113,7 +113,7 @@ static QString encode(const QString &input, const char *unescapedSet, bool *ok)
{
*ok = true;
QString output;
- const int length = input.length();
+ const int length = input.size();
int i = 0;
while (i < length) {
const QChar c = input.at(i);
@@ -187,8 +187,8 @@ static QString decode(const QString &input, DecodeMode decodeMode, bool *ok)
{
*ok = true;
QString output;
- output.reserve(input.length());
- const int length = input.length();
+ output.reserve(input.size());
+ const int length = input.size();
int i = 0;
const QChar percent = QLatin1Char('%');
while (i < length) {
@@ -381,7 +381,7 @@ ReturnedValue GlobalFunctions::method_parseInt(const FunctionObject *b, const Va
CHECK_EXCEPTION();
const QChar *pos = trimmed.constData();
- const QChar *end = pos + trimmed.length();
+ const QChar *end = pos + trimmed.size();
int sign = 1; // 3
if (pos != end) {
diff --git a/src/qml/jsruntime/qv4identifiertable.cpp b/src/qml/jsruntime/qv4identifiertable.cpp
index 5b0c2f25ee..96aa54018b 100644
--- a/src/qml/jsruntime/qv4identifiertable.cpp
+++ b/src/qml/jsruntime/qv4identifiertable.cpp
@@ -25,7 +25,7 @@ IdentifierTable::~IdentifierTable()
{
free(entriesByHash);
free(entriesById);
- for (const auto &h : qAsConst(idHashes))
+ for (const auto &h : std::as_const(idHashes))
h->identifierTable = nullptr;
}
@@ -100,7 +100,7 @@ void IdentifierTable::addEntry(Heap::StringOrSymbol *str)
Heap::String *IdentifierTable::insertString(const QString &s)
{
uint subtype;
- uint hash = String::createHashValue(s.constData(), s.length(), &subtype);
+ uint hash = String::createHashValue(s.constData(), s.size(), &subtype);
if (subtype == Heap::String::StringType_ArrayIndex) {
Heap::String *str = engine->newString(s);
str->stringHash = hash;
@@ -133,7 +133,7 @@ Heap::Symbol *IdentifierTable::insertSymbol(const QString &s)
Q_ASSERT(s.at(0) == QLatin1Char('@'));
uint subtype;
- uint hash = String::createHashValue(s.constData(), s.length(), &subtype);
+ uint hash = String::createHashValue(s.constData(), s.size(), &subtype);
uint idx = hash % alloc;
while (Heap::StringOrSymbol *e = entriesByHash[idx]) {
if (e->stringHash == hash && e->toQString() == s)
@@ -252,7 +252,7 @@ void IdentifierTable::sweep()
PropertyKey IdentifierTable::asPropertyKey(const QString &s)
{
uint subtype;
- const uint hash = String::createHashValue(s.constData(), s.length(), &subtype);
+ const uint hash = String::createHashValue(s.constData(), s.size(), &subtype);
if (subtype == Heap::String::StringType_ArrayIndex)
return PropertyKey::fromArrayIndex(hash);
return resolveStringEntry(s, hash, subtype)->identifier;
diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp
index 693cc436ef..57ff8c44ec 100644
--- a/src/qml/jsruntime/qv4jsonobject.cpp
+++ b/src/qml/jsruntime/qv4jsonobject.cpp
@@ -610,10 +610,32 @@ struct Stringify
QString makeMember(const QString &key, const Value &v);
};
+class [[nodiscard]] CallDepthAndCycleChecker
+{
+ Q_DISABLE_COPY_MOVE(CallDepthAndCycleChecker);
+
+public:
+ CallDepthAndCycleChecker(Stringify *stringify, Object *o)
+ : m_callDepthRecorder(stringify->v4)
+ {
+ if (stringify->stackContains(o)) {
+ stringify->v4->throwTypeError(
+ QStringLiteral("Cannot convert circular structure to JSON"));
+ }
+
+ stringify->v4->checkStackLimits();
+ }
+
+ bool foundProblem() const { return m_callDepthRecorder.ee->hasException; }
+
+private:
+ ExecutionEngineCallDepthRecorder<1> m_callDepthRecorder;
+};
+
static QString quote(const QString &str)
{
QString product;
- const int length = str.length();
+ const int length = str.size();
product.reserve(length + 2);
product += u'"';
for (int i = 0; i < length; ++i) {
@@ -740,10 +762,9 @@ QString Stringify::makeMember(const QString &key, const Value &v)
QString Stringify::JO(Object *o)
{
- if (stackContains(o)) {
- v4->throwTypeError();
+ CallDepthAndCycleChecker check(this, o);
+ if (check.foundProblem())
return QString();
- }
Scope scope(v4);
@@ -800,10 +821,9 @@ QString Stringify::JO(Object *o)
QString Stringify::JA(Object *a)
{
- if (stackContains(a)) {
- v4->throwTypeError();
+ CallDepthAndCycleChecker check(this, a);
+ if (check.foundProblem())
return QString();
- }
Scope scope(a->engine());
@@ -865,7 +885,7 @@ ReturnedValue JsonObject::method_parse(const FunctionObject *b, const Value *, c
jtext = argv[0].toQString();
DEBUG << "parsing source = " << jtext;
- JsonParser parser(v4, jtext.constData(), jtext.length());
+ JsonParser parser(v4, jtext.constData(), jtext.size());
QJsonParseError error;
ReturnedValue result = parser.parse(&error);
if (error.error != QJsonParseError::NoError) {
@@ -885,9 +905,10 @@ ReturnedValue JsonObject::method_stringify(const FunctionObject *b, const Value
if (o) {
stringify.replacerFunction = o->as<FunctionObject>();
if (o->isArrayObject()) {
- uint arrayLen = o->getLength();
+ int arrayLen = scope.engine->safeForAllocLength(o->getLength());
+ CHECK_EXCEPTION();
stringify.propertyList = static_cast<QV4::String *>(scope.alloc(arrayLen));
- for (uint i = 0; i < arrayLen; ++i) {
+ for (int i = 0; i < arrayLen; ++i) {
Value *v = stringify.propertyList + i;
*v = o->get(i);
if (v->as<NumberObject>() || v->as<StringObject>() || v->isNumber())
@@ -895,7 +916,7 @@ ReturnedValue JsonObject::method_stringify(const FunctionObject *b, const Value
if (!v->isString()) {
v->setM(nullptr);
} else {
- for (uint j = 0; j <i; ++j) {
+ for (int j = 0; j <i; ++j) {
if (stringify.propertyList[j].m() == v->m()) {
v->setM(nullptr);
break;
diff --git a/src/qml/jsruntime/qv4mapiterator_p.h b/src/qml/jsruntime/qv4mapiterator_p.h
index 2269473d4c..97a72db85c 100644
--- a/src/qml/jsruntime/qv4mapiterator_p.h
+++ b/src/qml/jsruntime/qv4mapiterator_p.h
@@ -30,7 +30,7 @@ namespace Heap {
Member(class, NoMark, quint32, mapNextIndex)
DECLARE_HEAP_OBJECT(MapIteratorObject, Object) {
- DECLARE_MARKOBJECTS(MapIteratorObject);
+ DECLARE_MARKOBJECTS(MapIteratorObject)
void init(Object *obj, QV4::ExecutionEngine *engine)
{
Object::init();
diff --git a/src/qml/jsruntime/qv4memberdata_p.h b/src/qml/jsruntime/qv4memberdata_p.h
index adcd1e8cf9..672b058fef 100644
--- a/src/qml/jsruntime/qv4memberdata_p.h
+++ b/src/qml/jsruntime/qv4memberdata_p.h
@@ -27,7 +27,7 @@ namespace Heap {
Member(class, ValueArray, ValueArray, values)
DECLARE_HEAP_OBJECT(MemberData, Base) {
- DECLARE_MARKOBJECTS(MemberData);
+ DECLARE_MARKOBJECTS(MemberData)
};
Q_STATIC_ASSERT(std::is_trivial_v<MemberData>);
diff --git a/src/qml/jsruntime/qv4module.cpp b/src/qml/jsruntime/qv4module.cpp
index 779eb77a36..1e1a059dfa 100644
--- a/src/qml/jsruntime/qv4module.cpp
+++ b/src/qml/jsruntime/qv4module.cpp
@@ -195,7 +195,7 @@ struct ModuleNamespaceIterator : ObjectOwnPropertyKeyIterator
PropertyKey ModuleNamespaceIterator::next(const Object *o, Property *pd, PropertyAttributes *attrs)
{
const Module *module = static_cast<const Module *>(o);
- if (exportIndex < exportedNames.count()) {
+ if (exportIndex < exportedNames.size()) {
if (attrs)
*attrs = Attr_Data;
Scope scope(module->engine());
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index aec04b167d..6a39b9e27f 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -1104,7 +1104,7 @@ void Heap::ArrayObject::init(const QStringList &list)
// The result is a new Array object with length equal to the length
// of the QStringList, and the elements being the QStringList's
// elements converted to JS Strings.
- int len = list.count();
+ int len = list.size();
a->arrayReserve(len);
ScopedValue v(scope);
for (int ii = 0; ii < len; ++ii)
diff --git a/src/qml/jsruntime/qv4persistent_p.h b/src/qml/jsruntime/qv4persistent_p.h
index e7b653b6f6..7e208bd4fd 100644
--- a/src/qml/jsruntime/qv4persistent_p.h
+++ b/src/qml/jsruntime/qv4persistent_p.h
@@ -69,7 +69,7 @@ public:
PersistentValue(PersistentValue &&other) noexcept : val(std::exchange(other.val, nullptr)) {}
void swap(PersistentValue &other) noexcept { qt_ptr_swap(val, other.val); }
- QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(PersistentValue);
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(PersistentValue)
~PersistentValue() { PersistentValueStorage::free(val); }
PersistentValue &operator=(const WeakValue &other);
diff --git a/src/qml/jsruntime/qv4profiling.cpp b/src/qml/jsruntime/qv4profiling.cpp
index 19da26989f..db33cd27f9 100644
--- a/src/qml/jsruntime/qv4profiling.cpp
+++ b/src/qml/jsruntime/qv4profiling.cpp
@@ -60,7 +60,7 @@ void Profiler::reportData()
FunctionLocationHash locations;
properties.reserve(m_data.size());
- for (const FunctionCall &call : qAsConst(m_data)) {
+ for (const FunctionCall &call : std::as_const(m_data)) {
properties.append(call.properties());
Function *function = call.function();
SentMarker &marker = m_sentLocations[reinterpret_cast<quintptr>(function)];
diff --git a/src/qml/jsruntime/qv4promiseobject_p.h b/src/qml/jsruntime/qv4promiseobject_p.h
index c0599987e5..1c11ebbfd6 100644
--- a/src/qml/jsruntime/qv4promiseobject_p.h
+++ b/src/qml/jsruntime/qv4promiseobject_p.h
@@ -34,7 +34,7 @@ class ReactionHandler : public QObject
public:
ReactionHandler(QObject *parent = nullptr);
- virtual ~ReactionHandler() override;
+ ~ReactionHandler() override;
void addReaction(ExecutionEngine *e, const Value *reaction, const Value *value);
void addResolveThenable(ExecutionEngine *e, const PromiseObject *promise, const Object *thenable, const FunctionObject *then);
diff --git a/src/qml/jsruntime/qv4propertykey.cpp b/src/qml/jsruntime/qv4propertykey.cpp
index 8a3e1adc65..e07df07543 100644
--- a/src/qml/jsruntime/qv4propertykey.cpp
+++ b/src/qml/jsruntime/qv4propertykey.cpp
@@ -66,7 +66,7 @@ QV4::Heap::String *QV4::PropertyKey::asFunctionName(ExecutionEngine *engine, Fun
QString str = s->toQString();
if (s->internalClass->vtable->isString)
n += s->toQString();
- else if (str.length() > 1)
+ else if (str.size() > 1)
n += QChar::fromLatin1('[') + QStringView{str}.mid(1) + QChar::fromLatin1(']');
}
return engine->newString(n);
diff --git a/src/qml/jsruntime/qv4qmlcontext_p.h b/src/qml/jsruntime/qv4qmlcontext_p.h
index a89e7f6f2f..bd4b5c2585 100644
--- a/src/qml/jsruntime/qv4qmlcontext_p.h
+++ b/src/qml/jsruntime/qv4qmlcontext_p.h
@@ -34,7 +34,7 @@ namespace Heap {
Member(class, Pointer, Module *, module)
DECLARE_HEAP_OBJECT(QQmlContextWrapper, Object) {
- DECLARE_MARKOBJECTS(QQmlContextWrapper);
+ DECLARE_MARKOBJECTS(QQmlContextWrapper)
void init(QQmlRefPointer<QQmlContextData> context, QObject *scopeObject);
void destroy();
@@ -47,7 +47,7 @@ DECLARE_HEAP_OBJECT(QQmlContextWrapper, Object) {
#define QmlContextMembers(class, Member)
DECLARE_HEAP_OBJECT(QmlContext, ExecutionContext) {
- DECLARE_MARKOBJECTS(QmlContext);
+ DECLARE_MARKOBJECTS(QmlContext)
QQmlContextWrapper *qml() { return static_cast<QQmlContextWrapper *>(activation.get()); }
void init(QV4::ExecutionContext *outerContext, QV4::QQmlContextWrapper *qml);
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index d5e6c1b84a..b9b552576c 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -99,15 +99,10 @@ static ReturnedValue loadProperty(ExecutionEngine *v4, QObject *object,
if (property.isQObject()) {
QObject *rv = nullptr;
property.readProperty(object, &rv);
- ReturnedValue ret = QObjectWrapper::wrap(v4, rv);
- if (propMetaType.flags().testFlag(QMetaType::IsConst)) {
- ScopedValue v(scope, ret);
- if (auto obj = v->as<Object>()) {
- obj->setInternalClass(obj->internalClass()->cryopreserved());
- return obj->asReturnedValue();
- }
- }
- return ret;
+ if (propMetaType.flags().testFlag(QMetaType::IsConst))
+ return QObjectWrapper::wrapConst(v4, rv);
+ else
+ return QObjectWrapper::wrap(v4, rv);
}
if (property.isQList() && propMetaType.flags().testFlag(QMetaType::IsQmlList))
@@ -669,6 +664,29 @@ ReturnedValue QObjectWrapper::wrap_slowPath(ExecutionEngine *engine, QObject *ob
}
}
+ReturnedValue QObjectWrapper::wrapConst_slowPath(ExecutionEngine *engine, QObject *object)
+{
+ const QObject *constObject = object;
+
+ QQmlData *ddata = QQmlData::get(object, true);
+
+ Scope scope(engine);
+ ScopedObject constWrapper(scope);
+ if (engine->m_multiplyWrappedQObjects && ddata->hasConstWrapper)
+ constWrapper = engine->m_multiplyWrappedQObjects->value(constObject);
+
+ if (!constWrapper) {
+ constWrapper = create(engine, object);
+ constWrapper->setInternalClass(constWrapper->internalClass()->cryopreserved());
+ if (!engine->m_multiplyWrappedQObjects)
+ engine->m_multiplyWrappedQObjects = new MultiplyWrappedQObjectMap;
+ engine->m_multiplyWrappedQObjects->insert(constObject, constWrapper->d());
+ ddata->hasConstWrapper = true;
+ }
+
+ return constWrapper.asReturnedValue();
+}
+
void QObjectWrapper::markWrapper(QObject *object, MarkStack *markStack)
{
if (QQmlData::wasDeleted(object))
@@ -683,6 +701,8 @@ void QObjectWrapper::markWrapper(QObject *object, MarkStack *markStack)
ddata->jsWrapper.markOnce(markStack);
else if (engine->m_multiplyWrappedQObjects && ddata->hasTaintedV4Object)
engine->m_multiplyWrappedQObjects->mark(object, markStack);
+ if (ddata->hasConstWrapper)
+ engine->m_multiplyWrappedQObjects->mark(static_cast<const QObject *>(object), markStack);
}
void QObjectWrapper::setProperty(ExecutionEngine *engine, int propertyIndex, const Value &value)
@@ -710,14 +730,13 @@ void QObjectWrapper::setProperty(ExecutionEngine *engine, QObject *object, int p
bool QObjectWrapper::virtualIsEqualTo(Managed *a, Managed *b)
{
Q_ASSERT(a->as<QObjectWrapper>());
- QObjectWrapper *qobjectWrapper = static_cast<QObjectWrapper *>(a);
- Object *o = b->as<Object>();
- if (o) {
- if (QQmlTypeWrapper *qmlTypeWrapper = o->as<QQmlTypeWrapper>())
- return qmlTypeWrapper->toVariant().value<QObject*>() == qobjectWrapper->object();
- }
+ const QObjectWrapper *aobjectWrapper = static_cast<QObjectWrapper *>(a);
+ if (const QQmlTypeWrapper *qmlTypeWrapper = b->as<QQmlTypeWrapper>())
+ return qmlTypeWrapper->object() == aobjectWrapper->object();
- return false;
+ // We can have a const and a non-const wrapper for the same object.
+ const QObjectWrapper *bobjectWrapper = b->as<QObjectWrapper>();
+ return bobjectWrapper && aobjectWrapper->object() == bobjectWrapper->object();
}
ReturnedValue QObjectWrapper::create(ExecutionEngine *engine, QObject *object)
@@ -1176,7 +1195,7 @@ ReturnedValue QObjectWrapper::method_disconnect(const FunctionObject *b, const V
static void markChildQObjectsRecursively(QObject *parent, MarkStack *markStack)
{
const QObjectList &children = parent->children();
- for (int i = 0; i < children.count(); ++i) {
+ for (int i = 0; i < children.size(); ++i) {
QObject *child = children.at(i);
if (!child)
continue;
@@ -1350,8 +1369,8 @@ static ReturnedValue CallMethod(const QQmlObjectOrGadget &object, int index, QMe
}
}
}
- QVarLengthArray<void *, 9> argData(args.count());
- for (int ii = 0; ii < args.count(); ++ii)
+ QVarLengthArray<void *, 9> argData(args.size());
+ for (int ii = 0; ii < args.size(); ++ii)
argData[ii] = args[ii].dataPtr();
object.metacall(callType, index, argData.data());
@@ -1903,14 +1922,16 @@ bool CallArgument::fromValue(QMetaType metaType, ExecutionEngine *engine, const
// Convert via QVariant below.
// TODO: Can't we just do qobjectPtr = qmlTypeWrapper->object() instead?
break;
+ } else if (QObject *obj = qmlTypeWrapper->object()) {
+ // attached object case
+ qobjectPtr = obj;
+ return true;
}
// If this is a plain type wrapper without an instance,
- // then indeed it's an undefined parameter.
- // (although we might interpret that as const QMetaObject *).
- // TODO: But what if it's an attached object?
+ // then we got a namespace, and that's a type error
type = QMetaType::UnknownType;
- return true;
+ return false;
}
qobjectPtr = nullptr;
@@ -2025,7 +2046,7 @@ bool CallArgument::fromValue(QMetaType metaType, ExecutionEngine *engine, const
}
const QQmlMetaObject mo = QQmlMetaType::rawMetaObjectForType(metaType);
- if (!mo.isNull()) {
+ if (!mo.isNull() && v.metaType().flags().testFlag(QMetaType::PointerToQObject)) {
QObject *obj = QQmlMetaType::toQObject(v);
if (obj != nullptr && !QQmlMetaObject::canConvert(obj, mo)) {
@@ -2095,11 +2116,11 @@ ReturnedValue CallArgument::toValue(ExecutionEngine *engine)
QList<QObject *> &list = *qlistPtr;
Scope scope(engine);
ScopedArrayObject array(scope, engine->newArrayObject());
- array->arrayReserve(list.count());
+ array->arrayReserve(list.size());
ScopedValue v(scope);
- for (int ii = 0; ii < list.count(); ++ii)
+ for (int ii = 0; ii < list.size(); ++ii)
array->arrayPut(ii, (v = QObjectWrapper::wrap(engine, list.at(ii))));
- array->setArrayLengthUnchecked(list.count());
+ array->setArrayLengthUnchecked(list.size());
return array.asReturnedValue();
}
@@ -2429,39 +2450,20 @@ void QmlSignalHandler::initProto(ExecutionEngine *engine)
engine->jsObjects[ExecutionEngine::SignalHandlerProto] = o->d();
}
-void MultiplyWrappedQObjectMap::insert(QObject *key, Heap::Object *value)
-{
- QHash<QObject*, WeakValue>::operator[](key).set(value->internalClass->engine, value);
- connect(key, SIGNAL(destroyed(QObject*)), this, SLOT(removeDestroyedObject(QObject*)));
-}
-
-
-MultiplyWrappedQObjectMap::Iterator MultiplyWrappedQObjectMap::erase(MultiplyWrappedQObjectMap::Iterator it)
+MultiplyWrappedQObjectMap::Iterator MultiplyWrappedQObjectMap::erase(
+ MultiplyWrappedQObjectMap::Iterator it)
{
- disconnect(it.key(), SIGNAL(destroyed(QObject*)), this, SLOT(removeDestroyedObject(QObject*)));
- return QHash<QObject*, WeakValue>::erase(it);
-}
-
-void MultiplyWrappedQObjectMap::remove(QObject *key)
-{
- Iterator it = find(key);
- if (it == end())
- return;
- erase(it);
-}
-
-void MultiplyWrappedQObjectMap::mark(QObject *key, MarkStack *markStack)
-{
- Iterator it = find(key);
- if (it == end())
- return;
- it->markOnce(markStack);
+ const QObjectBiPointer key = it.key();
+ const QObject *obj = key.isT1() ? key.asT1() : key.asT2();
+ disconnect(obj, &QObject::destroyed, this, &MultiplyWrappedQObjectMap::removeDestroyedObject);
+ return QHash<QObjectBiPointer, WeakValue>::erase(it);
}
void MultiplyWrappedQObjectMap::removeDestroyedObject(QObject *object)
{
- QHash<QObject*, WeakValue>::remove(object);
+ QHash<QObjectBiPointer, WeakValue>::remove(object);
+ QHash<QObjectBiPointer, WeakValue>::remove(static_cast<const QObject *>(object));
}
} // namespace QV4
diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h
index 4477c3c836..5a0d837746 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper_p.h
+++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h
@@ -65,7 +65,7 @@ private:
Member(class, NoMark, int, index)
DECLARE_HEAP_OBJECT(QObjectMethod, FunctionObject) {
- DECLARE_MARKOBJECTS(QObjectMethod);
+ DECLARE_MARKOBJECTS(QObjectMethod)
QQmlPropertyData *methods;
int methodCount;
@@ -140,6 +140,7 @@ struct Q_QML_EXPORT QObjectWrapper : public Object
QObject *object, String *name, RevisionMode revisionMode, const Value &value);
static ReturnedValue wrap(ExecutionEngine *engine, QObject *object);
+ static ReturnedValue wrapConst(ExecutionEngine *engine, QObject *object);
static void markWrapper(QObject *object, MarkStack *markStack);
using Object::get;
@@ -181,6 +182,7 @@ protected:
private:
Q_NEVER_INLINE static ReturnedValue wrap_slowPath(ExecutionEngine *engine, QObject *object);
+ Q_NEVER_INLINE static ReturnedValue wrapConst_slowPath(ExecutionEngine *engine, QObject *object);
};
inline ReturnedValue QObjectWrapper::wrap(ExecutionEngine *engine, QObject *object)
@@ -197,6 +199,15 @@ inline ReturnedValue QObjectWrapper::wrap(ExecutionEngine *engine, QObject *obje
return wrap_slowPath(engine, object);
}
+// Unfortunately we still need a non-const QObject* here because QQmlData needs to register itself in QObjectPrivate.
+inline ReturnedValue QObjectWrapper::wrapConst(ExecutionEngine *engine, QObject *object)
+{
+ if (Q_UNLIKELY(QQmlData::wasDeleted(object)))
+ return QV4::Encode::null();
+
+ return wrapConst_slowPath(engine, object);
+}
+
template <typename ReversalFunctor>
inline ReturnedValue QObjectWrapper::lookupGetterImpl(Lookup *lookup, ExecutionEngine *engine, const Value &object, bool useOriginalProperty, ReversalFunctor revertLookup)
{
@@ -292,23 +303,32 @@ struct Q_QML_EXPORT QmlSignalHandler : public QV4::Object
static void initProto(ExecutionEngine *v4);
};
+using QObjectBiPointer = QBiPointer<QObject, const QObject>;
+
class MultiplyWrappedQObjectMap : public QObject,
- private QHash<QObject*, QV4::WeakValue>
+ private QHash<QObjectBiPointer, QV4::WeakValue>
{
Q_OBJECT
public:
- typedef QHash<QObject*, QV4::WeakValue>::ConstIterator ConstIterator;
- typedef QHash<QObject*, QV4::WeakValue>::Iterator Iterator;
+ typedef QHash<QObjectBiPointer, QV4::WeakValue>::ConstIterator ConstIterator;
+ typedef QHash<QObjectBiPointer, QV4::WeakValue>::Iterator Iterator;
+
+ using value_type = QHash<QObjectBiPointer, QV4::WeakValue>::value_type;
- using value_type = QHash<QObject*, QV4::WeakValue>::value_type;
+ ConstIterator begin() const { return QHash<QObjectBiPointer, QV4::WeakValue>::constBegin(); }
+ Iterator begin() { return QHash<QObjectBiPointer, QV4::WeakValue>::begin(); }
+ ConstIterator end() const { return QHash<QObjectBiPointer, QV4::WeakValue>::constEnd(); }
+ Iterator end() { return QHash<QObjectBiPointer, QV4::WeakValue>::end(); }
- ConstIterator begin() const { return QHash<QObject*, QV4::WeakValue>::constBegin(); }
- Iterator begin() { return QHash<QObject*, QV4::WeakValue>::begin(); }
- ConstIterator end() const { return QHash<QObject*, QV4::WeakValue>::constEnd(); }
- Iterator end() { return QHash<QObject*, QV4::WeakValue>::end(); }
+ template<typename Pointer>
+ void insert(Pointer key, Heap::Object *value)
+ {
+ QHash<QObjectBiPointer, WeakValue>::operator[](key).set(value->internalClass->engine, value);
+ connect(key, SIGNAL(destroyed(QObject*)), this, SLOT(removeDestroyedObject(QObject*)));
+ }
- void insert(QObject *key, Heap::Object *value);
- ReturnedValue value(QObject *key) const
+ template<typename Pointer>
+ ReturnedValue value(Pointer key) const
{
ConstIterator it = find(key);
return it == end()
@@ -317,8 +337,24 @@ public:
}
Iterator erase(Iterator it);
- void remove(QObject *key);
- void mark(QObject *key, MarkStack *markStack);
+
+ template<typename Pointer>
+ void remove(Pointer key)
+ {
+ Iterator it = find(key);
+ if (it == end())
+ return;
+ erase(it);
+ }
+
+ template<typename Pointer>
+ void mark(Pointer key, MarkStack *markStack)
+ {
+ Iterator it = find(key);
+ if (it == end())
+ return;
+ it->markOnce(markStack);
+ }
private Q_SLOTS:
void removeDestroyedObject(QObject*);
diff --git a/src/qml/jsruntime/qv4reflect.cpp b/src/qml/jsruntime/qv4reflect.cpp
index abcc60726a..179663a0e1 100644
--- a/src/qml/jsruntime/qv4reflect.cpp
+++ b/src/qml/jsruntime/qv4reflect.cpp
@@ -40,7 +40,10 @@ struct CallArgs {
static CallArgs createListFromArrayLike(Scope &scope, const Object *o)
{
- int len = o->getLength();
+ int len = scope.engine->safeForAllocLength(o->getLength());
+ if (scope.engine->hasException)
+ return {nullptr, 0};
+
Value *arguments = scope.alloc(len);
for (int i = 0; i < len; ++i) {
diff --git a/src/qml/jsruntime/qv4regexp.cpp b/src/qml/jsruntime/qv4regexp.cpp
index 0c039967ba..be7ff77603 100644
--- a/src/qml/jsruntime/qv4regexp.cpp
+++ b/src/qml/jsruntime/qv4regexp.cpp
@@ -49,7 +49,7 @@ uint RegExp::match(const QString &string, int start, uint *matchOffsets)
uint ret = JSC::Yarr::offsetNoMatch;
#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
char buffer[8192];
- ret = uint(priv->jitCode->execute(s.characters16(), start, s.length(),
+ ret = uint(priv->jitCode->execute(s.characters16(), start, s.size(),
(int*)matchOffsets, buffer, 8192).start);
#else
ret = uint(priv->jitCode->execute(s.characters16(), start, s.length(),
@@ -74,18 +74,18 @@ uint RegExp::match(const QString &string, int start, uint *matchOffsets)
}
#endif // ENABLE(YARR_JIT)
- return JSC::Yarr::interpret(byteCode(), s.characters16(), string.length(), start, matchOffsets);
+ return JSC::Yarr::interpret(byteCode(), s.characters16(), string.size(), start, matchOffsets);
}
QString RegExp::getSubstitution(const QString &matched, const QString &str, int position, const Value *captures, int nCaptures, const QString &replacement)
{
QString result;
- int matchedLength = matched.length();
- Q_ASSERT(position >= 0 && position <= str.length());
+ int matchedLength = matched.size();
+ Q_ASSERT(position >= 0 && position <= str.size());
int tailPos = position + matchedLength;
int seenDollar = -1;
- for (int i = 0; i < replacement.length(); ++i) {
+ for (int i = 0; i < replacement.size(); ++i) {
QChar ch = replacement.at(i);
if (seenDollar >= 0) {
if (ch.unicode() == '$') {
@@ -98,7 +98,7 @@ QString RegExp::getSubstitution(const QString &matched, const QString &str, int
result += str.mid(tailPos);
} else if (ch.unicode() >= '0' && ch.unicode() <= '9') {
int n = ch.unicode() - '0';
- if (i + 1 < replacement.length()) {
+ if (i + 1 < replacement.size()) {
ch = replacement.at(i + 1);
if (ch.unicode() >= '0' && ch.unicode() <= '9') {
n = n*10 + (ch.unicode() - '0');
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index 365593e207..0fab40a281 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -48,7 +48,7 @@ void Heap::RegExpObject::init(QV4::RegExp *value)
static QString minimalPattern(const QString &pattern)
{
QString ecmaPattern;
- int len = pattern.length();
+ int len = pattern.size();
ecmaPattern.reserve(len);
int i = 0;
const QChar *wc = pattern.unicode();
@@ -146,7 +146,7 @@ ReturnedValue RegExpObject::builtinExec(ExecutionEngine *engine, const String *s
Scope scope(engine);
int offset = (global() || sticky()) ? lastIndex() : 0;
- if (offset < 0 || offset > s.length()) {
+ if (offset < 0 || offset > s.size()) {
setLastIndex(0);
RETURN_RESULT(Encode::null());
}
@@ -170,7 +170,7 @@ ReturnedValue RegExpObject::builtinExec(ExecutionEngine *engine, const String *s
int len = value()->captureCount();
array->arrayReserve(len);
ScopedValue v(scope);
- int strlen = s.length();
+ int strlen = s.size();
for (int i = 0; i < len; ++i) {
int start = matchOffsets[i * 2];
int end = matchOffsets[i * 2 + 1];
@@ -232,7 +232,7 @@ uint parseFlags(Scope &scope, const QV4::Value *f)
if (scope.hasException())
return flags;
QString str = s->toQString();
- for (int i = 0; i < str.length(); ++i) {
+ for (int i = 0; i < str.size(); ++i) {
if (str.at(i) == QLatin1Char('g') && !(flags & CompiledData::RegExp::RegExp_Global)) {
flags |= CompiledData::RegExp::RegExp_Global;
} else if (str.at(i) == QLatin1Char('i') && !(flags & CompiledData::RegExp::RegExp_IgnoreCase)) {
@@ -382,7 +382,7 @@ ReturnedValue RegExpPrototype::execFirstMatch(const FunctionObject *b, const Val
QString s = str->toQString();
int offset = r->lastIndex();
- if (offset < 0 || offset > s.length()) {
+ if (offset < 0 || offset > s.size()) {
r->setLastIndex(0);
RETURN_RESULT(Encode::null());
}
@@ -518,7 +518,7 @@ ReturnedValue RegExpPrototype::method_get_ignoreCase(const FunctionObject *f, co
static int advanceStringIndex(int index, const QString &str, bool unicode)
{
if (unicode) {
- if (index < str.length() - 1 &&
+ if (index < str.size() - 1 &&
str.at(index).isHighSurrogate() &&
str.at(index + 1).isLowSurrogate())
++index;
@@ -607,7 +607,7 @@ ReturnedValue RegExpPrototype::method_replace(const FunctionObject *f, const Val
if (scope.hasException())
return Encode::undefined();
- int lengthS = s->toQString().length();
+ int lengthS = s->toQString().size();
ScopedString replaceValue(scope);
ScopedFunctionObject replaceFunction(scope, (argc > 1 ? argv[1] : Value::undefinedValue()));
@@ -659,7 +659,7 @@ ReturnedValue RegExpPrototype::method_replace(const FunctionObject *f, const Val
if (scope.hasException())
return Encode::undefined();
QString m = matchString->toQString();
- int matchLength = m.length();
+ int matchLength = m.size();
v = resultObject->get(scope.engine->id_index());
int position = v->toInt32();
position = qMax(qMin(position, lengthS), 0);
@@ -786,7 +786,7 @@ ReturnedValue RegExpPrototype::method_split(const FunctionObject *f, const Value
return A->asReturnedValue();
QString S = s->toQString();
- int size = S.length();
+ int size = S.size();
if (size == 0) {
ScopedValue z(scope, exec(scope.engine, splitter, s));
if (z->isNull())
diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h
index 2f278f70a7..3171367351 100644
--- a/src/qml/jsruntime/qv4regexpobject_p.h
+++ b/src/qml/jsruntime/qv4regexpobject_p.h
@@ -56,7 +56,7 @@ DECLARE_HEAP_OBJECT(RegExpObject, Object) {
Member(class, NoMark, int, lastMatchEnd)
DECLARE_HEAP_OBJECT(RegExpCtor, FunctionObject) {
- DECLARE_MARKOBJECTS(RegExpCtor);
+ DECLARE_MARKOBJECTS(RegExpCtor)
void init(QV4::ExecutionContext *scope);
void clearLastMatch();
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index bd81c56bbd..f07f7e38a1 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -144,7 +144,7 @@ struct RuntimeCounters::Data {
}
std::sort(lines.begin(), lines.end(), Line::less);
outs << lines.size() << " counters:" << endl;
- for (const Line &line : qAsConst(lines))
+ for (const Line &line : std::as_const(lines))
outs << qSetFieldWidth(10) << line.count << qSetFieldWidth(0)
<< " | " << line.func
<< " | " << pretty(line.tag1)
@@ -217,7 +217,7 @@ void RuntimeHelpers::numberToString(QString *result, double num, int radix)
*result = qdtoa(num, &decpt, &sign);
if (decpt <= ecma_shortest_low || decpt > ecma_shortest_high) {
- if (result->length() > 1)
+ if (result->size() > 1)
result->insert(1, dot);
result->append(QLatin1Char('e'));
if (decpt > 0)
@@ -225,10 +225,10 @@ void RuntimeHelpers::numberToString(QString *result, double num, int radix)
result->append(QString::number(decpt - 1));
} else if (decpt <= 0) {
result->prepend(QLatin1String("0.") + QString(-decpt, zero));
- } else if (decpt < result->length()) {
+ } else if (decpt < result->size()) {
result->insert(decpt, dot);
} else {
- result->append(QString(decpt - result->length(), zero));
+ result->append(QString(decpt - result->size(), zero));
}
if (sign && num)
@@ -392,7 +392,7 @@ double RuntimeHelpers::stringToNumber(const QString &string)
// libdoubleconversion sources. The same maximum value would be represented by roughly 3.5 times
// as many binary digits.
const int excessiveLength = 16 * 1024;
- if (string.length() > excessiveLength)
+ if (string.size() > excessiveLength)
return qQNaN();
const QStringView s = QStringView(string).trimmed();
@@ -642,7 +642,7 @@ static Q_NEVER_INLINE ReturnedValue getElementIntFallback(ExecutionEngine *engin
ScopedObject o(scope, object);
if (!o) {
if (const String *str = object.as<String>()) {
- if (idx >= (uint)str->toQString().length()) {
+ if (idx >= (uint)str->toQString().size()) {
return Encode::undefined();
}
const QString s = str->toQString().mid(idx, 1);
@@ -1561,6 +1561,11 @@ static CallArgs createSpreadArguments(Scope &scope, Value *argv, int argc)
if (done->booleanValue())
break;
++argCount;
+ constexpr auto safetyMargin = 100; // leave some space on the stack for actual work with the elements
+ if (qint64(scope.engine->jsStackLimit - scope.engine->jsStackTop) < safetyMargin) {
+ scope.engine->throwRangeError(QLatin1String("Too many elements in array to use it with the spread operator"));
+ return { nullptr, 0 };
+ }
v = scope.alloc<Scope::Uninitialized>();
}
}
diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h
index 09e8b60c91..eee7fd8414 100644
--- a/src/qml/jsruntime/qv4scopedvalue_p.h
+++ b/src/qml/jsruntime/qv4scopedvalue_p.h
@@ -88,6 +88,10 @@ struct Scope {
/* Be careful when using Uninitialized, the stack has to be fully initialized before calling into the memory manager again */
Uninitialized
};
+
+ template <AllocMode mode = Undefined>
+ Value *alloc(qint64 nValues) const = delete; // use safeForAllocLength
+
template <AllocMode mode = Undefined>
QML_NEARLY_ALWAYS_INLINE Value *alloc(int nValues) const
{
@@ -408,7 +412,7 @@ struct ScopedProperty
{
ScopedProperty(Scope &scope)
{
- property = reinterpret_cast<Property*>(scope.alloc(sizeof(Property) / sizeof(Value)));
+ property = reinterpret_cast<Property*>(scope.alloc(int(sizeof(Property) / sizeof(Value))));
}
Property *operator->() { return property; }
diff --git a/src/qml/jsruntime/qv4setiterator_p.h b/src/qml/jsruntime/qv4setiterator_p.h
index e7ab85accb..37f912e01a 100644
--- a/src/qml/jsruntime/qv4setiterator_p.h
+++ b/src/qml/jsruntime/qv4setiterator_p.h
@@ -30,7 +30,7 @@ namespace Heap {
Member(class, NoMark, quint32, setNextIndex)
DECLARE_HEAP_OBJECT(SetIteratorObject, Object) {
- DECLARE_MARKOBJECTS(SetIteratorObject);
+ DECLARE_MARKOBJECTS(SetIteratorObject)
void init(Object *obj, QV4::ExecutionEngine *engine)
{
Object::init();
diff --git a/src/qml/jsruntime/qv4stringiterator.cpp b/src/qml/jsruntime/qv4stringiterator.cpp
index 99f10c55b4..9cb2711efb 100644
--- a/src/qml/jsruntime/qv4stringiterator.cpp
+++ b/src/qml/jsruntime/qv4stringiterator.cpp
@@ -35,7 +35,7 @@ ReturnedValue StringIteratorPrototype::method_next(const FunctionObject *b, cons
quint32 index = thisObject->d()->nextIndex;
QString str = s->toQString();
- quint32 len = str.length();
+ quint32 len = str.size();
if (index >= len) {
thisObject->d()->iteratedString.set(scope.engine, nullptr);
diff --git a/src/qml/jsruntime/qv4stringiterator_p.h b/src/qml/jsruntime/qv4stringiterator_p.h
index a445381ba6..742b8a895d 100644
--- a/src/qml/jsruntime/qv4stringiterator_p.h
+++ b/src/qml/jsruntime/qv4stringiterator_p.h
@@ -30,7 +30,7 @@ namespace Heap {
Member(class, NoMark, quint32, nextIndex)
DECLARE_HEAP_OBJECT(StringIteratorObject, Object) {
- DECLARE_MARKOBJECTS(StringIteratorObject);
+ DECLARE_MARKOBJECTS(StringIteratorObject)
void init(String *str, QV4::ExecutionEngine *engine)
{
Object::init();
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index 5e1d764aed..bec4132b5f 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -51,7 +51,7 @@ void Heap::StringObject::init(const QV4::String *str)
Heap::String *Heap::StringObject::getIndex(uint index) const
{
QString str = string->toQString();
- if (index >= (uint)str.length())
+ if (index >= (uint)str.size())
return nullptr;
return internalClass->engine->newString(str.mid(index, 1));
}
@@ -67,7 +67,7 @@ bool StringObject::virtualDeleteProperty(Managed *m, PropertyKey id)
if (id.isArrayIndex()) {
StringObject *o = static_cast<StringObject *>(m);
uint index = id.asArrayIndex();
- if (index < static_cast<uint>(o->d()->string->toQString().length()))
+ if (index < static_cast<uint>(o->d()->string->toQString().size()))
return false;
}
return Object::virtualDeleteProperty(m, id);
@@ -83,7 +83,7 @@ struct StringObjectOwnPropertyKeyIterator : ObjectOwnPropertyKeyIterator
PropertyKey StringObjectOwnPropertyKeyIterator::next(const QV4::Object *o, Property *pd, PropertyAttributes *attrs)
{
const StringObject *s = static_cast<const StringObject *>(o);
- uint slen = s->d()->string->toQString().length();
+ uint slen = s->d()->string->toQString().size();
if (arrayIndex < slen) {
uint index = arrayIndex;
++arrayIndex;
@@ -119,7 +119,7 @@ PropertyAttributes StringObject::virtualGetOwnProperty(const Managed *m, Propert
if (id.isArrayIndex()) {
const uint index = id.asArrayIndex();
const auto s = static_cast<const StringObject *>(m);
- if (index < uint(s->d()->string->toQString().length())) {
+ if (index < uint(s->d()->string->toQString().size())) {
if (p)
p->value = s->getIndex(index);
return Attr_NotConfigurable|Attr_NotWritable;
@@ -338,7 +338,7 @@ ReturnedValue StringPrototype::method_charAt(const FunctionObject *b, const Valu
pos = (int) argv[0].toInteger();
QString result;
- if (pos >= 0 && pos < str.length())
+ if (pos >= 0 && pos < str.size())
result += str.at(pos);
return Encode(v4->newString(result));
@@ -356,7 +356,7 @@ ReturnedValue StringPrototype::method_charCodeAt(const FunctionObject *b, const
pos = (int) argv[0].toInteger();
- if (pos >= 0 && pos < str.length())
+ if (pos >= 0 && pos < str.size())
RETURN_RESULT(Encode(str.at(pos).unicode()));
return Encode(qt_qnan());
@@ -419,11 +419,11 @@ ReturnedValue StringPrototype::method_endsWith(const FunctionObject *b, const Va
if (v4->hasException)
return Encode::undefined();
- int pos = value.length();
+ int pos = value.size();
if (argc > 1)
pos = (int) argv[1].toInteger();
- if (pos == value.length())
+ if (pos == value.size())
RETURN_RESULT(Encode(value.endsWith(searchString)));
QStringView stringToSearch = QStringView{value}.left(pos);
@@ -447,7 +447,7 @@ ReturnedValue StringPrototype::method_indexOf(const FunctionObject *b, const Val
int index = -1;
if (! value.isEmpty())
- index = value.indexOf(searchString, qMin(qMax(pos, 0), value.length()));
+ index = value.indexOf(searchString, qMin(qMax(pos, 0), value.size()));
return Encode(index);
}
@@ -470,7 +470,7 @@ ReturnedValue StringPrototype::method_includes(const FunctionObject *b, const Va
const Value &posArg = argv[1];
pos = (int) posArg.toInteger();
if (!posArg.isInteger() && posArg.isNumber() && qIsInf(posArg.toNumber()))
- pos = value.length();
+ pos = value.size();
}
if (pos == 0)
@@ -497,8 +497,8 @@ ReturnedValue StringPrototype::method_lastIndexOf(const FunctionObject *b, const
else
position = std::trunc(position);
- int pos = std::trunc(qMin(qMax(position, 0.0), double(value.length())));
- if (!searchString.isEmpty() && pos == value.length())
+ int pos = std::trunc(qMin(qMax(position, 0.0), double(value.size())));
+ if (!searchString.isEmpty() && pos == value.size())
--pos;
if (searchString.isNull() && pos == 0)
RETURN_RESULT(Encode(-1));
@@ -607,12 +607,12 @@ ReturnedValue StringPrototype::method_padEnd(const FunctionObject *f, const Valu
return s->asReturnedValue();
QString padded = s->toQString();
- int oldLength = padded.length();
+ int oldLength = padded.size();
int toFill = maxLen - oldLength;
padded.resize(maxLen);
QChar *ch = padded.data() + oldLength;
while (toFill) {
- int copy = qMin(fillString.length(), toFill);
+ int copy = qMin(fillString.size(), toFill);
memcpy(ch, fillString.constData(), copy*sizeof(QChar));
toFill -= copy;
ch += copy;
@@ -646,13 +646,13 @@ ReturnedValue StringPrototype::method_padStart(const FunctionObject *f, const Va
return s->asReturnedValue();
QString original = s->toQString();
- int oldLength = original.length();
+ int oldLength = original.size();
int toFill = maxLen - oldLength;
QString padded;
padded.resize(maxLen);
QChar *ch = padded.data();
while (toFill) {
- int copy = qMin(fillString.length(), toFill);
+ int copy = qMin(fillString.size(), toFill);
memcpy(ch, fillString.constData(), copy*sizeof(QChar));
toFill -= copy;
ch += copy;
@@ -682,9 +682,9 @@ ReturnedValue StringPrototype::method_repeat(const FunctionObject *b, const Valu
static void appendReplacementString(QString *result, const QString &input, const QString& replaceValue, uint* matchOffsets, int captureCount)
{
- result->reserve(result->length() + replaceValue.length());
- for (int i = 0; i < replaceValue.length(); ++i) {
- if (replaceValue.at(i) == QLatin1Char('$') && i < replaceValue.length() - 1) {
+ result->reserve(result->size() + replaceValue.size());
+ for (int i = 0; i < replaceValue.size(); ++i) {
+ if (replaceValue.at(i) == QLatin1Char('$') && i < replaceValue.size() - 1) {
ushort ch = replaceValue.at(i + 1).unicode();
uint substStart = JSC::Yarr::offsetNoMatch;
uint substEnd = JSC::Yarr::offsetNoMatch;
@@ -703,12 +703,12 @@ static void appendReplacementString(QString *result, const QString &input, const
skip = 1;
} else if (ch == '\'') {
substStart = matchOffsets[1];
- substEnd = input.length();
+ substEnd = input.size();
skip = 1;
} else if (ch >= '0' && ch <= '9') {
uint capture = ch - '0';
skip = 1;
- if (i < replaceValue.length() - 2) {
+ if (i < replaceValue.size() - 2) {
ch = replaceValue.at(i + 2).unicode();
if (ch >= '0' && ch <= '9') {
uint c = capture*10 + ch - '0';
@@ -793,7 +793,7 @@ ReturnedValue StringPrototype::method_replace(const FunctionObject *b, const Val
if (idx != -1) {
numStringMatches = 1;
matchOffsets[0] = idx;
- matchOffsets[1] = idx + searchString.length();
+ matchOffsets[1] = idx + searchString.size();
}
}
@@ -802,7 +802,7 @@ ReturnedValue StringPrototype::method_replace(const FunctionObject *b, const Val
ScopedValue replaceValue(scope, argc > 1 ? argv[1] : Value::undefinedValue());
ScopedFunctionObject searchCallback(scope, replaceValue);
if (!!searchCallback) {
- result.reserve(string.length() + 10*numStringMatches);
+ result.reserve(string.size() + 10*numStringMatches);
ScopedValue entry(scope);
Value *arguments = scope.alloc(numCaptures + 2);
int lastEnd = 0;
@@ -832,7 +832,7 @@ ReturnedValue StringPrototype::method_replace(const FunctionObject *b, const Val
result += QStringView{string}.mid(lastEnd);
} else {
QString newString = replaceValue->toQString();
- result.reserve(string.length() + numStringMatches*newString.size());
+ result.reserve(string.size() + numStringMatches*newString.size());
int lastEnd = 0;
for (int i = 0; i < numStringMatches; ++i) {
@@ -975,7 +975,7 @@ ReturnedValue StringPrototype::method_split(const FunctionObject *b, const Value
} else {
QString separator = separatorValue->toQString();
if (separator.isEmpty()) {
- for (uint i = 0; i < qMin(limit, uint(text.length())); ++i)
+ for (uint i = 0; i < qMin(limit, uint(text.size())); ++i)
array->push_back((s = scope.engine->newString(text.mid(i, 1))));
return array.asReturnedValue();
}
@@ -1033,7 +1033,7 @@ ReturnedValue StringPrototype::method_substr(const FunctionObject *b, const Valu
if (argc > 1)
length = argv[1].toInteger();
- double count = value.length();
+ double count = value.size();
if (start < 0)
start = qMax(count + start, 0.0);
@@ -1051,7 +1051,7 @@ ReturnedValue StringPrototype::method_substring(const FunctionObject *b, const V
if (v4->hasException)
return QV4::Encode::undefined();
- int length = value.length();
+ int length = value.size();
double start = 0;
double end = length;
@@ -1124,11 +1124,11 @@ ReturnedValue StringPrototype::method_trim(const FunctionObject *b, const Value
const QChar *chars = s.constData();
int start, end;
- for (start = 0; start < s.length(); ++start) {
+ for (start = 0; start < s.size(); ++start) {
if (!chars[start].isSpace() && chars[start].unicode() != 0xfeff)
break;
}
- for (end = s.length() - 1; end >= start; --end) {
+ for (end = s.size() - 1; end >= start; --end) {
if (!chars[end].isSpace() && chars[end].unicode() != 0xfeff)
break;
}
diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h
index e0c0e37815..451a989ef4 100644
--- a/src/qml/jsruntime/qv4stringobject_p.h
+++ b/src/qml/jsruntime/qv4stringobject_p.h
@@ -28,7 +28,7 @@ namespace Heap {
Member(class, Pointer, String *, string)
DECLARE_HEAP_OBJECT(StringObject, Object) {
- DECLARE_MARKOBJECTS(StringObject);
+ DECLARE_MARKOBJECTS(StringObject)
enum {
LengthPropertyIndex = 0
diff --git a/src/qml/jsruntime/qv4symbol_p.h b/src/qml/jsruntime/qv4symbol_p.h
index b85ddb3b36..e56510bd69 100644
--- a/src/qml/jsruntime/qv4symbol_p.h
+++ b/src/qml/jsruntime/qv4symbol_p.h
@@ -36,7 +36,7 @@ struct Symbol : StringOrSymbol {
Member(class, Pointer, Symbol *, symbol)
DECLARE_HEAP_OBJECT(SymbolObject, Object) {
- DECLARE_MARKOBJECTS(SymbolObject);
+ DECLARE_MARKOBJECTS(SymbolObject)
void init(const QV4::Symbol *s);
};
diff --git a/src/qml/jsruntime/qv4typedarray_p.h b/src/qml/jsruntime/qv4typedarray_p.h
index d7e9d7466c..0284dceb7b 100644
--- a/src/qml/jsruntime/qv4typedarray_p.h
+++ b/src/qml/jsruntime/qv4typedarray_p.h
@@ -80,7 +80,7 @@ namespace Heap {
Member(class, NoMark, uint, arrayType)
DECLARE_HEAP_OBJECT(TypedArray, Object) {
- DECLARE_MARKOBJECTS(TypedArray);
+ DECLARE_MARKOBJECTS(TypedArray)
using Type = TypedArrayType;
void init(Type t);
diff --git a/src/qml/jsruntime/qv4urlobject.cpp b/src/qml/jsruntime/qv4urlobject.cpp
index bc59b7a839..7f4a078d13 100644
--- a/src/qml/jsruntime/qv4urlobject.cpp
+++ b/src/qml/jsruntime/qv4urlobject.cpp
@@ -131,7 +131,7 @@ void UrlObject::setUrl(const QUrl &url)
d()->port.set(engine(),
engine()->newString(url.port() == -1 ? QLatin1String("")
: QString::number(url.port())));
- d()->protocol.set(engine(), engine()->newString(url.scheme()));
+ d()->protocol.set(engine(), engine()->newString(url.scheme() + QLatin1Char(':')));
d()->search.set(engine(), engine()->newString(url.query()));
d()->username.set(engine(), engine()->newString(url.userName()));
@@ -186,15 +186,23 @@ bool UrlObject::setPort(QString port)
return true;
}
-bool UrlObject::setProtocol(QString protocol)
+bool UrlObject::setProtocol(QString protocolOrScheme)
{
QUrl url = toQUrl();
- url.setScheme(protocol);
+ // If there is one or several ':' in the protocolOrScheme,
+ // everything from the first colon is removed.
+
+ qsizetype firstColonPos = protocolOrScheme.indexOf(QLatin1Char(':'));
+
+ if (firstColonPos != -1)
+ protocolOrScheme.truncate(firstColonPos);
+
+ url.setScheme(protocolOrScheme);
if (!url.isValid())
return false;
- d()->protocol.set(engine(), engine()->newString(url.scheme()));
+ d()->protocol.set(engine(), engine()->newString(url.scheme() + QLatin1Char(':')));
d()->href.set(engine(), engine()->newString(url.toString()));
updateOrigin();
diff --git a/src/qml/jsruntime/qv4urlobject_p.h b/src/qml/jsruntime/qv4urlobject_p.h
index 3b210547b3..e4a3ba073b 100644
--- a/src/qml/jsruntime/qv4urlobject_p.h
+++ b/src/qml/jsruntime/qv4urlobject_p.h
@@ -41,7 +41,7 @@ namespace Heap {
DECLARE_HEAP_OBJECT(UrlObject, Object)
{
- DECLARE_MARKOBJECTS(UrlObject);
+ DECLARE_MARKOBJECTS(UrlObject)
void init() { Object::init(); }
};
@@ -59,7 +59,7 @@ struct UrlCtor : FunctionObject
DECLARE_HEAP_OBJECT(UrlSearchParamsObject, Object)
{
- DECLARE_MARKOBJECTS(UrlSearchParamsObject);
+ DECLARE_MARKOBJECTS(UrlSearchParamsObject)
void init() { Object::init(); }
};
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index c41c6fafad..aaace7e9f6 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -943,7 +943,7 @@ void MemoryManager::sweep(bool lastSweep, ClassDestroyStatsCallback classCountPt
}
// Now it is time to free QV4::QObjectWrapper Value, we must check the Value's tag to make sure its object has been destroyed
- const int pendingCount = m_pendingFreedObjectWrapperValue.count();
+ const int pendingCount = m_pendingFreedObjectWrapperValue.size();
if (pendingCount) {
QVector<Value *> remainingWeakQObjectWrappers;
remainingWeakQObjectWrappers.reserve(pendingCount);
@@ -1078,7 +1078,7 @@ void MemoryManager::runGC()
std::swap(freedObjectStats, *freedObjectStatsGlobal());
typedef std::pair<const char*, int> ObjectStatInfo;
std::vector<ObjectStatInfo> freedObjectsSorted;
- freedObjectsSorted.reserve(freedObjectStats.count());
+ freedObjectsSorted.reserve(freedObjectStats.size());
for (auto it = freedObjectStats.constBegin(); it != freedObjectStats.constEnd(); ++it) {
freedObjectsSorted.push_back(std::make_pair(it.key(), it.value()));
}
diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g
index 93d110c19f..8c694af082 100644
--- a/src/qml/parser/qqmljs.g
+++ b/src/qml/parser/qqmljs.g
@@ -368,6 +368,7 @@ protected:
SavedToken *last_token = nullptr;
int functionNestingLevel = 0;
+ int classNestingLevel = 0;
enum CoverExpressionType {
CE_Invalid,
@@ -4278,16 +4279,16 @@ ClassDeclaration_Default: ClassDeclaration;
ClassLBrace: T_LBRACE;
/.
case $rule_number: {
- lexer->setStaticIsKeyword(true);
+ if (++classNestingLevel == 1)
+ lexer->setStaticIsKeyword(true);
} break;
./
ClassRBrace: T_RBRACE;
-/. case $rule_number: ./
-ClassStaticQualifier: T_STATIC;
/.
case $rule_number: {
- lexer->setStaticIsKeyword(false);
+ if (--classNestingLevel == 0)
+ lexer->setStaticIsKeyword(false);
} break;
./
@@ -4342,10 +4343,9 @@ ClassElement: MethodDefinition;
} break;
./
-ClassElement: ClassStaticQualifier MethodDefinition;
+ClassElement: T_STATIC MethodDefinition;
/.
case $rule_number: {
- lexer->setStaticIsKeyword(true);
AST::ClassElementList *node = new (pool) AST::ClassElementList(sym(2).PatternProperty, true);
sym(1).Node = node;
} break;
diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h
index e764ebfb06..c2aa8f2aaa 100644
--- a/src/qml/parser/qqmljsast_p.h
+++ b/src/qml/parser/qqmljsast_p.h
@@ -367,7 +367,7 @@ public:
TypeArgumentList(Type *typeId)
: typeId(typeId)
- , next(nullptr)
+ , next(this)
{ kind = K; }
TypeArgumentList(TypeArgumentList *previous, Type *typeId)
diff --git a/src/qml/parser/qqmljslexer.cpp b/src/qml/parser/qqmljslexer.cpp
index d44b5a29da..db5f1b92dd 100644
--- a/src/qml/parser/qqmljslexer.cpp
+++ b/src/qml/parser/qqmljslexer.cpp
@@ -75,7 +75,7 @@ void Lexer::setCode(const QString &code, int lineno, bool qmlMode)
_state.rawString = QStringView();
_state.codePtr = code.unicode();
- _endPtr = _state.codePtr + code.length();
+ _endPtr = _state.codePtr + code.size();
_state.tokenStartPtr = _state.codePtr;
_state.currentChar = u'\n';
diff --git a/src/qml/qml/ftw/qbipointer_p.h b/src/qml/qml/ftw/qbipointer_p.h
index 79a6676ebd..4039d6b60d 100644
--- a/src/qml/qml/ftw/qbipointer_p.h
+++ b/src/qml/qml/ftw/qbipointer_p.h
@@ -87,6 +87,11 @@ public:
inline T *asT1() const;
inline T2 *asT2() const;
+ friend size_t qHash(const QBiPointer<T, T2> &ptr, size_t seed = 0)
+ {
+ return qHash(ptr.isNull() ? quintptr(0) : ptr.ptr_value, seed);
+ }
+
private:
quintptr ptr_value = 0;
diff --git a/src/qml/qml/ftw/qhashedstring_p.h b/src/qml/qml/ftw/qhashedstring_p.h
index 9beaffc2ae..5e002fcbee 100644
--- a/src/qml/qml/ftw/qhashedstring_p.h
+++ b/src/qml/qml/ftw/qhashedstring_p.h
@@ -200,12 +200,12 @@ QHashedStringRef::QHashedStringRef()
}
QHashedStringRef::QHashedStringRef(const QString &str)
-: m_data(str.constData()), m_length(str.length()), m_hash(0)
+: m_data(str.constData()), m_length(str.size()), m_hash(0)
{
}
QHashedStringRef::QHashedStringRef(QStringView str)
-: m_data(str.constData()), m_length(str.length()), m_hash(0)
+: m_data(str.constData()), m_length(str.size()), m_hash(0)
{
}
@@ -220,7 +220,7 @@ QHashedStringRef::QHashedStringRef(const QChar *data, int length, quint32 hash)
}
QHashedStringRef::QHashedStringRef(const QHashedString &string)
-: m_data(string.constData()), m_length(string.length()), m_hash(string.m_hash)
+: m_data(string.constData()), m_length(string.size()), m_hash(string.m_hash)
{
}
@@ -248,7 +248,7 @@ bool QHashedStringRef::operator==(const QHashedString &string) const
if (m_hash && string.m_hash && m_hash != string.m_hash)
return false;
QStringView view {m_data, m_length};
- QStringView otherView {string.constData(), string.length()};
+ QStringView otherView {string.constData(), string.size()};
return view == otherView;
}
@@ -424,7 +424,7 @@ quint32 QHashedString::stringHash(const char *data, int length)
void QHashedString::computeHash() const
{
- m_hash = stringHash(constData(), length());
+ m_hash = stringHash(constData(), size());
}
namespace QtPrivate {
diff --git a/src/qml/qml/ftw/qstringhash_p.h b/src/qml/qml/ftw/qstringhash_p.h
index 1d0e7d6e97..ee2928ee59 100644
--- a/src/qml/qml/ftw/qstringhash_p.h
+++ b/src/qml/qml/ftw/qstringhash_p.h
@@ -38,7 +38,7 @@ public:
}
QStringHashNode(const QHashedString &key)
- : length(key.length()), hash(key.hash()), symbolId(0)
+ : length(key.size()), hash(key.hash()), symbolId(0)
, arrayData(mutableStringData(key).d_ptr())
, strData(mutableStringData(key).data())
{
@@ -491,7 +491,7 @@ int QStringHash<T>::numBuckets() const
template<class T>
void QStringHash<T>::initializeNode(Node *node, const QHashedString &key)
{
- node->length = key.length();
+ node->length = key.size();
node->hash = key.hash();
node->arrayData = mutableStringData(key).d_ptr();
node->strData = mutableStringData(key).data();
diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp
index 72a287c318..f0435ede45 100644
--- a/src/qml/qml/qqml.cpp
+++ b/src/qml/qml/qqml.cpp
@@ -581,7 +581,7 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data)
auto revisions = prepareRevisions(type.instanceMetaObject, added) + furtherRevisions;
uniqueRevisions(&revisions, type.version, added);
- for (QTypeRevision revision : qAsConst(revisions)) {
+ for (QTypeRevision revision : std::as_const(revisions)) {
if (revision.hasMajorVersion() && revision.majorVersion() > type.version.majorVersion())
break;
@@ -624,7 +624,7 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data)
revisions.append(added);
uniqueRevisions(&revisions, type.version, added);
- for (QTypeRevision revision : qAsConst(revisions)) {
+ for (QTypeRevision revision : std::as_const(revisions)) {
if (revision < added)
continue;
if (revision.hasMajorVersion() && revision.majorVersion() > type.version.majorVersion())
@@ -976,7 +976,8 @@ static ObjectLookupResult initObjectLookup(
// & 1 to tell the gc that this is not heap allocated; see markObjects in qv4lookup_p.h
l->qobjectFallbackLookup.metaObject = quintptr(metaObject) + 1;
l->qobjectFallbackLookup.coreIndex = coreIndex;
- l->qobjectFallbackLookup.notifyIndex = property.notifySignalIndex();
+ l->qobjectFallbackLookup.notifyIndex =
+ QMetaObjectPrivate::signalIndex(property.notifySignal());
l->qobjectFallbackLookup.isConstant = property.isConstant() ? 1 : 0;
return ObjectLookupResult::Fallback;
}
@@ -997,7 +998,7 @@ static bool initValueLookup(QV4::Lookup *l, QV4::ExecutableCompilationUnit *comp
const QByteArray name = compilationUnit->runtimeStrings[l->nameIndex]->toQString().toUtf8();
const int coreIndex = metaObject->indexOfProperty(name.constData());
QMetaType lookupType = metaObject->property(coreIndex).metaType();
- if (type.isValid() && lookupType != type)
+ if (!isTypeCompatible(type, lookupType))
return false;
l->qgadgetLookup.metaObject = quintptr(metaObject) + 1;
l->qgadgetLookup.coreIndex = coreIndex;
@@ -1587,7 +1588,12 @@ void AOTCompiledContext::initGetEnumLookup(
{
Q_ASSERT(!engine->hasError());
QV4::Lookup *l = compilationUnit->runtimeLookups + index;
- Q_ASSERT(metaObject);
+ if (!metaObject) {
+ engine->handle()->throwTypeError(
+ QStringLiteral("Cannot read property '%1' of undefined")
+ .arg(QString::fromUtf8(enumValue)));
+ return;
+ }
const int enumIndex = metaObject->indexOfEnumerator(enumerator);
const int value = metaObject->enumerator(enumIndex).keyToValue(enumValue);
l->qmlEnumValueLookup.encodedEnumValue = value;
diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp
index df8c64dab0..2b94da14a5 100644
--- a/src/qml/qml/qqmlapplicationengine.cpp
+++ b/src/qml/qml/qqmlapplicationengine.cpp
@@ -26,7 +26,7 @@ QQmlApplicationEnginePrivate::~QQmlApplicationEnginePrivate()
void QQmlApplicationEnginePrivate::cleanUp()
{
Q_Q(QQmlApplicationEngine);
- for (auto obj : qAsConst(objects))
+ for (auto obj : std::as_const(objects))
obj->disconnect(q);
qDeleteAll(objects);
@@ -214,7 +214,7 @@ void QQmlApplicationEnginePrivate::finishLoad(QQmlComponent *c)
QQmlApplicationEngine engine;
// quit on error
- QObject::connect(&app, QQmlApplicationEngine::objectCreationFailed,
+ QObject::connect(&engine, QQmlApplicationEngine::objectCreationFailed,
QCoreApplication::instance(), QCoreApplication::quit,
Qt::QueuedConnection);
engine.load(QUrl());
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp
index 49a72c17e9..10a9e60819 100644
--- a/src/qml/qml/qqmlbinding.cpp
+++ b/src/qml/qml/qqmlbinding.cpp
@@ -339,7 +339,7 @@ protected:
break;
default:
if (const QV4::QQmlValueTypeWrapper *vtw = result.as<const QV4::QQmlValueTypeWrapper>()) {
- if (vtw->d()->valueType()->metaType == pd->propType()) {
+ if (vtw->d()->valueType()->metaType() == pd->propType()) {
return vtw->write(m_target.data(), pd->coreIndex());
}
}
diff --git a/src/qml/qml/qqmlbinding_p.h b/src/qml/qml/qqmlbinding_p.h
index 4c8c0f4e61..9b468f3f17 100644
--- a/src/qml/qml/qqmlbinding_p.h
+++ b/src/qml/qml/qqmlbinding_p.h
@@ -76,6 +76,10 @@ public:
};
QVariant evaluate();
+ bool evaluate(void *result, QMetaType type)
+ {
+ return QQmlJavaScriptExpression::evaluate(&result, &type, 0);
+ }
void expressionChanged() override;
@@ -110,10 +114,6 @@ protected:
QQmlPropertyData::WriteFlags flags);
QV4::ReturnedValue evaluate(bool *isUndefined);
- bool evaluate(void *result, QMetaType type)
- {
- return QQmlJavaScriptExpression::evaluate(&result, &type, 0);
- }
private:
static QQmlBinding *newBinding(const QQmlPropertyData *property);
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 8c74272457..8f1ed8b31c 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -350,7 +350,7 @@ bool QQmlComponentPrivate::setInitialProperty(
QV4::ScopedObject object(scope, QV4::QObjectWrapper::wrap(scope.engine, base));
QV4::ScopedString segment(scope);
- for (int i = 0; i < properties.length() - 1; ++i) {
+ for (int i = 0; i < properties.size() - 1; ++i) {
segment = scope.engine->newString(properties.at(i));
object = object->get(segment);
if (scope.engine->hasException)
@@ -408,7 +408,7 @@ QQmlComponent::~QQmlComponent()
if (isError()) {
qWarning() << "This may have been caused by one of the following errors:";
- for (const QQmlError &error : qAsConst(d->state.errors))
+ for (const QQmlError &error : std::as_const(d->state.errors))
qWarning().nospace().noquote() << QLatin1String(" ") << error;
}
@@ -489,6 +489,16 @@ bool QQmlComponent::isLoading() const
}
/*!
+ Returns true if the component was created in a QML files that specifies
+ \c{pragma ComponentBehavior: Bound}, otherwise returns false.
+ */
+bool QQmlComponent::isBound() const
+{
+ Q_D(const QQmlComponent);
+ return d->isBound();
+}
+
+/*!
\qmlproperty real Component::progress
The progress of loading the component, from 0.0 (nothing loaded)
to 1.0 (finished).
@@ -914,7 +924,7 @@ QObject *QQmlComponentPrivate::beginCreate(QQmlRefPointer<QQmlContextData> conte
Q_Q(QQmlComponent);
auto cleanup = qScopeGuard([this] {
if (!state.errors.isEmpty() && lcQmlComponentGeneral().isDebugEnabled()) {
- for (const auto &e : qAsConst(state.errors)) {
+ for (const auto &e : std::as_const(state.errors)) {
qCDebug(lcQmlComponentGeneral) << "QQmlComponent: " << e.toString();
}
}
@@ -986,7 +996,7 @@ void QQmlComponentPrivate::beginDeferred(QQmlEnginePrivate *enginePriv,
deferredState->reserve(ddata->deferredData.size());
- for (QQmlData::DeferredData *deferredData : qAsConst(ddata->deferredData)) {
+ for (QQmlData::DeferredData *deferredData : std::as_const(ddata->deferredData)) {
enginePriv->inProgressCreations++;
ConstructionState state;
@@ -1270,7 +1280,7 @@ namespace Heap {
Member(class, NoMark, QV4QPointer<QObject>, parent)
DECLARE_HEAP_OBJECT(QmlIncubatorObject, Object) {
- DECLARE_MARKOBJECTS(QmlIncubatorObject);
+ DECLARE_MARKOBJECTS(QmlIncubatorObject)
void init(QQmlIncubator::IncubationMode = QQmlIncubator::Asynchronous);
inline void destroy();
@@ -1331,7 +1341,7 @@ static void QQmlComponent_setQmlParent(QObject *me, QObject *parent)
QList<APF> functions = QQmlMetaType::parentFunctions();
bool needParent = false;
- for (int ii = 0; ii < functions.count(); ++ii) {
+ for (int ii = 0; ii < functions.size(); ++ii) {
QQmlPrivate::AutoParentResult res = functions.at(ii)(me, parent);
if (res == QQmlPrivate::Parented) {
needParent = false;
@@ -1375,12 +1385,12 @@ static void QQmlComponent_setQmlParent(QObject *me, QObject *parent)
The \a properties argument is specified as a map of property-value items. For example, the code
below creates an object with initial \c x and \c y values of 100 and 100, respectively:
- \js
+ \qml
const component = Qt.createComponent("Button.qml");
if (component.status === Component.Ready) {
component.createObject(parent, { x: 100, y: 100 });
}
- \endjs
+ \endqml
Dynamically created instances can be deleted with the \c destroy() method.
See \l {Dynamic QML Object Creation from JavaScript} for more information.
@@ -1410,17 +1420,25 @@ void QQmlComponentPrivate::setInitialProperties(QV4::ExecutionEngine *engine, QV
object = o;
const QStringList properties = name->toQString().split(QLatin1Char('.'));
bool isTopLevelProperty = properties.size() == 1;
- for (int i = 0; i < properties.length() - 1; ++i) {
+ for (int i = 0; i < properties.size() - 1; ++i) {
name = engine->newString(properties.at(i));
object = object->get(name);
if (engine->hasException || !object) {
break;
}
}
- if (engine->hasException || !object) {
+ if (engine->hasException) {
qmlWarning(createdComponent, engine->catchExceptionAsQmlError());
continue;
}
+ if (!object) {
+ QQmlError error;
+ error.setUrl(qmlContext ? qmlContext->qmlContext()->url() : QUrl());
+ error.setDescription(QLatin1String("Cannot resolve property \"%1\".")
+ .arg(properties.join(u'.')));
+ qmlWarning(createdComponent, error);
+ continue;
+ }
name = engine->newString(properties.last());
object->put(name, val);
if (engine->hasException) {
@@ -1568,7 +1586,7 @@ QObject *QQmlComponent::createObject(QObject *parent, const QVariantMap &propert
if (!d->requiredProperties().empty()) {
QList<QQmlError> errors;
- for (const auto &requiredProperty: qAsConst(d->requiredProperties())) {
+ for (const auto &requiredProperty: std::as_const(d->requiredProperties())) {
errors.push_back(QQmlComponentPrivate::unsetRequiredPropertyToQQmlError(
requiredProperty));
}
@@ -1622,7 +1640,7 @@ QObject *QQmlComponent::createObject(QObject *parent, const QVariantMap &propert
The following example demonstrates how to use an incubator:
- \js
+ \qml
const component = Qt.createComponent("Button.qml");
const incubator = component.incubateObject(parent, { x: 10, y: 10 });
@@ -1635,7 +1653,7 @@ QObject *QQmlComponent::createObject(QObject *parent, const QVariantMap &propert
} else {
print("Object", incubator.object, "is ready immediately!");
}
- \endjs
+ \endqml
Dynamically created instances can be deleted with the \c destroy() method.
See \l {Dynamic QML Object Creation from JavaScript} for more information.
diff --git a/src/qml/qml/qqmlcomponent.h b/src/qml/qml/qqmlcomponent.h
index ccfece00f9..ca95d756a5 100644
--- a/src/qml/qml/qqmlcomponent.h
+++ b/src/qml/qml/qqmlcomponent.h
@@ -63,6 +63,8 @@ public:
bool isError() const;
bool isLoading() const;
+ bool isBound() const;
+
QList<QQmlError> errors() const;
Q_INVOKABLE QString errorString() const;
diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp
index baa8d6133e..0c9286693f 100644
--- a/src/qml/qml/qqmlcontext.cpp
+++ b/src/qml/qml/qqmlcontext.cpp
@@ -481,7 +481,7 @@ qsizetype QQmlContextPrivate::context_count(QQmlListProperty<QObject> *prop)
if (d->propertyValue(contextProperty).userType() != qMetaTypeId<QList<QObject*> >())
return 0;
else
- return ((const QList<QObject> *)d->propertyValue(contextProperty).constData())->count();
+ return ((const QList<QObject> *)d->propertyValue(contextProperty).constData())->size();
}
QObject *QQmlContextPrivate::context_at(QQmlListProperty<QObject> *prop, qsizetype index)
diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h
index aa50485a00..5489afb892 100644
--- a/src/qml/qml/qqmlcontext_p.h
+++ b/src/qml/qml/qqmlcontext_p.h
@@ -50,7 +50,7 @@ public:
int notifyIndex() const { return m_notifyIndex; }
void setNotifyIndex(int notifyIndex) { m_notifyIndex = notifyIndex; }
- int numPropertyValues() const { return m_propertyValues.count(); }
+ int numPropertyValues() const { return m_propertyValues.size(); }
void appendPropertyValue(const QVariant &value) { m_propertyValues.append(value); }
void setPropertyValue(int index, const QVariant &value) { m_propertyValues[index] = value; }
QVariant propertyValue(int index) const { return m_propertyValues[index]; }
diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp
index fba805f084..f284a82dbe 100644
--- a/src/qml/qml/qqmlcustomparser.cpp
+++ b/src/qml/qml/qqmlcustomparser.cpp
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#include "qml/qqmlpropertyvalidator_p.h"
#include "qqmlcustomparser_p.h"
#include <private/qv4compileddata_p.h>
@@ -81,7 +82,7 @@ void QQmlCustomParser::error(const QV4::CompiledData::Location &location, const
A valid \a ok must be provided, or the function will assert.
*/
-int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const
+int QQmlCustomParser::evaluateEnum(const QString &script, bool *ok) const
{
Q_ASSERT_X(ok, "QQmlCustomParser::evaluateEnum", "ok must not be a null pointer");
*ok = false;
@@ -91,15 +92,15 @@ int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const
// * <TypeName>.<ScopedEnumName>.<EnumValue>
auto nextDot = [&](int dot) {
- const int nextDot = script.indexOf('.', dot + 1);
- return (nextDot == script.length() - 1) ? -1 : nextDot;
+ const int nextDot = script.indexOf(u'.', dot + 1);
+ return (nextDot == script.size() - 1) ? -1 : nextDot;
};
int dot = nextDot(-1);
if (dot == -1)
return -1;
- QString scope = QString::fromUtf8(script.left(dot));
+ const QString scope = script.left(dot);
if (scope != QLatin1String("Qt")) {
if (imports.isNull())
@@ -108,23 +109,35 @@ int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const
if (imports.isT1()) {
QQmlImportNamespace *ns = nullptr;
- if (!imports.asT1()->resolveType(scope, &type, nullptr, &ns))
+
+ // Pass &recursionDetected to resolveType because that implicitly allows recursion.
+ // This way we can find the QQmlType of the document we're currently validating.
+ bool recursionDetected = false;
+
+ if (!imports.asT1()->resolveType(
+ scope, &type, nullptr, &ns, nullptr,
+ QQmlType::AnyRegistrationType, &recursionDetected)) {
return -1;
+ }
+
if (!type.isValid() && ns != nullptr) {
dot = nextDot(dot);
- if (dot == -1 || !imports.asT1()->resolveType(QString::fromUtf8(script.left(dot)),
- &type, nullptr, nullptr)) {
+ if (dot == -1 || !imports.asT1()->resolveType(
+ script.left(dot), &type, nullptr, nullptr, nullptr,
+ QQmlType::AnyRegistrationType, &recursionDetected)) {
return -1;
}
}
} else {
- QQmlTypeNameCache::Result result = imports.asT2()->query(scope);
+ // Allow recursion so that we can find enums from the same document.
+ const QQmlTypeNameCache::Result result
+ = imports.asT2()->query<QQmlImport::AllowRecursion>(scope);
if (result.isValid()) {
type = result.type;
} else if (result.importNamespace) {
dot = nextDot(dot);
if (dot != -1)
- type = imports.asT2()->query(QString::fromUtf8(script.left(dot))).type;
+ type = imports.asT2()->query<QQmlImport::AllowRecursion>(script.left(dot)).type;
}
}
@@ -133,19 +146,43 @@ int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const
const int dot2 = nextDot(dot);
const bool dot2Valid = (dot2 != -1);
- QByteArray enumValue = script.mid(dot2Valid ? dot2 + 1 : dot + 1);
- QByteArray scopedEnumName = (dot2Valid ? script.mid(dot + 1, dot2 - dot - 1) : QByteArray());
+ const QString enumValue = script.mid(dot2Valid ? dot2 + 1 : dot + 1);
+ const QString scopedEnumName = dot2Valid ? script.mid(dot + 1, dot2 - dot - 1) : QString();
+
+ // If we're currently validating the same document, we won't be able to find its enums using
+ // the QQmlType. However, we do have the property cache already, and that one contains the
+ // enums.
+ const QUrl documentUrl = validator ? validator->documentSourceUrl() : QUrl();
+ if (documentUrl.isValid() && documentUrl == type.sourceUrl()) {
+ const QQmlPropertyCache::ConstPtr rootCache = validator->rootPropertyCache();
+ const int count = rootCache->qmlEnumCount();
+ for (int ii = 0; ii < count; ++ii) {
+ const QQmlEnumData *enumData = rootCache->qmlEnum(ii);
+ if (!scopedEnumName.isEmpty() && scopedEnumName != enumData->name)
+ continue;
+
+ for (int jj = 0; jj < enumData->values.size(); ++jj) {
+ const QQmlEnumValue value = enumData->values.at(jj);
+ if (value.namedValue == enumValue) {
+ *ok = true;
+ return value.value;
+ }
+ }
+ }
+ return -1;
+ }
+
if (!scopedEnumName.isEmpty())
return type.scopedEnumValue(engine, scopedEnumName, enumValue, ok);
else
- return type.enumValue(engine, QHashedCStringRef(enumValue.constData(), enumValue.length()), ok);
+ return type.enumValue(engine, enumValue, ok);
}
- QByteArray enumValue = script.mid(dot + 1);
+ const QString enumValue = script.mid(dot + 1);
const QMetaObject *mo = &Qt::staticMetaObject;
int i = mo->enumeratorCount();
while (i--) {
- int v = mo->enumerator(i).keyToValue(enumValue.constData(), ok);
+ int v = mo->enumerator(i).keyToValue(enumValue.toUtf8().constData(), ok);
if (*ok)
return v;
}
diff --git a/src/qml/qml/qqmlcustomparser_p.h b/src/qml/qml/qqmlcustomparser_p.h
index afb5b810c2..98a9f21ae9 100644
--- a/src/qml/qml/qqmlcustomparser_p.h
+++ b/src/qml/qml/qqmlcustomparser_p.h
@@ -56,7 +56,7 @@ protected:
{ error(object->location, description); }
void error(const QV4::CompiledData::Location &location, const QString& description);
- int evaluateEnum(const QByteArray&, bool *ok) const;
+ int evaluateEnum(const QString &, bool *ok) const;
const QMetaObject *resolveType(const QString&) const;
diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h
index f72feb2ce6..5b7c05c61e 100644
--- a/src/qml/qml/qqmldata_p.h
+++ b/src/qml/qml/qqmldata_p.h
@@ -103,7 +103,9 @@ public:
// set when at least one of the object's properties is intercepted
quint32 hasInterceptorMetaObject:1;
quint32 hasVMEMetaObject:1;
- quint32 dummy:8;
+ // If we have another wrapper for a const QObject * in the multiply wrapped QObjects.
+ quint32 hasConstWrapper: 1;
+ quint32 dummy:7;
// When bindingBitsSize < sizeof(ptr), we store the binding bit flags inside
// bindingBitsValue. When we need more than sizeof(ptr) bits, we allocated
diff --git a/src/qml/qml/qqmldatablob.cpp b/src/qml/qml/qqmldatablob.cpp
index 6114c2846a..a8a4537844 100644
--- a/src/qml/qml/qqmldatablob.cpp
+++ b/src/qml/qml/qqmldatablob.cpp
@@ -254,7 +254,7 @@ void QQmlDataBlob::setError(const QList<QQmlError> &errors)
Q_ASSERT(m_errors.isEmpty());
// m_errors must be set before the m_data fence
- m_errors.reserve(errors.count());
+ m_errors.reserve(errors.size());
for (const QQmlError &error : errors) {
if (error.url().isEmpty()) {
QQmlError mutableError = error;
@@ -269,7 +269,7 @@ void QQmlDataBlob::setError(const QList<QQmlError> &errors)
if (dumpErrors()) {
qWarning().nospace() << "Errors for " << urlString();
- for (int ii = 0; ii < errors.count(); ++ii)
+ for (int ii = 0; ii < errors.size(); ++ii)
qWarning().nospace() << " " << qPrintable(errors.at(ii).toString());
}
cancelAllWaitingFor();
@@ -313,7 +313,7 @@ void QQmlDataBlob::addDependency(QQmlDataBlob *blob)
status() == Error || status() == Complete || m_isDone)
return;
- for (const auto &existingDep: qAsConst(m_waitingFor))
+ for (const auto &existingDep: std::as_const(m_waitingFor))
if (existingDep.data() == blob)
return;
@@ -503,7 +503,7 @@ void QQmlDataBlob::tryDone()
void QQmlDataBlob::cancelAllWaitingFor()
{
- while (m_waitingFor.count()) {
+ while (m_waitingFor.size()) {
QQmlRefPointer<QQmlDataBlob> blob = m_waitingFor.takeLast();
Q_ASSERT(blob->m_waitingOnMe.contains(this));
@@ -514,7 +514,7 @@ void QQmlDataBlob::cancelAllWaitingFor()
void QQmlDataBlob::notifyAllWaitingOnMe()
{
- while (m_waitingOnMe.count()) {
+ while (m_waitingOnMe.size()) {
QQmlDataBlob *blob = m_waitingOnMe.takeLast();
Q_ASSERT(std::any_of(blob->m_waitingFor.constBegin(), blob->m_waitingFor.constEnd(),
@@ -533,7 +533,7 @@ void QQmlDataBlob::notifyComplete(QQmlDataBlob *blob)
m_inCallback = true;
QQmlRefPointer<QQmlDataBlob> blobRef;
- for (int i = 0; i < m_waitingFor.count(); ++i) {
+ for (int i = 0; i < m_waitingFor.size(); ++i) {
if (m_waitingFor.at(i).data() == blob) {
blobRef = m_waitingFor.takeAt(i);
break;
@@ -576,7 +576,7 @@ QString QQmlDataBlob::SourceCodeData::readAll(QString *error) const
}
QByteArray data(fileSize, Qt::Uninitialized);
- if (f.read(data.data(), data.length()) != data.length()) {
+ if (f.read(data.data(), data.size()) != data.size()) {
*error = f.errorString();
return QString();
}
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 57df383257..4e12ab93d8 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -245,7 +245,7 @@ void QQmlPrivate::qdeclarativeelement_destructor(QObject *o)
QQmlData::QQmlData()
: ownMemory(true), indestructible(true), explicitIndestructibleSet(false),
hasTaintedV4Object(false), isQueuedForDeletion(false), rootObjectInCreation(false),
- hasInterceptorMetaObject(false), hasVMEMetaObject(false),
+ hasInterceptorMetaObject(false), hasVMEMetaObject(false), hasConstWrapper(false),
bindingBitsArraySize(InlineBindingArraySize), notifyList(nullptr),
bindings(nullptr), signalHandlers(nullptr), nextContextObject(nullptr), prevContextObject(nullptr),
lineNumber(0), columnNumber(0), jsEngineId(0),
diff --git a/src/qml/qml/qqmlerror.cpp b/src/qml/qml/qqmlerror.cpp
index 66192ff06c..a0b6440e7d 100644
--- a/src/qml/qml/qqmlerror.cpp
+++ b/src/qml/qml/qqmlerror.cpp
@@ -295,13 +295,13 @@ QDebug operator<<(QDebug debug, const QQmlError &error)
const QString code = stream.readAll();
const auto lines = QStringView{code}.split(QLatin1Char('\n'));
- if (lines.count() >= error.line()) {
+ if (lines.size() >= error.line()) {
const QStringView &line = lines.at(error.line() - 1);
debug << "\n " << line.toLocal8Bit().constData();
if(error.column() > 0) {
int column = qMax(0, error.column() - 1);
- column = qMin(column, line.length());
+ column = qMin(column, line.size());
QByteArray ind;
ind.reserve(column);
diff --git a/src/qml/qml/qqmlextensionplugin.cpp b/src/qml/qml/qqmlextensionplugin.cpp
index 6229c0a0e4..319accb768 100644
--- a/src/qml/qml/qqmlextensionplugin.cpp
+++ b/src/qml/qml/qqmlextensionplugin.cpp
@@ -7,6 +7,21 @@
QT_BEGIN_NAMESPACE
/*!
+ \since 5.0
+ \inmodule QtQml
+ \class QQmlExtensionPlugin
+ \brief The QQmlExtensionPlugin class provides an abstract base for custom QML extension plugins
+ with custom type registration functions.
+
+ \ingroup plugins
+
+ \note If you need to write a plugin manually (which is rare) you should always use
+ \l{QQmlEngineExtensionPlugin}. QQmlExtensionPlugin only provides the registerTypes() and
+ unregisterTypes() functions in addition. You should not use them, but rather declare your
+ types with \l{QML_ELEMENT} and friends and have the build system take care of the registration.
+*/
+
+/*!
\since 5.14
\inmodule QtQml
\class QQmlEngineExtensionPlugin
@@ -25,7 +40,6 @@ QT_BEGIN_NAMESPACE
/*!
\fn void QQmlExtensionPlugin::registerTypes(const char *uri)
- \internal
Registers the QML types in the given \a uri. Subclasses should implement
this to call qmlRegisterType() for all types which are provided by the extension
@@ -107,9 +121,10 @@ void QQmlExtensionPlugin::unregisterTypes()
}
/*!
- \internal
-*/
-
+ Initializes the extension from the \a uri using the \a engine. Here an application
+ plugin might, for example, expose some data or objects to QML,
+ as context properties on the engine's root context.
+ */
void QQmlExtensionPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
{
Q_UNUSED(engine);
diff --git a/src/qml/qml/qqmlfile.cpp b/src/qml/qml/qqmlfile.cpp
index af2f4d8510..d616616ebd 100644
--- a/src/qml/qml/qqmlfile.cpp
+++ b/src/qml/qml/qqmlfile.cpp
@@ -29,6 +29,9 @@ static char file_string[] = "file";
#if defined(Q_OS_ANDROID)
static char assets_string[] = "assets";
static char content_string[] = "content";
+static char authority_externalstorage[] = "com.android.externalstorage.documents";
+static char authority_downloads_documents[] = "com.android.providers.downloads.documents";
+static char authority_media_documents[] = "com.android.providers.media.documents";
#endif
class QQmlFilePrivate;
@@ -410,8 +413,8 @@ bool QQmlFile::isSynchronous(const QUrl &url)
{
QString scheme = url.scheme();
- if ((scheme.length() == 4 && 0 == scheme.compare(QLatin1String(file_string), Qt::CaseInsensitive)) ||
- (scheme.length() == 3 && 0 == scheme.compare(QLatin1String(qrc_string), Qt::CaseInsensitive))) {
+ if ((scheme.size() == 4 && 0 == scheme.compare(QLatin1String(file_string), Qt::CaseInsensitive)) ||
+ (scheme.size() == 3 && 0 == scheme.compare(QLatin1String(qrc_string), Qt::CaseInsensitive))) {
return true;
#if defined(Q_OS_ANDROID)
@@ -435,20 +438,20 @@ Synchronous urls have a qrc:/ or file:// scheme.
*/
bool QQmlFile::isSynchronous(const QString &url)
{
- if (url.length() < 5 /* qrc:/ */)
+ if (url.size() < 5 /* qrc:/ */)
return false;
QChar f = url[0];
if (f == QLatin1Char('f') || f == QLatin1Char('F')) {
- return url.length() >= 7 /* file:// */ &&
+ return url.size() >= 7 /* file:// */ &&
url.startsWith(QLatin1String(file_string), Qt::CaseInsensitive) &&
url[4] == QLatin1Char(':') && url[5] == QLatin1Char('/') && url[6] == QLatin1Char('/');
} else if (f == QLatin1Char('q') || f == QLatin1Char('Q')) {
- return url.length() >= 5 /* qrc:/ */ &&
+ return url.size() >= 5 /* qrc:/ */ &&
url.startsWith(QLatin1String(qrc_string), Qt::CaseInsensitive) &&
url[3] == QLatin1Char(':') && url[4] == QLatin1Char('/');
@@ -469,6 +472,17 @@ bool QQmlFile::isSynchronous(const QString &url)
return false;
}
+#if defined(Q_OS_ANDROID)
+static bool hasLocalContentAuthority(const QUrl &url)
+{
+ const QString authority = url.authority();
+ return authority.isEmpty()
+ || authority == QLatin1String(authority_externalstorage)
+ || authority == QLatin1String(authority_downloads_documents)
+ || authority == QLatin1String(authority_media_documents);
+}
+#endif
+
/*!
Returns true if \a url is a local file that can be opened with QFile.
@@ -483,27 +497,27 @@ bool QQmlFile::isLocalFile(const QUrl &url)
// file: URLs with two slashes following the scheme can be interpreted as local files
// where the slashes are part of the path. Therefore, disregard the authority.
// See QUrl::toLocalFile().
- if (scheme.length() == 4 && scheme.startsWith(QLatin1String(file_string), Qt::CaseInsensitive))
+ if (scheme.size() == 4 && scheme.startsWith(QLatin1String(file_string), Qt::CaseInsensitive))
return true;
- if (scheme.length() == 3 && scheme.startsWith(QLatin1String(qrc_string), Qt::CaseInsensitive))
+ if (scheme.size() == 3 && scheme.startsWith(QLatin1String(qrc_string), Qt::CaseInsensitive))
return url.authority().isEmpty();
#if defined(Q_OS_ANDROID)
- if ((scheme.length() == 6
+ if (scheme.length() == 6
&& scheme.startsWith(QLatin1String(assets_string), Qt::CaseInsensitive))
- || (scheme.length() == 7
- && scheme.startsWith(QLatin1String(content_string), Qt::CaseInsensitive))) {
return url.authority().isEmpty();
- }
+ if (scheme.length() == 7
+ && scheme.startsWith(QLatin1String(content_string), Qt::CaseInsensitive))
+ return hasLocalContentAuthority(url);
#endif
return false;
}
-static bool hasSchemeAndNoAuthority(const QString &url, const char *scheme, qsizetype schemeLength)
+static bool hasScheme(const QString &url, const char *scheme, qsizetype schemeLength)
{
- const qsizetype urlLength = url.length();
+ const qsizetype urlLength = url.size();
if (urlLength < schemeLength + 1)
return false;
@@ -514,19 +528,41 @@ static bool hasSchemeAndNoAuthority(const QString &url, const char *scheme, qsiz
if (url[schemeLength] != QLatin1Char(':'))
return false;
+ return true;
+}
+
+static qsizetype authorityOffset(const QString &url, qsizetype schemeLength)
+{
+ const qsizetype urlLength = url.size();
+
if (urlLength < schemeLength + 3)
- return true;
+ return -1;
const QLatin1Char slash('/');
if (url[schemeLength + 1] == slash && url[schemeLength + 2] == slash) {
- // Exactly two slashes denote an authority. We don't want that.
+ // Exactly two slashes denote an authority.
if (urlLength < schemeLength + 4 || url[schemeLength + 3] != slash)
- return false;
+ return schemeLength + 3;
}
- return true;
+ return -1;
+}
+
+#if defined(Q_OS_ANDROID)
+static bool hasLocalContentAuthority(const QString &url, qsizetype schemeLength)
+{
+ const qsizetype offset = authorityOffset(url, schemeLength);
+ if (offset == -1)
+ return true; // no authority is a local authority.
+
+ const QString authorityAndPath = url.sliced(offset);
+ return authorityAndPath.startsWith(QLatin1String(authority_externalstorage))
+ || authorityAndPath.startsWith(QLatin1String(authority_downloads_documents))
+ || authorityAndPath.startsWith(QLatin1String(authority_media_documents));
}
+#endif
+
/*!
Returns true if \a url is a local file that can be opened with QFile.
@@ -536,7 +572,7 @@ Local file urls have either a qrc: or file: scheme.
*/
bool QQmlFile::isLocalFile(const QString &url)
{
- if (url.length() < 4 /* qrc: */)
+ if (url.size() < 4 /* qrc: */)
return false;
switch (url[0].toLatin1()) {
@@ -548,19 +584,22 @@ bool QQmlFile::isLocalFile(const QString &url)
const qsizetype fileLength = strlen(file_string);
return url.startsWith(QLatin1String(file_string, file_string + fileLength),
Qt::CaseInsensitive)
- && url.length() > fileLength
+ && url.size() > fileLength
&& url[fileLength] == QLatin1Char(':');
}
case 'q':
case 'Q':
- return hasSchemeAndNoAuthority(url, qrc_string, strlen(qrc_string));
+ return hasScheme(url, qrc_string, strlen(qrc_string))
+ && authorityOffset(url, strlen(qrc_string)) == -1;
#if defined(Q_OS_ANDROID)
case 'a':
case 'A':
- return hasSchemeAndNoAuthority(url, assets_string, strlen(assets_string));
+ return hasScheme(url, assets_string, strlen(assets_string))
+ && authorityOffset(url, strlen(assets_string)) == -1;
case 'c':
case 'C':
- return hasSchemeAndNoAuthority(url, content_string, strlen(content_string));
+ return hasScheme(url, content_string, strlen(content_string))
+ && hasLocalContentAuthority(url, strlen(content_string));
#endif
default:
break;
@@ -584,10 +623,12 @@ QString QQmlFile::urlToLocalFileOrQrc(const QUrl& url)
#if defined(Q_OS_ANDROID)
if (url.scheme().compare(QLatin1String("assets"), Qt::CaseInsensitive) == 0)
return url.authority().isEmpty() ? url.toString() : QString();
- if (url.scheme().compare(QLatin1String("content"), Qt::CaseInsensitive) == 0)
- return url.authority().isEmpty() ? url.toString() : QString();
+ if (url.scheme().compare(QLatin1String("content"), Qt::CaseInsensitive) == 0) {
+ if (hasLocalContentAuthority(url))
+ return url.toString();
+ return QString();
+ }
#endif
-
return url.toLocalFile();
}
@@ -605,7 +646,7 @@ static QString toLocalFile(const QString &url)
static bool isDoubleSlashed(const QString &url, qsizetype offset)
{
- const qsizetype urlLength = url.length();
+ const qsizetype urlLength = url.size();
if (urlLength < offset + 2)
return false;
@@ -628,7 +669,7 @@ QString QQmlFile::urlToLocalFileOrQrc(const QString& url)
if (url.startsWith(QLatin1String("qrc://"), Qt::CaseInsensitive)) {
// Exactly two slashes are bad because that's a URL authority.
// One slash is fine and >= 3 slashes are file.
- if (url.length() == 6 || url[6] != QLatin1Char('/')) {
+ if (url.size() == 6 || url[6] != QLatin1Char('/')) {
Q_ASSERT(isDoubleSlashed(url, strlen("qrc:")));
return QString();
}
@@ -638,7 +679,7 @@ QString QQmlFile::urlToLocalFileOrQrc(const QString& url)
if (url.startsWith(QLatin1String("qrc:"), Qt::CaseInsensitive)) {
Q_ASSERT(!isDoubleSlashed(url, strlen("qrc:")));
- if (url.length() > 4)
+ if (url.size() > 4)
return QLatin1Char(':') + QStringView{url}.mid(4);
return QStringLiteral(":");
}
@@ -646,8 +687,8 @@ QString QQmlFile::urlToLocalFileOrQrc(const QString& url)
#if defined(Q_OS_ANDROID)
if (url.startsWith(QLatin1String("assets:"), Qt::CaseInsensitive))
return isDoubleSlashed(url, strlen("assets:")) ? QString() : url;
- if (url.startsWith(QLatin1String("content:"), Qt::CaseInsensitive))
- return isDoubleSlashed(url, strlen("content:")) ? QString() : url;
+ if (hasScheme(url, content_string, strlen(content_string)))
+ return hasLocalContentAuthority(url, strlen(content_string)) ? url : QString();
#endif
return toLocalFile(url);
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index a7af7cedd6..e09b254f46 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -32,6 +32,8 @@
#include <algorithm>
#include <functional>
+using namespace Qt::Literals::StringLiterals;
+
QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(qmlImportTrace, QML_IMPORT_TRACE)
@@ -123,7 +125,7 @@ QString resolveLocalUrl(const QString &url, const QString &relative)
QString base = baseRef + relative;
// Remove any relative directory elements in the path
- int length = base.length();
+ int length = base.size();
int index = 0;
while ((index = base.indexOf(QLatin1String("/."), index)) != -1) {
if ((length > (index + 2)) && (base.at(index + 2) == Dot) &&
@@ -235,7 +237,7 @@ void QQmlImports::populateCache(QQmlTypeNameCache *cache) const
{
const QQmlImportNamespace &set = m_unqualifiedset;
- for (int ii = set.imports.count() - 1; ii >= 0; --ii) {
+ for (int ii = set.imports.size() - 1; ii >= 0; --ii) {
const QQmlImportInstance *import = set.imports.at(ii);
QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->version);
if (module) {
@@ -251,7 +253,7 @@ void QQmlImports::populateCache(QQmlTypeNameCache *cache) const
QQmlImportRef &typeimport = cache->m_namedImports[set.prefix];
typeimport.m_qualifier = set.prefix;
- for (int ii = set.imports.count() - 1; ii >= 0; --ii) {
+ for (int ii = set.imports.size() - 1; ii >= 0; --ii) {
const QQmlImportInstance *import = set.imports.at(ii);
QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->version);
if (module) {
@@ -283,7 +285,7 @@ void findCompositeSingletons(const QQmlImportNamespace &set, QList<QQmlImports::
{
typedef QQmlDirComponents::const_iterator ConstIterator;
- for (int ii = set.imports.count() - 1; ii >= 0; --ii) {
+ for (int ii = set.imports.size() - 1; ii >= 0; --ii) {
const QQmlImportInstance *import = set.imports.at(ii);
const QQmlDirComponents &components = import->qmlDirComponents;
@@ -373,7 +375,7 @@ QList<QQmlImports::ScriptReference> QQmlImports::resolvedScripts() const
const QQmlImportNamespace &set = m_unqualifiedset;
- for (int ii = set.imports.count() - 1; ii >= 0; --ii) {
+ for (int ii = set.imports.size() - 1; ii >= 0; --ii) {
const QQmlImportInstance *import = set.imports.at(ii);
for (const QQmlDirParser::Script &script : import->qmlDirScripts) {
@@ -387,7 +389,7 @@ QList<QQmlImports::ScriptReference> QQmlImports::resolvedScripts() const
for (QQmlImportNamespace *ns = m_qualifiedSets.first(); ns; ns = m_qualifiedSets.next(ns)) {
const QQmlImportNamespace &set = *ns;
- for (int ii = set.imports.count() - 1; ii >= 0; --ii) {
+ for (int ii = set.imports.size() - 1; ii >= 0; --ii) {
const QQmlImportInstance *import = set.imports.at(ii);
for (const QQmlDirParser::Script &script : import->qmlDirScripts) {
@@ -736,7 +738,7 @@ bool QQmlImports::resolveType(
m_typeLoader, unqualifiedtype, version_return, type_return, &m_base, errors,
registrationType, typeRecursionDetected))
return true;
- if (nameSpace->imports.count() == 1
+ if (nameSpace->imports.size() == 1
&& !nameSpace->imports.at(0)->isLibrary
&& type_return
&& nameSpace != &m_unqualifiedset) {
@@ -868,13 +870,13 @@ bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedS
});
setNeedsSorting(false);
}
- for (int i=0; i<imports.count(); ++i) {
+ for (int i=0; i<imports.size(); ++i) {
const QQmlImportInstance *import = imports.at(i);
if (import->resolveType(typeLoader, type, version_return, type_return, base,
typeRecursionDetected, registrationType, recursionRestriction, errors)) {
if (qmlCheckTypes()) {
// check for type clashes
- for (int j = i+1; j<imports.count(); ++j) {
+ for (int j = i+1; j<imports.size(); ++j) {
const QQmlImportInstance *import2 = imports.at(j);
if (import2->resolveType(typeLoader, type, version_return, nullptr, base,
nullptr, registrationType)) {
@@ -1010,9 +1012,9 @@ QString QQmlImports::resolvedUri(const QString &dir_arg, QQmlImportDatabase *dat
std::sort(paths.begin(), paths.end(), std::greater<QString>()); // Ensure subdirs preceed their parents.
QString stableRelativePath = dir;
- for (const QString &path : qAsConst(paths)) {
+ for (const QString &path : std::as_const(paths)) {
if (dir.startsWith(path)) {
- stableRelativePath = dir.mid(path.length()+1);
+ stableRelativePath = dir.mid(path.size()+1);
break;
}
}
@@ -1034,6 +1036,26 @@ QString QQmlImports::resolvedUri(const QString &dir_arg, QQmlImportDatabase *dat
return stableRelativePath;
}
+/* removes all file selector occurrences in path
+ firstPlus is the position of the initial '+' in the path
+ which we always have as we check for '+' to decide whether
+ we need to do some work at all
+*/
+static QString pathWithoutFileSelectors(QString path, // we want a copy of path
+ qsizetype firstPlus)
+{
+ do {
+ Q_ASSERT(path.at(firstPlus) == u'+');
+ const auto eos = path.size();
+ qsizetype terminatingSlashPos = firstPlus + 1;
+ while (terminatingSlashPos != eos && path.at(terminatingSlashPos) != u'/')
+ ++terminatingSlashPos;
+ path.remove(firstPlus, terminatingSlashPos - firstPlus + 1);
+ firstPlus = path.indexOf(u'+', firstPlus);
+ } while (firstPlus != -1);
+ return path;
+}
+
/*!
\internal
@@ -1080,10 +1102,42 @@ QTypeRevision QQmlImports::matchingQmldirVersion(
typedef QQmlDirComponents::const_iterator ConstIterator;
const QQmlDirComponents &components = qmldir.components();
+ QMultiHash<QString, ConstIterator> baseFileName2ConflictingComponents;
+
ConstIterator cend = components.constEnd();
for (ConstIterator cit = components.constBegin(); cit != cend; ++cit) {
for (ConstIterator cit2 = components.constBegin(); cit2 != cit; ++cit2) {
if (cit2->typeName == cit->typeName && cit2->version == cit->version) {
+ // ugly heuristic to deal with file selectors
+ const auto comp2PotentialFileSelectorPos = cit2->fileName.indexOf(u'+');
+ const bool comp2MightHaveFileSelector = comp2PotentialFileSelectorPos != -1;
+ /* If we detect conflicting paths, we check if they agree when we remove anything looking like a
+ file selector.
+ We need to create copies of the filenames, otherwise QString::replace would modify the
+ existing file-names
+ */
+ QString compFileName1 = cit->fileName;
+ QString compFileName2 = cit2->fileName;
+ if (auto fileSelectorPos1 = compFileName1.indexOf(u'+'); fileSelectorPos1 != -1) {
+ // existing entry was file selector entry, fix it up
+ // it could also be the case that _both_ are using file selectors
+ QString baseName = comp2MightHaveFileSelector ? pathWithoutFileSelectors(compFileName2,
+ comp2PotentialFileSelectorPos)
+ : compFileName2;
+ if (pathWithoutFileSelectors(compFileName1, fileSelectorPos1) == baseName) {
+ baseFileName2ConflictingComponents.insert(baseName, cit);
+ baseFileName2ConflictingComponents.insert(baseName, cit2);
+ continue;
+ }
+ // fall through to error case
+ } else if (comp2MightHaveFileSelector) {
+ // new entry contains file selector (and we now that cit did not)
+ if (pathWithoutFileSelectors(compFileName2, comp2PotentialFileSelectorPos) == compFileName1) {
+ baseFileName2ConflictingComponents.insert(compFileName1, cit2);
+ continue;
+ }
+ // fall through to error case
+ }
// This entry clashes with a predecessor
QQmlError error;
error.setDescription(QQmlImportDatabase::tr("\"%1\" version %2.%3 is defined more than once in module \"%4\"")
@@ -1097,6 +1151,14 @@ QTypeRevision QQmlImports::matchingQmldirVersion(
addVersion(cit->version);
}
+ // ensure that all components point to the actual base URL, and let the file selectors resolve them correctly during URL resolution
+ for (auto keyIt = baseFileName2ConflictingComponents.keyBegin(); keyIt != baseFileName2ConflictingComponents.keyEnd(); ++keyIt) {
+ const QString& baseFileName = *keyIt;
+ const auto conflictingComponents = baseFileName2ConflictingComponents.values(baseFileName);
+ for (ConstIterator component: conflictingComponents)
+ component->fileName = baseFileName;
+ }
+
typedef QList<QQmlDirParser::Script>::const_iterator SConstIterator;
const QQmlDirScripts &scripts = qmldir.scripts();
@@ -1496,7 +1558,7 @@ QUrl QQmlImports::urlFromLocalFileOrQrcOrUrl(const QString &file)
QUrl url(QLatin1String(file.at(0) == Colon ? "qrc" : "") + file);
// We don't support single character schemes as those conflict with windows drive letters.
- if (url.scheme().length() < 2)
+ if (url.scheme().size() < 2)
return QUrl::fromLocalFile(file);
return url;
}
@@ -1547,7 +1609,7 @@ QQmlImportDatabase::QQmlImportDatabase(QQmlEngine *e)
auto addEnvImportPath = [this](const char *var) {
if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty(var))) {
const QStringList paths = parseEnvPath(qEnvironmentVariable(var));
- for (int ii = paths.count() - 1; ii >= 0; --ii)
+ for (int ii = paths.size() - 1; ii >= 0; --ii)
addImportPath(paths.at(ii));
}
};
@@ -1562,7 +1624,7 @@ QQmlImportDatabase::QQmlImportDatabase(QQmlEngine *e)
auto addEnvPluginPath = [this](const char *var) {
if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty(var))) {
const QStringList paths = parseEnvPath(qEnvironmentVariable(var));
- for (int ii = paths.count() - 1; ii >= 0; --ii)
+ for (int ii = paths.size() - 1; ii >= 0; --ii)
addPluginPath(paths.at(ii));
}
};
@@ -1609,7 +1671,7 @@ void QQmlImportDatabase::addPluginPath(const QString& path)
QUrl url = QUrl(path);
if (url.isRelative() || url.scheme() == QLatin1String("file")
- || (url.scheme().length() == 1 && QFile::exists(path)) ) { // windows path
+ || (url.scheme().size() == 1 && QFile::exists(path)) ) { // windows path
QDir dir = QDir(path);
filePluginPath.prepend(dir.canonicalPath());
} else {
@@ -1643,7 +1705,7 @@ void QQmlImportDatabase::addImportPath(const QString& path)
cPath = QLatin1String("qrc") + path;
cPath.replace(Backslash, Slash);
} else if (url.isRelative() ||
- (url.scheme().length() == 1 && QFile::exists(path)) ) { // windows path
+ (url.scheme().size() == 1 && QFile::exists(path)) ) { // windows path
QDir dir = QDir(path);
cPath = dir.canonicalPath();
} else {
diff --git a/src/qml/qml/qqmlincubator.cpp b/src/qml/qml/qqmlincubator.cpp
index 31dc1b449f..5e6afe25c6 100644
--- a/src/qml/qml/qqmlincubator.cpp
+++ b/src/qml/qml/qqmlincubator.cpp
@@ -233,6 +233,7 @@ void QQmlIncubatorPrivate::forceCompletion(QQmlInstantiationInterrupt &i)
}
}
+
void QQmlIncubatorPrivate::incubate(QQmlInstantiationInterrupt &i)
{
if (!compilationUnit)
@@ -244,6 +245,20 @@ void QQmlIncubatorPrivate::incubate(QQmlInstantiationInterrupt &i)
// get a copy of the engine pointer as it might get reset;
QQmlEnginePrivate *enginePriv = this->enginePriv;
+ // Incubating objects takes quite a bit more stack space than our usual V4 function
+ enum { EstimatedSizeInV4Frames = 2 };
+ QV4::ExecutionEngineCallDepthRecorder<EstimatedSizeInV4Frames> callDepthRecorder(
+ compilationUnit->engine);
+ if (callDepthRecorder.hasOverflow()) {
+ QQmlError error;
+ error.setMessageType(QtCriticalMsg);
+ error.setUrl(compilationUnit->url());
+ error.setDescription(QQmlComponent::tr("Maximum call stack size exceeded."));
+ errors << error;
+ progress = QQmlIncubatorPrivate::Completed;
+ goto finishIncubate;
+ }
+
if (!vmeGuard.isOK()) {
QQmlError error;
error.setMessageType(QtInfoMsg);
diff --git a/src/qml/qml/qqmlirloader.cpp b/src/qml/qml/qqmlirloader.cpp
index 4ead4d05cb..5c322ab021 100644
--- a/src/qml/qml/qqmlirloader.cpp
+++ b/src/qml/qml/qqmlirloader.cpp
@@ -98,7 +98,7 @@ QmlIR::Object *QQmlIRLoader::loadObject(const QV4::CompiledData::Object *seriali
object->bindings->append(b);
if (b->type() == QV4::CompiledData::Binding::Type_Script) {
functionIndices.append(b->value.compiledScriptIndex);
- b->value.compiledScriptIndex = functionIndices.count() - 1;
+ b->value.compiledScriptIndex = functionIndices.size() - 1;
QmlIR::CompiledFunctionOrExpression *foe = pool->New<QmlIR::CompiledFunctionOrExpression>();
foe->nameIndex = 0;
@@ -106,9 +106,9 @@ QmlIR::Object *QQmlIRLoader::loadObject(const QV4::CompiledData::Object *seriali
QQmlJS::AST::ExpressionNode *expr;
if (b->stringIndex != quint32(0)) {
- const int start = output->code.length();
+ const int start = output->code.size();
const QString script = output->stringAt(b->stringIndex);
- const int length = script.length();
+ const int length = script.size();
output->code.append(script);
expr = new (pool) FakeExpression(start, length);
} else
@@ -118,7 +118,7 @@ QmlIR::Object *QQmlIRLoader::loadObject(const QV4::CompiledData::Object *seriali
}
}
- Q_ASSERT(object->functionsAndExpressions->count == functionIndices.count());
+ Q_ASSERT(object->functionsAndExpressions->count == functionIndices.size());
for (uint i = 0; i < serializedObject->nSignals; ++i) {
const QV4::CompiledData::Signal *serializedSignal = serializedObject->signalAt(i);
@@ -174,7 +174,7 @@ QmlIR::Object *QQmlIRLoader::loadObject(const QV4::CompiledData::Object *seriali
const QV4::CompiledData::Function *compiledFunction = unit->functionAt(*functionIdx);
functionIndices.append(*functionIdx);
- f->index = functionIndices.count() - 1;
+ f->index = functionIndices.size() - 1;
f->location = compiledFunction->location;
f->nameIndex = compiledFunction->nameIndex;
f->returnType = compiledFunction->returnType;
diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp
index 3fb1bd45cd..304c5da29a 100644
--- a/src/qml/qml/qqmljavascriptexpression.cpp
+++ b/src/qml/qml/qqmljavascriptexpression.cpp
@@ -176,7 +176,7 @@ public:
~QQmlJavaScriptExpressionCapture()
{
if (capture.errorString) {
- for (int ii = 0; ii < capture.errorString->count(); ++ii)
+ for (int ii = 0; ii < capture.errorString->size(); ++ii)
qWarning("%s", qPrintable(capture.errorString->at(ii)));
delete capture.errorString;
capture.errorString = nullptr;
diff --git a/src/qml/qml/qqmllist.h b/src/qml/qml/qqmllist.h
index 051f3d67ff..4c1455b2e2 100644
--- a/src/qml/qml/qqmllist.h
+++ b/src/qml/qml/qqmllist.h
@@ -91,7 +91,7 @@ private:
reinterpret_cast<QList<T *> *>(p->data)->append(v);
}
static qsizetype qlist_count(QQmlListProperty *p) {
- return reinterpret_cast<QList<T *> *>(p->data)->count();
+ return reinterpret_cast<QList<T *> *>(p->data)->size();
}
static T *qlist_at(QQmlListProperty *p, qsizetype idx) {
return reinterpret_cast<QList<T *> *>(p->data)->at(idx);
@@ -118,7 +118,7 @@ private:
for (qsizetype i = 0; i < length; ++i)
stash.append(i == idx ? v : list->at(list, i));
list->clear(list);
- for (T *item : qAsConst(stash))
+ for (T *item : std::as_const(stash))
list->append(list, item);
} else {
stash.reserve(length - idx - 1);
@@ -149,7 +149,7 @@ private:
for (qsizetype i = 0; i < length; ++i)
stash.append(list->at(list, i));
list->clear(list);
- for (T *item : qAsConst(stash))
+ for (T *item : std::as_const(stash))
list->append(list, item);
}
};
diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp
index cd356271a9..3ee8fee5c3 100644
--- a/src/qml/qml/qqmllocale.cpp
+++ b/src/qml/qml/qqmllocale.cpp
@@ -353,7 +353,7 @@ QV4::ReturnedValue QQmlNumberExtension::method_toLocaleString(const QV4::Functio
if (!argv[1].isString())
THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
QString fs = argv[1].toQString();
- if (fs.length())
+ if (fs.size())
format = fs.at(0).unicode();
}
int prec = 2;
@@ -415,7 +415,7 @@ ReturnedValue QQmlNumberExtension::method_fromLocaleString(const QV4::FunctionOb
}
QString ns = argv[numberIdx].toQString();
- if (!ns.length())
+ if (!ns.size())
RETURN_RESULT(QV4::Encode(Q_QNAN));
bool ok = false;
@@ -667,7 +667,9 @@ ReturnedValue QQmlLocaleData::method_get_ ## VARIABLE (const QV4::FunctionObject
LOCALE_STRING_PROPERTY(name)
LOCALE_STRING_PROPERTY(nativeLanguageName)
+#if QT_DEPRECATED_SINCE(6, 6)
QT_IGNORE_DEPRECATIONS(LOCALE_STRING_PROPERTY(nativeCountryName))
+#endif
LOCALE_STRING_PROPERTY(nativeTerritoryName)
LOCALE_STRING_PROPERTY(decimalPoint)
LOCALE_STRING_PROPERTY(groupSeparator)
@@ -714,7 +716,9 @@ QV4LocaleDataDeletable::QV4LocaleDataDeletable(QV4::ExecutionEngine *engine)
o->defineAccessorProperty(QStringLiteral("groupSeparator"), QQmlLocaleData::method_get_groupSeparator, nullptr);
o->defineAccessorProperty(QStringLiteral("decimalPoint"), QQmlLocaleData::method_get_decimalPoint, nullptr);
o->defineAccessorProperty(QStringLiteral("nativeLanguageName"), QQmlLocaleData::method_get_nativeLanguageName, nullptr);
+#if QT_DEPRECATED_SINCE(6, 6)
o->defineAccessorProperty(QStringLiteral("nativeCountryName"), QQmlLocaleData::method_get_nativeCountryName, nullptr);
+#endif
o->defineAccessorProperty(QStringLiteral("nativeTerritoryName"), QQmlLocaleData::method_get_nativeTerritoryName, nullptr);
o->defineAccessorProperty(QStringLiteral("zeroDigit"), QQmlLocaleData::method_get_zeroDigit, nullptr);
o->defineAccessorProperty(QStringLiteral("amText"), QQmlLocaleData::method_get_amText, nullptr);
@@ -866,10 +870,10 @@ ReturnedValue QQmlLocale::method_localeCompare(const QV4::FunctionObject *b, con
/*!
\qmlproperty string QtQml::Locale::name
- Holds the language and country of this locale as a
- string of the form "language_country", where
+ Holds the language and territory of this locale as a
+ string of the form "language_territory", where
language is a lowercase, two-letter ISO 639 language code,
- and country is an uppercase, two- or three-letter ISO 3166 country code.
+ and territory is an uppercase, two- or three-letter ISO 3166 territory code.
*/
/*!
@@ -1096,7 +1100,7 @@ ReturnedValue QQmlLocale::method_localeCompare(const QV4::FunctionObject *b, con
Holds a native name of the language for the locale. For example
"Schwiizertüütsch" for Swiss-German locale.
- \sa nativeCountryName
+ \sa nativeTerritoryName
*/
/*!
diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h
index 598b8c0bd1..8d9718ffb8 100644
--- a/src/qml/qml/qqmllocale_p.h
+++ b/src/qml/qml/qqmllocale_p.h
@@ -165,7 +165,9 @@ struct QQmlLocaleData : public QV4::Object
static QV4::ReturnedValue method_get_name(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
static QV4::ReturnedValue method_get_nativeLanguageName(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+#if QT_DEPRECATED_SINCE(6, 6)
static QV4::ReturnedValue method_get_nativeCountryName(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+#endif
static QV4::ReturnedValue method_get_nativeTerritoryName(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
static QV4::ReturnedValue method_get_decimalPoint(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
static QV4::ReturnedValue method_get_groupSeparator(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index e87eed27bc..10f0a6f438 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -311,6 +311,7 @@ void QQmlMetaType::clearTypeRegistrations()
data->urlToNonFileImportType.clear();
data->metaObjectToType.clear();
data->undeletableTypes.clear();
+ data->propertyCaches.clear();
}
int QQmlMetaType::registerAutoParentFunction(const QQmlPrivate::RegisterAutoParent &function)
@@ -322,7 +323,7 @@ int QQmlMetaType::registerAutoParentFunction(const QQmlPrivate::RegisterAutoPare
data->parentFunctions.append(function.function);
- return data->parentFunctions.count() - 1;
+ return data->parentFunctions.size() - 1;
}
void QQmlMetaType::unregisterAutoParentFunction(const QQmlPrivate::AutoParentFunction &function)
@@ -390,7 +391,7 @@ static bool checkRegistration(
// There can also be types that aren't even gadgets, and there can be types for namespaces.
// We cannot check those, but namespaces should be uppercase.
- int typeNameLen = typeName.length();
+ int typeNameLen = typeName.size();
for (int ii = 0; ii < typeNameLen; ++ii) {
if (!(typeName.at(ii).isLetterOrNumber() || typeName.at(ii) == u'_')) {
QString failure(QCoreApplication::translate("qmlRegisterType", "Invalid QML %1 name \"%2\""));
@@ -834,7 +835,7 @@ QQmlMetaType::RegistrationResult QQmlMetaType::registerPluginTypes(
if (!failures.isEmpty()) {
if (errors) {
- for (const QString &failure : qAsConst(failures)) {
+ for (const QString &failure : std::as_const(failures)) {
QQmlError error;
error.setDescription(failure);
errors->prepend(error);
@@ -1148,7 +1149,7 @@ QQmlType QQmlMetaType::qmlType(const QString &qualifiedName, QTypeRevision versi
return QQmlType();
QHashedStringRef module(qualifiedName.constData(), slash);
- QHashedStringRef name(qualifiedName.constData() + slash + 1, qualifiedName.length() - slash - 1);
+ QHashedStringRef name(qualifiedName.constData() + slash + 1, qualifiedName.size() - slash - 1);
return qmlType(name, module, version);
}
@@ -1406,7 +1407,7 @@ void QQmlMetaType::registerMetaObjectForType(const QMetaObject *metaobject, QQml
static bool hasActiveInlineComponents(const QQmlTypePrivate *d)
{
- for (const QQmlType &ic : qAsConst(d->objectIdToICType)) {
+ for (const QQmlType &ic : std::as_const(d->objectIdToICType)) {
const QQmlTypePrivate *icPriv = ic.priv();
if (icPriv && icPriv->count() > 1)
return true;
@@ -1471,7 +1472,7 @@ QList<QString> QQmlMetaType::qmlTypeNames()
const QQmlMetaTypeDataPtr data;
QList<QString> names;
- names.reserve(data->nameToType.count());
+ names.reserve(data->nameToType.size());
QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.cbegin();
while (it != data->nameToType.cend()) {
QQmlType t(*it);
@@ -1513,7 +1514,7 @@ QList<QQmlType> QQmlMetaType::qmlSingletonTypes()
const QQmlMetaTypeDataPtr data;
QList<QQmlType> retn;
- for (const auto t : qAsConst(data->nameToType)) {
+ for (const auto t : std::as_const(data->nameToType)) {
QQmlType type(t);
if (type.isSingleton())
retn.append(type);
@@ -1525,7 +1526,7 @@ const QQmlPrivate::CachedQmlUnit *QQmlMetaType::findCachedCompilationUnit(const
{
const QQmlMetaTypeDataPtr data;
- for (const auto lookup : qAsConst(data->lookupCachedQmlUnit)) {
+ for (const auto lookup : std::as_const(data->lookupCachedQmlUnit)) {
if (const QQmlPrivate::CachedQmlUnit *unit = lookup(uri)) {
QString error;
if (!QV4::ExecutableCompilationUnit::verifyHeader(unit->qmlData, QDateTime(), &error)) {
diff --git a/src/qml/qml/qqmlmetatypedata.cpp b/src/qml/qml/qqmlmetatypedata.cpp
index 2dd86c1c2a..ab6054349a 100644
--- a/src/qml/qml/qqmlmetatypedata.cpp
+++ b/src/qml/qml/qqmlmetatypedata.cpp
@@ -28,7 +28,7 @@ QQmlMetaTypeData::~QQmlMetaTypeData()
// This expects a "fresh" QQmlTypePrivate and adopts its reference.
void QQmlMetaTypeData::registerType(QQmlTypePrivate *priv)
{
- for (int i = 0; i < types.count(); ++i) {
+ for (int i = 0; i < types.size(); ++i) {
if (!types.at(i).isValid()) {
types[i] = QQmlType(priv);
priv->index = i;
@@ -37,7 +37,7 @@ void QQmlMetaTypeData::registerType(QQmlTypePrivate *priv)
}
}
types.append(QQmlType(priv));
- priv->index = types.count() - 1;
+ priv->index = types.size() - 1;
priv->release();
}
@@ -86,7 +86,7 @@ bool QQmlMetaTypeData::registerModuleTypes(const QString &uri)
QQmlPropertyCache::ConstPtr QQmlMetaTypeData::propertyCacheForVersion(
int index, QTypeRevision version) const
{
- return (index < typePropertyCaches.length())
+ return (index < typePropertyCaches.size())
? typePropertyCaches.at(index).value(version)
: QQmlPropertyCache::ConstPtr();
}
@@ -94,14 +94,14 @@ QQmlPropertyCache::ConstPtr QQmlMetaTypeData::propertyCacheForVersion(
void QQmlMetaTypeData::setPropertyCacheForVersion(int index, QTypeRevision version,
const QQmlPropertyCache::ConstPtr &cache)
{
- if (index >= typePropertyCaches.length())
+ if (index >= typePropertyCaches.size())
typePropertyCaches.resize(index + 1);
typePropertyCaches[index][version] = cache;
}
void QQmlMetaTypeData::clearPropertyCachesForVersion(int index)
{
- if (index < typePropertyCaches.length())
+ if (index < typePropertyCaches.size())
typePropertyCaches[index].clear();
}
@@ -167,13 +167,13 @@ QQmlPropertyCache::ConstPtr QQmlMetaTypeData::propertyCache(
QQmlPropertyCache::ConstPtr raw = propertyCache(type.metaObject(), combinedVersion);
QQmlPropertyCache::Ptr copied;
- for (int ii = 0; ii < types.count(); ++ii) {
+ for (int ii = 0; ii < types.size(); ++ii) {
const QQmlType &currentType = types.at(ii);
if (!currentType.isValid())
continue;
QTypeRevision rev = currentType.metaObjectRevision();
- int moIndex = types.count() - 1 - ii;
+ int moIndex = types.size() - 1 - ii;
if (raw->allowedRevision(moIndex) != rev) {
if (copied.isNull()) {
diff --git a/src/qml/qml/qqmlnotifier.cpp b/src/qml/qml/qqmlnotifier.cpp
index e36be3840e..e7b8799f82 100644
--- a/src/qml/qml/qqmlnotifier.cpp
+++ b/src/qml/qml/qqmlnotifier.cpp
@@ -89,10 +89,10 @@ void QQmlNotifierEndpoint::connect(QObject *source, int sourceSignal, QQmlEngine
QString sourceName;
QDebug(&sourceName) << source;
- sourceName = sourceName.left(sourceName.length() - 1);
+ sourceName = sourceName.left(sourceName.size() - 1);
QString engineName;
QDebug(&engineName).nospace() << engine;
- engineName = engineName.left(engineName.length() - 1);
+ engineName = engineName.left(engineName.size() - 1);
qFatal("QQmlEngine: Illegal attempt to connect to %s that is in"
" a different thread than the QML engine %s.", qPrintable(sourceName),
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 05951edfbc..64d1f79044 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -1408,16 +1408,24 @@ bool QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interrupt)
void *argv[] = { &bindable };
// allow interception
target->metaObject()->metacall(target, QMetaObject::BindableProperty, index, argv);
- bindable.setBinding(qmlBinding);
+ const bool success = bindable.setBinding(qmlBinding);
+
+ // Only pop_front after setting the binding as the bindings are refcounted.
sharedState->allQPropertyBindings.pop_front();
- if (auto priv = QPropertyBindingPrivate::get(qmlBinding); priv->hasCustomVTable()) {
- auto qmlBindingPriv = static_cast<QQmlPropertyBinding *>(priv);
- auto jsExpression = qmlBindingPriv->jsExpression();
- const bool canRemove = !qmlBinding.error().hasError() && !qmlBindingPriv->hasDependencies()
- && !jsExpression->hasUnresolvedNames();
- if (canRemove)
- bindable.takeBinding();
+
+ // If the binding was actually not set, it's deleted now.
+ if (success) {
+ if (auto priv = QPropertyBindingPrivate::get(qmlBinding); priv->hasCustomVTable()) {
+ auto qmlBindingPriv = static_cast<QQmlPropertyBinding *>(priv);
+ auto jsExpression = qmlBindingPriv->jsExpression();
+ const bool canRemove = !qmlBinding.error().hasError()
+ && !qmlBindingPriv->hasDependencies()
+ && !jsExpression->hasUnresolvedNames();
+ if (canRemove)
+ bindable.takeBinding();
+ }
}
+
if (watcher.hasRecursed() || interrupt.shouldInterrupt())
return false;
}
diff --git a/src/qml/qml/qqmlopenmetaobject.cpp b/src/qml/qml/qqmlopenmetaobject.cpp
index b6ea0ee2e6..cf51286677 100644
--- a/src/qml/qml/qqmlopenmetaobject.cpp
+++ b/src/qml/qml/qqmlopenmetaobject.cpp
@@ -59,19 +59,19 @@ int QQmlOpenMetaObjectType::signalOffset() const
int QQmlOpenMetaObjectType::propertyCount() const
{
- return d->names.count();
+ return d->names.size();
}
QByteArray QQmlOpenMetaObjectType::propertyName(int idx) const
{
- Q_ASSERT(idx >= 0 && idx < d->names.count());
+ Q_ASSERT(idx >= 0 && idx < d->names.size());
return d->mob.property(idx).name();
}
void QQmlOpenMetaObjectType::createProperties(const QVector<QByteArray> &names)
{
- for (int i = 0; i < names.count(); ++i) {
+ for (int i = 0; i < names.size(); ++i) {
const QByteArray &name = names.at(i);
const int id = d->mob.propertyCount();
d->mob.addSignal("__" + QByteArray::number(id) + "()");
@@ -114,7 +114,7 @@ int QQmlOpenMetaObjectType::createProperty(const QByteArray &name)
void QQmlOpenMetaObjectType::propertyCreated(int id, QMetaPropertyBuilder &builder)
{
- if (d->referers.count())
+ if (d->referers.size())
(*d->referers.begin())->propertyCreated(id, builder);
}
@@ -163,13 +163,13 @@ public:
};
inline void setPropertyValue(int idx, const QVariant &value) {
- if (data.count() <= idx)
+ if (data.size() <= idx)
data.resize(idx + 1);
data[idx].setValue(value);
}
inline Property &propertyRef(int idx) {
- if (data.count() <= idx)
+ if (data.size() <= idx)
data.resize(idx + 1);
Property &prop = data[idx];
if (!prop.valueSet)
@@ -188,7 +188,7 @@ public:
}
inline bool hasProperty(int idx) const {
- if (idx >= data.count())
+ if (idx >= data.size())
return false;
return data[idx].valueSet;
}
@@ -270,7 +270,7 @@ int QQmlOpenMetaObject::metaCall(QObject *o, QMetaObject::Call c, int id, void *
propertyRead(propId);
*reinterpret_cast<QVariant *>(a[0]) = d->propertyValue(propId);
} else if (c == QMetaObject::WriteProperty) {
- if (propId >= d->data.count() || d->data.at(propId).value() != *reinterpret_cast<QVariant *>(a[0])) {
+ if (propId >= d->data.size() || d->data.at(propId).value() != *reinterpret_cast<QVariant *>(a[0])) {
propertyWrite(propId);
d->setPropertyValue(propId, propertyWriteValue(propId, *reinterpret_cast<QVariant *>(a[0])));
propertyWritten(propId);
@@ -375,7 +375,7 @@ void QQmlOpenMetaObject::setValues(const QHash<QByteArray, QVariant> &values, bo
d->type->createProperties(missingProperties);
d->dropPropertyCache();
- for (const QByteArray &name : qAsConst(missingProperties))
+ for (const QByteArray &name : std::as_const(missingProperties))
checkedSetValue(names[name], values[name], force);
}
@@ -461,12 +461,12 @@ QVariant QQmlOpenMetaObject::initialValue(int)
int QQmlOpenMetaObject::count() const
{
- return d->type->d->names.count();
+ return d->type->d->names.size();
}
QByteArray QQmlOpenMetaObject::name(int idx) const
{
- Q_ASSERT(idx >= 0 && idx < d->type->d->names.count());
+ Q_ASSERT(idx >= 0 && idx < d->type->d->names.size());
return d->type->d->mob.property(idx).name();
}
diff --git a/src/qml/qml/qqmlpluginimporter.cpp b/src/qml/qml/qqmlpluginimporter.cpp
index 62b3a4b4a4..0b14d1f561 100644
--- a/src/qml/qml/qqmlpluginimporter.cpp
+++ b/src/qml/qml/qqmlpluginimporter.cpp
@@ -91,7 +91,7 @@ static QStringList versionUriList(const QString &uri, QTypeRevision version)
{
QStringList result;
for (int mode = QQmlImports::FullyVersioned; mode <= QQmlImports::Unversioned; ++mode) {
- int index = uri.length();
+ int index = uri.size();
do {
QString versionUri = uri;
versionUri.insert(index, QQmlImports::versionString(
@@ -129,7 +129,7 @@ static bool unloadPlugin(const std::pair<const QString, QmlPlugin> &plugin)
void qmlClearEnginePlugins()
{
PluginMapPtr plugins(qmlPluginsById());
- for (const auto &plugin : qAsConst(*plugins))
+ for (const auto &plugin : std::as_const(*plugins))
unloadPlugin(plugin);
plugins->clear();
}
@@ -395,7 +395,7 @@ QString QQmlPluginImporter::resolvePlugin(const QString &qmldirPluginPath, const
if (!qmldirPluginPathIsRelative)
searchPaths.prepend(qmldirPluginPath);
- for (const QString &pluginPath : qAsConst(searchPaths)) {
+ for (const QString &pluginPath : std::as_const(searchPaths)) {
QString resolvedBasePath;
if (pluginPath == QLatin1String(".")) {
if (qmldirPluginPathIsRelative && !qmldirPluginPath.isEmpty()
@@ -501,7 +501,7 @@ bool QQmlPluginImporter::populatePluginDataVector(QVector<StaticPluginData> &res
QTypeRevision QQmlPluginImporter::importPlugins() {
const auto qmldirPlugins = qmldir->plugins();
- const int qmldirPluginCount = qmldirPlugins.count();
+ const int qmldirPluginCount = qmldirPlugins.size();
QTypeRevision importVersion = version;
// If the path contains a version marker or if we have more than one plugin,
@@ -550,7 +550,7 @@ QTypeRevision QQmlPluginImporter::importPlugins() {
return QTypeRevision();
for (const QString &versionUri : versionUris) {
- for (const StaticPluginData &pair : qAsConst(pluginPairs)) {
+ for (const StaticPluginData &pair : std::as_const(pluginPairs)) {
for (const QJsonValueConstRef metaTagUri : pair.uriList) {
if (versionUri == metaTagUri.toString()) {
staticPluginsFound++;
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index f2b4cc85ed..4cf57a9ae9 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -32,6 +32,7 @@
#include <cmath>
#include <QtQml/QQmlPropertyMap>
#include <QtCore/private/qproperty_p.h>
+#include <QtCore/qsequentialiterable.h>
Q_DECLARE_METATYPE(QList<int>)
Q_DECLARE_METATYPE(QList<qreal>)
@@ -248,7 +249,7 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name,
if (path.isEmpty()) return;
// Everything up to the last property must be an "object type" property
- for (int ii = 0; ii < path.count() - 1; ++ii) {
+ for (int ii = 0; ii < path.size() - 1; ++ii) {
const QStringView &pathName = path.at(ii);
// Types must begin with an uppercase letter (see checkRegistration()
@@ -264,7 +265,7 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name,
currentObject = qmlAttachedPropertiesObject(currentObject, func);
if (!currentObject) return; // Something is broken with the attachable type
} else if (r.importNamespace) {
- if (++ii == path.count())
+ if (++ii == path.size())
return; // No type following the namespace
// TODO: Do we really _not_ want to query the namespaced types here?
@@ -320,7 +321,7 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name,
return; // Not an object property
}
- if (ii == (path.count() - 2) && QQmlMetaType::isValueType(property->propType())) {
+ if (ii == (path.size() - 2) && QQmlMetaType::isValueType(property->propType())) {
// We're now at a value type property
const QMetaObject *valueTypeMetaObject = QQmlMetaType::metaObjectForValueType(property->propType());
if (!valueTypeMetaObject) return; // Not a value type
@@ -374,7 +375,7 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name,
auto findChangeSignal = [&](QStringView signalName) {
const QString changed = QStringLiteral("Changed");
if (signalName.endsWith(changed)) {
- const QStringView propName = signalName.first(signalName.length() - changed.length());
+ const QStringView propName = signalName.first(signalName.size() - changed.size());
const QQmlPropertyData *d = ddata->propertyCache->property(propName, currentObject, context);
while (d && d->isFunction())
d = ddata->propertyCache->overrideData(d);
@@ -392,7 +393,7 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name,
if (QmlIR::IRBuilder::isSignalPropertyName(terminalString)) {
QString signalName = terminalString.mid(2);
int firstNon_;
- int length = signalName.length();
+ int length = signalName.size();
for (firstNon_ = 0; firstNon_ < length; ++firstNon_)
if (signalName.at(firstNon_) != u'_')
break;
@@ -753,7 +754,7 @@ QString QQmlProperty::name() const
} else if (type() & SignalProperty) {
// ### Qt7: Return the original signal name here. Do not prepend "on"
QString name = QStringLiteral("on") + d->core.name(d->object);
- for (int i = 2, end = name.length(); i != end; ++i) {
+ for (int i = 2, end = name.size(); i != end; ++i) {
const QChar c = name.at(i);
if (c != u'_') {
name[i] = c.toUpper();
@@ -1451,7 +1452,7 @@ bool QQmlPropertyPrivate::write(
} else if (variantMetaType == QMetaType::fromType<QList<QObject *>>()) {
const QList<QObject *> &list = qvariant_cast<QList<QObject *> >(value);
- for (qsizetype ii = 0; ii < list.count(); ++ii) {
+ for (qsizetype ii = 0; ii < list.size(); ++ii) {
QObject *o = list.at(ii);
if (o && !QQmlMetaObject::canConvert(o, valueMetaObject))
o = nullptr;
@@ -1505,40 +1506,46 @@ bool QQmlPropertyPrivate::write(
}
if (!ok) {
// the only other options are that they are assigning a single value
- // to a sequence type property (eg, an int to a QList<int> property).
- // or that we encountered an interface type
+ // or a QVariantList to a sequence type property (eg, an int to a
+ // QList<int> property) or that we encountered an interface type.
// Note that we've already handled single-value assignment to QList<QUrl> properties.
- if (variantMetaType == QMetaType::fromType<int>()
- && propertyMetaType == QMetaType::fromType<QList<int>>()) {
- QList<int> list;
- list << value.toInt();
- v = QVariant::fromValue<QList<int> >(list);
- ok = true;
- } else if ((variantMetaType == QMetaType::fromType<double>()
- || variantMetaType == QMetaType::fromType<int>())
- && (propertyMetaType == QMetaType::fromType<QList<qreal>>())) {
- QList<qreal> list;
- list << value.toReal();
- v = QVariant::fromValue<QList<qreal> >(list);
- ok = true;
- } else if (variantMetaType == QMetaType::fromType<bool>()
- && propertyMetaType == QMetaType::fromType<QList<bool>>()) {
- QList<bool> list;
- list << value.toBool();
- v = QVariant::fromValue<QList<bool> >(list);
- ok = true;
- } else if (variantMetaType == QMetaType::fromType<QString>()
- && propertyMetaType == QMetaType::fromType<QList<QString>>()) {
- QList<QString> list;
- list << value.toString();
- v = QVariant::fromValue<QList<QString> >(list);
- ok = true;
- } else if (variantMetaType == QMetaType::fromType<QString>()
- && propertyMetaType == QMetaType::fromType<QStringList>()) {
- QStringList list;
- list << value.toString();
- v = QVariant::fromValue<QStringList>(list);
- ok = true;
+ QSequentialIterable iterable;
+ v = QVariant(propertyMetaType);
+ if (QMetaType::view(
+ propertyMetaType, v.data(),
+ QMetaType::fromType<QSequentialIterable>(),
+ &iterable)) {
+ const QMetaSequence metaContainer = iterable.metaContainer();
+ if (metaContainer.canAddValueAtEnd()) {
+ const QMetaType elementMetaType = iterable.valueMetaType();
+ void *container = iterable.mutableIterable();
+ if (variantMetaType == elementMetaType) {
+ metaContainer.addValueAtEnd(container, value.constData());
+ ok = true;
+ } else if (variantMetaType == QMetaType::fromType<QVariantList>()) {
+ const QVariantList list = value.value<QVariantList>();
+ for (const QVariant &valueElement : list) {
+ if (valueElement.metaType() == elementMetaType) {
+ metaContainer.addValueAtEnd(
+ container, valueElement.constData());
+ } else {
+ QVariant converted(elementMetaType);
+ QMetaType::convert(
+ valueElement.metaType(), valueElement.constData(),
+ elementMetaType, converted.data());
+ metaContainer.addValueAtEnd(
+ container, converted.constData());
+ }
+ }
+ ok = true;
+ } else {
+ QVariant converted = value;
+ if (converted.convert(elementMetaType)) {
+ metaContainer.addValueAtEnd(container, converted.constData());
+ ok = true;
+ }
+ }
+ }
}
}
@@ -1788,7 +1795,7 @@ QMetaMethod QQmlPropertyPrivate::findSignalByName(const QMetaObject *mo, const Q
// If no signal is found, but the signal is of the form "onBlahChanged",
// return the notify signal for the property "Blah"
if (name.endsWith("Changed")) {
- QByteArray propName = name.mid(0, name.length() - 7);
+ QByteArray propName = name.mid(0, name.size() - 7);
int propIdx = mo->indexOfProperty(propName.constData());
if (propIdx >= 0) {
QMetaProperty prop = mo->property(propIdx);
diff --git a/src/qml/qml/qqmlproperty.h b/src/qml/qml/qqmlproperty.h
index 4d4e1d0ebf..0878034bab 100644
--- a/src/qml/qml/qqmlproperty.h
+++ b/src/qml/qml/qqmlproperty.h
@@ -56,7 +56,7 @@ public:
QQmlProperty &operator=(const QQmlProperty &);
QQmlProperty(QQmlProperty &&other) noexcept : d(std::exchange(other.d, nullptr)) {}
- QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QQmlProperty);
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QQmlProperty)
void swap(QQmlProperty &other) noexcept { qt_ptr_swap(d, other.d); }
bool operator==(const QQmlProperty &) const;
diff --git a/src/qml/qml/qqmlpropertybinding.cpp b/src/qml/qml/qqmlpropertybinding.cpp
index d55f1021f2..24fd48ffae 100644
--- a/src/qml/qml/qqmlpropertybinding.cpp
+++ b/src/qml/qml/qqmlpropertybinding.cpp
@@ -131,7 +131,8 @@ QUntypedPropertyBinding QQmlPropertyBinding::createFromBoundFunction(const QQmlP
void QQmlPropertyBindingJS::expressionChanged()
{
- if (!asBinding()->propertyDataPtr)
+ auto binding = asBinding();
+ if (!binding->propertyDataPtr)
return;
const auto currentTag = m_error.tag();
if (currentTag == InEvaluationLoop) {
@@ -151,8 +152,9 @@ void QQmlPropertyBindingJS::expressionChanged()
return;
}
m_error.setTag(InEvaluationLoop);
- asBinding()->evaluateRecursive();
- asBinding()->notifyRecursive();
+ PendingBindingObserverList bindingObservers;
+ binding->evaluateRecursive(bindingObservers);
+ binding->notifyNonRecursive(bindingObservers);
m_error.setTag(NoTag);
}
diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp
index c61254ae56..cd6ca93356 100644
--- a/src/qml/qml/qqmlpropertycache.cpp
+++ b/src/qml/qml/qqmlpropertycache.cpp
@@ -15,8 +15,8 @@
#include <QtCore/qdebug.h>
#include <QtCore/QCryptographicHash>
+#include <QtCore/private/qtools_p.h>
-#include <ctype.h> // for toupper
#include <limits.h>
#include <algorithm>
@@ -166,9 +166,9 @@ QQmlPropertyCache::Ptr QQmlPropertyCache::copy(const QQmlMetaObjectPointer &mo,
QQmlPropertyCache::Ptr cache = QQmlPropertyCache::Ptr(
new QQmlPropertyCache(mo), QQmlPropertyCache::Ptr::Adopt);
cache->_parent.reset(this);
- cache->propertyIndexCacheStart = propertyIndexCache.count() + propertyIndexCacheStart;
- cache->methodIndexCacheStart = methodIndexCache.count() + methodIndexCacheStart;
- cache->signalHandlerIndexCacheStart = signalHandlerIndexCache.count() + signalHandlerIndexCacheStart;
+ cache->propertyIndexCacheStart = propertyIndexCache.size() + propertyIndexCacheStart;
+ cache->methodIndexCacheStart = methodIndexCache.size() + methodIndexCacheStart;
+ cache->signalHandlerIndexCacheStart = signalHandlerIndexCache.size() + signalHandlerIndexCacheStart;
cache->stringCache.linkAndReserve(stringCache, reserve);
cache->allowedRevisionCache = allowedRevisionCache;
cache->_defaultPropertyName = _defaultPropertyName;
@@ -214,7 +214,7 @@ void QQmlPropertyCache::appendProperty(const QString &name, QQmlPropertyData::Fl
if (overrideResult == InvalidOverride)
return;
- int index = propertyIndexCache.count();
+ int index = propertyIndexCache.size();
propertyIndexCache.append(data);
setNamedProperty(name, index + propertyOffset(), propertyIndexCache.data() + index,
@@ -235,7 +235,7 @@ void QQmlPropertyCache::appendSignal(const QString &name, QQmlPropertyData::Flag
handler.m_flags.setIsSignalHandler(true);
if (types) {
- const auto argumentCount = names.length();
+ const auto argumentCount = names.size();
QQmlPropertyCacheMethodArguments *args = createArgumentsObject(argumentCount, names);
new (args->types) QMetaType; // Invalid return type
::memcpy(args->types + 1, types, argumentCount * sizeof(QMetaType));
@@ -246,10 +246,10 @@ void QQmlPropertyCache::appendSignal(const QString &name, QQmlPropertyData::Flag
if (overrideResult == InvalidOverride)
return;
- int methodIndex = methodIndexCache.count();
+ int methodIndex = methodIndexCache.size();
methodIndexCache.append(data);
- int signalHandlerIndex = signalHandlerIndexCache.count();
+ int signalHandlerIndex = signalHandlerIndexCache.size();
signalHandlerIndexCache.append(handler);
QString handlerName = QLatin1String("on") + name;
@@ -267,7 +267,7 @@ void QQmlPropertyCache::appendMethod(const QString &name, QQmlPropertyData::Flag
const QList<QByteArray> &names,
const QVector<QMetaType> &parameterTypes)
{
- int argumentCount = names.count();
+ int argumentCount = names.size();
QQmlPropertyData data;
data.setPropType(returnType);
@@ -283,7 +283,7 @@ void QQmlPropertyCache::appendMethod(const QString &name, QQmlPropertyData::Flag
new (args->types + ii + 1) QMetaType(parameterTypes.at(ii));
data.setArguments(args);
- int methodIndex = methodIndexCache.count();
+ int methodIndex = methodIndexCache.size();
methodIndexCache.append(data);
setNamedProperty(name, methodIndex + methodOffset(), methodIndexCache.data() + methodIndex,
@@ -435,8 +435,8 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject,
data->load(m);
- Q_ASSERT((allowedRevisionCache.count() - 1) < Q_INT16_MAX);
- data->setMetaObjectOffset(allowedRevisionCache.count() - 1);
+ Q_ASSERT((allowedRevisionCache.size() - 1) < Q_INT16_MAX);
+ data->setMetaObjectOffset(allowedRevisionCache.size() - 1);
if (data->isSignal()) {
sigdata = &signalHandlerIndexCache[signalHandlerIndex - signalHandlerIndexCacheStart];
@@ -473,7 +473,7 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject,
QVarLengthArray<char, 128> str(length+3);
str[0] = 'o';
str[1] = 'n';
- str[2] = toupper(rawName[0]);
+ str[2] = QtMiscUtils::toAsciiUpper(rawName[0]);
if (length > 1)
memcpy(&str[3], &rawName[1], length - 1);
str[length + 2] = '\0';
@@ -516,8 +516,8 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject,
data->load(p);
data->setTypeVersion(typeVersion);
- Q_ASSERT((allowedRevisionCache.count() - 1) < Q_INT16_MAX);
- data->setMetaObjectOffset(allowedRevisionCache.count() - 1);
+ Q_ASSERT((allowedRevisionCache.size() - 1) < Q_INT16_MAX);
+ data->setMetaObjectOffset(allowedRevisionCache.size() - 1);
QQmlPropertyData *old = nullptr;
@@ -591,9 +591,9 @@ void QQmlPropertyCache::invalidate(const QMetaObject *metaObject)
int reserve = pc + mc + sc;
if (parent()) {
- propertyIndexCacheStart = parent()->propertyIndexCache.count() + parent()->propertyIndexCacheStart;
- methodIndexCacheStart = parent()->methodIndexCache.count() + parent()->methodIndexCacheStart;
- signalHandlerIndexCacheStart = parent()->signalHandlerIndexCache.count() + parent()->signalHandlerIndexCacheStart;
+ propertyIndexCacheStart = parent()->propertyIndexCache.size() + parent()->propertyIndexCacheStart;
+ methodIndexCacheStart = parent()->methodIndexCache.size() + parent()->methodIndexCacheStart;
+ signalHandlerIndexCacheStart = parent()->signalHandlerIndexCache.size() + parent()->signalHandlerIndexCacheStart;
stringCache.linkAndReserve(parent()->stringCache, reserve);
append(metaObject, QTypeRevision());
} else {
@@ -743,7 +743,7 @@ QString QQmlPropertyCache::signalParameterStringForJS(QV4::ExecutionEngine *engi
const QSet<QString> &illegalNames = engine->illegalNames();
QString parameters;
- for (int i = 0; i < parameterNameList.count(); ++i) {
+ for (int i = 0; i < parameterNameList.size(); ++i) {
if (i > 0)
parameters += QLatin1Char(',');
const QByteArray &param = parameterNameList.at(i);
@@ -976,13 +976,13 @@ void QQmlPropertyCache::toMetaObjectBuilder(QMetaObjectBuilder &builder) const
for (StringCache::ConstIterator iter = stringCache.begin(), cend = stringCache.end(); iter != cend; ++iter)
Insert::in(this, properties, methods, iter, iter.value().second);
- Q_ASSERT(properties.count() == propertyIndexCache.count());
- Q_ASSERT(methods.count() == methodIndexCache.count());
+ Q_ASSERT(properties.size() == propertyIndexCache.size());
+ Q_ASSERT(methods.size() == methodIndexCache.size());
std::sort(properties.begin(), properties.end(), Sort::lt);
std::sort(methods.begin(), methods.end(), Sort::lt);
- for (int ii = 0; ii < properties.count(); ++ii) {
+ for (int ii = 0; ii < properties.size(); ++ii) {
const QQmlPropertyData *data = properties.at(ii).second;
int notifierId = -1;
@@ -998,9 +998,10 @@ void QQmlPropertyCache::toMetaObjectBuilder(QMetaObjectBuilder &builder) const
property.setWritable(data->isWritable());
property.setResettable(data->isResettable());
property.setBindable(data->isBindable());
+ property.setAlias(data->isAlias());
}
- for (int ii = 0; ii < methods.count(); ++ii) {
+ for (int ii = 0; ii < methods.size(); ++ii) {
const QQmlPropertyData *data = methods.at(ii).second;
QByteArray returnType;
@@ -1014,7 +1015,7 @@ void QQmlPropertyCache::toMetaObjectBuilder(QMetaObjectBuilder &builder) const
QQmlPropertyCacheMethodArguments *arguments = nullptr;
if (data->hasArguments()) {
arguments = data->arguments();
- for (int ii = 0, end = arguments->names ? arguments->names->length() : 0;
+ for (int ii = 0, end = arguments->names ? arguments->names->size() : 0;
ii < end; ++ii) {
if (ii != 0)
signature.append(',');
@@ -1039,11 +1040,11 @@ void QQmlPropertyCache::toMetaObjectBuilder(QMetaObjectBuilder &builder) const
method.setReturnType(returnType);
}
- for (int ii = 0; ii < enumCache.count(); ++ii) {
+ for (int ii = 0; ii < enumCache.size(); ++ii) {
const QQmlEnumData &enumData = enumCache.at(ii);
QMetaEnumBuilder enumeration = builder.addEnumerator(enumData.name.toUtf8());
enumeration.setIsScoped(true);
- for (int jj = 0; jj < enumData.values.count(); ++jj) {
+ for (int jj = 0; jj < enumData.values.size(); ++jj) {
const QQmlEnumValue &value = enumData.values.at(jj);
enumeration.addKey(value.namedValue.toUtf8(), value.value);
}
diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h
index 681945d5f8..1ba23a15e3 100644
--- a/src/qml/qml/qqmlpropertycache_p.h
+++ b/src/qml/qml/qqmlpropertycache_p.h
@@ -343,7 +343,7 @@ inline const QQmlPropertyData *QQmlPropertyCache::property(int index) const
inline const QQmlPropertyData *QQmlPropertyCache::method(int index) const
{
- if (index < 0 || index >= (methodIndexCacheStart + methodIndexCache.count()))
+ if (index < 0 || index >= (methodIndexCacheStart + methodIndexCache.size()))
return nullptr;
if (index < methodIndexCacheStart)
@@ -358,7 +358,7 @@ inline const QQmlPropertyData *QQmlPropertyCache::method(int index) const
*/
inline const QQmlPropertyData *QQmlPropertyCache::signal(int index) const
{
- if (index < 0 || index >= (signalHandlerIndexCacheStart + signalHandlerIndexCache.count()))
+ if (index < 0 || index >= (signalHandlerIndexCacheStart + signalHandlerIndexCache.size()))
return nullptr;
if (index < signalHandlerIndexCacheStart)
@@ -371,7 +371,7 @@ inline const QQmlPropertyData *QQmlPropertyCache::signal(int index) const
inline QQmlEnumData *QQmlPropertyCache::qmlEnum(int index) const
{
- if (index < 0 || index >= enumCache.count())
+ if (index < 0 || index >= enumCache.size())
return nullptr;
return const_cast<QQmlEnumData *>(&enumCache.at(index));
@@ -379,7 +379,7 @@ inline QQmlEnumData *QQmlPropertyCache::qmlEnum(int index) const
inline int QQmlPropertyCache::methodIndexToSignalIndex(int index) const
{
- if (index < 0 || index >= (methodIndexCacheStart + methodIndexCache.count()))
+ if (index < 0 || index >= (methodIndexCacheStart + methodIndexCache.size()))
return index;
if (index < methodIndexCacheStart)
@@ -419,7 +419,7 @@ bool QQmlPropertyCache::isAllowedInRevision(const QQmlPropertyData *data) const
return true;
Q_ASSERT(offset >= 0);
- Q_ASSERT(offset < allowedRevisionCache.length());
+ Q_ASSERT(offset < allowedRevisionCache.size());
const QTypeRevision allowed = allowedRevisionCache[offset];
if (requested.hasMajorVersion()) {
@@ -434,7 +434,7 @@ bool QQmlPropertyCache::isAllowedInRevision(const QQmlPropertyData *data) const
int QQmlPropertyCache::propertyCount() const
{
- return propertyIndexCacheStart + propertyIndexCache.count();
+ return propertyIndexCacheStart + propertyIndexCache.size();
}
int QQmlPropertyCache::propertyOffset() const
@@ -444,7 +444,7 @@ int QQmlPropertyCache::propertyOffset() const
int QQmlPropertyCache::methodCount() const
{
- return methodIndexCacheStart + methodIndexCache.count();
+ return methodIndexCacheStart + methodIndexCache.size();
}
int QQmlPropertyCache::methodOffset() const
@@ -454,7 +454,7 @@ int QQmlPropertyCache::methodOffset() const
int QQmlPropertyCache::signalCount() const
{
- return signalHandlerIndexCacheStart + signalHandlerIndexCache.count();
+ return signalHandlerIndexCacheStart + signalHandlerIndexCache.size();
}
int QQmlPropertyCache::signalOffset() const
@@ -464,7 +464,7 @@ int QQmlPropertyCache::signalOffset() const
int QQmlPropertyCache::qmlEnumCount() const
{
- return enumCache.count();
+ return enumCache.size();
}
bool QQmlPropertyCache::callJSFactoryMethod(QObject *object, void **args) const
diff --git a/src/qml/qml/qqmlpropertycachecreator.cpp b/src/qml/qml/qqmlpropertycachecreator.cpp
index c6e628e02f..4bc903c22e 100644
--- a/src/qml/qml/qqmlpropertycachecreator.cpp
+++ b/src/qml/qml/qqmlpropertycachecreator.cpp
@@ -58,7 +58,7 @@ QByteArray QQmlPropertyCacheCreatorBase::createClassNameTypeByUrl(const QUrl &ur
if (lastSlash <= -1)
return QByteArray();
// ### this might not be correct for .ui.qml files
- const QStringView nameBase = QStringView{path}.mid(lastSlash + 1, path.length() - lastSlash - 5);
+ const QStringView nameBase = QStringView{path}.mid(lastSlash + 1, path.size() - lastSlash - 5);
// Not a reusable type if it doesn't start with a upper case letter.
if (nameBase.isEmpty() || !nameBase.at(0).isUpper())
return QByteArray();
@@ -94,8 +94,10 @@ bool QQmlBindingInstantiationContext::resolveInstantiatingProperty()
return true;
}
+ if (!referencingObjectPropertyCache)
+ return false;
+
Q_ASSERT(referencingObjectIndex >= 0);
- Q_ASSERT(referencingObjectPropertyCache);
Q_ASSERT(instantiatingBinding->propertyNameIndex != 0);
bool notInRevision = false;
diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h
index 6d0e5925a8..1901688174 100644
--- a/src/qml/qml/qqmlpropertycachecreator_p.h
+++ b/src/qml/qml/qqmlpropertycachecreator_p.h
@@ -720,8 +720,15 @@ inline QMetaType QQmlPropertyCacheCreator<ObjectContainer>::metaTypeForParameter
QQmlType::AnyRegistrationType, &selfReference))
return QMetaType();
- if (!qmltype.isComposite())
- return qmltype.typeId();
+ if (!qmltype.isComposite()) {
+ const QMetaType typeId = qmltype.typeId();
+ if (!typeId.isValid() && qmltype.isInlineComponentType()) {
+ const int objectId = qmltype.inlineComponentId();
+ return objectContainer->typeIdsForComponent(objectId).id;
+ } else {
+ return typeId;
+ }
+ }
if (selfReference)
return objectContainer->typeIdsForComponent().id;
@@ -823,7 +830,7 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasPropertie
do {
QVector<int> pendingObjects;
- for (int objectIndex: qAsConst(objectsWithAliases)) {
+ for (int objectIndex: std::as_const(objectsWithAliases)) {
const CompiledObject &object = *objectContainer->objectAt(objectIndex);
if (allAliasTargetsExist(object)) {
@@ -919,10 +926,16 @@ inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataFor
}
const auto referencedType = typeRef->type();
- if (referencedType.isValid())
+ if (referencedType.isValid()) {
*type = referencedType.typeId();
- else
+ if (!type->isValid() && referencedType.isInlineComponentType()) {
+ int objectId = referencedType.inlineComponentId();
+ *type = objectContainer->typeIdsForComponent(objectId).id;
+ Q_ASSERT(type->isValid());
+ }
+ } else {
*type = typeRef->compilationUnit()->typeIds.id;
+ }
*version = typeRef->version();
@@ -1000,8 +1013,8 @@ inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasesTo
QQmlPropertyCache::Ptr propertyCache = propertyCaches->ownAt(objectIndex);
Q_ASSERT(propertyCache);
- int effectiveSignalIndex = propertyCache->signalHandlerIndexCacheStart + propertyCache->propertyIndexCache.count();
- int effectivePropertyIndex = propertyCache->propertyIndexCacheStart + propertyCache->propertyIndexCache.count();
+ int effectiveSignalIndex = propertyCache->signalHandlerIndexCacheStart + propertyCache->propertyIndexCache.size();
+ int effectivePropertyIndex = propertyCache->propertyIndexCacheStart + propertyCache->propertyIndexCache.size();
int aliasIndex = 0;
auto alias = object.aliasesBegin();
diff --git a/src/qml/qml/qqmlpropertycachevector_p.h b/src/qml/qml/qqmlpropertycachevector_p.h
index 71a4896315..6386795086 100644
--- a/src/qml/qml/qqmlpropertycachevector_p.h
+++ b/src/qml/qml/qqmlpropertycachevector_p.h
@@ -36,10 +36,10 @@ public:
return data.resize(size);
}
- int count() const { return data.count(); }
+ int count() const { return data.size(); }
void clear()
{
- for (int i = 0; i < data.count(); ++i) {
+ for (int i = 0; i < data.size(); ++i) {
const auto &cache = data.at(i);
if (cache.isT2()) {
if (QQmlPropertyCache *data = cache.asT2())
diff --git a/src/qml/qml/qqmlpropertydata_p.h b/src/qml/qml/qqmlpropertydata_p.h
index 83ae5ff9a8..dd9aa21c7b 100644
--- a/src/qml/qml/qqmlpropertydata_p.h
+++ b/src/qml/qml/qqmlpropertydata_p.h
@@ -240,7 +240,6 @@ public:
{
Q_ASSERT(idx >= std::numeric_limits<qint16>::min());
Q_ASSERT(idx <= std::numeric_limits<qint16>::max());
- Q_ASSERT(idx != m_coreIndex);
m_overrideIndex = qint16(idx);
}
diff --git a/src/qml/qml/qqmlpropertyresolver.cpp b/src/qml/qml/qqmlpropertyresolver.cpp
index 6be2c205ed..ff29c38997 100644
--- a/src/qml/qml/qqmlpropertyresolver.cpp
+++ b/src/qml/qml/qqmlpropertyresolver.cpp
@@ -44,7 +44,7 @@ const QQmlPropertyData *QQmlPropertyResolver::signal(const QString &name, bool *
}
if (name.endsWith(QLatin1String("Changed"))) {
- QString propName = name.mid(0, name.length() - static_cast<int>(strlen("Changed")));
+ QString propName = name.mid(0, name.size() - static_cast<int>(strlen("Changed")));
d = property(propName, notInRevision);
if (d)
diff --git a/src/qml/qml/qqmlpropertyvalidator_p.h b/src/qml/qml/qqmlpropertyvalidator_p.h
index bd81b75e78..e1154347ec 100644
--- a/src/qml/qml/qqmlpropertyvalidator_p.h
+++ b/src/qml/qml/qqmlpropertyvalidator_p.h
@@ -32,6 +32,9 @@ public:
QVector<QQmlError> validate();
+ QQmlPropertyCache::ConstPtr rootPropertyCache() const { return propertyCaches.at(0); }
+ QUrl documentSourceUrl() const { return compilationUnit->url(); }
+
private:
QVector<QQmlError> validateObject(
int objectIndex, const QV4::CompiledData::Binding *instantiatingBinding,
diff --git a/src/qml/qml/qqmlproxymetaobject.cpp b/src/qml/qml/qqmlproxymetaobject.cpp
index 9a5347bd74..ad67856c02 100644
--- a/src/qml/qml/qqmlproxymetaobject.cpp
+++ b/src/qml/qml/qqmlproxymetaobject.cpp
@@ -32,8 +32,8 @@ QQmlProxyMetaObject::~QQmlProxyMetaObject()
QObject *QQmlProxyMetaObject::getProxy(int index)
{
if (!proxies) {
- proxies = new QObject *[metaObjects->count()];
- ::memset(proxies, 0, sizeof(QObject *) * metaObjects->count());
+ proxies = new QObject *[metaObjects->size()];
+ ::memset(proxies, 0, sizeof(QObject *) * metaObjects->size());
}
if (!proxies[index]) {
@@ -71,7 +71,7 @@ int QQmlProxyMetaObject::metaCall(QObject *o, QMetaObject::Call c, int id, void
if (id < metaObjects->constLast().propertyOffset)
break;
- for (int ii = 0; ii < metaObjects->count(); ++ii) {
+ for (int ii = 0; ii < metaObjects->size(); ++ii) {
const int globalPropertyOffset = metaObjects->at(ii).propertyOffset;
if (id < globalPropertyOffset)
continue;
@@ -94,7 +94,7 @@ int QQmlProxyMetaObject::metaCall(QObject *o, QMetaObject::Call c, int id, void
return -1;
}
- for (int ii = 0; ii < metaObjects->count(); ++ii) {
+ for (int ii = 0; ii < metaObjects->size(); ++ii) {
const int globalMethodOffset = metaObjects->at(ii).methodOffset;
if (id < globalMethodOffset)
continue;
diff --git a/src/qml/qml/qqmlscriptblob.cpp b/src/qml/qml/qqmlscriptblob.cpp
index 5bfa6d3470..505a57636f 100644
--- a/src/qml/qml/qqmlscriptblob.cpp
+++ b/src/qml/qml/qqmlscriptblob.cpp
@@ -126,7 +126,7 @@ void QQmlScriptBlob::done()
return;
// Check all script dependencies for errors
- for (int ii = 0; ii < m_scripts.count(); ++ii) {
+ for (int ii = 0; ii < m_scripts.size(); ++ii) {
const ScriptReference &script = m_scripts.at(ii);
Q_ASSERT(script.script->isCompleteOrError());
if (script.script->isError()) {
@@ -147,7 +147,7 @@ void QQmlScriptBlob::done()
QSet<QString> ns;
- for (int scriptIndex = 0; scriptIndex < m_scripts.count(); ++scriptIndex) {
+ for (int scriptIndex = 0; scriptIndex < m_scripts.size(); ++scriptIndex) {
const ScriptReference &script = m_scripts.at(scriptIndex);
m_scriptData->scripts.append(script.script);
diff --git a/src/qml/qml/qqmlscriptdata.cpp b/src/qml/qml/qqmlscriptdata.cpp
index 994a76c96e..b5ba04c93e 100644
--- a/src/qml/qml/qqmlscriptdata.cpp
+++ b/src/qml/qml/qqmlscriptdata.cpp
@@ -55,14 +55,14 @@ QQmlRefPointer<QQmlContextData> QQmlScriptData::qmlContextDataForContext(
QV4::Scope scope(v4);
QV4::ScopedObject scriptsArray(scope);
if (qmlContextData->importedScripts().isNullOrUndefined()) {
- scriptsArray = v4->newArrayObject(scripts.count());
+ scriptsArray = v4->newArrayObject(scripts.size());
qmlContextData->setImportedScripts(
QV4::PersistentValue(v4, scriptsArray.asReturnedValue()));
} else {
scriptsArray = qmlContextData->importedScripts().valueRef();
}
QV4::ScopedValue v(scope);
- for (int ii = 0; ii < scripts.count(); ++ii) {
+ for (int ii = 0; ii < scripts.size(); ++ii) {
v = scripts.at(ii)->scriptData()->scriptValueForContext(qmlContextData);
scriptsArray->put(ii, v);
}
diff --git a/src/qml/qml/qqmlscriptstring.cpp b/src/qml/qml/qqmlscriptstring.cpp
index d872d4b55c..370573b199 100644
--- a/src/qml/qml/qqmlscriptstring.cpp
+++ b/src/qml/qml/qqmlscriptstring.cpp
@@ -154,7 +154,7 @@ Otherwise returns a null QString.
QString QQmlScriptString::stringLiteral() const
{
if (d->isStringLiteral)
- return d->script.mid(1, d->script.length()-2);
+ return d->script.mid(1, d->script.size()-2);
return QString();
}
diff --git a/src/qml/qml/qqmltype.cpp b/src/qml/qml/qqmltype.cpp
index 5c3cfa94a5..52437348d9 100644
--- a/src/qml/qml/qqmltype.cpp
+++ b/src/qml/qml/qqmltype.cpp
@@ -208,7 +208,7 @@ void QQmlTypePrivate::init() const
mo, baseMetaObject, metaObjects.isEmpty() ? nullptr
: metaObjects.constLast().metaObject));
- for (int ii = 0; ii < metaObjects.count(); ++ii) {
+ for (int ii = 0; ii < metaObjects.size(); ++ii) {
metaObjects[ii].propertyOffset =
metaObjects.at(ii).metaObject->propertyOffset();
metaObjects[ii].methodOffset =
@@ -320,7 +320,7 @@ void QQmlTypePrivate::insertEnums(const QMetaObject *metaObject) const
if (isScoped) {
scopedEnums << scoped;
- scopedEnumIndex.insert(QString::fromUtf8(e.name()), scopedEnums.count()-1);
+ scopedEnumIndex.insert(QString::fromUtf8(e.name()), scopedEnums.size()-1);
}
}
}
@@ -371,7 +371,7 @@ void QQmlTypePrivate::createEnumConflictReport(const QMetaObject *metaObject, co
qWarning().noquote() << QLatin1String("Possible conflicting items:");
// find items with conflicting key
- for (const auto &i : qAsConst(enumInfoList)) {
+ for (const auto &i : std::as_const(enumInfoList)) {
if (i.enumKey == conflictingKey)
qWarning().noquote().nospace() << " " << i.metaObjectName << "." << i.enumName << "." << i.enumKey << " from scope "
<< i.metaEnumScope << " injected by " << i.path.join(QLatin1String("->"));
@@ -392,13 +392,13 @@ void QQmlTypePrivate::insertEnumsFromPropertyCache(
QStringHash<int> *scoped = new QStringHash<int>();
QQmlEnumData *enumData = currentCache->qmlEnum(ii);
- for (int jj = 0; jj < enumData->values.count(); ++jj) {
+ for (int jj = 0; jj < enumData->values.size(); ++jj) {
const QQmlEnumValue &value = enumData->values.at(jj);
enums.insert(value.namedValue, value.value);
scoped->insert(value.namedValue, value.value);
}
scopedEnums << scoped;
- scopedEnumIndex.insert(enumData->name, scopedEnums.count()-1);
+ scopedEnumIndex.insert(enumData->name, scopedEnums.size()-1);
}
}
insertEnums(cppMetaObject);
@@ -822,7 +822,7 @@ int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, int index, const QV4::S
*ok = true;
if (d) {
- Q_ASSERT(index > -1 && index < d->scopedEnums.count());
+ Q_ASSERT(index > -1 && index < d->scopedEnums.size());
int *rv = d->scopedEnums.at(index)->value(name);
if (rv)
return *rv;
@@ -839,7 +839,7 @@ int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, int index, const QStrin
*ok = true;
if (d) {
- Q_ASSERT(index > -1 && index < d->scopedEnums.count());
+ Q_ASSERT(index > -1 && index < d->scopedEnums.size());
int *rv = d->scopedEnums.at(index)->value(name);
if (rv)
return *rv;
@@ -857,11 +857,11 @@ int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, const QByteArray &scope
d->initEnums(engine);
- int *rv = d->scopedEnumIndex.value(QHashedCStringRef(scopedEnumName.constData(), scopedEnumName.length()));
+ int *rv = d->scopedEnumIndex.value(QHashedCStringRef(scopedEnumName.constData(), scopedEnumName.size()));
if (rv) {
int index = *rv;
- Q_ASSERT(index > -1 && index < d->scopedEnums.count());
- rv = d->scopedEnums.at(index)->value(QHashedCStringRef(name.constData(), name.length()));
+ Q_ASSERT(index > -1 && index < d->scopedEnums.size());
+ rv = d->scopedEnums.at(index)->value(QHashedCStringRef(name.constData(), name.size()));
if (rv)
return *rv;
}
@@ -882,7 +882,7 @@ int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, QStringView scopedEnumN
int *rv = d->scopedEnumIndex.value(QHashedStringRef(scopedEnumName));
if (rv) {
int index = *rv;
- Q_ASSERT(index > -1 && index < d->scopedEnums.count());
+ Q_ASSERT(index > -1 && index < d->scopedEnums.size());
rv = d->scopedEnums.at(index)->value(QHashedStringRef(name));
if (rv)
return *rv;
diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp
index 64a9238739..c2aff473fd 100644
--- a/src/qml/qml/qqmltypecompiler.cpp
+++ b/src/qml/qml/qqmltypecompiler.cpp
@@ -117,7 +117,7 @@ QQmlRefPointer<QV4::ExecutableCompilationUnit> QQmlTypeCompiler::compile()
document->jsModule.fileName = typeData->urlString();
document->jsModule.finalUrl = typeData->finalUrlString();
QmlIR::JSCodeGen v4CodeGenerator(document, engine->v4engine()->illegalNames());
- for (QmlIR::Object *object : qAsConst(document->objects)) {
+ for (QmlIR::Object *object : std::as_const(document->objects)) {
if (!v4CodeGenerator.generateRuntimeFunctions(object)) {
Q_ASSERT(v4CodeGenerator.hasError());
recordError(v4CodeGenerator.error());
@@ -243,7 +243,7 @@ void QQmlTypeCompiler::addImport(const QString &module, const QString &qualifier
const quint32 moduleIdx = registerString(module);
const quint32 qualifierIdx = registerString(qualifier);
- for (int i = 0, count = document->imports.count(); i < count; ++i) {
+ for (int i = 0, count = document->imports.size(); i < count; ++i) {
const QV4::CompiledData::Import *existingImport = document->imports.at(i);
if (existingImport->type == QV4::CompiledData::Import::ImportLibrary
&& existingImport->uriIndex == moduleIdx
@@ -282,7 +282,7 @@ SignalHandlerResolver::SignalHandlerResolver(QQmlTypeCompiler *typeCompiler)
bool SignalHandlerResolver::resolveSignalHandlerExpressions()
{
- for (int objectIndex = 0; objectIndex < qmlObjects.count(); ++objectIndex) {
+ for (int objectIndex = 0; objectIndex < qmlObjects.size(); ++objectIndex) {
const QmlIR::Object * const obj = qmlObjects.at(objectIndex);
QQmlPropertyCache::ConstPtr cache = propertyCaches->at(objectIndex);
if (!cache)
@@ -335,7 +335,7 @@ bool SignalHandlerResolver::resolveSignalHandlerExpressions(
QString qPropertyName;
if (signalName.endsWith(QLatin1String("Changed")))
- qPropertyName = signalName.mid(0, signalName.length() - static_cast<int>(strlen("Changed")));
+ qPropertyName = signalName.mid(0, signalName.size() - static_cast<int>(strlen("Changed")));
bool notInRevision = false;
const QQmlPropertyData * const signal = resolver.signal(signalName, &notInRevision);
@@ -353,7 +353,7 @@ bool SignalHandlerResolver::resolveSignalHandlerExpressions(
bool unnamedParameter = false;
QList<QByteArray> parameterNames = propertyCache->signalParameterNames(sigIndex);
- for (int i = 0; i < parameterNames.count(); ++i) {
+ for (int i = 0; i < parameterNames.size(); ++i) {
const QString param = QString::fromUtf8(parameterNames.at(i));
if (param.isEmpty())
unnamedParameter = true;
@@ -442,7 +442,7 @@ QQmlEnumTypeResolver::QQmlEnumTypeResolver(QQmlTypeCompiler *typeCompiler)
bool QQmlEnumTypeResolver::resolveEnumBindings()
{
- for (int i = 0; i < qmlObjects.count(); ++i) {
+ for (int i = 0; i < qmlObjects.size(); ++i) {
QQmlPropertyCache::ConstPtr propertyCache = propertyCaches->at(i);
if (!propertyCache)
continue;
@@ -517,11 +517,11 @@ bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(
// * <TypeName>.<ScopedEnumName>.<EnumValue>
int dot = string.indexOf(QLatin1Char('.'));
- if (dot == -1 || dot == string.length()-1)
+ if (dot == -1 || dot == string.size()-1)
return true;
int dot2 = string.indexOf(QLatin1Char('.'), dot+1);
- if (dot2 != -1 && dot2 != string.length()-1) {
+ if (dot2 != -1 && dot2 != string.size()-1) {
if (!string.at(dot+1).isUpper())
return true;
if (string.indexOf(QLatin1Char('.'), dot2+1) != -1)
@@ -612,7 +612,7 @@ int QQmlEnumTypeResolver::evaluateEnum(const QString &scope, QStringView enumNam
return -1;
if (!enumName.isEmpty())
return type.scopedEnumValue(compiler->enginePrivate(), enumName, enumValue, ok);
- return type.enumValue(compiler->enginePrivate(), QHashedStringRef(enumValue.constData(), enumValue.length()), ok);
+ return type.enumValue(compiler->enginePrivate(), QHashedStringRef(enumValue.constData(), enumValue.size()), ok);
}
const QMetaObject *mo = &Qt::staticMetaObject;
@@ -674,7 +674,7 @@ QQmlAliasAnnotator::QQmlAliasAnnotator(QQmlTypeCompiler *typeCompiler)
void QQmlAliasAnnotator::annotateBindingsToAliases()
{
- for (int i = 0; i < qmlObjects.count(); ++i) {
+ for (int i = 0; i < qmlObjects.size(); ++i) {
QQmlPropertyCache::ConstPtr propertyCache = propertyCaches->at(i);
if (!propertyCache)
continue;
@@ -706,7 +706,7 @@ QQmlScriptStringScanner::QQmlScriptStringScanner(QQmlTypeCompiler *typeCompiler)
void QQmlScriptStringScanner::scan()
{
const QMetaType scriptStringMetaType = QMetaType::fromType<QQmlScriptString>();
- for (int i = 0; i < qmlObjects.count(); ++i) {
+ for (int i = 0; i < qmlObjects.size(); ++i) {
QQmlPropertyCache::ConstPtr propertyCache = propertyCaches->at(i);
if (!propertyCache)
continue;
@@ -833,7 +833,7 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(
}
qmlObjects->append(syntheticComponent);
- const int componentIndex = qmlObjects->count() - 1;
+ const int componentIndex = qmlObjects->size() - 1;
// Keep property caches symmetric
QQmlPropertyCache::ConstPtr componentCache
= QQmlMetaType::propertyCache(&QQmlComponent::staticMetaObject);
@@ -863,7 +863,7 @@ bool QQmlComponentAndAliasResolver::resolve(int root)
// someItemDelegate: Item {}
// In the implicit case Item is surrounded by a synthetic Component {} because the property
// on the left hand side is of QQmlComponent type.
- const int objCountWithoutSynthesizedComponents = qmlObjects->count();
+ const int objCountWithoutSynthesizedComponents = qmlObjects->size();
const int startObjectIndex = root == 0 ? root : root+1; // root+1, as ic root is handled at the end
for (int i = startObjectIndex; i < objCountWithoutSynthesizedComponents; ++i) {
QmlIR::Object *obj = qmlObjects->at(i);
@@ -931,7 +931,7 @@ bool QQmlComponentAndAliasResolver::resolve(int root)
}
- for (int i = 0; i < componentRoots.count(); ++i) {
+ for (int i = 0; i < componentRoots.size(); ++i) {
QmlIR::Object *component = qmlObjects->at(componentRoots.at(i));
const QmlIR::Binding *rootBinding = component->firstBinding();
@@ -977,7 +977,7 @@ bool QQmlComponentAndAliasResolver::collectIdsAndAliases(int objectIndex)
recordError(obj->locationOfIdProperty, tr("id is not unique"));
return false;
}
- obj->id = _idToObjectIndex.count();
+ obj->id = _idToObjectIndex.size();
_idToObjectIndex.insert(obj->idNameIndex, objectIndex);
}
@@ -1016,7 +1016,7 @@ bool QQmlComponentAndAliasResolver::resolveAliases(int componentIndex)
atLeastOneAliasResolved = false;
QVector<int> pendingObjects;
- for (int objectIndex: qAsConst(_objectsWithAliases)) {
+ for (int objectIndex: std::as_const(_objectsWithAliases)) {
QQmlError error;
const auto result = resolveAliasesInObject(objectIndex, &error);
@@ -1396,7 +1396,7 @@ QQmlDefaultPropertyMerger::QQmlDefaultPropertyMerger(QQmlTypeCompiler *typeCompi
void QQmlDefaultPropertyMerger::mergeDefaultProperties()
{
- for (int i = 0; i < qmlObjects.count(); ++i)
+ for (int i = 0; i < qmlObjects.size(); ++i)
mergeDefaultProperties(i);
}
diff --git a/src/qml/qml/qqmltypecompiler_p.h b/src/qml/qml/qqmltypecompiler_p.h
index 188eda471f..02edbb0c08 100644
--- a/src/qml/qml/qqmltypecompiler_p.h
+++ b/src/qml/qml/qqmltypecompiler_p.h
@@ -55,7 +55,7 @@ public:
using ListPropertyAssignBehavior = QmlIR::Pragma::ListPropertyAssignBehaviorValue;
const QmlIR::Object *objectAt(int index) const { return document->objects.at(index); }
- int objectCount() const { return document->objects.count(); }
+ int objectCount() const { return document->objects.size(); }
QString stringAt(int idx) const;
QmlIR::PoolList<QmlIR::Function>::Iterator objectFunctionsBegin(const QmlIR::Object *object) const { return object->functionsBegin(); }
QmlIR::PoolList<QmlIR::Function>::Iterator objectFunctionsEnd(const QmlIR::Object *object) const { return object->functionsEnd(); }
diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp
index 972723326a..c56acaef0d 100644
--- a/src/qml/qml/qqmltypedata.cpp
+++ b/src/qml/qml/qqmltypedata.cpp
@@ -292,7 +292,7 @@ void QQmlTypeData::done()
return;
// Check all script dependencies for errors
- for (int ii = 0; ii < m_scripts.count(); ++ii) {
+ for (int ii = 0; ii < m_scripts.size(); ++ii) {
const ScriptReference &script = m_scripts.at(ii);
Q_ASSERT(script.script->isCompleteOrError());
if (script.script->isError()) {
@@ -309,7 +309,7 @@ void QQmlTypeData::done()
}
// Check all type dependencies for errors
- for (auto it = qAsConst(m_resolvedTypes).begin(), end = qAsConst(m_resolvedTypes).end(); it != end;
+ for (auto it = std::as_const(m_resolvedTypes).begin(), end = std::as_const(m_resolvedTypes).end(); it != end;
++it) {
const TypeReference &type = *it;
Q_ASSERT(!type.typeData || type.typeData->isCompleteOrError() || type.type.isInlineComponentType());
@@ -349,7 +349,7 @@ void QQmlTypeData::done()
}
// Check all composite singleton type dependencies for errors
- for (int ii = 0; ii < m_compositeSingletons.count(); ++ii) {
+ for (int ii = 0; ii < m_compositeSingletons.size(); ++ii) {
const TypeReference &type = m_compositeSingletons.at(ii);
Q_ASSERT(!type.typeData || type.typeData->isCompleteOrError());
if (type.typeData && type.typeData->isError()) {
@@ -470,7 +470,7 @@ void QQmlTypeData::done()
auto type = QQmlMetaType::typeForUrl(finalUrlString(), hashedStringRef, false, &errors);
Q_ASSERT(errors.empty());
if (type.isValid()) {
- for (auto const &icDatum : qAsConst(m_inlineComponentData)) {
+ for (auto const &icDatum : std::as_const(m_inlineComponentData)) {
Q_ASSERT(icDatum.typeIds.isValid());
QQmlType existingType = type.lookupInlineComponentById(type.lookupInlineComponentIdByName(m_compiledData->stringAt(icDatum.nameIndex)));
type.associateInlineComponent(m_compiledData->stringAt(icDatum.nameIndex),
@@ -482,8 +482,8 @@ void QQmlTypeData::done()
{
// Collect imported scripts
- m_compiledData->dependentScripts.reserve(m_scripts.count());
- for (int scriptIndex = 0; scriptIndex < m_scripts.count(); ++scriptIndex) {
+ m_compiledData->dependentScripts.reserve(m_scripts.size());
+ for (int scriptIndex = 0; scriptIndex < m_scripts.size(); ++scriptIndex) {
const QQmlTypeData::ScriptReference &script = m_scripts.at(scriptIndex);
QStringView qualifier(script.qualifier);
@@ -599,8 +599,8 @@ bool QQmlTypeData::loadFromSource()
if (!compiler.generateFromQml(source, finalUrlString(), m_document.data())) {
QList<QQmlError> errors;
- errors.reserve(compiler.errors.count());
- for (const QQmlJS::DiagnosticMessage &msg : qAsConst(compiler.errors)) {
+ errors.reserve(compiler.errors.size());
+ for (const QQmlJS::DiagnosticMessage &msg : std::as_const(compiler.errors)) {
QQmlError e;
e.setUrl(url());
e.setLine(qmlConvertSourceCoordinate<quint32, int>(msg.loc.startLine));
@@ -668,7 +668,7 @@ void QQmlTypeData::continueLoadFromIR()
QList<QQmlError> errors;
- for (const QV4::CompiledData::Import *import : qAsConst(m_document->imports)) {
+ for (const QV4::CompiledData::Import *import : std::as_const(m_document->imports)) {
if (!addImport(import, {}, &errors)) {
Q_ASSERT(errors.size());
@@ -723,7 +723,7 @@ void QQmlTypeData::allDependenciesDone()
void QQmlTypeData::downloadProgressChanged(qreal p)
{
- for (int ii = 0; ii < m_callbacks.count(); ++ii) {
+ for (int ii = 0; ii < m_callbacks.size(); ++ii) {
TypeDataCallback *callback = m_callbacks.at(ii);
callback->typeDataProgress(this, p);
}
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 046ee0ef51..ab3ea80d35 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -614,7 +614,7 @@ bool QQmlTypeLoader::Blob::addLibraryImport(PendingImportPtr import, QList<QQmlE
scriptImported(blob, import->location, script.nameSpace, import->qualifier);
}
}
- if (!qmldir.plugins().count()) {
+ if (!qmldir.plugins().size()) {
// If the qmldir does not register a plugin, we might still have declaratively
// registered types (if we are dealing with an application instead of a library)
auto module = QQmlMetaType::typeModule(import->uri, import->version);
@@ -1035,7 +1035,7 @@ QString QQmlTypeLoader::absoluteFilePath(const QString &path)
return QString();
QString absoluteFilePath;
- QString fileName(path.mid(lastSlash+1, path.length()-lastSlash-1));
+ QString fileName(path.mid(lastSlash+1, path.size()-lastSlash-1));
bool *value = fileSet->object(fileName);
if (value) {
@@ -1048,7 +1048,7 @@ QString QQmlTypeLoader::absoluteFilePath(const QString &path)
absoluteFilePath = path;
}
- if (absoluteFilePath.length() > 2 && absoluteFilePath.at(0) != QLatin1Char('/') && absoluteFilePath.at(1) != QLatin1Char(':'))
+ if (absoluteFilePath.size() > 2 && absoluteFilePath.at(0) != QLatin1Char('/') && absoluteFilePath.at(1) != QLatin1Char(':'))
absoluteFilePath = QFileInfo(absoluteFilePath).absoluteFilePath();
return absoluteFilePath;
@@ -1134,7 +1134,7 @@ bool QQmlTypeLoader::directoryExists(const QString &path)
return fileInfo.exists() && fileInfo.isDir();
}
- int length = path.length();
+ int length = path.size();
if (path.endsWith(QLatin1Char('/')))
--length;
QString dirPath(path.left(length));
@@ -1171,7 +1171,7 @@ const QQmlTypeLoaderQmldirContent QQmlTypeLoader::qmldirContent(const QString &f
// Yet, this heuristic is the best we can do until we pass more structured information here,
// for example a QUrl also for local files.
QUrl url(filePathIn);
- if (url.scheme().length() < 2) {
+ if (url.scheme().size() < 2) {
filePath = filePathIn;
} else {
filePath = QQmlFile::urlToLocalFileOrQrc(url);
diff --git a/src/qml/qml/qqmltypemodule.cpp b/src/qml/qml/qqmltypemodule.cpp
index 4360bf8fb9..b188b7fb90 100644
--- a/src/qml/qml/qqmltypemodule.cpp
+++ b/src/qml/qml/qqmltypemodule.cpp
@@ -30,7 +30,7 @@ void QQmlTypeModule::add(QQmlTypePrivate *type)
addMinorVersion(type->version.minorVersion());
QList<QQmlTypePrivate *> &list = m_typeHash[type->elementName];
- for (int ii = 0; ii < list.count(); ++ii) {
+ for (int ii = 0; ii < list.size(); ++ii) {
QQmlTypePrivate *in_list = list.at(ii);
Q_ASSERT(in_list);
if (in_list->version.minorVersion() < type->version.minorVersion()) {
@@ -54,7 +54,7 @@ void QQmlTypeModule::remove(const QQmlTypePrivate *type)
QQmlType QQmlTypeModule::findType(const QList<QQmlTypePrivate *> *types, QTypeRevision version)
{
if (types) {
- for (int ii = 0; ii < types->count(); ++ii)
+ for (int ii = 0; ii < types->size(); ++ii)
if (types->at(ii)->version.minorVersion() <= version.minorVersion())
return QQmlType(types->at(ii));
}
diff --git a/src/qml/qml/qqmltypenamecache.cpp b/src/qml/qml/qqmltypenamecache.cpp
index bf270cef7d..d3088a6c7c 100644
--- a/src/qml/qml/qqmltypenamecache.cpp
+++ b/src/qml/qml/qqmltypenamecache.cpp
@@ -9,7 +9,7 @@ QT_BEGIN_NAMESPACE
void QQmlTypeNameCache::add(const QHashedString &name, const QUrl &url, const QHashedString &nameSpace)
{
- if (nameSpace.length() != 0) {
+ if (nameSpace.size() != 0) {
QQmlImportRef *i = m_namedImports.value(nameSpace);
Q_ASSERT(i != nullptr);
i->compositeSingletons.insert(name, url);
@@ -28,7 +28,7 @@ void QQmlTypeNameCache::add(const QHashedString &name, int importedScriptIndex,
import.scriptIndex = importedScriptIndex;
import.m_qualifier = name;
- if (nameSpace.length() != 0) {
+ if (nameSpace.size() != 0) {
QQmlImportRef *i = m_namedImports.value(nameSpace);
Q_ASSERT(i != nullptr);
m_namespacedImports[i].insert(name, import);
diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp
index 7365255935..8cb18104b6 100644
--- a/src/qml/qml/qqmlvaluetype.cpp
+++ b/src/qml/qml/qqmlvaluetype.cpp
@@ -11,20 +11,9 @@
QT_BEGIN_NAMESPACE
-QQmlValueType::QQmlValueType(QMetaType type, const QMetaObject *gadgetMetaObject)
- : metaType(type)
-{
- QMetaObjectBuilder builder(gadgetMetaObject);
-
- // This is required for calling readOnGadget() on properties from this metaObject.
- builder.setFlags(PropertyAccessInStaticMetaCall);
-
- dynamicMetaObject = builder.toMetaObject();
-}
-
QQmlValueType::~QQmlValueType()
{
- ::free(dynamicMetaObject);
+ ::free(m_dynamicMetaObject);
}
QQmlGadgetPtrWrapper *QQmlGadgetPtrWrapper::instance(QQmlEngine *engine, QMetaType type)
@@ -54,7 +43,7 @@ void QQmlGadgetPtrWrapper::read(QObject *obj, int idx)
QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}
-void QQmlGadgetPtrWrapper::write(QObject *obj, int idx, QQmlPropertyData::WriteFlags flags)
+void QQmlGadgetPtrWrapper::write(QObject *obj, int idx, QQmlPropertyData::WriteFlags flags) const
{
Q_ASSERT(m_gadgetPtr);
int status = -1;
@@ -62,16 +51,16 @@ void QQmlGadgetPtrWrapper::write(QObject *obj, int idx, QQmlPropertyData::WriteF
QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}
-QVariant QQmlGadgetPtrWrapper::value()
+QVariant QQmlGadgetPtrWrapper::value() const
{
Q_ASSERT(m_gadgetPtr);
- return QVariant(QMetaType(metaTypeId()), m_gadgetPtr);
+ return QVariant(metaType(), m_gadgetPtr);
}
void QQmlGadgetPtrWrapper::setValue(const QVariant &value)
{
Q_ASSERT(m_gadgetPtr);
- Q_ASSERT(metaTypeId() == value.userType());
+ Q_ASSERT(metaType() == value.metaType());
const QQmlValueType *type = valueType();
type->destruct(m_gadgetPtr);
type->construct(m_gadgetPtr, value.constData());
@@ -80,7 +69,7 @@ void QQmlGadgetPtrWrapper::setValue(const QVariant &value)
int QQmlGadgetPtrWrapper::metaCall(QMetaObject::Call type, int id, void **argv)
{
Q_ASSERT(m_gadgetPtr);
- const QMetaObject *metaObject = valueType()->metaObject();
+ const QMetaObject *metaObject = valueType()->staticMetaObject();
QQmlMetaObject::resolveGadgetMethodOrPropertyIndex(type, &metaObject, &id);
metaObject->d.static_metacall(static_cast<QObject *>(m_gadgetPtr), type, id, argv);
return id;
@@ -94,7 +83,16 @@ const QQmlValueType *QQmlGadgetPtrWrapper::valueType() const
QMetaObject *QQmlValueType::toDynamicMetaObject(QObject *)
{
- return dynamicMetaObject;
+ if (!m_dynamicMetaObject) {
+ QMetaObjectBuilder builder(m_staticMetaObject);
+
+ // Do not set PropertyAccessInStaticMetaCall here. QQmlGadgetPtrWrapper likes to
+ // to intercept the metacalls since it needs to use its gadgetPtr.
+ // For QQmlValueType::metaObject() we use the base type that has the flag.
+
+ m_dynamicMetaObject = builder.toMetaObject();
+ }
+ return m_dynamicMetaObject;
}
void QQmlValueType::objectDestroyed(QObject *)
diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h
index 6b7df3f1b9..5376130b0f 100644
--- a/src/qml/qml/qqmlvaluetype_p.h
+++ b/src/qml/qml/qqmlvaluetype_p.h
@@ -34,18 +34,20 @@ QT_BEGIN_NAMESPACE
class Q_QML_PRIVATE_EXPORT QQmlValueType : public QDynamicMetaObjectData
{
public:
- QQmlValueType() : metaType(QMetaType::UnknownType) {}
- QQmlValueType(QMetaType type, const QMetaObject *metaObject);
+ QQmlValueType() = default;
+ QQmlValueType(QMetaType type, const QMetaObject *staticMetaObject)
+ : m_metaType(type), m_staticMetaObject(staticMetaObject)
+ {}
~QQmlValueType();
- void *create() const { return metaType.create(); }
- void destroy(void *gadgetPtr) const { metaType.destroy(gadgetPtr); }
+ void *create() const { return m_metaType.create(); }
+ void destroy(void *gadgetPtr) const { m_metaType.destroy(gadgetPtr); }
- void construct(void *gadgetPtr, const void *copy) const { metaType.construct(gadgetPtr, copy); }
- void destruct(void *gadgetPtr) const { metaType.destruct(gadgetPtr); }
+ void construct(void *gadgetPtr, const void *copy) const { m_metaType.construct(gadgetPtr, copy); }
+ void destruct(void *gadgetPtr) const { m_metaType.destruct(gadgetPtr); }
- int metaTypeId() const { return metaType.id(); }
- const QMetaObject *metaObject() const { return dynamicMetaObject; }
+ QMetaType metaType() const { return m_metaType; }
+ const QMetaObject *staticMetaObject() const { return m_staticMetaObject; }
// ---- dynamic meta object data interface
QMetaObject *toDynamicMetaObject(QObject *) override;
@@ -53,9 +55,10 @@ public:
int metaCall(QObject *obj, QMetaObject::Call type, int _id, void **argv) override;
// ----
-public:
- QMetaType metaType;
- QMetaObject *dynamicMetaObject = nullptr;
+private:
+ QMetaType m_metaType;
+ const QMetaObject *m_staticMetaObject = nullptr;
+ QMetaObject *m_dynamicMetaObject = nullptr;
};
class Q_QML_PRIVATE_EXPORT QQmlGadgetPtrWrapper : public QObject
@@ -68,14 +71,18 @@ public:
~QQmlGadgetPtrWrapper();
void read(QObject *obj, int idx);
- void write(QObject *obj, int idx, QQmlPropertyData::WriteFlags flags);
- QVariant value();
+ void write(QObject *obj, int idx, QQmlPropertyData::WriteFlags flags) const;
+ QVariant value() const;
void setValue(const QVariant &value);
- int metaTypeId() const { return valueType()->metaTypeId(); }
+ QMetaType metaType() const { return valueType()->metaType(); }
int metaCall(QMetaObject::Call type, int id, void **argv);
- QMetaProperty property(int index) { return valueType()->metaObject()->property(index); }
+ QMetaProperty property(int index) const
+ {
+ return valueType()->staticMetaObject()->property(index);
+ }
+
QVariant readOnGadget(const QMetaProperty &property) const
{
return property.readOnGadget(m_gadgetPtr);
@@ -88,7 +95,6 @@ public:
private:
const QQmlValueType *valueType() const;
-
void *m_gadgetPtr = nullptr;
};
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index 34de9faef9..d088d5e411 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -35,7 +35,7 @@ using namespace QV4;
void Heap::QQmlValueTypeWrapper::destroy()
{
if (m_gadgetPtr) {
- m_valueType->metaType.destruct(m_gadgetPtr);
+ m_valueType->metaType().destruct(m_gadgetPtr);
::operator delete(m_gadgetPtr);
}
Object::destroy();
@@ -44,22 +44,22 @@ void Heap::QQmlValueTypeWrapper::destroy()
void Heap::QQmlValueTypeWrapper::setData(const void *data) const
{
if (auto *gadget = gadgetPtr())
- valueType()->metaType.destruct(gadget);
+ valueType()->metaType().destruct(gadget);
if (!gadgetPtr())
- setGadgetPtr(::operator new(valueType()->metaType.sizeOf()));
- valueType()->metaType.construct(gadgetPtr(), data);
+ setGadgetPtr(::operator new(valueType()->metaType().sizeOf()));
+ valueType()->metaType().construct(gadgetPtr(), data);
}
void Heap::QQmlValueTypeWrapper::setValue(const QVariant &value) const
{
- Q_ASSERT(valueType()->metaType.id() == value.userType());
+ Q_ASSERT(valueType()->metaType().id() == value.userType());
setData(value.constData());
}
QVariant Heap::QQmlValueTypeWrapper::toVariant() const
{
Q_ASSERT(gadgetPtr());
- return QVariant(valueType()->metaType, gadgetPtr());
+ return QVariant(valueType()->metaType(), gadgetPtr());
}
@@ -86,7 +86,7 @@ bool QQmlValueTypeReference::readReferenceValue() const
if (QQmlMetaType::isValueType(variantReferenceType)) {
const QMetaObject *mo = QQmlMetaType::metaObjectForValueType(variantReferenceType);
if (d()->gadgetPtr()) {
- d()->valueType()->metaType.destruct(d()->gadgetPtr());
+ d()->valueType()->metaType().destruct(d()->gadgetPtr());
::operator delete(d()->gadgetPtr());
}
d()->setGadgetPtr(nullptr);
@@ -101,8 +101,8 @@ bool QQmlValueTypeReference::readReferenceValue() const
d()->setValue(variantReferenceValue);
} else {
if (!d()->gadgetPtr()) {
- d()->setGadgetPtr(::operator new(d()->valueType()->metaType.sizeOf()));
- d()->valueType()->metaType.construct(d()->gadgetPtr(), nullptr);
+ d()->setGadgetPtr(::operator new(d()->valueType()->metaType().sizeOf()));
+ d()->valueType()->metaType().construct(d()->gadgetPtr(), nullptr);
}
// value-type reference
void *args[] = { d()->gadgetPtr(), nullptr };
@@ -145,7 +145,7 @@ ReturnedValue QQmlValueTypeWrapper::create(
ExecutionEngine *engine, const QVariant &value, const QMetaObject *metaObject,
QMetaType type)
{
- Q_ASSERT(value.metaType() == QQmlMetaType::valueType(type)->metaType);
+ Q_ASSERT(value.metaType() == QQmlMetaType::valueType(type)->metaType());
return create(engine, value.constData(), metaObject, type);
}
@@ -181,7 +181,7 @@ bool QQmlValueTypeWrapper::toGadget(void *data) const
if (const QQmlValueTypeReference *ref = as<const QQmlValueTypeReference>())
if (!ref->readReferenceValue())
return false;
- const QMetaType type = d()->valueType()->metaType;
+ const QMetaType type = d()->valueType()->metaType();
type.destruct(data);
type.construct(data, d()->gadgetPtr());
return true;
@@ -367,12 +367,12 @@ bool QQmlValueTypeWrapper::isEqual(const QVariant& value) const
int QQmlValueTypeWrapper::typeId() const
{
- return d()->valueType()->metaType.id();
+ return d()->valueType()->metaType().id();
}
QMetaType QQmlValueTypeWrapper::type() const
{
- return d()->valueType()->metaType;
+ return d()->valueType()->metaType();
}
bool QQmlValueTypeWrapper::write(QObject *target, int propertyIndex) const
@@ -381,9 +381,9 @@ bool QQmlValueTypeWrapper::write(QObject *target, int propertyIndex) const
Q_ALLOCA_DECLARE(void, gadget);
if (const QQmlValueTypeReference *ref = as<const QQmlValueTypeReference>()) {
if (!d()->gadgetPtr()) {
- Q_ALLOCA_ASSIGN(void, gadget, d()->valueType()->metaType.sizeOf());
+ Q_ALLOCA_ASSIGN(void, gadget, d()->valueType()->metaType().sizeOf());
d()->setGadgetPtr(gadget);
- d()->valueType()->metaType.construct(d()->gadgetPtr(), nullptr);
+ d()->valueType()->metaType().construct(d()->gadgetPtr(), nullptr);
destructGadgetOnExit = true;
}
if (!ref->readReferenceValue())
@@ -396,7 +396,7 @@ bool QQmlValueTypeWrapper::write(QObject *target, int propertyIndex) const
QMetaObject::metacall(target, QMetaObject::WriteProperty, propertyIndex, a);
if (destructGadgetOnExit) {
- d()->valueType()->metaType.destruct(d()->gadgetPtr());
+ d()->valueType()->metaType().destruct(d()->gadgetPtr());
d()->setGadgetPtr(nullptr);
}
return true;
@@ -434,9 +434,9 @@ ReturnedValue QQmlValueTypeWrapper::method_toString(const FunctionObject *b, con
RETURN_UNDEFINED();
QString result;
- if (!QMetaType::convert(w->d()->valueType()->metaType, w->d()->gadgetPtr(),
+ if (!QMetaType::convert(w->d()->valueType()->metaType(), w->d()->gadgetPtr(),
QMetaType(QMetaType::QString), &result)) {
- result = QString::fromUtf8(w->d()->valueType()->metaType.name()) + QLatin1Char('(');
+ result = QString::fromUtf8(w->d()->valueType()->metaType().name()) + QLatin1Char('(');
const QMetaObject *mo = w->d()->metaObject();
const int propCount = mo->propertyCount();
for (int i = 0; i < propCount; ++i) {
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index 8a0bc1a08e..710aadda45 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -99,7 +99,7 @@ static void list_append(QQmlListProperty<QObject> *prop, QObject *o)
static qsizetype list_count(QQmlListProperty<QObject> *prop)
{
- return ResolvedList(prop).list()->count();
+ return ResolvedList(prop).list()->size();
}
static QObject *list_at(QQmlListProperty<QObject> *prop, qsizetype index)
@@ -203,13 +203,10 @@ void QQmlVMEMetaObjectEndpoint::tryConnect()
if (!target)
return;
- QQmlData *targetDData = QQmlData::get(target, /*create*/false);
- if (!targetDData)
- return;
QQmlPropertyIndex encodedIndex = QQmlPropertyIndex::fromEncoded(aliasData->encodedMetaPropertyIndex);
int coreIndex = encodedIndex.coreIndex();
int valueTypeIndex = encodedIndex.valueTypeIndex();
- const QQmlPropertyData *pd = targetDData->propertyCache->property(coreIndex);
+ const QQmlPropertyData *pd = QQmlData::ensurePropertyCache(target)->property(coreIndex);
if (pd && valueTypeIndex != -1 && !QQmlMetaType::valueType(pd->propType())) {
// deep alias
const QQmlPropertyCache::ConstPtr newPropertyCache
@@ -899,7 +896,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
QObject *arg = *reinterpret_cast<QObject **>(a[0]);
if (const auto *wrap = sv->as<QV4::QObjectWrapper>())
needActivate = wrap->object() != arg;
- else
+ else if (arg != nullptr || !sv->isNull())
needActivate = true;
if (needActivate)
writeProperty(id, arg);
@@ -1053,7 +1050,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
auto arguments = methodData->hasArguments() ? methodData->arguments() : nullptr;
if (arguments && arguments->names) {
- const quint32 parameterCount = arguments->names->count();
+ const quint32 parameterCount = arguments->names->size();
Q_ASSERT(parameterCount == function->formalParameterCount());
if (void *result = a[0])
arguments->types[0].destruct(result);
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index 4d3ba7df24..daaeb16c13 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -504,7 +504,7 @@ ReturnedValue NodePrototype::method_get_previousSibling(const FunctionObject *b,
if (!r->d()->d->parent)
RETURN_RESULT(Encode::null());
- for (int ii = 0; ii < r->d()->d->parent->children.count(); ++ii) {
+ for (int ii = 0; ii < r->d()->d->parent->children.size(); ++ii) {
if (r->d()->d->parent->children.at(ii) == r->d()->d) {
if (ii == 0)
return Encode::null();
@@ -526,9 +526,9 @@ ReturnedValue NodePrototype::method_get_nextSibling(const FunctionObject *b, con
if (!r->d()->d->parent)
RETURN_RESULT(Encode::null());
- for (int ii = 0; ii < r->d()->d->parent->children.count(); ++ii) {
+ for (int ii = 0; ii < r->d()->d->parent->children.size(); ++ii) {
if (r->d()->d->parent->children.at(ii) == r->d()->d) {
- if ((ii + 1) == r->d()->d->parent->children.count())
+ if ((ii + 1) == r->d()->d->parent->children.size())
return Encode::null();
else
return Node::create(scope.engine, r->d()->d->parent->children.at(ii + 1));
@@ -666,7 +666,7 @@ ReturnedValue CharacterData::method_length(const FunctionObject *b, const Value
if (!r)
RETURN_UNDEFINED();
- return Encode(int(r->d()->d->data.length()));
+ return Encode(int(r->d()->d->data.size()));
}
ReturnedValue CharacterData::prototype(ExecutionEngine *v4)
@@ -859,7 +859,7 @@ ReturnedValue NamedNodeMap::virtualGet(const Managed *m, PropertyKey id, const V
if (id.isArrayIndex()) {
uint index = id.asArrayIndex();
- if ((int)index < r->d()->list().count()) {
+ if ((int)index < r->d()->list().size()) {
if (hasProperty)
*hasProperty = true;
return Node::create(v4, r->d()->list().at(index));
@@ -873,10 +873,10 @@ ReturnedValue NamedNodeMap::virtualGet(const Managed *m, PropertyKey id, const V
return Object::virtualGet(m, id, receiver, hasProperty);
if (id == v4->id_length()->propertyKey())
- return Value::fromInt32(r->d()->list().count()).asReturnedValue();
+ return Value::fromInt32(r->d()->list().size()).asReturnedValue();
QString str = id.toQString();
- for (int ii = 0; ii < r->d()->list().count(); ++ii) {
+ for (int ii = 0; ii < r->d()->list().size(); ++ii) {
if (r->d()->list().at(ii)->name == str) {
if (hasProperty)
*hasProperty = true;
@@ -902,7 +902,7 @@ ReturnedValue NodeList::virtualGet(const Managed *m, PropertyKey id, const Value
if (id.isArrayIndex()) {
uint index = id.asArrayIndex();
- if ((int)index < r->d()->d->children.count()) {
+ if ((int)index < r->d()->d->children.size()) {
if (hasProperty)
*hasProperty = true;
return Node::create(v4, r->d()->d->children.at(index));
@@ -913,7 +913,7 @@ ReturnedValue NodeList::virtualGet(const Managed *m, PropertyKey id, const Value
}
if (id == v4->id_length()->propertyKey())
- return Value::fromInt32(r->d()->d->children.count()).asReturnedValue();
+ return Value::fromInt32(r->d()->d->children.size()).asReturnedValue();
return Object::virtualGet(m, id, receiver, hasProperty);
}
@@ -1138,7 +1138,7 @@ QString QQmlXMLHttpRequest::headers() const
QString ret;
for (const HeaderPair &header : m_headersList) {
- if (ret.length())
+ if (ret.size())
ret.append(QLatin1String("\r\n"));
ret += QString::fromUtf8(header.first) + QLatin1String(": ")
+ QString::fromUtf8(header.second);
@@ -1202,7 +1202,7 @@ void QQmlXMLHttpRequest::requestFromUrl(const QUrl &url)
int n = 0;
int semiColon = str.indexOf(QLatin1Char(';'), charsetIdx);
if (semiColon == -1) {
- n = str.length() - charsetIdx;
+ n = str.size() - charsetIdx;
} else {
n = semiColon - charsetIdx;
}
@@ -1436,7 +1436,7 @@ void QQmlXMLHttpRequest::finished()
void QQmlXMLHttpRequest::readEncoding()
{
- for (const HeaderPair &header : qAsConst(m_headersList)) {
+ for (const HeaderPair &header : std::as_const(m_headersList)) {
if (header.first == "content-type") {
int separatorIdx = header.second.indexOf(';');
if (separatorIdx == -1) {
@@ -1447,7 +1447,7 @@ void QQmlXMLHttpRequest::readEncoding()
if (charsetIdx != -1) {
charsetIdx += 8;
separatorIdx = header.second.indexOf(';', charsetIdx);
- m_charset = header.second.mid(charsetIdx, separatorIdx >= 0 ? separatorIdx : header.second.length());
+ m_charset = header.second.mid(charsetIdx, separatorIdx >= 0 ? separatorIdx : header.second.size());
}
}
break;
@@ -1480,7 +1480,7 @@ QV4::ReturnedValue QQmlXMLHttpRequest::jsonResponseBody(QV4::ExecutionEngine* en
QJsonParseError error;
const QString& jtext = responseBody();
- JsonParser parser(scope.engine, jtext.constData(), jtext.length());
+ JsonParser parser(scope.engine, jtext.constData(), jtext.size());
ScopedValue jsonObject(scope, parser.parse(&error));
if (error.error != QJsonParseError::NoError)
return engine->throwSyntaxError(QStringLiteral("JSON.parse: Parse error"));
@@ -1513,11 +1513,8 @@ QStringDecoder QQmlXMLHttpRequest::findTextDecoder() const
decoder = QStringDecoder(reader.documentEncoding().toString().toUtf8());
}
- if (!decoder.isValid() && m_mime == "text/html") {
- auto encoding = QStringConverter::encodingForHtml(m_responseEntityBody);
- if (encoding)
- decoder = QStringDecoder(*encoding);
- }
+ if (!decoder.isValid() && m_mime == "text/html")
+ decoder = QStringDecoder::decoderForHtml(m_responseEntityBody);
if (!decoder.isValid()) {
auto encoding = QStringConverter::encodingForData(m_responseEntityBody);
@@ -1621,7 +1618,7 @@ struct QQmlXMLHttpRequestWrapper : Object {
Member(class, Pointer, Object *, proto)
DECLARE_HEAP_OBJECT(QQmlXMLHttpRequestCtor, FunctionObject) {
- DECLARE_MARKOBJECTS(QQmlXMLHttpRequestCtor);
+ DECLARE_MARKOBJECTS(QQmlXMLHttpRequestCtor)
void init(ExecutionEngine *engine);
};
diff --git a/src/qml/qmldirparser/qqmldirparser.cpp b/src/qml/qmldirparser/qqmldirparser.cpp
index 6415e6cee2..112c7d12d0 100644
--- a/src/qml/qmldirparser/qqmldirparser.cpp
+++ b/src/qml/qmldirparser/qqmldirparser.cpp
@@ -11,13 +11,13 @@ static int parseInt(QStringView str, bool *ok)
{
int pos = 0;
int number = 0;
- while (pos < str.length() && str.at(pos).isDigit()) {
+ while (pos < str.size() && str.at(pos).isDigit()) {
if (pos != 0)
number *= 10;
number += str.at(pos).unicode() - '0';
++pos;
}
- if (pos != str.length())
+ if (pos != str.size())
*ok = false;
else
*ok = true;
@@ -31,7 +31,7 @@ static QTypeRevision parseVersion(const QString &str)
bool ok = false;
const int major = parseInt(QStringView(str).left(dotIndex), &ok);
if (!ok) return QTypeRevision();
- const int minor = parseInt(QStringView(str).mid(dotIndex + 1, str.length() - dotIndex - 1), &ok);
+ const int minor = parseInt(QStringView(str).mid(dotIndex + 1, str.size() - dotIndex - 1), &ok);
return ok ? QTypeRevision::fromVersion(major, minor) : QTypeRevision();
}
return QTypeRevision();
diff --git a/src/qml/qmldirparser/qqmlimportresolver.cpp b/src/qml/qmldirparser/qqmlimportresolver.cpp
index b4f4dbf7a1..15ec7765b0 100644
--- a/src/qml/qmldirparser/qqmlimportresolver.cpp
+++ b/src/qml/qmldirparser/qqmlimportresolver.cpp
@@ -28,7 +28,7 @@ QStringList qQmlResolveImportPaths(QStringView uri, const QStringList &basePaths
QStringList importPaths;
// fully & partially versioned parts + 1 unversioned for each base path
- importPaths.reserve(2 * parts.count() + 1);
+ importPaths.reserve(2 * parts.size() + 1);
auto versionString = [](QTypeRevision version, ImportVersion mode)
{
@@ -71,7 +71,7 @@ QStringList qQmlResolveImportPaths(QStringView uri, const QStringList &basePaths
if (mode != Unversioned) {
// insert in the middle
- for (int index = parts.count() - 2; index >= 0; --index) {
+ for (int index = parts.size() - 2; index >= 0; --index) {
importPaths += dir + joinStringRefs(parts.mid(0, index + 1), Slash)
+ ver + Slash
+ joinStringRefs(parts.mid(index + 1), Slash);
diff --git a/src/qml/types/qqmlbind.cpp b/src/qml/types/qqmlbind.cpp
index fb2664da73..34f288b9d5 100644
--- a/src/qml/types/qqmlbind.cpp
+++ b/src/qml/types/qqmlbind.cpp
@@ -307,7 +307,7 @@ void QQmlBindPrivate::validate(QQmlBind *q) const
if (!when)
return;
- qsizetype iterationEnd = entries.length();
+ qsizetype iterationEnd = entries.size();
if (lastIsTarget) {
if (obj) {
Q_ASSERT(!entries.isEmpty());
@@ -604,7 +604,7 @@ void QQmlBind::setDelayed(bool delayed)
oldEntries.pop_back();
}
- for (qsizetype i = 0, end = oldEntries.length(); i < end; ++i) {
+ for (qsizetype i = 0, end = oldEntries.size(); i < end; ++i) {
QQmlBindEntry &newEntry = d->entries[i];
QQmlBindEntry &oldEntry = oldEntries[i];
newEntry.previousKind = newEntry.previous.set(
@@ -757,7 +757,8 @@ void QQmlBindPrivate::decodeBinding(
if (!immediateState)
return;
- QQmlProperty property(q, propertyName);
+ QQmlProperty property = QQmlPropertyPrivate::create(
+ q, propertyName, contextData, QQmlPropertyPrivate::InitFlag::AllowSignal);
if (property.isValid()) {
if (!immediateState->creator) {
immediateState->completePending = true;
@@ -794,7 +795,7 @@ void QQmlBindPrivate::decodeBinding(
if (delayed) {
if (!delayedValues)
createDelayedValues();
- const QString delayedName = QString::number(entries.length());
+ const QString delayedName = QString::number(entries.size());
delayedValues->insert(delayedName, QVariant());
QQmlProperty bindingTarget = QQmlProperty(delayedValues.get(), delayedName);
Q_ASSERT(bindingTarget.isValid());
@@ -863,7 +864,7 @@ void QQmlBindPrivate::evalDelayed()
bool ok;
const int delayedIndex = delayedName.toInt(&ok);
Q_ASSERT(ok);
- Q_ASSERT(delayedIndex >= 0 && delayedIndex < entries.length());
+ Q_ASSERT(delayedIndex >= 0 && delayedIndex < entries.size());
entries[delayedIndex].prop.write((*delayedValues)[delayedName]);
}
(*delayedValues)[pendingName].setValue(QStringList());
@@ -1010,7 +1011,7 @@ void QQmlBind::eval()
return;
d->writingProperty = true;
- for (qsizetype i = 0, end = d->entries.length(); i != end; ++i) {
+ for (qsizetype i = 0, end = d->entries.size(); i != end; ++i) {
QQmlBindEntry &entry = d->entries[i];
if (!entry.prop.isValid())
continue;
diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp
index 60d0e7a085..1527a2ea34 100644
--- a/src/qml/types/qqmlconnections.cpp
+++ b/src/qml/types/qqmlconnections.cpp
@@ -24,15 +24,13 @@ Q_LOGGING_CATEGORY(lcQmlConnections, "qt.qml.connections")
class QQmlConnectionsPrivate : public QObjectPrivate
{
public:
- QQmlConnectionsPrivate() : target(nullptr), enabled(true), targetSet(false), ignoreUnknownSignals(false), componentcomplete(true) {}
-
QList<QQmlBoundSignal*> boundsignals;
- QObject *target;
+ QQmlGuard<QObject> target;
- bool enabled;
- bool targetSet;
- bool ignoreUnknownSignals;
- bool componentcomplete;
+ bool enabled = true;
+ bool targetSet = false;
+ bool ignoreUnknownSignals = false;
+ bool componentcomplete = true;
QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit;
QList<const QV4::CompiledData::Binding *> bindings;
@@ -94,6 +92,12 @@ public:
}
\endqml
+ \note For backwards compatibility you can also specify the signal handlers
+ without \c{function}, like you would specify them directly in the target
+ object. This is not recommended. If you specify one signal handler this way,
+ then all signal handlers specified as \c{function} in the same Connections
+ object are ignored.
+
\sa {Qt QML}
*/
QQmlConnections::QQmlConnections(QObject *parent) :
@@ -113,7 +117,7 @@ QQmlConnections::QQmlConnections(QObject *parent) :
QObject *QQmlConnections::target() const
{
Q_D(const QQmlConnections);
- return d->targetSet ? d->target : parent();
+ return d->targetSet ? d->target.data() : parent();
}
class QQmlBoundSignalDeleter : public QObject
@@ -132,7 +136,7 @@ void QQmlConnections::setTarget(QObject *obj)
if (d->targetSet && d->target == obj)
return;
d->targetSet = true; // even if setting to 0, it is *set*
- for (QQmlBoundSignal *s : qAsConst(d->boundsignals)) {
+ for (QQmlBoundSignal *s : std::as_const(d->boundsignals)) {
// It is possible that target is being changed due to one of our signal
// handlers -> use deleteLater().
if (s->isNotifying())
@@ -168,7 +172,7 @@ void QQmlConnections::setEnabled(bool enabled)
d->enabled = enabled;
- for (QQmlBoundSignal *s : qAsConst(d->boundsignals))
+ for (QQmlBoundSignal *s : std::as_const(d->boundsignals))
s->setEnabled(d->enabled);
emit enabledChanged();
@@ -197,11 +201,11 @@ void QQmlConnections::setIgnoreUnknownSignals(bool ignore)
void QQmlConnectionsParser::verifyBindings(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QList<const QV4::CompiledData::Binding *> &props)
{
- for (int ii = 0; ii < props.count(); ++ii) {
+ for (int ii = 0; ii < props.size(); ++ii) {
const QV4::CompiledData::Binding *binding = props.at(ii);
const QString &propName = compilationUnit->stringAt(binding->propertyNameIndex);
- const bool thirdCharacterIsValid = (propName.length() >= 2)
+ const bool thirdCharacterIsValid = (propName.size() >= 2)
&& (propName.at(2).isUpper() || propName.at(2) == u'_');
if (!propName.startsWith(QLatin1String("on")) || !thirdCharacterIsValid) {
error(props.at(ii), QQmlConnections::tr("Cannot assign to non-existent property \"%1\"").arg(propName));
@@ -298,7 +302,7 @@ void QQmlConnections::connectSignalsToMethods()
signal->takeExpression(expression);
d->boundsignals += signal;
} else if (!d->ignoreUnknownSignals
- && propName.startsWith(QLatin1String("on")) && propName.length() > 2
+ && propName.startsWith(QLatin1String("on")) && propName.size() > 2
&& propName.at(2).isUpper()) {
qmlWarning(this) << tr("Detected function \"%1\" in Connections element. "
"This is probably intended to be a signal handler but no "
@@ -315,7 +319,7 @@ void QQmlConnections::connectSignalsToBindings()
QQmlData *ddata = QQmlData::get(this);
QQmlRefPointer<QQmlContextData> ctxtdata = ddata ? ddata->outerContext : nullptr;
- for (const QV4::CompiledData::Binding *binding : qAsConst(d->bindings)) {
+ for (const QV4::CompiledData::Binding *binding : std::as_const(d->bindings)) {
Q_ASSERT(binding->type() == QV4::CompiledData::Binding::Type_Script);
QString propName = d->compilationUnit->stringAt(binding->propertyNameIndex);
diff --git a/src/qml/util/qqmlpropertymap.cpp b/src/qml/util/qqmlpropertymap.cpp
index 663d4974a7..494bf4e744 100644
--- a/src/qml/util/qqmlpropertymap.cpp
+++ b/src/qml/util/qqmlpropertymap.cpp
@@ -263,7 +263,7 @@ QStringList QQmlPropertyMap::keys() const
int QQmlPropertyMap::count() const
{
Q_D(const QQmlPropertyMap);
- return d->keys.count();
+ return d->keys.size();
}
/*!