aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--src/3rdparty/double-conversion/README6
-rw-r--r--src/3rdparty/double-conversion/bignum-dtoa.cc641
-rw-r--r--src/3rdparty/double-conversion/bignum-dtoa.h84
-rw-r--r--src/3rdparty/double-conversion/bignum.cc766
-rw-r--r--src/3rdparty/double-conversion/bignum.h145
-rw-r--r--src/3rdparty/double-conversion/cached-powers.cc178
-rw-r--r--src/3rdparty/double-conversion/cached-powers.h64
-rw-r--r--src/3rdparty/double-conversion/diy-fp.cc57
-rw-r--r--src/3rdparty/double-conversion/diy-fp.h118
-rw-r--r--src/3rdparty/double-conversion/double-conversion.cc975
-rw-r--r--src/3rdparty/double-conversion/double-conversion.h543
-rw-r--r--src/3rdparty/double-conversion/double-conversion.pri24
-rw-r--r--src/3rdparty/double-conversion/fast-dtoa.cc665
-rw-r--r--src/3rdparty/double-conversion/fast-dtoa.h88
-rw-r--r--src/3rdparty/double-conversion/fixed-dtoa.cc404
-rw-r--r--src/3rdparty/double-conversion/fixed-dtoa.h56
-rw-r--r--src/3rdparty/double-conversion/ieee.h402
-rw-r--r--src/3rdparty/double-conversion/strtod.cc555
-rw-r--r--src/3rdparty/double-conversion/strtod.h45
-rw-r--r--src/3rdparty/double-conversion/utils.h330
-rw-r--r--src/3rdparty/masm/wtf/Platform.h5
-rw-r--r--src/imports/folderlistmodel/fileinfothread.cpp14
-rw-r--r--src/imports/folderlistmodel/fileinfothread_p.h2
-rw-r--r--src/imports/folderlistmodel/plugin.cpp9
-rw-r--r--src/imports/folderlistmodel/qquickfolderlistmodel.cpp27
-rw-r--r--src/imports/folderlistmodel/qquickfolderlistmodel.h3
-rw-r--r--src/imports/localstorage/plugin.cpp11
-rw-r--r--src/imports/models/plugin.cpp8
-rw-r--r--src/imports/particles/plugin.cpp8
-rw-r--r--src/imports/qtquick2/plugin.cpp8
-rw-r--r--src/imports/settings/plugin.cpp8
-rw-r--r--src/imports/statemachine/plugin.cpp8
-rw-r--r--src/imports/testlib/main.cpp8
-rw-r--r--src/imports/window/plugin.cpp9
-rw-r--r--src/imports/xmllistmodel/plugin.cpp8
-rw-r--r--src/particles/qquickparticleaffector_p.h3
-rw-r--r--src/particles/qquickparticlesystem_p.h9
-rw-r--r--src/particles/qquickv4particledata.cpp4
-rw-r--r--src/particles/qquickwander.cpp2
-rw-r--r--src/plugins/qmltooling/packetprotocol/packetprotocol.pro13
-rw-r--r--src/plugins/qmltooling/packetprotocol/qpacket.cpp112
-rw-r--r--src/plugins/qmltooling/packetprotocol/qpacket_p.h67
-rw-r--r--src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp293
-rw-r--r--src/plugins/qmltooling/packetprotocol/qpacketprotocol_p.h (renamed from tools/qmlprofiler/qpacketprotocol.h)78
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.cpp31
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.h15
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qmldbg_debugger.pro6
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservicefactory.cpp4
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp33
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.h8
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qqmlnativedebugservice.cpp15
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qqmlnativedebugservice.h10
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp186
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h90
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp416
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugger.h192
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp108
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.h18
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp295
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h29
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.cpp23
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/inspecttool.cpp2
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro3
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/qqmlinspectorservice.cpp8
-rw-r--r--src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp1
-rw-r--r--src/plugins/qmltooling/qmldbg_native/qmldbg_native.pro9
-rw-r--r--src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp83
-rw-r--r--src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.h83
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qmldbg_profiler.pro3
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp38
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.h28
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp14
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.h2
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp86
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h33
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.cpp4
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp115
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h20
-rw-r--r--src/plugins/qmltooling/qmldbg_quickprofiler/qmldbg_quickprofiler.pro20
-rw-r--r--src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp169
-rw-r--r--src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.h70
-rw-r--r--src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.json3
-rw-r--r--src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapterfactory.cpp (renamed from tools/qmlprofiler/qmlprofilereventlocation.h)25
-rw-r--r--src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapterfactory.h63
-rw-r--r--src/plugins/qmltooling/qmldbg_server/qmldbg_server.pro9
-rw-r--r--src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp150
-rw-r--r--src/plugins/qmltooling/qmltooling.pro17
-rw-r--r--src/plugins/qmltooling/shared/qpacketprotocol.cpp531
-rw-r--r--src/plugins/qmltooling/shared/qqmlconfigurabledebugservice.h8
-rw-r--r--src/plugins/qmltooling/shared/qqmldebugpacket.h64
-rw-r--r--src/plugins/qmltooling/shared/qqmldebugserver.h2
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp1
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp2
-rw-r--r--src/qml/compiler/qv4jsir.cpp20
-rw-r--r--src/qml/compiler/qv4ssa.cpp2
-rw-r--r--src/qml/debugger/qqmlabstractprofileradapter_p.h14
-rw-r--r--src/qml/debugger/qqmldebug.cpp81
-rw-r--r--src/qml/debugger/qqmldebug.h7
-rw-r--r--src/qml/debugger/qqmldebugconnector.cpp3
-rw-r--r--src/qml/debugger/qqmldebugconnector_p.h11
-rw-r--r--src/qml/debugger/qqmldebugservice.cpp34
-rw-r--r--src/qml/debugger/qqmldebugservice_p.h26
-rw-r--r--src/qml/debugger/qqmldebugserviceinterfaces.cpp2
-rw-r--r--src/qml/debugger/qqmldebugserviceinterfaces_p.h47
-rw-r--r--src/qml/debugger/qqmlprofilerdefinitions_p.h23
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/imports.qdoc1
-rw-r--r--src/qml/jit/qv4binop.cpp2
-rw-r--r--src/qml/jsapi/qjsengine.cpp24
-rw-r--r--src/qml/jsapi/qjsengine_p.h3
-rw-r--r--src/qml/jsapi/qjsvalue.cpp3
-rw-r--r--src/qml/jsapi/qjsvalueiterator_p.h2
-rw-r--r--src/qml/jsruntime/jsruntime.pri4
-rw-r--r--src/qml/jsruntime/qv4dataview.cpp2
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp48
-rw-r--r--src/qml/jsruntime/qv4dateobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4debugging.cpp286
-rw-r--r--src/qml/jsruntime/qv4debugging_p.h159
-rw-r--r--src/qml/jsruntime/qv4global_p.h2
-rw-r--r--src/qml/jsruntime/qv4globalobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4identifier_p.h2
-rw-r--r--src/qml/jsruntime/qv4include_p.h1
-rw-r--r--src/qml/jsruntime/qv4math_p.h73
-rw-r--r--src/qml/jsruntime/qv4mathobject.cpp42
-rw-r--r--src/qml/jsruntime/qv4numberobject.cpp48
-rw-r--r--src/qml/jsruntime/qv4numberobject_p.h9
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp3
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp37
-rw-r--r--src/qml/jsruntime/qv4serialize_p.h2
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp2
-rw-r--r--src/qml/parser/qqmljsengine_p.cpp4
-rw-r--r--src/qml/parser/qqmljskeywords_p.h2
-rw-r--r--src/qml/qml/qqmlapplicationengine.cpp4
-rw-r--r--src/qml/qml/qqmlboundsignal.cpp25
-rw-r--r--src/qml/qml/qqmlboundsignal_p.h4
-rw-r--r--src/qml/qml/qqmlcomponent_p.h2
-rw-r--r--src/qml/qml/qqmlengine.cpp12
-rw-r--r--src/qml/qml/qqmlglobal_p.h2
-rw-r--r--src/qml/qml/qqmlimport.cpp18
-rw-r--r--src/qml/qml/qqmllistwrapper_p.h2
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp7
-rw-r--r--src/qml/qml/qqmlplatform.cpp2
-rw-r--r--src/qml/qml/qqmlproperty.cpp8
-rw-r--r--src/qml/qml/qqmlpropertycache_p.h1
-rw-r--r--src/qml/qml/qqmlstringconverters.cpp16
-rw-r--r--src/qml/qml/qqmltypeloader.cpp1
-rw-r--r--src/qml/qml/qqmltypewrapper_p.h1
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper_p.h1
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp6
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp2
-rw-r--r--src/qml/qml/qqmlxmlhttprequest_p.h2
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp12
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions_p.h1
-rw-r--r--src/qml/qml/v8/qv8engine_p.h1
-rw-r--r--src/qml/types/qqmlconnections.cpp31
-rw-r--r--src/qml/types/qqmlconnections_p.h5
-rw-r--r--src/qml/types/qqmllistmodelworkeragent.cpp4
-rw-r--r--src/qml/types/qqmllistmodelworkeragent_p.h6
-rw-r--r--src/qmldebug/qmldebug.pro21
-rw-r--r--src/qmldebug/qqmldebugclient.cpp124
-rw-r--r--src/qmldebug/qqmldebugclient_p.h (renamed from tools/qmlprofiler/qqmldebugclient.h)68
-rw-r--r--src/qmldebug/qqmldebugclient_p_p.h66
-rw-r--r--src/qmldebug/qqmldebugconnection.cpp458
-rw-r--r--src/qmldebug/qqmldebugconnection_p.h (renamed from tests/auto/qml/debugger/shared/qqmldebugclient.h)101
-rw-r--r--src/qmldebug/qqmlenginecontrolclient.cpp147
-rw-r--r--src/qmldebug/qqmlenginecontrolclient_p.h (renamed from src/plugins/qmltooling/shared/qpacketprotocol.h)91
-rw-r--r--src/qmldebug/qqmlenginecontrolclient_p_p.h85
-rw-r--r--src/qmldebug/qqmleventlocation_p.h67
-rw-r--r--src/qmldebug/qqmlprofilerclient.cpp354
-rw-r--r--src/qmldebug/qqmlprofilerclient_p.h108
-rw-r--r--src/qmldebug/qqmlprofilerclient_p_p.h64
-rw-r--r--src/qmldevtools/qmldevtools.pro2
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp6
-rw-r--r--src/quick/items/qquickgridview.cpp22
-rw-r--r--src/quick/items/qquickitem.cpp88
-rw-r--r--src/quick/items/qquickitem.h4
-rw-r--r--src/quick/items/qquickitem_p.h2
-rw-r--r--src/quick/items/qquickitemsmodule.cpp3
-rw-r--r--src/quick/items/qquickitemview.cpp26
-rw-r--r--src/quick/items/qquickitemview_p.h5
-rw-r--r--src/quick/items/qquickitemview_p_p.h2
-rw-r--r--src/quick/items/qquicklistview.cpp68
-rw-r--r--src/quick/items/qquickloader.cpp18
-rw-r--r--src/quick/items/qquickshadereffect.cpp10
-rw-r--r--src/quick/items/qquickspriteengine.cpp12
-rw-r--r--src/quick/items/qquicktext.cpp4
-rw-r--r--src/quick/items/qquicktextcontrol.cpp2
-rw-r--r--src/quick/items/qquicktextedit_p_p.h4
-rw-r--r--src/quick/items/qquicktextinput.cpp6
-rw-r--r--src/quick/items/qquicktextinput_p_p.h4
-rw-r--r--src/quick/items/qquicktextnode_p.h2
-rw-r--r--src/quick/items/qquickview.cpp10
-rw-r--r--src/quick/items/qquickwindow.cpp16
-rw-r--r--src/quick/qtquick2.cpp4
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp104
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h9
-rw-r--r--src/quick/scenegraph/qsgrenderloop.cpp35
-rw-r--r--src/quick/scenegraph/util/qsgatlastexture.cpp4
-rw-r--r--src/quick/scenegraph/util/qsgtexture.cpp2
-rw-r--r--src/quick/util/qquickanimatorjob.cpp3
-rw-r--r--src/quick/util/qquickglobal.cpp10
-rw-r--r--src/quick/util/qquickpixmapcache.cpp3
-rw-r--r--src/quick/util/qquickprofiler.cpp117
-rw-r--r--src/quick/util/qquickprofiler_p.h52
-rw-r--r--src/quickwidgets/qquickwidget.cpp29
-rw-r--r--src/src.pro1
-rw-r--r--sync.profile2
-rw-r--r--tests/auto/particles/qquickage/qquickage.pro1
-rw-r--r--tests/auto/particles/qquickangleddirection/qquickangleddirection.pro1
-rw-r--r--tests/auto/particles/qquickcumulativedirection/qquickcumulativedirection.pro1
-rw-r--r--tests/auto/particles/qquickcustomaffector/qquickcustomaffector.pro1
-rw-r--r--tests/auto/particles/qquickcustomparticle/qquickcustomparticle.pro2
-rw-r--r--tests/auto/particles/qquickellipseextruder/qquickellipseextruder.pro1
-rw-r--r--tests/auto/particles/qquickfriction/qquickfriction.pro1
-rw-r--r--tests/auto/particles/qquickgravity/qquickgravity.pro1
-rw-r--r--tests/auto/particles/qquickgroupgoal/qquickgroupgoal.pro1
-rw-r--r--tests/auto/particles/qquickimageparticle/qquickimageparticle.pro1
-rw-r--r--tests/auto/particles/qquickitemparticle/qquickitemparticle.pro2
-rw-r--r--tests/auto/particles/qquicklineextruder/qquicklineextruder.pro1
-rw-r--r--tests/auto/particles/qquickmaskextruder/qquickmaskextruder.pro1
-rw-r--r--tests/auto/particles/qquickparticlegroup/qquickparticlegroup.pro1
-rw-r--r--tests/auto/particles/qquickparticlesystem/qquickparticlesystem.pro1
-rw-r--r--tests/auto/particles/qquickpointattractor/qquickpointattractor.pro1
-rw-r--r--tests/auto/particles/qquickpointdirection/qquickpointdirection.pro1
-rw-r--r--tests/auto/particles/qquickrectangleextruder/qquickrectangleextruder.pro1
-rw-r--r--tests/auto/particles/qquickspritegoal/qquickspritegoal.pro1
-rw-r--r--tests/auto/particles/qquicktargetdirection/qquicktargetdirection.pro1
-rw-r--r--tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro1
-rw-r--r--tests/auto/particles/qquickturbulence/qquickturbulence.pro1
-rw-r--r--tests/auto/particles/qquickwander/qquickwander.pro1
-rw-r--r--tests/auto/qml/animation/qabstractanimationjob/qabstractanimationjob.pro3
-rw-r--r--tests/auto/qml/animation/qanimationgroupjob/qanimationgroupjob.pro3
-rw-r--r--tests/auto/qml/animation/qparallelanimationgroupjob/qparallelanimationgroupjob.pro2
-rw-r--r--tests/auto/qml/animation/qpauseanimationjob/qpauseanimationjob.pro2
-rw-r--r--tests/auto/qml/animation/qsequentialanimationgroupjob/qsequentialanimationgroupjob.pro3
-rw-r--r--tests/auto/qml/debugger/debugger.pro4
-rw-r--r--tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro3
-rw-r--r--tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp40
-rw-r--r--tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro4
-rw-r--r--tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp131
-rw-r--r--tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro3
-rw-r--r--tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp32
-rw-r--r--tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp111
-rw-r--r--tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenablerserver/qqmldebuggingenablerserver.cpp9
-rw-r--r--tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenablerserver/qqmldebuggingenablerserver.pro2
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro26
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/breakpointRelocation.qml (renamed from tests/auto/qml/debugger/qqmldebugjs/data/breakpointRelocation.qml)0
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/changeBreakpoint.qml (renamed from tests/auto/qml/debugger/qqmldebugjs/data/changeBreakpoint.qml)0
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/condition.qml (renamed from tests/auto/qml/debugger/qqmldebugjs/data/condition.qml)0
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/createComponent.qml (renamed from tests/auto/qml/debugger/qqmldebugjs/data/createComponent.qml)0
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/exception.qml (renamed from tests/auto/qml/debugger/qqmldebugjs/data/exception.qml)0
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/loadjsfile.qml (renamed from tests/auto/qml/debugger/qqmldebugjs/data/loadjsfile.qml)0
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/oncompleted.qml (renamed from tests/auto/qml/debugger/qqmldebugjs/data/oncompleted.qml)0
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/quit.qml (renamed from tests/auto/qml/debugger/qqmldebugjs/data/quit.qml)0
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/stepAction.qml (renamed from tests/auto/qml/debugger/qqmldebugjs/data/stepAction.qml)0
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/test.js (renamed from tests/auto/qml/debugger/qqmldebugjs/data/test.js)0
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/test.qml (renamed from tests/auto/qml/debugger/qqmldebugjs/data/test.qml)0
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/timer.qml (renamed from tests/auto/qml/debugger/qqmldebugjs/data/timer.qml)0
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro24
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp (renamed from tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp)169
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjsserver/qqmldebugjsserver.cpp48
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjsserver/qqmldebugjsserver.pro12
-rw-r--r--tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro3
-rw-r--r--tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp20
-rw-r--r--tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro3
-rw-r--r--tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp40
-rw-r--r--tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro3
-rw-r--r--tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp132
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro3
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp27
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro3
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp38
-rw-r--r--tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro3
-rw-r--r--tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp24
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro3
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp484
-rw-r--r--tests/auto/qml/debugger/qv4debugger/qv4debugger.pro17
-rw-r--r--tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp (renamed from tests/auto/qml/qv4debugger/tst_qv4debugger.cpp)94
-rw-r--r--tests/auto/qml/debugger/shared/debugutil.cpp50
-rw-r--r--tests/auto/qml/debugger/shared/debugutil.pri10
-rw-r--r--tests/auto/qml/debugger/shared/debugutil_p.h24
-rw-r--r--tests/auto/qml/debugger/shared/qqmldebugclient.cpp511
-rw-r--r--tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp100
-rw-r--r--tests/auto/qml/debugger/shared/qqmlenginedebugclient.h13
-rw-r--r--tests/auto/qml/debugger/shared/qqmlinspectorclient.cpp17
-rw-r--r--tests/auto/qml/debugger/shared/qqmlinspectorclient.h2
-rw-r--r--tests/auto/qml/parserstress/parserstress.pro2
-rw-r--r--tests/auto/qml/qjsengine/qjsengine.pro2
-rw-r--r--tests/auto/qml/qjsonbinding/qjsonbinding.pro2
-rw-r--r--tests/auto/qml/qjsvalue/qjsvalue.pro2
-rw-r--r--tests/auto/qml/qjsvalue/tst_qjsvalue.cpp18
-rw-r--r--tests/auto/qml/qjsvalueiterator/qjsvalueiterator.pro2
-rw-r--r--tests/auto/qml/qml.pro1
-rw-r--r--tests/auto/qml/qmlmin/qmlmin.pro2
-rw-r--r--tests/auto/qml/qmlplugindump/qmlplugindump.pro2
-rw-r--r--tests/auto/qml/qqmlbinding/qqmlbinding.pro3
-rw-r--r--tests/auto/qml/qqmlchangeset/qqmlchangeset.pro3
-rw-r--r--tests/auto/qml/qqmlcomponent/qqmlcomponent.pro1
-rw-r--r--tests/auto/qml/qqmlconnections/data/test-connection.qml2
-rw-r--r--tests/auto/qml/qqmlconnections/qqmlconnections.pro3
-rw-r--r--tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp28
-rw-r--r--tests/auto/qml/qqmlconsole/qqmlconsole.pro3
-rw-r--r--tests/auto/qml/qqmlcontext/qqmlcontext.pro3
-rw-r--r--tests/auto/qml/qqmlcpputils/qqmlcpputils.pro3
-rw-r--r--tests/auto/qml/qqmldirparser/qqmldirparser.pro3
-rw-r--r--tests/auto/qml/qqmlecmascript/qqmlecmascript.pro2
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp32
-rw-r--r--tests/auto/qml/qqmlengine/qqmlengine.pro1
-rw-r--r--tests/auto/qml/qqmlenginecleanup/qqmlenginecleanup.pro1
-rw-r--r--tests/auto/qml/qqmlerror/qqmlerror.pro3
-rw-r--r--tests/auto/qml/qqmlexpression/qqmlexpression.pro3
-rw-r--r--tests/auto/qml/qqmlfileselector/qqmlfileselector.pro2
-rw-r--r--tests/auto/qml/qqmlglobal/qqmlglobal.pro2
-rw-r--r--tests/auto/qml/qqmlimport/qqmlimport.pro3
-rw-r--r--tests/auto/qml/qqmlimport/tst_qqmlimport.cpp26
-rw-r--r--tests/auto/qml/qqmlincubator/qqmlincubator.pro2
-rw-r--r--tests/auto/qml/qqmlinfo/qqmlinfo.pro2
-rw-r--r--tests/auto/qml/qqmlitemmodels/qqmlitemmodels.pro3
-rw-r--r--tests/auto/qml/qqmllanguage/qqmllanguage.pro1
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp6
-rw-r--r--tests/auto/qml/qqmllistcompositor/qqmllistcompositor.pro3
-rw-r--r--tests/auto/qml/qqmllistmodel/qqmllistmodel.pro3
-rw-r--r--tests/auto/qml/qqmllistmodelworkerscript/qqmllistmodelworkerscript.pro1
-rw-r--r--tests/auto/qml/qqmllistreference/qqmllistreference.pro3
-rw-r--r--tests/auto/qml/qqmllocale/qqmllocale.pro2
-rw-r--r--tests/auto/qml/qqmlmetaobject/qqmlmetaobject.pro2
-rw-r--r--tests/auto/qml/qqmlmetatype/qqmlmetatype.pro2
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/invalidFirstCommandModule/invalidFirstCommandModule.pro1
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/invalidNamespaceModule/invalidNamespaceModule.pro1
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/invalidStrictModule.pro1
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/nestedPlugin/nestedPlugin.pro1
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/nonstrictModule/nonstrictModule.pro1
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/plugin.2.1/plugin.2.1.pro1
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/plugin.2/plugin.2.pro1
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/plugin/plugin.pro1
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/pluginMixed/pluginMixed.pro1
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/pluginVersion/pluginVersion.pro1
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/pluginWithQmlFile/pluginWithQmlFile.pro1
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/pluginWrongCase/pluginWrongCase.pro1
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/preemptedStrictModule/preemptedStrictModule.pro1
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/preemptiveModule/preemptiveModule.pro1
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/protectedModule/protectedModule.pro1
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro2
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/strictModule.2/strictModule.2.pro1
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/strictModule/strictModule.pro1
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.pro1
-rw-r--r--tests/auto/qml/qqmlobjectmodel/qqmlobjectmodel.pro2
-rw-r--r--tests/auto/qml/qqmlopenmetaobject/qqmlopenmetaobject.pro2
-rw-r--r--tests/auto/qml/qqmlparser/qqmlparser.pro3
-rw-r--r--tests/auto/qml/qqmlproperty/data/floatToStringPrecision.qml24
-rw-r--r--tests/auto/qml/qqmlproperty/qqmlproperty.pro3
-rw-r--r--tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp44
-rw-r--r--tests/auto/qml/qqmlpropertycache/qqmlpropertycache.pro2
-rw-r--r--tests/auto/qml/qqmlpropertymap/qqmlpropertymap.pro3
-rw-r--r--tests/auto/qml/qqmlqt/qqmlqt.pro1
-rw-r--r--tests/auto/qml/qqmlsettings/qqmlsettings.pro1
-rw-r--r--tests/auto/qml/qqmlsqldatabase/qqmlsqldatabase.pro1
-rw-r--r--tests/auto/qml/qqmlstatemachine/qqmlstatemachine.pro2
-rw-r--r--tests/auto/qml/qqmltimer/qqmltimer.pro2
-rw-r--r--tests/auto/qml/qqmltranslation/qqmltranslation.pro3
-rw-r--r--tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.pro2
-rw-r--r--tests/auto/qml/qqmlvaluetypeproviders/qqmlvaluetypeproviders.pro3
-rw-r--r--tests/auto/qml/qqmlvaluetypes/qqmlvaluetypes.pro3
-rw-r--r--tests/auto/qml/qqmlxmlhttprequest/qqmlxmlhttprequest.pro1
-rw-r--r--tests/auto/qml/qquickfolderlistmodel/qquickfolderlistmodel.pro2
-rw-r--r--tests/auto/qml/qquickworkerscript/qquickworkerscript.pro3
-rw-r--r--tests/auto/qml/qrcqml/qrcqml.pro3
-rw-r--r--tests/auto/qml/qtqmlmodules/qtqmlmodules.pro1
-rw-r--r--tests/auto/qml/qv4debugger/qv4debugger.pro15
-rw-r--r--tests/auto/qml/v4misc/v4misc.pro2
-rw-r--r--tests/auto/qmldevtools/compile/compile.pro1
-rw-r--r--tests/auto/qmltest/qmltest.pro1
-rw-r--r--tests/auto/quick/examples/examples.pro2
-rw-r--r--tests/auto/quick/geometry/geometry.pro1
-rw-r--r--tests/auto/quick/nodes/nodes.pro1
-rw-r--r--tests/auto/quick/nokeywords/nokeywords.pro1
-rw-r--r--tests/auto/quick/qquickaccessible/qquickaccessible.pro3
-rw-r--r--tests/auto/quick/qquickanchors/qquickanchors.pro3
-rw-r--r--tests/auto/quick/qquickanimatedimage/qquickanimatedimage.pro1
-rw-r--r--tests/auto/quick/qquickanimatedsprite/qquickanimatedsprite.pro3
-rw-r--r--tests/auto/quick/qquickanimationcontroller/qquickanimationcontroller.pro2
-rw-r--r--tests/auto/quick/qquickanimations/qquickanimations.pro57
-rw-r--r--tests/auto/quick/qquickapplication/qquickapplication.pro2
-rw-r--r--tests/auto/quick/qquickbehaviors/qquickbehaviors.pro3
-rw-r--r--tests/auto/quick/qquickborderimage/qquickborderimage.pro1
-rw-r--r--tests/auto/quick/qquickcanvasitem/qquickcanvasitem.pro30
-rw-r--r--tests/auto/quick/qquickdesignersupport/qquickdesignersupport.pro1
-rw-r--r--tests/auto/quick/qquickdrag/qquickdrag.pro3
-rw-r--r--tests/auto/quick/qquickdroparea/qquickdroparea.pro3
-rw-r--r--tests/auto/quick/qquickdynamicpropertyanimation/qquickdynamicpropertyanimation.pro3
-rw-r--r--tests/auto/quick/qquickflickable/qquickflickable.pro1
-rw-r--r--tests/auto/quick/qquickflipable/qquickflipable.pro3
-rw-r--r--tests/auto/quick/qquickfocusscope/qquickfocusscope.pro1
-rw-r--r--tests/auto/quick/qquickfontloader/qquickfontloader.pro1
-rw-r--r--tests/auto/quick/qquickfontmetrics/qquickfontmetrics.pro3
-rw-r--r--tests/auto/quick/qquickframebufferobject/qquickframebufferobject.pro1
-rw-r--r--tests/auto/quick/qquickgridview/qquickgridview.pro1
-rw-r--r--tests/auto/quick/qquickgridview/tst_qquickgridview.cpp67
-rw-r--r--tests/auto/quick/qquickimage/qquickimage.pro1
-rw-r--r--tests/auto/quick/qquickimageprovider/qquickimageprovider.pro3
-rw-r--r--tests/auto/quick/qquickitem/qquickitem.pro1
-rw-r--r--tests/auto/quick/qquickitem2/qquickitem2.pro1
-rw-r--r--tests/auto/quick/qquickitem2/tst_qquickitem.cpp38
-rw-r--r--tests/auto/quick/qquickitemlayer/qquickitemlayer.pro2
-rw-r--r--tests/auto/quick/qquicklistview/qquicklistview.pro1
-rw-r--r--tests/auto/quick/qquicklistview/tst_qquicklistview.cpp67
-rw-r--r--tests/auto/quick/qquickloader/qquickloader.pro1
-rw-r--r--tests/auto/quick/qquickloader/tst_qquickloader.cpp69
-rw-r--r--tests/auto/quick/qquickmousearea/qquickmousearea.pro1
-rw-r--r--tests/auto/quick/qquickmultipointtoucharea/qquickmultipointtoucharea.pro2
-rw-r--r--tests/auto/quick/qquickopenglinfo/qquickopenglinfo.pro1
-rw-r--r--tests/auto/quick/qquickpainteditem/qquickpainteditem.pro3
-rw-r--r--tests/auto/quick/qquickpath/qquickpath.pro3
-rw-r--r--tests/auto/quick/qquickpathview/qquickpathview.pro1
-rw-r--r--tests/auto/quick/qquickpincharea/qquickpincharea.pro2
-rw-r--r--tests/auto/quick/qquickpixmapcache/qquickpixmapcache.pro1
-rw-r--r--tests/auto/quick/qquickpositioners/qquickpositioners.pro1
-rw-r--r--tests/auto/quick/qquickrectangle/qquickrectangle.pro1
-rw-r--r--tests/auto/quick/qquickrepeater/qquickrepeater.pro2
-rw-r--r--tests/auto/quick/qquickscreen/qquickscreen.pro2
-rw-r--r--tests/auto/quick/qquickshadereffect/qquickshadereffect.pro2
-rw-r--r--tests/auto/quick/qquickshortcut/qquickshortcut.pro1
-rw-r--r--tests/auto/quick/qquicksmoothedanimation/qquicksmoothedanimation.pro3
-rw-r--r--tests/auto/quick/qquickspringanimation/qquickspringanimation.pro3
-rw-r--r--tests/auto/quick/qquickspritesequence/qquickspritesequence.pro3
-rw-r--r--tests/auto/quick/qquickstates/qquickstates.pro2
-rw-r--r--tests/auto/quick/qquickstyledtext/qquickstyledtext.pro2
-rw-r--r--tests/auto/quick/qquicksystempalette/qquicksystempalette.pro2
-rw-r--r--tests/auto/quick/qquicktext/qquicktext.pro1
-rw-r--r--tests/auto/quick/qquicktextdocument/qquicktextdocument.pro3
-rw-r--r--tests/auto/quick/qquicktextedit/qquicktextedit.pro2
-rw-r--r--tests/auto/quick/qquicktextinput/qquicktextinput.pro2
-rw-r--r--tests/auto/quick/qquicktextmetrics/qquicktextmetrics.pro3
-rw-r--r--tests/auto/quick/qquicktimeline/qquicktimeline.pro2
-rw-r--r--tests/auto/quick/qquickview/qquickview.pro2
-rw-r--r--tests/auto/quick/qquickvisualdatamodel/qquickvisualdatamodel.pro1
-rw-r--r--tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp14
-rw-r--r--tests/auto/quick/qquickwindow/qquickwindow.pro2
-rw-r--r--tests/auto/quick/qquickwindow/tst_qquickwindow.cpp2
-rw-r--r--tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro3
-rw-r--r--tests/auto/quick/rendernode/rendernode.pro2
-rw-r--r--tests/auto/quick/scenegraph/scenegraph.pro1
-rw-r--r--tests/auto/quick/shared/viewtestutil.cpp12
-rw-r--r--tests/auto/quick/shared/viewtestutil.h1
-rw-r--r--tests/auto/quick/touchmouse/touchmouse.pro1
-rw-r--r--tests/auto/quickwidgets/qquickwidget/qquickwidget.pro1
-rw-r--r--tests/auto/toolsupport/toolsupport.pro2
-rw-r--r--tests/benchmarks/particles/affectors/affectors.pro1
-rw-r--r--tests/benchmarks/particles/emission/emission.pro1
-rw-r--r--tests/benchmarks/qml/animation/animation.pro1
-rw-r--r--tests/benchmarks/qml/binding/binding.pro1
-rw-r--r--tests/benchmarks/qml/compilation/compilation.pro1
-rw-r--r--tests/benchmarks/qml/creation/creation.pro1
-rw-r--r--tests/benchmarks/qml/holistic/holistic.pro1
-rw-r--r--tests/benchmarks/qml/javascript/javascript.pro1
-rw-r--r--tests/benchmarks/qml/js/qjsengine/qjsengine.pro1
-rw-r--r--tests/benchmarks/qml/js/qjsvalue/qjsvalue.pro1
-rw-r--r--tests/benchmarks/qml/js/qjsvalueiterator/qjsvalueiterator.pro1
-rw-r--r--tests/benchmarks/qml/painting/painting.pro1
-rw-r--r--tests/benchmarks/qml/pointers/pointers.pro2
-rw-r--r--tests/benchmarks/qml/pointers/tst_pointers.cpp2
-rw-r--r--tests/benchmarks/qml/qmltime/qmltime.pro1
-rw-r--r--tests/benchmarks/qml/qqmlcomponent/qqmlcomponent.pro1
-rw-r--r--tests/benchmarks/qml/qqmldebugtrace/qqmldebugtrace.pro1
-rw-r--r--tests/benchmarks/qml/qqmlimage/qqmlimage.pro1
-rw-r--r--tests/benchmarks/qml/qqmlmetaproperty/qqmlmetaproperty.pro1
-rw-r--r--tests/benchmarks/qml/qquickwindow/qquickwindow.pro1
-rw-r--r--tests/benchmarks/qml/typeimports/typeimports.pro1
-rw-r--r--tests/benchmarks/script/qjsvalue/qjsvalue.pro1
-rw-r--r--tools/qmleasing/splineeditor.cpp2
-rw-r--r--tools/qmleasing/splineeditor.h2
-rw-r--r--tools/qmlmin/main.cpp2
-rw-r--r--tools/qmlprofiler/qmlprofiler.pro11
-rw-r--r--tools/qmlprofiler/qmlprofilerapplication.cpp157
-rw-r--r--tools/qmlprofiler/qmlprofilerapplication.h24
-rw-r--r--tools/qmlprofiler/qmlprofilerclient.cpp371
-rw-r--r--tools/qmlprofiler/qmlprofilerclient.h111
-rw-r--r--tools/qmlprofiler/qmlprofilerdata.cpp242
-rw-r--r--tools/qmlprofiler/qmlprofilerdata.h18
-rw-r--r--tools/qmlprofiler/qpacketprotocol.cpp527
-rw-r--r--tools/qmlprofiler/qqmldebugclient.cpp403
481 files changed, 6720 insertions, 11937 deletions
diff --git a/.qmake.conf b/.qmake.conf
index fc13c75da5..3bc6c0a02b 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -2,4 +2,4 @@ load(qt_build_config)
CONFIG += qt_example_installs
CONFIG += warning_clean
-MODULE_VERSION = 5.6.0
+MODULE_VERSION = 5.7.0
diff --git a/src/3rdparty/double-conversion/README b/src/3rdparty/double-conversion/README
deleted file mode 100644
index 3a9733d795..0000000000
--- a/src/3rdparty/double-conversion/README
+++ /dev/null
@@ -1,6 +0,0 @@
-This is a copy of the library for binary-decimal and decimal-binary conversion routines for IEEE doubles, taken
-from
-
- http://code.google.com/p/double-conversion/
-
-commit 2fb03de56faa32bbba5e02222528e7b760f71d77
diff --git a/src/3rdparty/double-conversion/bignum-dtoa.cc b/src/3rdparty/double-conversion/bignum-dtoa.cc
deleted file mode 100644
index f1ad7a5ae8..0000000000
--- a/src/3rdparty/double-conversion/bignum-dtoa.cc
+++ /dev/null
@@ -1,641 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include <math.h>
-
-#include "bignum-dtoa.h"
-
-#include "bignum.h"
-#include "ieee.h"
-
-namespace double_conversion {
-
-static int NormalizedExponent(uint64_t significand, int exponent) {
- ASSERT(significand != 0);
- while ((significand & Double::kHiddenBit) == 0) {
- significand = significand << 1;
- exponent = exponent - 1;
- }
- return exponent;
-}
-
-
-// Forward declarations:
-// Returns an estimation of k such that 10^(k-1) <= v < 10^k.
-static int EstimatePower(int exponent);
-// Computes v / 10^estimated_power exactly, as a ratio of two bignums, numerator
-// and denominator.
-static void InitialScaledStartValues(uint64_t significand,
- int exponent,
- bool lower_boundary_is_closer,
- int estimated_power,
- bool need_boundary_deltas,
- Bignum* numerator,
- Bignum* denominator,
- Bignum* delta_minus,
- Bignum* delta_plus);
-// Multiplies numerator/denominator so that its values lies in the range 1-10.
-// Returns decimal_point s.t.
-// v = numerator'/denominator' * 10^(decimal_point-1)
-// where numerator' and denominator' are the values of numerator and
-// denominator after the call to this function.
-static void FixupMultiply10(int estimated_power, bool is_even,
- int* decimal_point,
- Bignum* numerator, Bignum* denominator,
- Bignum* delta_minus, Bignum* delta_plus);
-// Generates digits from the left to the right and stops when the generated
-// digits yield the shortest decimal representation of v.
-static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
- Bignum* delta_minus, Bignum* delta_plus,
- bool is_even,
- Vector<char> buffer, int* length);
-// Generates 'requested_digits' after the decimal point.
-static void BignumToFixed(int requested_digits, int* decimal_point,
- Bignum* numerator, Bignum* denominator,
- Vector<char>(buffer), int* length);
-// Generates 'count' digits of numerator/denominator.
-// Once 'count' digits have been produced rounds the result depending on the
-// remainder (remainders of exactly .5 round upwards). Might update the
-// decimal_point when rounding up (for example for 0.9999).
-static void GenerateCountedDigits(int count, int* decimal_point,
- Bignum* numerator, Bignum* denominator,
- Vector<char>(buffer), int* length);
-
-
-void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits,
- Vector<char> buffer, int* length, int* decimal_point) {
- ASSERT(v > 0);
- ASSERT(!Double(v).IsSpecial());
- uint64_t significand;
- int exponent;
- bool lower_boundary_is_closer;
- if (mode == BIGNUM_DTOA_SHORTEST_SINGLE) {
- float f = static_cast<float>(v);
- ASSERT(f == v);
- significand = Single(f).Significand();
- exponent = Single(f).Exponent();
- lower_boundary_is_closer = Single(f).LowerBoundaryIsCloser();
- } else {
- significand = Double(v).Significand();
- exponent = Double(v).Exponent();
- lower_boundary_is_closer = Double(v).LowerBoundaryIsCloser();
- }
- bool need_boundary_deltas =
- (mode == BIGNUM_DTOA_SHORTEST || mode == BIGNUM_DTOA_SHORTEST_SINGLE);
-
- bool is_even = (significand & 1) == 0;
- int normalized_exponent = NormalizedExponent(significand, exponent);
- // estimated_power might be too low by 1.
- int estimated_power = EstimatePower(normalized_exponent);
-
- // Shortcut for Fixed.
- // The requested digits correspond to the digits after the point. If the
- // number is much too small, then there is no need in trying to get any
- // digits.
- if (mode == BIGNUM_DTOA_FIXED && -estimated_power - 1 > requested_digits) {
- buffer[0] = '\0';
- *length = 0;
- // Set decimal-point to -requested_digits. This is what Gay does.
- // Note that it should not have any effect anyways since the string is
- // empty.
- *decimal_point = -requested_digits;
- return;
- }
-
- Bignum numerator;
- Bignum denominator;
- Bignum delta_minus;
- Bignum delta_plus;
- // Make sure the bignum can grow large enough. The smallest double equals
- // 4e-324. In this case the denominator needs fewer than 324*4 binary digits.
- // The maximum double is 1.7976931348623157e308 which needs fewer than
- // 308*4 binary digits.
- ASSERT(Bignum::kMaxSignificantBits >= 324*4);
- InitialScaledStartValues(significand, exponent, lower_boundary_is_closer,
- estimated_power, need_boundary_deltas,
- &numerator, &denominator,
- &delta_minus, &delta_plus);
- // We now have v = (numerator / denominator) * 10^estimated_power.
- FixupMultiply10(estimated_power, is_even, decimal_point,
- &numerator, &denominator,
- &delta_minus, &delta_plus);
- // We now have v = (numerator / denominator) * 10^(decimal_point-1), and
- // 1 <= (numerator + delta_plus) / denominator < 10
- switch (mode) {
- case BIGNUM_DTOA_SHORTEST:
- case BIGNUM_DTOA_SHORTEST_SINGLE:
- GenerateShortestDigits(&numerator, &denominator,
- &delta_minus, &delta_plus,
- is_even, buffer, length);
- break;
- case BIGNUM_DTOA_FIXED:
- BignumToFixed(requested_digits, decimal_point,
- &numerator, &denominator,
- buffer, length);
- break;
- case BIGNUM_DTOA_PRECISION:
- GenerateCountedDigits(requested_digits, decimal_point,
- &numerator, &denominator,
- buffer, length);
- break;
- default:
- UNREACHABLE();
- }
- buffer[*length] = '\0';
-}
-
-
-// The procedure starts generating digits from the left to the right and stops
-// when the generated digits yield the shortest decimal representation of v. A
-// decimal representation of v is a number lying closer to v than to any other
-// double, so it converts to v when read.
-//
-// This is true if d, the decimal representation, is between m- and m+, the
-// upper and lower boundaries. d must be strictly between them if !is_even.
-// m- := (numerator - delta_minus) / denominator
-// m+ := (numerator + delta_plus) / denominator
-//
-// Precondition: 0 <= (numerator+delta_plus) / denominator < 10.
-// If 1 <= (numerator+delta_plus) / denominator < 10 then no leading 0 digit
-// will be produced. This should be the standard precondition.
-static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
- Bignum* delta_minus, Bignum* delta_plus,
- bool is_even,
- Vector<char> buffer, int* length) {
- // Small optimization: if delta_minus and delta_plus are the same just reuse
- // one of the two bignums.
- if (Bignum::Equal(*delta_minus, *delta_plus)) {
- delta_plus = delta_minus;
- }
- *length = 0;
- for (;;) {
- uint16_t digit;
- digit = numerator->DivideModuloIntBignum(*denominator);
- ASSERT(digit <= 9); // digit is a uint16_t and therefore always positive.
- // digit = numerator / denominator (integer division).
- // numerator = numerator % denominator.
- buffer[(*length)++] = static_cast<char>(digit + '0');
-
- // Can we stop already?
- // If the remainder of the division is less than the distance to the lower
- // boundary we can stop. In this case we simply round down (discarding the
- // remainder).
- // Similarly we test if we can round up (using the upper boundary).
- bool in_delta_room_minus;
- bool in_delta_room_plus;
- if (is_even) {
- in_delta_room_minus = Bignum::LessEqual(*numerator, *delta_minus);
- } else {
- in_delta_room_minus = Bignum::Less(*numerator, *delta_minus);
- }
- if (is_even) {
- in_delta_room_plus =
- Bignum::PlusCompare(*numerator, *delta_plus, *denominator) >= 0;
- } else {
- in_delta_room_plus =
- Bignum::PlusCompare(*numerator, *delta_plus, *denominator) > 0;
- }
- if (!in_delta_room_minus && !in_delta_room_plus) {
- // Prepare for next iteration.
- numerator->Times10();
- delta_minus->Times10();
- // We optimized delta_plus to be equal to delta_minus (if they share the
- // same value). So don't multiply delta_plus if they point to the same
- // object.
- if (delta_minus != delta_plus) {
- delta_plus->Times10();
- }
- } else if (in_delta_room_minus && in_delta_room_plus) {
- // Let's see if 2*numerator < denominator.
- // If yes, then the next digit would be < 5 and we can round down.
- int compare = Bignum::PlusCompare(*numerator, *numerator, *denominator);
- if (compare < 0) {
- // Remaining digits are less than .5. -> Round down (== do nothing).
- } else if (compare > 0) {
- // Remaining digits are more than .5 of denominator. -> Round up.
- // Note that the last digit could not be a '9' as otherwise the whole
- // loop would have stopped earlier.
- // We still have an assert here in case the preconditions were not
- // satisfied.
- ASSERT(buffer[(*length) - 1] != '9');
- buffer[(*length) - 1]++;
- } else {
- // Halfway case.
- // TODO(floitsch): need a way to solve half-way cases.
- // For now let's round towards even (since this is what Gay seems to
- // do).
-
- if ((buffer[(*length) - 1] - '0') % 2 == 0) {
- // Round down => Do nothing.
- } else {
- ASSERT(buffer[(*length) - 1] != '9');
- buffer[(*length) - 1]++;
- }
- }
- return;
- } else if (in_delta_room_minus) {
- // Round down (== do nothing).
- return;
- } else { // in_delta_room_plus
- // Round up.
- // Note again that the last digit could not be '9' since this would have
- // stopped the loop earlier.
- // We still have an ASSERT here, in case the preconditions were not
- // satisfied.
- ASSERT(buffer[(*length) -1] != '9');
- buffer[(*length) - 1]++;
- return;
- }
- }
-}
-
-
-// Let v = numerator / denominator < 10.
-// Then we generate 'count' digits of d = x.xxxxx... (without the decimal point)
-// from left to right. Once 'count' digits have been produced we decide wether
-// to round up or down. Remainders of exactly .5 round upwards. Numbers such
-// as 9.999999 propagate a carry all the way, and change the
-// exponent (decimal_point), when rounding upwards.
-static void GenerateCountedDigits(int count, int* decimal_point,
- Bignum* numerator, Bignum* denominator,
- Vector<char> buffer, int* length) {
- ASSERT(count >= 0);
- for (int i = 0; i < count - 1; ++i) {
- uint16_t digit;
- digit = numerator->DivideModuloIntBignum(*denominator);
- ASSERT(digit <= 9); // digit is a uint16_t and therefore always positive.
- // digit = numerator / denominator (integer division).
- // numerator = numerator % denominator.
- buffer[i] = static_cast<char>(digit + '0');
- // Prepare for next iteration.
- numerator->Times10();
- }
- // Generate the last digit.
- uint16_t digit;
- digit = numerator->DivideModuloIntBignum(*denominator);
- if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) {
- digit++;
- }
- ASSERT(digit <= 10);
- buffer[count - 1] = static_cast<char>(digit + '0');
- // Correct bad digits (in case we had a sequence of '9's). Propagate the
- // carry until we hat a non-'9' or til we reach the first digit.
- for (int i = count - 1; i > 0; --i) {
- if (buffer[i] != '0' + 10) break;
- buffer[i] = '0';
- buffer[i - 1]++;
- }
- if (buffer[0] == '0' + 10) {
- // Propagate a carry past the top place.
- buffer[0] = '1';
- (*decimal_point)++;
- }
- *length = count;
-}
-
-
-// Generates 'requested_digits' after the decimal point. It might omit
-// trailing '0's. If the input number is too small then no digits at all are
-// generated (ex.: 2 fixed digits for 0.00001).
-//
-// Input verifies: 1 <= (numerator + delta) / denominator < 10.
-static void BignumToFixed(int requested_digits, int* decimal_point,
- Bignum* numerator, Bignum* denominator,
- Vector<char>(buffer), int* length) {
- // Note that we have to look at more than just the requested_digits, since
- // a number could be rounded up. Example: v=0.5 with requested_digits=0.
- // Even though the power of v equals 0 we can't just stop here.
- if (-(*decimal_point) > requested_digits) {
- // The number is definitively too small.
- // Ex: 0.001 with requested_digits == 1.
- // Set decimal-point to -requested_digits. This is what Gay does.
- // Note that it should not have any effect anyways since the string is
- // empty.
- *decimal_point = -requested_digits;
- *length = 0;
- return;
- } else if (-(*decimal_point) == requested_digits) {
- // We only need to verify if the number rounds down or up.
- // Ex: 0.04 and 0.06 with requested_digits == 1.
- ASSERT(*decimal_point == -requested_digits);
- // Initially the fraction lies in range (1, 10]. Multiply the denominator
- // by 10 so that we can compare more easily.
- denominator->Times10();
- if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) {
- // If the fraction is >= 0.5 then we have to include the rounded
- // digit.
- buffer[0] = '1';
- *length = 1;
- (*decimal_point)++;
- } else {
- // Note that we caught most of similar cases earlier.
- *length = 0;
- }
- return;
- } else {
- // The requested digits correspond to the digits after the point.
- // The variable 'needed_digits' includes the digits before the point.
- int needed_digits = (*decimal_point) + requested_digits;
- GenerateCountedDigits(needed_digits, decimal_point,
- numerator, denominator,
- buffer, length);
- }
-}
-
-
-// Returns an estimation of k such that 10^(k-1) <= v < 10^k where
-// v = f * 2^exponent and 2^52 <= f < 2^53.
-// v is hence a normalized double with the given exponent. The output is an
-// approximation for the exponent of the decimal approimation .digits * 10^k.
-//
-// The result might undershoot by 1 in which case 10^k <= v < 10^k+1.
-// Note: this property holds for v's upper boundary m+ too.
-// 10^k <= m+ < 10^k+1.
-// (see explanation below).
-//
-// Examples:
-// EstimatePower(0) => 16
-// EstimatePower(-52) => 0
-//
-// Note: e >= 0 => EstimatedPower(e) > 0. No similar claim can be made for e<0.
-static int EstimatePower(int exponent) {
- // This function estimates log10 of v where v = f*2^e (with e == exponent).
- // Note that 10^floor(log10(v)) <= v, but v <= 10^ceil(log10(v)).
- // Note that f is bounded by its container size. Let p = 53 (the double's
- // significand size). Then 2^(p-1) <= f < 2^p.
- //
- // Given that log10(v) == log2(v)/log2(10) and e+(len(f)-1) is quite close
- // to log2(v) the function is simplified to (e+(len(f)-1)/log2(10)).
- // The computed number undershoots by less than 0.631 (when we compute log3
- // and not log10).
- //
- // Optimization: since we only need an approximated result this computation
- // can be performed on 64 bit integers. On x86/x64 architecture the speedup is
- // not really measurable, though.
- //
- // Since we want to avoid overshooting we decrement by 1e10 so that
- // floating-point imprecisions don't affect us.
- //
- // Explanation for v's boundary m+: the computation takes advantage of
- // the fact that 2^(p-1) <= f < 2^p. Boundaries still satisfy this requirement
- // (even for denormals where the delta can be much more important).
-
- const double k1Log10 = 0.30102999566398114; // 1/lg(10)
-
- // For doubles len(f) == 53 (don't forget the hidden bit).
- const int kSignificandSize = Double::kSignificandSize;
- double estimate = ceil((exponent + kSignificandSize - 1) * k1Log10 - 1e-10);
- return static_cast<int>(estimate);
-}
-
-
-// See comments for InitialScaledStartValues.
-static void InitialScaledStartValuesPositiveExponent(
- uint64_t significand, int exponent,
- int estimated_power, bool need_boundary_deltas,
- Bignum* numerator, Bignum* denominator,
- Bignum* delta_minus, Bignum* delta_plus) {
- // A positive exponent implies a positive power.
- ASSERT(estimated_power >= 0);
- // Since the estimated_power is positive we simply multiply the denominator
- // by 10^estimated_power.
-
- // numerator = v.
- numerator->AssignUInt64(significand);
- numerator->ShiftLeft(exponent);
- // denominator = 10^estimated_power.
- denominator->AssignPowerUInt16(10, estimated_power);
-
- if (need_boundary_deltas) {
- // Introduce a common denominator so that the deltas to the boundaries are
- // integers.
- denominator->ShiftLeft(1);
- numerator->ShiftLeft(1);
- // Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common
- // denominator (of 2) delta_plus equals 2^e.
- delta_plus->AssignUInt16(1);
- delta_plus->ShiftLeft(exponent);
- // Same for delta_minus. The adjustments if f == 2^p-1 are done later.
- delta_minus->AssignUInt16(1);
- delta_minus->ShiftLeft(exponent);
- }
-}
-
-
-// See comments for InitialScaledStartValues
-static void InitialScaledStartValuesNegativeExponentPositivePower(
- uint64_t significand, int exponent,
- int estimated_power, bool need_boundary_deltas,
- Bignum* numerator, Bignum* denominator,
- Bignum* delta_minus, Bignum* delta_plus) {
- // v = f * 2^e with e < 0, and with estimated_power >= 0.
- // This means that e is close to 0 (have a look at how estimated_power is
- // computed).
-
- // numerator = significand
- // since v = significand * 2^exponent this is equivalent to
- // numerator = v * / 2^-exponent
- numerator->AssignUInt64(significand);
- // denominator = 10^estimated_power * 2^-exponent (with exponent < 0)
- denominator->AssignPowerUInt16(10, estimated_power);
- denominator->ShiftLeft(-exponent);
-
- if (need_boundary_deltas) {
- // Introduce a common denominator so that the deltas to the boundaries are
- // integers.
- denominator->ShiftLeft(1);
- numerator->ShiftLeft(1);
- // Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common
- // denominator (of 2) delta_plus equals 2^e.
- // Given that the denominator already includes v's exponent the distance
- // to the boundaries is simply 1.
- delta_plus->AssignUInt16(1);
- // Same for delta_minus. The adjustments if f == 2^p-1 are done later.
- delta_minus->AssignUInt16(1);
- }
-}
-
-
-// See comments for InitialScaledStartValues
-static void InitialScaledStartValuesNegativeExponentNegativePower(
- uint64_t significand, int exponent,
- int estimated_power, bool need_boundary_deltas,
- Bignum* numerator, Bignum* denominator,
- Bignum* delta_minus, Bignum* delta_plus) {
- // Instead of multiplying the denominator with 10^estimated_power we
- // multiply all values (numerator and deltas) by 10^-estimated_power.
-
- // Use numerator as temporary container for power_ten.
- Bignum* power_ten = numerator;
- power_ten->AssignPowerUInt16(10, -estimated_power);
-
- if (need_boundary_deltas) {
- // Since power_ten == numerator we must make a copy of 10^estimated_power
- // before we complete the computation of the numerator.
- // delta_plus = delta_minus = 10^estimated_power
- delta_plus->AssignBignum(*power_ten);
- delta_minus->AssignBignum(*power_ten);
- }
-
- // numerator = significand * 2 * 10^-estimated_power
- // since v = significand * 2^exponent this is equivalent to
- // numerator = v * 10^-estimated_power * 2 * 2^-exponent.
- // Remember: numerator has been abused as power_ten. So no need to assign it
- // to itself.
- ASSERT(numerator == power_ten);
- numerator->MultiplyByUInt64(significand);
-
- // denominator = 2 * 2^-exponent with exponent < 0.
- denominator->AssignUInt16(1);
- denominator->ShiftLeft(-exponent);
-
- if (need_boundary_deltas) {
- // Introduce a common denominator so that the deltas to the boundaries are
- // integers.
- numerator->ShiftLeft(1);
- denominator->ShiftLeft(1);
- // With this shift the boundaries have their correct value, since
- // delta_plus = 10^-estimated_power, and
- // delta_minus = 10^-estimated_power.
- // These assignments have been done earlier.
- // The adjustments if f == 2^p-1 (lower boundary is closer) are done later.
- }
-}
-
-
-// Let v = significand * 2^exponent.
-// Computes v / 10^estimated_power exactly, as a ratio of two bignums, numerator
-// and denominator. The functions GenerateShortestDigits and
-// GenerateCountedDigits will then convert this ratio to its decimal
-// representation d, with the required accuracy.
-// Then d * 10^estimated_power is the representation of v.
-// (Note: the fraction and the estimated_power might get adjusted before
-// generating the decimal representation.)
-//
-// The initial start values consist of:
-// - a scaled numerator: s.t. numerator/denominator == v / 10^estimated_power.
-// - a scaled (common) denominator.
-// optionally (used by GenerateShortestDigits to decide if it has the shortest
-// decimal converting back to v):
-// - v - m-: the distance to the lower boundary.
-// - m+ - v: the distance to the upper boundary.
-//
-// v, m+, m-, and therefore v - m- and m+ - v all share the same denominator.
-//
-// Let ep == estimated_power, then the returned values will satisfy:
-// v / 10^ep = numerator / denominator.
-// v's boundarys m- and m+:
-// m- / 10^ep == v / 10^ep - delta_minus / denominator
-// m+ / 10^ep == v / 10^ep + delta_plus / denominator
-// Or in other words:
-// m- == v - delta_minus * 10^ep / denominator;
-// m+ == v + delta_plus * 10^ep / denominator;
-//
-// Since 10^(k-1) <= v < 10^k (with k == estimated_power)
-// or 10^k <= v < 10^(k+1)
-// we then have 0.1 <= numerator/denominator < 1
-// or 1 <= numerator/denominator < 10
-//
-// It is then easy to kickstart the digit-generation routine.
-//
-// The boundary-deltas are only filled if the mode equals BIGNUM_DTOA_SHORTEST
-// or BIGNUM_DTOA_SHORTEST_SINGLE.
-
-static void InitialScaledStartValues(uint64_t significand,
- int exponent,
- bool lower_boundary_is_closer,
- int estimated_power,
- bool need_boundary_deltas,
- Bignum* numerator,
- Bignum* denominator,
- Bignum* delta_minus,
- Bignum* delta_plus) {
- if (exponent >= 0) {
- InitialScaledStartValuesPositiveExponent(
- significand, exponent, estimated_power, need_boundary_deltas,
- numerator, denominator, delta_minus, delta_plus);
- } else if (estimated_power >= 0) {
- InitialScaledStartValuesNegativeExponentPositivePower(
- significand, exponent, estimated_power, need_boundary_deltas,
- numerator, denominator, delta_minus, delta_plus);
- } else {
- InitialScaledStartValuesNegativeExponentNegativePower(
- significand, exponent, estimated_power, need_boundary_deltas,
- numerator, denominator, delta_minus, delta_plus);
- }
-
- if (need_boundary_deltas && lower_boundary_is_closer) {
- // The lower boundary is closer at half the distance of "normal" numbers.
- // Increase the common denominator and adapt all but the delta_minus.
- denominator->ShiftLeft(1); // *2
- numerator->ShiftLeft(1); // *2
- delta_plus->ShiftLeft(1); // *2
- }
-}
-
-
-// This routine multiplies numerator/denominator so that its values lies in the
-// range 1-10. That is after a call to this function we have:
-// 1 <= (numerator + delta_plus) /denominator < 10.
-// Let numerator the input before modification and numerator' the argument
-// after modification, then the output-parameter decimal_point is such that
-// numerator / denominator * 10^estimated_power ==
-// numerator' / denominator' * 10^(decimal_point - 1)
-// In some cases estimated_power was too low, and this is already the case. We
-// then simply adjust the power so that 10^(k-1) <= v < 10^k (with k ==
-// estimated_power) but do not touch the numerator or denominator.
-// Otherwise the routine multiplies the numerator and the deltas by 10.
-static void FixupMultiply10(int estimated_power, bool is_even,
- int* decimal_point,
- Bignum* numerator, Bignum* denominator,
- Bignum* delta_minus, Bignum* delta_plus) {
- bool in_range;
- if (is_even) {
- // For IEEE doubles half-way cases (in decimal system numbers ending with 5)
- // are rounded to the closest floating-point number with even significand.
- in_range = Bignum::PlusCompare(*numerator, *delta_plus, *denominator) >= 0;
- } else {
- in_range = Bignum::PlusCompare(*numerator, *delta_plus, *denominator) > 0;
- }
- if (in_range) {
- // Since numerator + delta_plus >= denominator we already have
- // 1 <= numerator/denominator < 10. Simply update the estimated_power.
- *decimal_point = estimated_power + 1;
- } else {
- *decimal_point = estimated_power;
- numerator->Times10();
- if (Bignum::Equal(*delta_minus, *delta_plus)) {
- delta_minus->Times10();
- delta_plus->AssignBignum(*delta_minus);
- } else {
- delta_minus->Times10();
- delta_plus->Times10();
- }
- }
-}
-
-} // namespace double_conversion
diff --git a/src/3rdparty/double-conversion/bignum-dtoa.h b/src/3rdparty/double-conversion/bignum-dtoa.h
deleted file mode 100644
index 34b961992d..0000000000
--- a/src/3rdparty/double-conversion/bignum-dtoa.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef DOUBLE_CONVERSION_BIGNUM_DTOA_H_
-#define DOUBLE_CONVERSION_BIGNUM_DTOA_H_
-
-#include "utils.h"
-
-namespace double_conversion {
-
-enum BignumDtoaMode {
- // Return the shortest correct representation.
- // For example the output of 0.299999999999999988897 is (the less accurate but
- // correct) 0.3.
- BIGNUM_DTOA_SHORTEST,
- // Same as BIGNUM_DTOA_SHORTEST but for single-precision floats.
- BIGNUM_DTOA_SHORTEST_SINGLE,
- // Return a fixed number of digits after the decimal point.
- // For instance fixed(0.1, 4) becomes 0.1000
- // If the input number is big, the output will be big.
- BIGNUM_DTOA_FIXED,
- // Return a fixed number of digits, no matter what the exponent is.
- BIGNUM_DTOA_PRECISION
-};
-
-// Converts the given double 'v' to ascii.
-// The result should be interpreted as buffer * 10^(point-length).
-// The buffer will be null-terminated.
-//
-// The input v must be > 0 and different from NaN, and Infinity.
-//
-// The output depends on the given mode:
-// - SHORTEST: produce the least amount of digits for which the internal
-// identity requirement is still satisfied. If the digits are printed
-// (together with the correct exponent) then reading this number will give
-// 'v' again. The buffer will choose the representation that is closest to
-// 'v'. If there are two at the same distance, than the number is round up.
-// In this mode the 'requested_digits' parameter is ignored.
-// - FIXED: produces digits necessary to print a given number with
-// 'requested_digits' digits after the decimal point. The produced digits
-// might be too short in which case the caller has to fill the gaps with '0's.
-// Example: toFixed(0.001, 5) is allowed to return buffer="1", point=-2.
-// Halfway cases are rounded up. The call toFixed(0.15, 2) thus returns
-// buffer="2", point=0.
-// Note: the length of the returned buffer has no meaning wrt the significance
-// of its digits. That is, just because it contains '0's does not mean that
-// any other digit would not satisfy the internal identity requirement.
-// - PRECISION: produces 'requested_digits' where the first digit is not '0'.
-// Even though the length of produced digits usually equals
-// 'requested_digits', the function is allowed to return fewer digits, in
-// which case the caller has to fill the missing digits with '0's.
-// Halfway cases are again rounded up.
-// 'BignumDtoa' expects the given buffer to be big enough to hold all digits
-// and a terminating null-character.
-void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits,
- Vector<char> buffer, int* length, int* point);
-
-} // namespace double_conversion
-
-#endif // DOUBLE_CONVERSION_BIGNUM_DTOA_H_
diff --git a/src/3rdparty/double-conversion/bignum.cc b/src/3rdparty/double-conversion/bignum.cc
deleted file mode 100644
index 2743d67e8d..0000000000
--- a/src/3rdparty/double-conversion/bignum.cc
+++ /dev/null
@@ -1,766 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "bignum.h"
-#include "utils.h"
-
-namespace double_conversion {
-
-Bignum::Bignum()
- : bigits_(bigits_buffer_, kBigitCapacity), used_digits_(0), exponent_(0) {
- for (int i = 0; i < kBigitCapacity; ++i) {
- bigits_[i] = 0;
- }
-}
-
-
-template<typename S>
-static int BitSize(S value) {
- (void) value; // Mark variable as used.
- return 8 * sizeof(value);
-}
-
-// Guaranteed to lie in one Bigit.
-void Bignum::AssignUInt16(uint16_t value) {
- ASSERT(kBigitSize >= BitSize(value));
- Zero();
- if (value == 0) return;
-
- EnsureCapacity(1);
- bigits_[0] = value;
- used_digits_ = 1;
-}
-
-
-void Bignum::AssignUInt64(uint64_t value) {
- const int kUInt64Size = 64;
-
- Zero();
- if (value == 0) return;
-
- int needed_bigits = kUInt64Size / kBigitSize + 1;
- EnsureCapacity(needed_bigits);
- for (int i = 0; i < needed_bigits; ++i) {
- bigits_[i] = value & kBigitMask;
- value = value >> kBigitSize;
- }
- used_digits_ = needed_bigits;
- Clamp();
-}
-
-
-void Bignum::AssignBignum(const Bignum& other) {
- exponent_ = other.exponent_;
- for (int i = 0; i < other.used_digits_; ++i) {
- bigits_[i] = other.bigits_[i];
- }
- // Clear the excess digits (if there were any).
- for (int i = other.used_digits_; i < used_digits_; ++i) {
- bigits_[i] = 0;
- }
- used_digits_ = other.used_digits_;
-}
-
-
-static uint64_t ReadUInt64(Vector<const char> buffer,
- int from,
- int digits_to_read) {
- uint64_t result = 0;
- for (int i = from; i < from + digits_to_read; ++i) {
- int digit = buffer[i] - '0';
- ASSERT(0 <= digit && digit <= 9);
- result = result * 10 + digit;
- }
- return result;
-}
-
-
-void Bignum::AssignDecimalString(Vector<const char> value) {
- // 2^64 = 18446744073709551616 > 10^19
- const int kMaxUint64DecimalDigits = 19;
- Zero();
- int length = value.length();
- int pos = 0;
- // Let's just say that each digit needs 4 bits.
- while (length >= kMaxUint64DecimalDigits) {
- uint64_t digits = ReadUInt64(value, pos, kMaxUint64DecimalDigits);
- pos += kMaxUint64DecimalDigits;
- length -= kMaxUint64DecimalDigits;
- MultiplyByPowerOfTen(kMaxUint64DecimalDigits);
- AddUInt64(digits);
- }
- uint64_t digits = ReadUInt64(value, pos, length);
- MultiplyByPowerOfTen(length);
- AddUInt64(digits);
- Clamp();
-}
-
-
-static int HexCharValue(char c) {
- if ('0' <= c && c <= '9') return c - '0';
- if ('a' <= c && c <= 'f') return 10 + c - 'a';
- ASSERT('A' <= c && c <= 'F');
- return 10 + c - 'A';
-}
-
-
-void Bignum::AssignHexString(Vector<const char> value) {
- Zero();
- int length = value.length();
-
- int needed_bigits = length * 4 / kBigitSize + 1;
- EnsureCapacity(needed_bigits);
- int string_index = length - 1;
- for (int i = 0; i < needed_bigits - 1; ++i) {
- // These bigits are guaranteed to be "full".
- Chunk current_bigit = 0;
- for (int j = 0; j < kBigitSize / 4; j++) {
- current_bigit += HexCharValue(value[string_index--]) << (j * 4);
- }
- bigits_[i] = current_bigit;
- }
- used_digits_ = needed_bigits - 1;
-
- Chunk most_significant_bigit = 0; // Could be = 0;
- for (int j = 0; j <= string_index; ++j) {
- most_significant_bigit <<= 4;
- most_significant_bigit += HexCharValue(value[j]);
- }
- if (most_significant_bigit != 0) {
- bigits_[used_digits_] = most_significant_bigit;
- used_digits_++;
- }
- Clamp();
-}
-
-
-void Bignum::AddUInt64(uint64_t operand) {
- if (operand == 0) return;
- Bignum other;
- other.AssignUInt64(operand);
- AddBignum(other);
-}
-
-
-void Bignum::AddBignum(const Bignum& other) {
- ASSERT(IsClamped());
- ASSERT(other.IsClamped());
-
- // If this has a greater exponent than other append zero-bigits to this.
- // After this call exponent_ <= other.exponent_.
- Align(other);
-
- // There are two possibilities:
- // aaaaaaaaaaa 0000 (where the 0s represent a's exponent)
- // bbbbb 00000000
- // ----------------
- // ccccccccccc 0000
- // or
- // aaaaaaaaaa 0000
- // bbbbbbbbb 0000000
- // -----------------
- // cccccccccccc 0000
- // In both cases we might need a carry bigit.
-
- EnsureCapacity(1 + Max(BigitLength(), other.BigitLength()) - exponent_);
- Chunk carry = 0;
- int bigit_pos = other.exponent_ - exponent_;
- ASSERT(bigit_pos >= 0);
- for (int i = 0; i < other.used_digits_; ++i) {
- Chunk sum = bigits_[bigit_pos] + other.bigits_[i] + carry;
- bigits_[bigit_pos] = sum & kBigitMask;
- carry = sum >> kBigitSize;
- bigit_pos++;
- }
-
- while (carry != 0) {
- Chunk sum = bigits_[bigit_pos] + carry;
- bigits_[bigit_pos] = sum & kBigitMask;
- carry = sum >> kBigitSize;
- bigit_pos++;
- }
- used_digits_ = Max(bigit_pos, used_digits_);
- ASSERT(IsClamped());
-}
-
-
-void Bignum::SubtractBignum(const Bignum& other) {
- ASSERT(IsClamped());
- ASSERT(other.IsClamped());
- // We require this to be bigger than other.
- ASSERT(LessEqual(other, *this));
-
- Align(other);
-
- int offset = other.exponent_ - exponent_;
- Chunk borrow = 0;
- int i;
- for (i = 0; i < other.used_digits_; ++i) {
- ASSERT((borrow == 0) || (borrow == 1));
- Chunk difference = bigits_[i + offset] - other.bigits_[i] - borrow;
- bigits_[i + offset] = difference & kBigitMask;
- borrow = difference >> (kChunkSize - 1);
- }
- while (borrow != 0) {
- Chunk difference = bigits_[i + offset] - borrow;
- bigits_[i + offset] = difference & kBigitMask;
- borrow = difference >> (kChunkSize - 1);
- ++i;
- }
- Clamp();
-}
-
-
-void Bignum::ShiftLeft(int shift_amount) {
- if (used_digits_ == 0) return;
- exponent_ += shift_amount / kBigitSize;
- int local_shift = shift_amount % kBigitSize;
- EnsureCapacity(used_digits_ + 1);
- BigitsShiftLeft(local_shift);
-}
-
-
-void Bignum::MultiplyByUInt32(uint32_t factor) {
- if (factor == 1) return;
- if (factor == 0) {
- Zero();
- return;
- }
- if (used_digits_ == 0) return;
-
- // The product of a bigit with the factor is of size kBigitSize + 32.
- // Assert that this number + 1 (for the carry) fits into double chunk.
- ASSERT(kDoubleChunkSize >= kBigitSize + 32 + 1);
- DoubleChunk carry = 0;
- for (int i = 0; i < used_digits_; ++i) {
- DoubleChunk product = static_cast<DoubleChunk>(factor) * bigits_[i] + carry;
- bigits_[i] = static_cast<Chunk>(product & kBigitMask);
- carry = (product >> kBigitSize);
- }
- while (carry != 0) {
- EnsureCapacity(used_digits_ + 1);
- bigits_[used_digits_] = carry & kBigitMask;
- used_digits_++;
- carry >>= kBigitSize;
- }
-}
-
-
-void Bignum::MultiplyByUInt64(uint64_t factor) {
- if (factor == 1) return;
- if (factor == 0) {
- Zero();
- return;
- }
- ASSERT(kBigitSize < 32);
- uint64_t carry = 0;
- uint64_t low = factor & 0xFFFFFFFF;
- uint64_t high = factor >> 32;
- for (int i = 0; i < used_digits_; ++i) {
- uint64_t product_low = low * bigits_[i];
- uint64_t product_high = high * bigits_[i];
- uint64_t tmp = (carry & kBigitMask) + product_low;
- bigits_[i] = tmp & kBigitMask;
- carry = (carry >> kBigitSize) + (tmp >> kBigitSize) +
- (product_high << (32 - kBigitSize));
- }
- while (carry != 0) {
- EnsureCapacity(used_digits_ + 1);
- bigits_[used_digits_] = carry & kBigitMask;
- used_digits_++;
- carry >>= kBigitSize;
- }
-}
-
-
-void Bignum::MultiplyByPowerOfTen(int exponent) {
- const uint64_t kFive27 = UINT64_2PART_C(0x6765c793, fa10079d);
- const uint16_t kFive1 = 5;
- const uint16_t kFive2 = kFive1 * 5;
- const uint16_t kFive3 = kFive2 * 5;
- const uint16_t kFive4 = kFive3 * 5;
- const uint16_t kFive5 = kFive4 * 5;
- const uint16_t kFive6 = kFive5 * 5;
- const uint32_t kFive7 = kFive6 * 5;
- const uint32_t kFive8 = kFive7 * 5;
- const uint32_t kFive9 = kFive8 * 5;
- const uint32_t kFive10 = kFive9 * 5;
- const uint32_t kFive11 = kFive10 * 5;
- const uint32_t kFive12 = kFive11 * 5;
- const uint32_t kFive13 = kFive12 * 5;
- const uint32_t kFive1_to_12[] =
- { kFive1, kFive2, kFive3, kFive4, kFive5, kFive6,
- kFive7, kFive8, kFive9, kFive10, kFive11, kFive12 };
-
- ASSERT(exponent >= 0);
- if (exponent == 0) return;
- if (used_digits_ == 0) return;
-
- // We shift by exponent at the end just before returning.
- int remaining_exponent = exponent;
- while (remaining_exponent >= 27) {
- MultiplyByUInt64(kFive27);
- remaining_exponent -= 27;
- }
- while (remaining_exponent >= 13) {
- MultiplyByUInt32(kFive13);
- remaining_exponent -= 13;
- }
- if (remaining_exponent > 0) {
- MultiplyByUInt32(kFive1_to_12[remaining_exponent - 1]);
- }
- ShiftLeft(exponent);
-}
-
-
-void Bignum::Square() {
- ASSERT(IsClamped());
- int product_length = 2 * used_digits_;
- EnsureCapacity(product_length);
-
- // Comba multiplication: compute each column separately.
- // Example: r = a2a1a0 * b2b1b0.
- // r = 1 * a0b0 +
- // 10 * (a1b0 + a0b1) +
- // 100 * (a2b0 + a1b1 + a0b2) +
- // 1000 * (a2b1 + a1b2) +
- // 10000 * a2b2
- //
- // In the worst case we have to accumulate nb-digits products of digit*digit.
- //
- // Assert that the additional number of bits in a DoubleChunk are enough to
- // sum up used_digits of Bigit*Bigit.
- if ((1 << (2 * (kChunkSize - kBigitSize))) <= used_digits_) {
- UNIMPLEMENTED();
- }
- DoubleChunk accumulator = 0;
- // First shift the digits so we don't overwrite them.
- int copy_offset = used_digits_;
- for (int i = 0; i < used_digits_; ++i) {
- bigits_[copy_offset + i] = bigits_[i];
- }
- // We have two loops to avoid some 'if's in the loop.
- for (int i = 0; i < used_digits_; ++i) {
- // Process temporary digit i with power i.
- // The sum of the two indices must be equal to i.
- int bigit_index1 = i;
- int bigit_index2 = 0;
- // Sum all of the sub-products.
- while (bigit_index1 >= 0) {
- Chunk chunk1 = bigits_[copy_offset + bigit_index1];
- Chunk chunk2 = bigits_[copy_offset + bigit_index2];
- accumulator += static_cast<DoubleChunk>(chunk1) * chunk2;
- bigit_index1--;
- bigit_index2++;
- }
- bigits_[i] = static_cast<Chunk>(accumulator) & kBigitMask;
- accumulator >>= kBigitSize;
- }
- for (int i = used_digits_; i < product_length; ++i) {
- int bigit_index1 = used_digits_ - 1;
- int bigit_index2 = i - bigit_index1;
- // Invariant: sum of both indices is again equal to i.
- // Inner loop runs 0 times on last iteration, emptying accumulator.
- while (bigit_index2 < used_digits_) {
- Chunk chunk1 = bigits_[copy_offset + bigit_index1];
- Chunk chunk2 = bigits_[copy_offset + bigit_index2];
- accumulator += static_cast<DoubleChunk>(chunk1) * chunk2;
- bigit_index1--;
- bigit_index2++;
- }
- // The overwritten bigits_[i] will never be read in further loop iterations,
- // because bigit_index1 and bigit_index2 are always greater
- // than i - used_digits_.
- bigits_[i] = static_cast<Chunk>(accumulator) & kBigitMask;
- accumulator >>= kBigitSize;
- }
- // Since the result was guaranteed to lie inside the number the
- // accumulator must be 0 now.
- ASSERT(accumulator == 0);
-
- // Don't forget to update the used_digits and the exponent.
- used_digits_ = product_length;
- exponent_ *= 2;
- Clamp();
-}
-
-
-void Bignum::AssignPowerUInt16(uint16_t base, int power_exponent) {
- ASSERT(base != 0);
- ASSERT(power_exponent >= 0);
- if (power_exponent == 0) {
- AssignUInt16(1);
- return;
- }
- Zero();
- int shifts = 0;
- // We expect base to be in range 2-32, and most often to be 10.
- // It does not make much sense to implement different algorithms for counting
- // the bits.
- while ((base & 1) == 0) {
- base >>= 1;
- shifts++;
- }
- int bit_size = 0;
- int tmp_base = base;
- while (tmp_base != 0) {
- tmp_base >>= 1;
- bit_size++;
- }
- int final_size = bit_size * power_exponent;
- // 1 extra bigit for the shifting, and one for rounded final_size.
- EnsureCapacity(final_size / kBigitSize + 2);
-
- // Left to Right exponentiation.
- int mask = 1;
- while (power_exponent >= mask) mask <<= 1;
-
- // The mask is now pointing to the bit above the most significant 1-bit of
- // power_exponent.
- // Get rid of first 1-bit;
- mask >>= 2;
- uint64_t this_value = base;
-
- bool delayed_multipliciation = false;
- const uint64_t max_32bits = 0xFFFFFFFF;
- while (mask != 0 && this_value <= max_32bits) {
- this_value = this_value * this_value;
- // Verify that there is enough space in this_value to perform the
- // multiplication. The first bit_size bits must be 0.
- if ((power_exponent & mask) != 0) {
- uint64_t base_bits_mask =
- ~((static_cast<uint64_t>(1) << (64 - bit_size)) - 1);
- bool high_bits_zero = (this_value & base_bits_mask) == 0;
- if (high_bits_zero) {
- this_value *= base;
- } else {
- delayed_multipliciation = true;
- }
- }
- mask >>= 1;
- }
- AssignUInt64(this_value);
- if (delayed_multipliciation) {
- MultiplyByUInt32(base);
- }
-
- // Now do the same thing as a bignum.
- while (mask != 0) {
- Square();
- if ((power_exponent & mask) != 0) {
- MultiplyByUInt32(base);
- }
- mask >>= 1;
- }
-
- // And finally add the saved shifts.
- ShiftLeft(shifts * power_exponent);
-}
-
-
-// Precondition: this/other < 16bit.
-uint16_t Bignum::DivideModuloIntBignum(const Bignum& other) {
- ASSERT(IsClamped());
- ASSERT(other.IsClamped());
- ASSERT(other.used_digits_ > 0);
-
- // Easy case: if we have less digits than the divisor than the result is 0.
- // Note: this handles the case where this == 0, too.
- if (BigitLength() < other.BigitLength()) {
- return 0;
- }
-
- Align(other);
-
- uint16_t result = 0;
-
- // Start by removing multiples of 'other' until both numbers have the same
- // number of digits.
- while (BigitLength() > other.BigitLength()) {
- // This naive approach is extremely inefficient if `this` divided by other
- // is big. This function is implemented for doubleToString where
- // the result should be small (less than 10).
- ASSERT(other.bigits_[other.used_digits_ - 1] >= ((1 << kBigitSize) / 16));
- ASSERT(bigits_[used_digits_ - 1] < 0x10000);
- // Remove the multiples of the first digit.
- // Example this = 23 and other equals 9. -> Remove 2 multiples.
- result += static_cast<uint16_t>(bigits_[used_digits_ - 1]);
- SubtractTimes(other, bigits_[used_digits_ - 1]);
- }
-
- ASSERT(BigitLength() == other.BigitLength());
-
- // Both bignums are at the same length now.
- // Since other has more than 0 digits we know that the access to
- // bigits_[used_digits_ - 1] is safe.
- Chunk this_bigit = bigits_[used_digits_ - 1];
- Chunk other_bigit = other.bigits_[other.used_digits_ - 1];
-
- if (other.used_digits_ == 1) {
- // Shortcut for easy (and common) case.
- int quotient = this_bigit / other_bigit;
- bigits_[used_digits_ - 1] = this_bigit - other_bigit * quotient;
- ASSERT(quotient < 0x10000);
- result += static_cast<uint16_t>(quotient);
- Clamp();
- return result;
- }
-
- int division_estimate = this_bigit / (other_bigit + 1);
- ASSERT(division_estimate < 0x10000);
- result += static_cast<uint16_t>(division_estimate);
- SubtractTimes(other, division_estimate);
-
- if (other_bigit * (division_estimate + 1) > this_bigit) {
- // No need to even try to subtract. Even if other's remaining digits were 0
- // another subtraction would be too much.
- return result;
- }
-
- while (LessEqual(other, *this)) {
- SubtractBignum(other);
- result++;
- }
- return result;
-}
-
-
-template<typename S>
-static int SizeInHexChars(S number) {
- ASSERT(number > 0);
- int result = 0;
- while (number != 0) {
- number >>= 4;
- result++;
- }
- return result;
-}
-
-
-static char HexCharOfValue(int value) {
- ASSERT(0 <= value && value <= 16);
- if (value < 10) return static_cast<char>(value + '0');
- return static_cast<char>(value - 10 + 'A');
-}
-
-
-bool Bignum::ToHexString(char* buffer, int buffer_size) const {
- ASSERT(IsClamped());
- // Each bigit must be printable as separate hex-character.
- ASSERT(kBigitSize % 4 == 0);
- const int kHexCharsPerBigit = kBigitSize / 4;
-
- if (used_digits_ == 0) {
- if (buffer_size < 2) return false;
- buffer[0] = '0';
- buffer[1] = '\0';
- return true;
- }
- // We add 1 for the terminating '\0' character.
- int needed_chars = (BigitLength() - 1) * kHexCharsPerBigit +
- SizeInHexChars(bigits_[used_digits_ - 1]) + 1;
- if (needed_chars > buffer_size) return false;
- int string_index = needed_chars - 1;
- buffer[string_index--] = '\0';
- for (int i = 0; i < exponent_; ++i) {
- for (int j = 0; j < kHexCharsPerBigit; ++j) {
- buffer[string_index--] = '0';
- }
- }
- for (int i = 0; i < used_digits_ - 1; ++i) {
- Chunk current_bigit = bigits_[i];
- for (int j = 0; j < kHexCharsPerBigit; ++j) {
- buffer[string_index--] = HexCharOfValue(current_bigit & 0xF);
- current_bigit >>= 4;
- }
- }
- // And finally the last bigit.
- Chunk most_significant_bigit = bigits_[used_digits_ - 1];
- while (most_significant_bigit != 0) {
- buffer[string_index--] = HexCharOfValue(most_significant_bigit & 0xF);
- most_significant_bigit >>= 4;
- }
- return true;
-}
-
-
-Bignum::Chunk Bignum::BigitAt(int index) const {
- if (index >= BigitLength()) return 0;
- if (index < exponent_) return 0;
- return bigits_[index - exponent_];
-}
-
-
-int Bignum::Compare(const Bignum& a, const Bignum& b) {
- ASSERT(a.IsClamped());
- ASSERT(b.IsClamped());
- int bigit_length_a = a.BigitLength();
- int bigit_length_b = b.BigitLength();
- if (bigit_length_a < bigit_length_b) return -1;
- if (bigit_length_a > bigit_length_b) return +1;
- for (int i = bigit_length_a - 1; i >= Min(a.exponent_, b.exponent_); --i) {
- Chunk bigit_a = a.BigitAt(i);
- Chunk bigit_b = b.BigitAt(i);
- if (bigit_a < bigit_b) return -1;
- if (bigit_a > bigit_b) return +1;
- // Otherwise they are equal up to this digit. Try the next digit.
- }
- return 0;
-}
-
-
-int Bignum::PlusCompare(const Bignum& a, const Bignum& b, const Bignum& c) {
- ASSERT(a.IsClamped());
- ASSERT(b.IsClamped());
- ASSERT(c.IsClamped());
- if (a.BigitLength() < b.BigitLength()) {
- return PlusCompare(b, a, c);
- }
- if (a.BigitLength() + 1 < c.BigitLength()) return -1;
- if (a.BigitLength() > c.BigitLength()) return +1;
- // The exponent encodes 0-bigits. So if there are more 0-digits in 'a' than
- // 'b' has digits, then the bigit-length of 'a'+'b' must be equal to the one
- // of 'a'.
- if (a.exponent_ >= b.BigitLength() && a.BigitLength() < c.BigitLength()) {
- return -1;
- }
-
- Chunk borrow = 0;
- // Starting at min_exponent all digits are == 0. So no need to compare them.
- int min_exponent = Min(Min(a.exponent_, b.exponent_), c.exponent_);
- for (int i = c.BigitLength() - 1; i >= min_exponent; --i) {
- Chunk chunk_a = a.BigitAt(i);
- Chunk chunk_b = b.BigitAt(i);
- Chunk chunk_c = c.BigitAt(i);
- Chunk sum = chunk_a + chunk_b;
- if (sum > chunk_c + borrow) {
- return +1;
- } else {
- borrow = chunk_c + borrow - sum;
- if (borrow > 1) return -1;
- borrow <<= kBigitSize;
- }
- }
- if (borrow == 0) return 0;
- return -1;
-}
-
-
-void Bignum::Clamp() {
- while (used_digits_ > 0 && bigits_[used_digits_ - 1] == 0) {
- used_digits_--;
- }
- if (used_digits_ == 0) {
- // Zero.
- exponent_ = 0;
- }
-}
-
-
-bool Bignum::IsClamped() const {
- return used_digits_ == 0 || bigits_[used_digits_ - 1] != 0;
-}
-
-
-void Bignum::Zero() {
- for (int i = 0; i < used_digits_; ++i) {
- bigits_[i] = 0;
- }
- used_digits_ = 0;
- exponent_ = 0;
-}
-
-
-void Bignum::Align(const Bignum& other) {
- if (exponent_ > other.exponent_) {
- // If "X" represents a "hidden" digit (by the exponent) then we are in the
- // following case (a == this, b == other):
- // a: aaaaaaXXXX or a: aaaaaXXX
- // b: bbbbbbX b: bbbbbbbbXX
- // We replace some of the hidden digits (X) of a with 0 digits.
- // a: aaaaaa000X or a: aaaaa0XX
- int zero_digits = exponent_ - other.exponent_;
- EnsureCapacity(used_digits_ + zero_digits);
- for (int i = used_digits_ - 1; i >= 0; --i) {
- bigits_[i + zero_digits] = bigits_[i];
- }
- for (int i = 0; i < zero_digits; ++i) {
- bigits_[i] = 0;
- }
- used_digits_ += zero_digits;
- exponent_ -= zero_digits;
- ASSERT(used_digits_ >= 0);
- ASSERT(exponent_ >= 0);
- }
-}
-
-
-void Bignum::BigitsShiftLeft(int shift_amount) {
- ASSERT(shift_amount < kBigitSize);
- ASSERT(shift_amount >= 0);
- Chunk carry = 0;
- for (int i = 0; i < used_digits_; ++i) {
- Chunk new_carry = bigits_[i] >> (kBigitSize - shift_amount);
- bigits_[i] = ((bigits_[i] << shift_amount) + carry) & kBigitMask;
- carry = new_carry;
- }
- if (carry != 0) {
- bigits_[used_digits_] = carry;
- used_digits_++;
- }
-}
-
-
-void Bignum::SubtractTimes(const Bignum& other, int factor) {
- ASSERT(exponent_ <= other.exponent_);
- if (factor < 3) {
- for (int i = 0; i < factor; ++i) {
- SubtractBignum(other);
- }
- return;
- }
- Chunk borrow = 0;
- int exponent_diff = other.exponent_ - exponent_;
- for (int i = 0; i < other.used_digits_; ++i) {
- DoubleChunk product = static_cast<DoubleChunk>(factor) * other.bigits_[i];
- DoubleChunk remove = borrow + product;
- Chunk difference = bigits_[i + exponent_diff] - (remove & kBigitMask);
- bigits_[i + exponent_diff] = difference & kBigitMask;
- borrow = static_cast<Chunk>((difference >> (kChunkSize - 1)) +
- (remove >> kBigitSize));
- }
- for (int i = other.used_digits_ + exponent_diff; i < used_digits_; ++i) {
- if (borrow == 0) return;
- Chunk difference = bigits_[i] - borrow;
- bigits_[i] = difference & kBigitMask;
- borrow = difference >> (kChunkSize - 1);
- }
- Clamp();
-}
-
-
-} // namespace double_conversion
diff --git a/src/3rdparty/double-conversion/bignum.h b/src/3rdparty/double-conversion/bignum.h
deleted file mode 100644
index 5ec3544f57..0000000000
--- a/src/3rdparty/double-conversion/bignum.h
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef DOUBLE_CONVERSION_BIGNUM_H_
-#define DOUBLE_CONVERSION_BIGNUM_H_
-
-#include "utils.h"
-
-namespace double_conversion {
-
-class Bignum {
- public:
- // 3584 = 128 * 28. We can represent 2^3584 > 10^1000 accurately.
- // This bignum can encode much bigger numbers, since it contains an
- // exponent.
- static const int kMaxSignificantBits = 3584;
-
- Bignum();
- void AssignUInt16(uint16_t value);
- void AssignUInt64(uint64_t value);
- void AssignBignum(const Bignum& other);
-
- void AssignDecimalString(Vector<const char> value);
- void AssignHexString(Vector<const char> value);
-
- void AssignPowerUInt16(uint16_t base, int exponent);
-
- void AddUInt16(uint16_t operand);
- void AddUInt64(uint64_t operand);
- void AddBignum(const Bignum& other);
- // Precondition: this >= other.
- void SubtractBignum(const Bignum& other);
-
- void Square();
- void ShiftLeft(int shift_amount);
- void MultiplyByUInt32(uint32_t factor);
- void MultiplyByUInt64(uint64_t factor);
- void MultiplyByPowerOfTen(int exponent);
- void Times10() { return MultiplyByUInt32(10); }
- // Pseudocode:
- // int result = this / other;
- // this = this % other;
- // In the worst case this function is in O(this/other).
- uint16_t DivideModuloIntBignum(const Bignum& other);
-
- bool ToHexString(char* buffer, int buffer_size) const;
-
- // Returns
- // -1 if a < b,
- // 0 if a == b, and
- // +1 if a > b.
- static int Compare(const Bignum& a, const Bignum& b);
- static bool Equal(const Bignum& a, const Bignum& b) {
- return Compare(a, b) == 0;
- }
- static bool LessEqual(const Bignum& a, const Bignum& b) {
- return Compare(a, b) <= 0;
- }
- static bool Less(const Bignum& a, const Bignum& b) {
- return Compare(a, b) < 0;
- }
- // Returns Compare(a + b, c);
- static int PlusCompare(const Bignum& a, const Bignum& b, const Bignum& c);
- // Returns a + b == c
- static bool PlusEqual(const Bignum& a, const Bignum& b, const Bignum& c) {
- return PlusCompare(a, b, c) == 0;
- }
- // Returns a + b <= c
- static bool PlusLessEqual(const Bignum& a, const Bignum& b, const Bignum& c) {
- return PlusCompare(a, b, c) <= 0;
- }
- // Returns a + b < c
- static bool PlusLess(const Bignum& a, const Bignum& b, const Bignum& c) {
- return PlusCompare(a, b, c) < 0;
- }
- private:
- typedef uint32_t Chunk;
- typedef uint64_t DoubleChunk;
-
- static const int kChunkSize = sizeof(Chunk) * 8;
- static const int kDoubleChunkSize = sizeof(DoubleChunk) * 8;
- // With bigit size of 28 we loose some bits, but a double still fits easily
- // into two chunks, and more importantly we can use the Comba multiplication.
- static const int kBigitSize = 28;
- static const Chunk kBigitMask = (1 << kBigitSize) - 1;
- // Every instance allocates kBigitLength chunks on the stack. Bignums cannot
- // grow. There are no checks if the stack-allocated space is sufficient.
- static const int kBigitCapacity = kMaxSignificantBits / kBigitSize;
-
- void EnsureCapacity(int size) {
- if (size > kBigitCapacity) {
- UNREACHABLE();
- }
- }
- void Align(const Bignum& other);
- void Clamp();
- bool IsClamped() const;
- void Zero();
- // Requires this to have enough capacity (no tests done).
- // Updates used_digits_ if necessary.
- // shift_amount must be < kBigitSize.
- void BigitsShiftLeft(int shift_amount);
- // BigitLength includes the "hidden" digits encoded in the exponent.
- int BigitLength() const { return used_digits_ + exponent_; }
- Chunk BigitAt(int index) const;
- void SubtractTimes(const Bignum& other, int factor);
-
- Chunk bigits_buffer_[kBigitCapacity];
- // A vector backed by bigits_buffer_. This way accesses to the array are
- // checked for out-of-bounds errors.
- Vector<Chunk> bigits_;
- int used_digits_;
- // The Bignum's value equals value(bigits_) * 2^(exponent_ * kBigitSize).
- int exponent_;
-
- DISALLOW_COPY_AND_ASSIGN(Bignum);
-};
-
-} // namespace double_conversion
-
-#endif // DOUBLE_CONVERSION_BIGNUM_H_
diff --git a/src/3rdparty/double-conversion/cached-powers.cc b/src/3rdparty/double-conversion/cached-powers.cc
deleted file mode 100644
index 9536f26927..0000000000
--- a/src/3rdparty/double-conversion/cached-powers.cc
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include <stdarg.h>
-#include <limits.h>
-#include <math.h>
-
-#include "utils.h"
-
-#include "cached-powers.h"
-
-namespace double_conversion {
-
-struct CachedPower {
- uint64_t significand;
- int16_t binary_exponent;
- int16_t decimal_exponent;
-};
-
-static const CachedPower kCachedPowers[] = {
- {UINT64_2PART_C(0xfa8fd5a0, 081c0288), -1220, -348},
- {UINT64_2PART_C(0xbaaee17f, a23ebf76), -1193, -340},
- {UINT64_2PART_C(0x8b16fb20, 3055ac76), -1166, -332},
- {UINT64_2PART_C(0xcf42894a, 5dce35ea), -1140, -324},
- {UINT64_2PART_C(0x9a6bb0aa, 55653b2d), -1113, -316},
- {UINT64_2PART_C(0xe61acf03, 3d1a45df), -1087, -308},
- {UINT64_2PART_C(0xab70fe17, c79ac6ca), -1060, -300},
- {UINT64_2PART_C(0xff77b1fc, bebcdc4f), -1034, -292},
- {UINT64_2PART_C(0xbe5691ef, 416bd60c), -1007, -284},
- {UINT64_2PART_C(0x8dd01fad, 907ffc3c), -980, -276},
- {UINT64_2PART_C(0xd3515c28, 31559a83), -954, -268},
- {UINT64_2PART_C(0x9d71ac8f, ada6c9b5), -927, -260},
- {UINT64_2PART_C(0xea9c2277, 23ee8bcb), -901, -252},
- {UINT64_2PART_C(0xaecc4991, 4078536d), -874, -244},
- {UINT64_2PART_C(0x823c1279, 5db6ce57), -847, -236},
- {UINT64_2PART_C(0xc2109436, 4dfb5637), -821, -228},
- {UINT64_2PART_C(0x9096ea6f, 3848984f), -794, -220},
- {UINT64_2PART_C(0xd77485cb, 25823ac7), -768, -212},
- {UINT64_2PART_C(0xa086cfcd, 97bf97f4), -741, -204},
- {UINT64_2PART_C(0xef340a98, 172aace5), -715, -196},
- {UINT64_2PART_C(0xb23867fb, 2a35b28e), -688, -188},
- {UINT64_2PART_C(0x84c8d4df, d2c63f3b), -661, -180},
- {UINT64_2PART_C(0xc5dd4427, 1ad3cdba), -635, -172},
- {UINT64_2PART_C(0x936b9fce, bb25c996), -608, -164},
- {UINT64_2PART_C(0xdbac6c24, 7d62a584), -582, -156},
- {UINT64_2PART_C(0xa3ab6658, 0d5fdaf6), -555, -148},
- {UINT64_2PART_C(0xf3e2f893, dec3f126), -529, -140},
- {UINT64_2PART_C(0xb5b5ada8, aaff80b8), -502, -132},
- {UINT64_2PART_C(0x87625f05, 6c7c4a8b), -475, -124},
- {UINT64_2PART_C(0xc9bcff60, 34c13053), -449, -116},
- {UINT64_2PART_C(0x964e858c, 91ba2655), -422, -108},
- {UINT64_2PART_C(0xdff97724, 70297ebd), -396, -100},
- {UINT64_2PART_C(0xa6dfbd9f, b8e5b88f), -369, -92},
- {UINT64_2PART_C(0xf8a95fcf, 88747d94), -343, -84},
- {UINT64_2PART_C(0xb9447093, 8fa89bcf), -316, -76},
- {UINT64_2PART_C(0x8a08f0f8, bf0f156b), -289, -68},
- {UINT64_2PART_C(0xcdb02555, 653131b6), -263, -60},
- {UINT64_2PART_C(0x993fe2c6, d07b7fac), -236, -52},
- {UINT64_2PART_C(0xe45c10c4, 2a2b3b06), -210, -44},
- {UINT64_2PART_C(0xaa242499, 697392d3), -183, -36},
- {UINT64_2PART_C(0xfd87b5f2, 8300ca0e), -157, -28},
- {UINT64_2PART_C(0xbce50864, 92111aeb), -130, -20},
- {UINT64_2PART_C(0x8cbccc09, 6f5088cc), -103, -12},
- {UINT64_2PART_C(0xd1b71758, e219652c), -77, -4},
- {UINT64_2PART_C(0x9c400000, 00000000), -50, 4},
- {UINT64_2PART_C(0xe8d4a510, 00000000), -24, 12},
- {UINT64_2PART_C(0xad78ebc5, ac620000), 3, 20},
- {UINT64_2PART_C(0x813f3978, f8940984), 30, 28},
- {UINT64_2PART_C(0xc097ce7b, c90715b3), 56, 36},
- {UINT64_2PART_C(0x8f7e32ce, 7bea5c70), 83, 44},
- {UINT64_2PART_C(0xd5d238a4, abe98068), 109, 52},
- {UINT64_2PART_C(0x9f4f2726, 179a2245), 136, 60},
- {UINT64_2PART_C(0xed63a231, d4c4fb27), 162, 68},
- {UINT64_2PART_C(0xb0de6538, 8cc8ada8), 189, 76},
- {UINT64_2PART_C(0x83c7088e, 1aab65db), 216, 84},
- {UINT64_2PART_C(0xc45d1df9, 42711d9a), 242, 92},
- {UINT64_2PART_C(0x924d692c, a61be758), 269, 100},
- {UINT64_2PART_C(0xda01ee64, 1a708dea), 295, 108},
- {UINT64_2PART_C(0xa26da399, 9aef774a), 322, 116},
- {UINT64_2PART_C(0xf209787b, b47d6b85), 348, 124},
- {UINT64_2PART_C(0xb454e4a1, 79dd1877), 375, 132},
- {UINT64_2PART_C(0x865b8692, 5b9bc5c2), 402, 140},
- {UINT64_2PART_C(0xc83553c5, c8965d3d), 428, 148},
- {UINT64_2PART_C(0x952ab45c, fa97a0b3), 455, 156},
- {UINT64_2PART_C(0xde469fbd, 99a05fe3), 481, 164},
- {UINT64_2PART_C(0xa59bc234, db398c25), 508, 172},
- {UINT64_2PART_C(0xf6c69a72, a3989f5c), 534, 180},
- {UINT64_2PART_C(0xb7dcbf53, 54e9bece), 561, 188},
- {UINT64_2PART_C(0x88fcf317, f22241e2), 588, 196},
- {UINT64_2PART_C(0xcc20ce9b, d35c78a5), 614, 204},
- {UINT64_2PART_C(0x98165af3, 7b2153df), 641, 212},
- {UINT64_2PART_C(0xe2a0b5dc, 971f303a), 667, 220},
- {UINT64_2PART_C(0xa8d9d153, 5ce3b396), 694, 228},
- {UINT64_2PART_C(0xfb9b7cd9, a4a7443c), 720, 236},
- {UINT64_2PART_C(0xbb764c4c, a7a44410), 747, 244},
- {UINT64_2PART_C(0x8bab8eef, b6409c1a), 774, 252},
- {UINT64_2PART_C(0xd01fef10, a657842c), 800, 260},
- {UINT64_2PART_C(0x9b10a4e5, e9913129), 827, 268},
- {UINT64_2PART_C(0xe7109bfb, a19c0c9d), 853, 276},
- {UINT64_2PART_C(0xac2820d9, 623bf429), 880, 284},
- {UINT64_2PART_C(0x80444b5e, 7aa7cf85), 907, 292},
- {UINT64_2PART_C(0xbf21e440, 03acdd2d), 933, 300},
- {UINT64_2PART_C(0x8e679c2f, 5e44ff8f), 960, 308},
- {UINT64_2PART_C(0xd433179d, 9c8cb841), 986, 316},
- {UINT64_2PART_C(0x9e19db92, b4e31ba9), 1013, 324},
- {UINT64_2PART_C(0xeb96bf6e, badf77d9), 1039, 332},
- {UINT64_2PART_C(0xaf87023b, 9bf0ee6b), 1066, 340},
-};
-
-static const int kCachedPowersLength = ARRAY_SIZE(kCachedPowers);
-static const int kCachedPowersOffset = 348; // -1 * the first decimal_exponent.
-static const double kD_1_LOG2_10 = 0.30102999566398114; // 1 / lg(10)
-// Difference between the decimal exponents in the table above.
-const int PowersOfTenCache::kDecimalExponentDistance = 8;
-const int PowersOfTenCache::kMinDecimalExponent = -348;
-const int PowersOfTenCache::kMaxDecimalExponent = 340;
-
-void PowersOfTenCache::GetCachedPowerForBinaryExponentRange(
- int min_exponent,
- int max_exponent,
- DiyFp* power,
- int* decimal_exponent) {
- (void)max_exponent; // Silence unused parameter warning in release builds
- (void)kCachedPowersLength; // Silence unused parameter warning in release builds
- int kQ = DiyFp::kSignificandSize;
- double k = ceil((min_exponent + kQ - 1) * kD_1_LOG2_10);
- int foo = kCachedPowersOffset;
- int index =
- (foo + static_cast<int>(k) - 1) / kDecimalExponentDistance + 1;
- ASSERT(0 <= index && index < kCachedPowersLength);
- CachedPower cached_power = kCachedPowers[index];
- ASSERT(min_exponent <= cached_power.binary_exponent);
- (void) max_exponent; // Mark variable as used.
- ASSERT(cached_power.binary_exponent <= max_exponent);
- *decimal_exponent = cached_power.decimal_exponent;
- *power = DiyFp(cached_power.significand, cached_power.binary_exponent);
-}
-
-
-void PowersOfTenCache::GetCachedPowerForDecimalExponent(int requested_exponent,
- DiyFp* power,
- int* found_exponent) {
- ASSERT(kMinDecimalExponent <= requested_exponent);
- ASSERT(requested_exponent < kMaxDecimalExponent + kDecimalExponentDistance);
- int index =
- (requested_exponent + kCachedPowersOffset) / kDecimalExponentDistance;
- CachedPower cached_power = kCachedPowers[index];
- *power = DiyFp(cached_power.significand, cached_power.binary_exponent);
- *found_exponent = cached_power.decimal_exponent;
- ASSERT(*found_exponent <= requested_exponent);
- ASSERT(requested_exponent < *found_exponent + kDecimalExponentDistance);
-}
-
-} // namespace double_conversion
diff --git a/src/3rdparty/double-conversion/cached-powers.h b/src/3rdparty/double-conversion/cached-powers.h
deleted file mode 100644
index 61a50614cf..0000000000
--- a/src/3rdparty/double-conversion/cached-powers.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef DOUBLE_CONVERSION_CACHED_POWERS_H_
-#define DOUBLE_CONVERSION_CACHED_POWERS_H_
-
-#include "diy-fp.h"
-
-namespace double_conversion {
-
-class PowersOfTenCache {
- public:
-
- // Not all powers of ten are cached. The decimal exponent of two neighboring
- // cached numbers will differ by kDecimalExponentDistance.
- static const int kDecimalExponentDistance;
-
- static const int kMinDecimalExponent;
- static const int kMaxDecimalExponent;
-
- // Returns a cached power-of-ten with a binary exponent in the range
- // [min_exponent; max_exponent] (boundaries included).
- static void GetCachedPowerForBinaryExponentRange(int min_exponent,
- int max_exponent,
- DiyFp* power,
- int* decimal_exponent);
-
- // Returns a cached power of ten x ~= 10^k such that
- // k <= decimal_exponent < k + kCachedPowersDecimalDistance.
- // The given decimal_exponent must satisfy
- // kMinDecimalExponent <= requested_exponent, and
- // requested_exponent < kMaxDecimalExponent + kDecimalExponentDistance.
- static void GetCachedPowerForDecimalExponent(int requested_exponent,
- DiyFp* power,
- int* found_exponent);
-};
-
-} // namespace double_conversion
-
-#endif // DOUBLE_CONVERSION_CACHED_POWERS_H_
diff --git a/src/3rdparty/double-conversion/diy-fp.cc b/src/3rdparty/double-conversion/diy-fp.cc
deleted file mode 100644
index ddd1891b16..0000000000
--- a/src/3rdparty/double-conversion/diy-fp.cc
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-#include "diy-fp.h"
-#include "utils.h"
-
-namespace double_conversion {
-
-void DiyFp::Multiply(const DiyFp& other) {
- // Simply "emulates" a 128 bit multiplication.
- // However: the resulting number only contains 64 bits. The least
- // significant 64 bits are only used for rounding the most significant 64
- // bits.
- const uint64_t kM32 = 0xFFFFFFFFU;
- uint64_t a = f_ >> 32;
- uint64_t b = f_ & kM32;
- uint64_t c = other.f_ >> 32;
- uint64_t d = other.f_ & kM32;
- uint64_t ac = a * c;
- uint64_t bc = b * c;
- uint64_t ad = a * d;
- uint64_t bd = b * d;
- uint64_t tmp = (bd >> 32) + (ad & kM32) + (bc & kM32);
- // By adding 1U << 31 to tmp we round the final result.
- // Halfway cases will be round up.
- tmp += 1U << 31;
- uint64_t result_f = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32);
- e_ += other.e_ + 64;
- f_ = result_f;
-}
-
-} // namespace double_conversion
diff --git a/src/3rdparty/double-conversion/diy-fp.h b/src/3rdparty/double-conversion/diy-fp.h
deleted file mode 100644
index 9dcf8fbdba..0000000000
--- a/src/3rdparty/double-conversion/diy-fp.h
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef DOUBLE_CONVERSION_DIY_FP_H_
-#define DOUBLE_CONVERSION_DIY_FP_H_
-
-#include "utils.h"
-
-namespace double_conversion {
-
-// This "Do It Yourself Floating Point" class implements a floating-point number
-// with a uint64 significand and an int exponent. Normalized DiyFp numbers will
-// have the most significant bit of the significand set.
-// Multiplication and Subtraction do not normalize their results.
-// DiyFp are not designed to contain special doubles (NaN and Infinity).
-class DiyFp {
- public:
- static const int kSignificandSize = 64;
-
- DiyFp() : f_(0), e_(0) {}
- DiyFp(uint64_t f, int e) : f_(f), e_(e) {}
-
- // this = this - other.
- // The exponents of both numbers must be the same and the significand of this
- // must be bigger than the significand of other.
- // The result will not be normalized.
- void Subtract(const DiyFp& other) {
- ASSERT(e_ == other.e_);
- ASSERT(f_ >= other.f_);
- f_ -= other.f_;
- }
-
- // Returns a - b.
- // The exponents of both numbers must be the same and this must be bigger
- // than other. The result will not be normalized.
- static DiyFp Minus(const DiyFp& a, const DiyFp& b) {
- DiyFp result = a;
- result.Subtract(b);
- return result;
- }
-
-
- // this = this * other.
- void Multiply(const DiyFp& other);
-
- // returns a * b;
- static DiyFp Times(const DiyFp& a, const DiyFp& b) {
- DiyFp result = a;
- result.Multiply(b);
- return result;
- }
-
- void Normalize() {
- ASSERT(f_ != 0);
- uint64_t f = f_;
- int e = e_;
-
- // This method is mainly called for normalizing boundaries. In general
- // boundaries need to be shifted by 10 bits. We thus optimize for this case.
- const uint64_t k10MSBits = UINT64_2PART_C(0xFFC00000, 00000000);
- while ((f & k10MSBits) == 0) {
- f <<= 10;
- e -= 10;
- }
- while ((f & kUint64MSB) == 0) {
- f <<= 1;
- e--;
- }
- f_ = f;
- e_ = e;
- }
-
- static DiyFp Normalize(const DiyFp& a) {
- DiyFp result = a;
- result.Normalize();
- return result;
- }
-
- uint64_t f() const { return f_; }
- int e() const { return e_; }
-
- void set_f(uint64_t new_value) { f_ = new_value; }
- void set_e(int new_value) { e_ = new_value; }
-
- private:
- static const uint64_t kUint64MSB = UINT64_2PART_C(0x80000000, 00000000);
-
- uint64_t f_;
- int e_;
-};
-
-} // namespace double_conversion
-
-#endif // DOUBLE_CONVERSION_DIY_FP_H_
diff --git a/src/3rdparty/double-conversion/double-conversion.cc b/src/3rdparty/double-conversion/double-conversion.cc
deleted file mode 100644
index 909985be82..0000000000
--- a/src/3rdparty/double-conversion/double-conversion.cc
+++ /dev/null
@@ -1,975 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include <limits.h>
-#include <math.h>
-
-#include "double-conversion.h"
-
-#include "bignum-dtoa.h"
-#include "fast-dtoa.h"
-#include "fixed-dtoa.h"
-#include "ieee.h"
-#include "strtod.h"
-#include "utils.h"
-
-namespace double_conversion {
-
-const DoubleToStringConverter& DoubleToStringConverter::EcmaScriptConverter() {
- int flags = UNIQUE_ZERO | EMIT_POSITIVE_EXPONENT_SIGN;
- static DoubleToStringConverter converter(flags,
- "Infinity",
- "NaN",
- 'e',
- -6, 21,
- 6, 0);
- return converter;
-}
-
-
-bool DoubleToStringConverter::HandleSpecialValues(
- double value,
- StringBuilder* result_builder) const {
- Double double_inspect(value);
- if (double_inspect.IsInfinite()) {
- if (infinity_symbol_ == NULL) return false;
- if (value < 0) {
- result_builder->AddCharacter('-');
- }
- result_builder->AddString(infinity_symbol_);
- return true;
- }
- if (double_inspect.IsNan()) {
- if (nan_symbol_ == NULL) return false;
- result_builder->AddString(nan_symbol_);
- return true;
- }
- return false;
-}
-
-
-void DoubleToStringConverter::CreateExponentialRepresentation(
- const char* decimal_digits,
- int length,
- int exponent,
- StringBuilder* result_builder) const {
- ASSERT(length != 0);
- result_builder->AddCharacter(decimal_digits[0]);
- if (length != 1) {
- result_builder->AddCharacter('.');
- result_builder->AddSubstring(&decimal_digits[1], length-1);
- }
- result_builder->AddCharacter(exponent_character_);
- if (exponent < 0) {
- result_builder->AddCharacter('-');
- exponent = -exponent;
- } else {
- if ((flags_ & EMIT_POSITIVE_EXPONENT_SIGN) != 0) {
- result_builder->AddCharacter('+');
- }
- }
- if (exponent == 0) {
- result_builder->AddCharacter('0');
- return;
- }
- ASSERT(exponent < 1e4);
- const int kMaxExponentLength = 5;
- char buffer[kMaxExponentLength + 1];
- buffer[kMaxExponentLength] = '\0';
- int first_char_pos = kMaxExponentLength;
- while (exponent > 0) {
- buffer[--first_char_pos] = '0' + (exponent % 10);
- exponent /= 10;
- }
- result_builder->AddSubstring(&buffer[first_char_pos],
- kMaxExponentLength - first_char_pos);
-}
-
-
-void DoubleToStringConverter::CreateDecimalRepresentation(
- const char* decimal_digits,
- int length,
- int decimal_point,
- int digits_after_point,
- StringBuilder* result_builder) const {
- // Create a representation that is padded with zeros if needed.
- if (decimal_point <= 0) {
- // "0.00000decimal_rep".
- result_builder->AddCharacter('0');
- if (digits_after_point > 0) {
- result_builder->AddCharacter('.');
- result_builder->AddPadding('0', -decimal_point);
- ASSERT(length <= digits_after_point - (-decimal_point));
- result_builder->AddSubstring(decimal_digits, length);
- int remaining_digits = digits_after_point - (-decimal_point) - length;
- result_builder->AddPadding('0', remaining_digits);
- }
- } else if (decimal_point >= length) {
- // "decimal_rep0000.00000" or "decimal_rep.0000"
- result_builder->AddSubstring(decimal_digits, length);
- result_builder->AddPadding('0', decimal_point - length);
- if (digits_after_point > 0) {
- result_builder->AddCharacter('.');
- result_builder->AddPadding('0', digits_after_point);
- }
- } else {
- // "decima.l_rep000"
- ASSERT(digits_after_point > 0);
- result_builder->AddSubstring(decimal_digits, decimal_point);
- result_builder->AddCharacter('.');
- ASSERT(length - decimal_point <= digits_after_point);
- result_builder->AddSubstring(&decimal_digits[decimal_point],
- length - decimal_point);
- int remaining_digits = digits_after_point - (length - decimal_point);
- result_builder->AddPadding('0', remaining_digits);
- }
- if (digits_after_point == 0) {
- if ((flags_ & EMIT_TRAILING_DECIMAL_POINT) != 0) {
- result_builder->AddCharacter('.');
- }
- if ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) {
- result_builder->AddCharacter('0');
- }
- }
-}
-
-
-bool DoubleToStringConverter::ToShortestIeeeNumber(
- double value,
- StringBuilder* result_builder,
- DoubleToStringConverter::DtoaMode mode) const {
- ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE);
- if (Double(value).IsSpecial()) {
- return HandleSpecialValues(value, result_builder);
- }
-
- int decimal_point;
- bool sign;
- const int kDecimalRepCapacity = kBase10MaximalLength + 1;
- char decimal_rep[kDecimalRepCapacity];
- int decimal_rep_length;
-
- DoubleToAscii(value, mode, 0, decimal_rep, kDecimalRepCapacity,
- &sign, &decimal_rep_length, &decimal_point);
-
- bool unique_zero = (flags_ & UNIQUE_ZERO) != 0;
- if (sign && (value != 0.0 || !unique_zero)) {
- result_builder->AddCharacter('-');
- }
-
- int exponent = decimal_point - 1;
- if ((decimal_in_shortest_low_ <= exponent) &&
- (exponent < decimal_in_shortest_high_)) {
- CreateDecimalRepresentation(decimal_rep, decimal_rep_length,
- decimal_point,
- Max(0, decimal_rep_length - decimal_point),
- result_builder);
- } else {
- CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent,
- result_builder);
- }
- return true;
-}
-
-
-bool DoubleToStringConverter::ToFixed(double value,
- int requested_digits,
- StringBuilder* result_builder) const {
- ASSERT(kMaxFixedDigitsBeforePoint == 60);
- const double kFirstNonFixed = 1e60;
-
- if (Double(value).IsSpecial()) {
- return HandleSpecialValues(value, result_builder);
- }
-
- if (requested_digits > kMaxFixedDigitsAfterPoint) return false;
- if (value >= kFirstNonFixed || value <= -kFirstNonFixed) return false;
-
- // Find a sufficiently precise decimal representation of n.
- int decimal_point;
- bool sign;
- // Add space for the '\0' byte.
- const int kDecimalRepCapacity =
- kMaxFixedDigitsBeforePoint + kMaxFixedDigitsAfterPoint + 1;
- char decimal_rep[kDecimalRepCapacity];
- int decimal_rep_length;
- DoubleToAscii(value, FIXED, requested_digits,
- decimal_rep, kDecimalRepCapacity,
- &sign, &decimal_rep_length, &decimal_point);
-
- bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
- if (sign && (value != 0.0 || !unique_zero)) {
- result_builder->AddCharacter('-');
- }
-
- CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
- requested_digits, result_builder);
- return true;
-}
-
-
-bool DoubleToStringConverter::ToExponential(
- double value,
- int requested_digits,
- StringBuilder* result_builder) const {
- if (Double(value).IsSpecial()) {
- return HandleSpecialValues(value, result_builder);
- }
-
- if (requested_digits < -1) return false;
- if (requested_digits > kMaxExponentialDigits) return false;
-
- int decimal_point;
- bool sign;
- // Add space for digit before the decimal point and the '\0' character.
- const int kDecimalRepCapacity = kMaxExponentialDigits + 2;
- ASSERT(kDecimalRepCapacity > kBase10MaximalLength);
- char decimal_rep[kDecimalRepCapacity];
- int decimal_rep_length;
-
- if (requested_digits == -1) {
- DoubleToAscii(value, SHORTEST, 0,
- decimal_rep, kDecimalRepCapacity,
- &sign, &decimal_rep_length, &decimal_point);
- } else {
- DoubleToAscii(value, PRECISION, requested_digits + 1,
- decimal_rep, kDecimalRepCapacity,
- &sign, &decimal_rep_length, &decimal_point);
- ASSERT(decimal_rep_length <= requested_digits + 1);
-
- for (int i = decimal_rep_length; i < requested_digits + 1; ++i) {
- decimal_rep[i] = '0';
- }
- decimal_rep_length = requested_digits + 1;
- }
-
- bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
- if (sign && (value != 0.0 || !unique_zero)) {
- result_builder->AddCharacter('-');
- }
-
- int exponent = decimal_point - 1;
- CreateExponentialRepresentation(decimal_rep,
- decimal_rep_length,
- exponent,
- result_builder);
- return true;
-}
-
-
-bool DoubleToStringConverter::ToPrecision(double value,
- int precision,
- StringBuilder* result_builder) const {
- if (Double(value).IsSpecial()) {
- return HandleSpecialValues(value, result_builder);
- }
-
- if (precision < kMinPrecisionDigits || precision > kMaxPrecisionDigits) {
- return false;
- }
-
- // Find a sufficiently precise decimal representation of n.
- int decimal_point;
- bool sign;
- // Add one for the terminating null character.
- const int kDecimalRepCapacity = kMaxPrecisionDigits + 1;
- char decimal_rep[kDecimalRepCapacity];
- int decimal_rep_length;
-
- DoubleToAscii(value, PRECISION, precision,
- decimal_rep, kDecimalRepCapacity,
- &sign, &decimal_rep_length, &decimal_point);
- ASSERT(decimal_rep_length <= precision);
-
- bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
- if (sign && (value != 0.0 || !unique_zero)) {
- result_builder->AddCharacter('-');
- }
-
- // The exponent if we print the number as x.xxeyyy. That is with the
- // decimal point after the first digit.
- int exponent = decimal_point - 1;
-
- int extra_zero = ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) ? 1 : 0;
- if ((-decimal_point + 1 > max_leading_padding_zeroes_in_precision_mode_) ||
- (decimal_point - precision + extra_zero >
- max_trailing_padding_zeroes_in_precision_mode_)) {
- // Fill buffer to contain 'precision' digits.
- // Usually the buffer is already at the correct length, but 'DoubleToAscii'
- // is allowed to return less characters.
- for (int i = decimal_rep_length; i < precision; ++i) {
- decimal_rep[i] = '0';
- }
-
- CreateExponentialRepresentation(decimal_rep,
- precision,
- exponent,
- result_builder);
- } else {
- CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
- Max(0, precision - decimal_point),
- result_builder);
- }
- return true;
-}
-
-
-static BignumDtoaMode DtoaToBignumDtoaMode(
- DoubleToStringConverter::DtoaMode dtoa_mode) {
- switch (dtoa_mode) {
- case DoubleToStringConverter::SHORTEST: return BIGNUM_DTOA_SHORTEST;
- case DoubleToStringConverter::SHORTEST_SINGLE:
- return BIGNUM_DTOA_SHORTEST_SINGLE;
- case DoubleToStringConverter::FIXED: return BIGNUM_DTOA_FIXED;
- case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION;
- default:
- UNREACHABLE();
- }
-}
-
-
-void DoubleToStringConverter::DoubleToAscii(double v,
- DtoaMode mode,
- int requested_digits,
- char* buffer,
- int buffer_length,
- bool* sign,
- int* length,
- int* point) {
- Vector<char> vector(buffer, buffer_length);
- ASSERT(!Double(v).IsSpecial());
- ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE || requested_digits >= 0);
-
- if (Double(v).Sign() < 0) {
- *sign = true;
- v = -v;
- } else {
- *sign = false;
- }
-
- if (mode == PRECISION && requested_digits == 0) {
- vector[0] = '\0';
- *length = 0;
- return;
- }
-
- if (v == 0) {
- vector[0] = '0';
- vector[1] = '\0';
- *length = 1;
- *point = 1;
- return;
- }
-
- bool fast_worked;
- switch (mode) {
- case SHORTEST:
- fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST, 0, vector, length, point);
- break;
- case SHORTEST_SINGLE:
- fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST_SINGLE, 0,
- vector, length, point);
- break;
- case FIXED:
- fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point);
- break;
- case PRECISION:
- fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits,
- vector, length, point);
- break;
- default:
- fast_worked = false;
- UNREACHABLE();
- }
- if (fast_worked) return;
-
- // If the fast dtoa didn't succeed use the slower bignum version.
- BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode);
- BignumDtoa(v, bignum_mode, requested_digits, vector, length, point);
- vector[*length] = '\0';
-}
-
-
-// Consumes the given substring from the iterator.
-// Returns false, if the substring does not match.
-template <class Iterator>
-static bool ConsumeSubString(Iterator* current,
- Iterator end,
- const char* substring) {
- ASSERT(**current == *substring);
- for (substring++; *substring != '\0'; substring++) {
- ++*current;
- if (*current == end || **current != *substring) return false;
- }
- ++*current;
- return true;
-}
-
-
-// Maximum number of significant digits in decimal representation.
-// The longest possible double in decimal representation is
-// (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074
-// (768 digits). If we parse a number whose first digits are equal to a
-// mean of 2 adjacent doubles (that could have up to 769 digits) the result
-// must be rounded to the bigger one unless the tail consists of zeros, so
-// we don't need to preserve all the digits.
-const int kMaxSignificantDigits = 772;
-
-
-static const char kWhitespaceTable7[] = { 32, 13, 10, 9, 11, 12 };
-static const int kWhitespaceTable7Length = ARRAY_SIZE(kWhitespaceTable7);
-
-
-static const uc16 kWhitespaceTable16[] = {
- 160, 8232, 8233, 5760, 6158, 8192, 8193, 8194, 8195,
- 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279
-};
-static const int kWhitespaceTable16Length = ARRAY_SIZE(kWhitespaceTable16);
-
-
-static bool isWhitespace(int x) {
- if (x < 128) {
- for (int i = 0; i < kWhitespaceTable7Length; i++) {
- if (kWhitespaceTable7[i] == x) return true;
- }
- } else {
- for (int i = 0; i < kWhitespaceTable16Length; i++) {
- if (kWhitespaceTable16[i] == x) return true;
- }
- }
- return false;
-}
-
-
-// Returns true if a nonspace found and false if the end has reached.
-template <class Iterator>
-static inline bool AdvanceToNonspace(Iterator* current, Iterator end) {
- while (*current != end) {
- if (!isWhitespace(**current)) return true;
- ++*current;
- }
- return false;
-}
-
-
-static bool isDigit(int x, int radix) {
- return (x >= '0' && x <= '9' && x < '0' + radix)
- || (radix > 10 && x >= 'a' && x < 'a' + radix - 10)
- || (radix > 10 && x >= 'A' && x < 'A' + radix - 10);
-}
-
-
-static double SignedZero(bool sign) {
- return sign ? -0.0 : 0.0;
-}
-
-
-// Returns true if 'c' is a decimal digit that is valid for the given radix.
-//
-// The function is small and could be inlined, but VS2012 emitted a warning
-// because it constant-propagated the radix and concluded that the last
-// condition was always true. By moving it into a separate function the
-// compiler wouldn't warn anymore.
-static bool IsDecimalDigitForRadix(int c, int radix) {
- return '0' <= c && c <= '9' && (c - '0') < radix;
-}
-
-// Returns true if 'c' is a character digit that is valid for the given radix.
-// The 'a_character' should be 'a' or 'A'.
-//
-// The function is small and could be inlined, but VS2012 emitted a warning
-// because it constant-propagated the radix and concluded that the first
-// condition was always false. By moving it into a separate function the
-// compiler wouldn't warn anymore.
-static bool IsCharacterDigitForRadix(int c, int radix, char a_character) {
- return radix > 10 && c >= a_character && c < a_character + radix - 10;
-}
-
-
-// Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
-template <int radix_log_2, class Iterator>
-static double RadixStringToIeee(Iterator* current,
- Iterator end,
- bool sign,
- bool allow_trailing_junk,
- double junk_string_value,
- bool read_as_double,
- bool* result_is_junk) {
- ASSERT(*current != end);
-
- const int kDoubleSize = Double::kSignificandSize;
- const int kSingleSize = Single::kSignificandSize;
- const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize;
-
- *result_is_junk = true;
-
- // Skip leading 0s.
- while (**current == '0') {
- ++(*current);
- if (*current == end) {
- *result_is_junk = false;
- return SignedZero(sign);
- }
- }
-
- int64_t number = 0;
- int exponent = 0;
- const int radix = (1 << radix_log_2);
-
- do {
- int digit;
- if (IsDecimalDigitForRadix(**current, radix)) {
- digit = static_cast<char>(**current) - '0';
- } else if (IsCharacterDigitForRadix(**current, radix, 'a')) {
- digit = static_cast<char>(**current) - 'a' + 10;
- } else if (IsCharacterDigitForRadix(**current, radix, 'A')) {
- digit = static_cast<char>(**current) - 'A' + 10;
- } else {
- if (allow_trailing_junk || !AdvanceToNonspace(current, end)) {
- break;
- } else {
- return junk_string_value;
- }
- }
-
- number = number * radix + digit;
- int overflow = static_cast<int>(number >> kSignificandSize);
- if (overflow != 0) {
- // Overflow occurred. Need to determine which direction to round the
- // result.
- int overflow_bits_count = 1;
- while (overflow > 1) {
- overflow_bits_count++;
- overflow >>= 1;
- }
-
- int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
- int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
- number >>= overflow_bits_count;
- exponent = overflow_bits_count;
-
- bool zero_tail = true;
- for (;;) {
- ++(*current);
- if (*current == end || !isDigit(**current, radix)) break;
- zero_tail = zero_tail && **current == '0';
- exponent += radix_log_2;
- }
-
- if (!allow_trailing_junk && AdvanceToNonspace(current, end)) {
- return junk_string_value;
- }
-
- int middle_value = (1 << (overflow_bits_count - 1));
- if (dropped_bits > middle_value) {
- number++; // Rounding up.
- } else if (dropped_bits == middle_value) {
- // Rounding to even to consistency with decimals: half-way case rounds
- // up if significant part is odd and down otherwise.
- if ((number & 1) != 0 || !zero_tail) {
- number++; // Rounding up.
- }
- }
-
- // Rounding up may cause overflow.
- if ((number & ((int64_t)1 << kSignificandSize)) != 0) {
- exponent++;
- number >>= 1;
- }
- break;
- }
- ++(*current);
- } while (*current != end);
-
- ASSERT(number < ((int64_t)1 << kSignificandSize));
- ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
-
- *result_is_junk = false;
-
- if (exponent == 0) {
- if (sign) {
- if (number == 0) return -0.0;
- number = -number;
- }
- return static_cast<double>(number);
- }
-
- ASSERT(number != 0);
- return Double(DiyFp(number, exponent)).value();
-}
-
-
-template <class Iterator>
-double StringToDoubleConverter::StringToIeee(
- Iterator input,
- int length,
- bool read_as_double,
- int* processed_characters_count) const {
- Iterator current = input;
- Iterator end = input + length;
-
- *processed_characters_count = 0;
-
- const bool allow_trailing_junk = (flags_ & ALLOW_TRAILING_JUNK) != 0;
- const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0;
- const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0;
- const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0;
-
- // To make sure that iterator dereferencing is valid the following
- // convention is used:
- // 1. Each '++current' statement is followed by check for equality to 'end'.
- // 2. If AdvanceToNonspace returned false then current == end.
- // 3. If 'current' becomes equal to 'end' the function returns or goes to
- // 'parsing_done'.
- // 4. 'current' is not dereferenced after the 'parsing_done' label.
- // 5. Code before 'parsing_done' may rely on 'current != end'.
- if (current == end) return empty_string_value_;
-
- if (allow_leading_spaces || allow_trailing_spaces) {
- if (!AdvanceToNonspace(&current, end)) {
- *processed_characters_count = static_cast<int>(current - input);
- return empty_string_value_;
- }
- if (!allow_leading_spaces && (input != current)) {
- // No leading spaces allowed, but AdvanceToNonspace moved forward.
- return junk_string_value_;
- }
- }
-
- // The longest form of simplified number is: "-<significant digits>.1eXXX\0".
- const int kBufferSize = kMaxSignificantDigits + 10;
- char buffer[kBufferSize]; // NOLINT: size is known at compile time.
- int buffer_pos = 0;
-
- // Exponent will be adjusted if insignificant digits of the integer part
- // or insignificant leading zeros of the fractional part are dropped.
- int exponent = 0;
- int significant_digits = 0;
- int insignificant_digits = 0;
- bool nonzero_digit_dropped = false;
-
- bool sign = false;
-
- if (*current == '+' || *current == '-') {
- sign = (*current == '-');
- ++current;
- Iterator next_non_space = current;
- // Skip following spaces (if allowed).
- if (!AdvanceToNonspace(&next_non_space, end)) return junk_string_value_;
- if (!allow_spaces_after_sign && (current != next_non_space)) {
- return junk_string_value_;
- }
- current = next_non_space;
- }
-
- if (infinity_symbol_ != NULL) {
- if (*current == infinity_symbol_[0]) {
- if (!ConsumeSubString(&current, end, infinity_symbol_)) {
- return junk_string_value_;
- }
-
- if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
- return junk_string_value_;
- }
- if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
- return junk_string_value_;
- }
-
- ASSERT(buffer_pos == 0);
- *processed_characters_count = static_cast<int>(current - input);
- return sign ? -Double::Infinity() : Double::Infinity();
- }
- }
-
- if (nan_symbol_ != NULL) {
- if (*current == nan_symbol_[0]) {
- if (!ConsumeSubString(&current, end, nan_symbol_)) {
- return junk_string_value_;
- }
-
- if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
- return junk_string_value_;
- }
- if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
- return junk_string_value_;
- }
-
- ASSERT(buffer_pos == 0);
- *processed_characters_count = static_cast<int>(current - input);
- return sign ? -Double::NaN() : Double::NaN();
- }
- }
-
- bool leading_zero = false;
- if (*current == '0') {
- ++current;
- if (current == end) {
- *processed_characters_count = static_cast<int>(current - input);
- return SignedZero(sign);
- }
-
- leading_zero = true;
-
- // It could be hexadecimal value.
- if ((flags_ & ALLOW_HEX) && (*current == 'x' || *current == 'X')) {
- ++current;
- if (current == end || !isDigit(*current, 16)) {
- return junk_string_value_; // "0x".
- }
-
- bool result_is_junk;
- double result = RadixStringToIeee<4>(&current,
- end,
- sign,
- allow_trailing_junk,
- junk_string_value_,
- read_as_double,
- &result_is_junk);
- if (!result_is_junk) {
- if (allow_trailing_spaces) AdvanceToNonspace(&current, end);
- *processed_characters_count = static_cast<int>(current - input);
- }
- return result;
- }
-
- // Ignore leading zeros in the integer part.
- while (*current == '0') {
- ++current;
- if (current == end) {
- *processed_characters_count = static_cast<int>(current - input);
- return SignedZero(sign);
- }
- }
- }
-
- bool octal = leading_zero && (flags_ & ALLOW_OCTALS) != 0;
-
- // Copy significant digits of the integer part (if any) to the buffer.
- while (*current >= '0' && *current <= '9') {
- if (significant_digits < kMaxSignificantDigits) {
- ASSERT(buffer_pos < kBufferSize);
- buffer[buffer_pos++] = static_cast<char>(*current);
- significant_digits++;
- // Will later check if it's an octal in the buffer.
- } else {
- insignificant_digits++; // Move the digit into the exponential part.
- nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
- }
- octal = octal && *current < '8';
- ++current;
- if (current == end) goto parsing_done;
- }
-
- if (significant_digits == 0) {
- octal = false;
- }
-
- if (*current == '.') {
- if (octal && !allow_trailing_junk) return junk_string_value_;
- if (octal) goto parsing_done;
-
- ++current;
- if (current == end) {
- if (significant_digits == 0 && !leading_zero) {
- return junk_string_value_;
- } else {
- goto parsing_done;
- }
- }
-
- if (significant_digits == 0) {
- // octal = false;
- // Integer part consists of 0 or is absent. Significant digits start after
- // leading zeros (if any).
- while (*current == '0') {
- ++current;
- if (current == end) {
- *processed_characters_count = static_cast<int>(current - input);
- return SignedZero(sign);
- }
- exponent--; // Move this 0 into the exponent.
- }
- }
-
- // There is a fractional part.
- // We don't emit a '.', but adjust the exponent instead.
- while (*current >= '0' && *current <= '9') {
- if (significant_digits < kMaxSignificantDigits) {
- ASSERT(buffer_pos < kBufferSize);
- buffer[buffer_pos++] = static_cast<char>(*current);
- significant_digits++;
- exponent--;
- } else {
- // Ignore insignificant digits in the fractional part.
- nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
- }
- ++current;
- if (current == end) goto parsing_done;
- }
- }
-
- if (!leading_zero && exponent == 0 && significant_digits == 0) {
- // If leading_zeros is true then the string contains zeros.
- // If exponent < 0 then string was [+-]\.0*...
- // If significant_digits != 0 the string is not equal to 0.
- // Otherwise there are no digits in the string.
- return junk_string_value_;
- }
-
- // Parse exponential part.
- if (*current == 'e' || *current == 'E') {
- if (octal && !allow_trailing_junk) return junk_string_value_;
- if (octal) goto parsing_done;
- ++current;
- if (current == end) {
- if (allow_trailing_junk) {
- goto parsing_done;
- } else {
- return junk_string_value_;
- }
- }
- char sign = '+';
- if (*current == '+' || *current == '-') {
- sign = static_cast<char>(*current);
- ++current;
- if (current == end) {
- if (allow_trailing_junk) {
- goto parsing_done;
- } else {
- return junk_string_value_;
- }
- }
- }
-
- if (current == end || *current < '0' || *current > '9') {
- if (allow_trailing_junk) {
- goto parsing_done;
- } else {
- return junk_string_value_;
- }
- }
-
- const int max_exponent = INT_MAX / 2;
- ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
- int num = 0;
- do {
- // Check overflow.
- int digit = *current - '0';
- if (num >= max_exponent / 10
- && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
- num = max_exponent;
- } else {
- num = num * 10 + digit;
- }
- ++current;
- } while (current != end && *current >= '0' && *current <= '9');
-
- exponent += (sign == '-' ? -num : num);
- }
-
- if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
- return junk_string_value_;
- }
- if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
- return junk_string_value_;
- }
- if (allow_trailing_spaces) {
- AdvanceToNonspace(&current, end);
- }
-
- parsing_done:
- exponent += insignificant_digits;
-
- if (octal) {
- double result;
- bool result_is_junk;
- char* start = buffer;
- result = RadixStringToIeee<3>(&start,
- buffer + buffer_pos,
- sign,
- allow_trailing_junk,
- junk_string_value_,
- read_as_double,
- &result_is_junk);
- ASSERT(!result_is_junk);
- *processed_characters_count = static_cast<int>(current - input);
- return result;
- }
-
- if (nonzero_digit_dropped) {
- buffer[buffer_pos++] = '1';
- exponent--;
- }
-
- ASSERT(buffer_pos < kBufferSize);
- buffer[buffer_pos] = '\0';
-
- double converted;
- if (read_as_double) {
- converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
- } else {
- converted = Strtof(Vector<const char>(buffer, buffer_pos), exponent);
- }
- *processed_characters_count = static_cast<int>(current - input);
- return sign? -converted: converted;
-}
-
-
-double StringToDoubleConverter::StringToDouble(
- const char* buffer,
- int length,
- int* processed_characters_count) const {
- return StringToIeee(buffer, length, true, processed_characters_count);
-}
-
-
-double StringToDoubleConverter::StringToDouble(
- const uc16* buffer,
- int length,
- int* processed_characters_count) const {
- return StringToIeee(buffer, length, true, processed_characters_count);
-}
-
-
-float StringToDoubleConverter::StringToFloat(
- const char* buffer,
- int length,
- int* processed_characters_count) const {
- return static_cast<float>(StringToIeee(buffer, length, false,
- processed_characters_count));
-}
-
-
-float StringToDoubleConverter::StringToFloat(
- const uc16* buffer,
- int length,
- int* processed_characters_count) const {
- return static_cast<float>(StringToIeee(buffer, length, false,
- processed_characters_count));
-}
-
-} // namespace double_conversion
diff --git a/src/3rdparty/double-conversion/double-conversion.h b/src/3rdparty/double-conversion/double-conversion.h
deleted file mode 100644
index 6bdfa8d25d..0000000000
--- a/src/3rdparty/double-conversion/double-conversion.h
+++ /dev/null
@@ -1,543 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_
-#define DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_
-
-#include "utils.h"
-
-namespace double_conversion {
-
-class DoubleToStringConverter {
- public:
- // When calling ToFixed with a double > 10^kMaxFixedDigitsBeforePoint
- // or a requested_digits parameter > kMaxFixedDigitsAfterPoint then the
- // function returns false.
- static const int kMaxFixedDigitsBeforePoint = 60;
- static const int kMaxFixedDigitsAfterPoint = 60;
-
- // When calling ToExponential with a requested_digits
- // parameter > kMaxExponentialDigits then the function returns false.
- static const int kMaxExponentialDigits = 120;
-
- // When calling ToPrecision with a requested_digits
- // parameter < kMinPrecisionDigits or requested_digits > kMaxPrecisionDigits
- // then the function returns false.
- static const int kMinPrecisionDigits = 1;
- static const int kMaxPrecisionDigits = 120;
-
- enum Flags {
- NO_FLAGS = 0,
- EMIT_POSITIVE_EXPONENT_SIGN = 1,
- EMIT_TRAILING_DECIMAL_POINT = 2,
- EMIT_TRAILING_ZERO_AFTER_POINT = 4,
- UNIQUE_ZERO = 8
- };
-
- // Flags should be a bit-or combination of the possible Flags-enum.
- // - NO_FLAGS: no special flags.
- // - EMIT_POSITIVE_EXPONENT_SIGN: when the number is converted into exponent
- // form, emits a '+' for positive exponents. Example: 1.2e+2.
- // - EMIT_TRAILING_DECIMAL_POINT: when the input number is an integer and is
- // converted into decimal format then a trailing decimal point is appended.
- // Example: 2345.0 is converted to "2345.".
- // - EMIT_TRAILING_ZERO_AFTER_POINT: in addition to a trailing decimal point
- // emits a trailing '0'-character. This flag requires the
- // EXMIT_TRAILING_DECIMAL_POINT flag.
- // Example: 2345.0 is converted to "2345.0".
- // - UNIQUE_ZERO: "-0.0" is converted to "0.0".
- //
- // Infinity symbol and nan_symbol provide the string representation for these
- // special values. If the string is NULL and the special value is encountered
- // then the conversion functions return false.
- //
- // The exponent_character is used in exponential representations. It is
- // usually 'e' or 'E'.
- //
- // When converting to the shortest representation the converter will
- // represent input numbers in decimal format if they are in the interval
- // [10^decimal_in_shortest_low; 10^decimal_in_shortest_high[
- // (lower boundary included, greater boundary excluded).
- // Example: with decimal_in_shortest_low = -6 and
- // decimal_in_shortest_high = 21:
- // ToShortest(0.000001) -> "0.000001"
- // ToShortest(0.0000001) -> "1e-7"
- // ToShortest(111111111111111111111.0) -> "111111111111111110000"
- // ToShortest(100000000000000000000.0) -> "100000000000000000000"
- // ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21"
- //
- // When converting to precision mode the converter may add
- // max_leading_padding_zeroes before returning the number in exponential
- // format.
- // Example with max_leading_padding_zeroes_in_precision_mode = 6.
- // ToPrecision(0.0000012345, 2) -> "0.0000012"
- // ToPrecision(0.00000012345, 2) -> "1.2e-7"
- // Similarily the converter may add up to
- // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid
- // returning an exponential representation. A zero added by the
- // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit.
- // Examples for max_trailing_padding_zeroes_in_precision_mode = 1:
- // ToPrecision(230.0, 2) -> "230"
- // ToPrecision(230.0, 2) -> "230." with EMIT_TRAILING_DECIMAL_POINT.
- // ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT.
- DoubleToStringConverter(int flags,
- const char* infinity_symbol,
- const char* nan_symbol,
- char exponent_character,
- int decimal_in_shortest_low,
- int decimal_in_shortest_high,
- int max_leading_padding_zeroes_in_precision_mode,
- int max_trailing_padding_zeroes_in_precision_mode)
- : flags_(flags),
- infinity_symbol_(infinity_symbol),
- nan_symbol_(nan_symbol),
- exponent_character_(exponent_character),
- decimal_in_shortest_low_(decimal_in_shortest_low),
- decimal_in_shortest_high_(decimal_in_shortest_high),
- max_leading_padding_zeroes_in_precision_mode_(
- max_leading_padding_zeroes_in_precision_mode),
- max_trailing_padding_zeroes_in_precision_mode_(
- max_trailing_padding_zeroes_in_precision_mode) {
- // When 'trailing zero after the point' is set, then 'trailing point'
- // must be set too.
- ASSERT(((flags & EMIT_TRAILING_DECIMAL_POINT) != 0) ||
- !((flags & EMIT_TRAILING_ZERO_AFTER_POINT) != 0));
- }
-
- // Returns a converter following the EcmaScript specification.
- static const DoubleToStringConverter& EcmaScriptConverter();
-
- // Computes the shortest string of digits that correctly represent the input
- // number. Depending on decimal_in_shortest_low and decimal_in_shortest_high
- // (see constructor) it then either returns a decimal representation, or an
- // exponential representation.
- // Example with decimal_in_shortest_low = -6,
- // decimal_in_shortest_high = 21,
- // EMIT_POSITIVE_EXPONENT_SIGN activated, and
- // EMIT_TRAILING_DECIMAL_POINT deactived:
- // ToShortest(0.000001) -> "0.000001"
- // ToShortest(0.0000001) -> "1e-7"
- // ToShortest(111111111111111111111.0) -> "111111111111111110000"
- // ToShortest(100000000000000000000.0) -> "100000000000000000000"
- // ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21"
- //
- // Note: the conversion may round the output if the returned string
- // is accurate enough to uniquely identify the input-number.
- // For example the most precise representation of the double 9e59 equals
- // "899999999999999918767229449717619953810131273674690656206848", but
- // the converter will return the shorter (but still correct) "9e59".
- //
- // Returns true if the conversion succeeds. The conversion always succeeds
- // except when the input value is special and no infinity_symbol or
- // nan_symbol has been given to the constructor.
- bool ToShortest(double value, StringBuilder* result_builder) const {
- return ToShortestIeeeNumber(value, result_builder, SHORTEST);
- }
-
- // Same as ToShortest, but for single-precision floats.
- bool ToShortestSingle(float value, StringBuilder* result_builder) const {
- return ToShortestIeeeNumber(value, result_builder, SHORTEST_SINGLE);
- }
-
-
- // Computes a decimal representation with a fixed number of digits after the
- // decimal point. The last emitted digit is rounded.
- //
- // Examples:
- // ToFixed(3.12, 1) -> "3.1"
- // ToFixed(3.1415, 3) -> "3.142"
- // ToFixed(1234.56789, 4) -> "1234.5679"
- // ToFixed(1.23, 5) -> "1.23000"
- // ToFixed(0.1, 4) -> "0.1000"
- // ToFixed(1e30, 2) -> "1000000000000000019884624838656.00"
- // ToFixed(0.1, 30) -> "0.100000000000000005551115123126"
- // ToFixed(0.1, 17) -> "0.10000000000000001"
- //
- // If requested_digits equals 0, then the tail of the result depends on
- // the EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT.
- // Examples, for requested_digits == 0,
- // let EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT be
- // - false and false: then 123.45 -> 123
- // 0.678 -> 1
- // - true and false: then 123.45 -> 123.
- // 0.678 -> 1.
- // - true and true: then 123.45 -> 123.0
- // 0.678 -> 1.0
- //
- // Returns true if the conversion succeeds. The conversion always succeeds
- // except for the following cases:
- // - the input value is special and no infinity_symbol or nan_symbol has
- // been provided to the constructor,
- // - 'value' > 10^kMaxFixedDigitsBeforePoint, or
- // - 'requested_digits' > kMaxFixedDigitsAfterPoint.
- // The last two conditions imply that the result will never contain more than
- // 1 + kMaxFixedDigitsBeforePoint + 1 + kMaxFixedDigitsAfterPoint characters
- // (one additional character for the sign, and one for the decimal point).
- bool ToFixed(double value,
- int requested_digits,
- StringBuilder* result_builder) const;
-
- // Computes a representation in exponential format with requested_digits
- // after the decimal point. The last emitted digit is rounded.
- // If requested_digits equals -1, then the shortest exponential representation
- // is computed.
- //
- // Examples with EMIT_POSITIVE_EXPONENT_SIGN deactivated, and
- // exponent_character set to 'e'.
- // ToExponential(3.12, 1) -> "3.1e0"
- // ToExponential(5.0, 3) -> "5.000e0"
- // ToExponential(0.001, 2) -> "1.00e-3"
- // ToExponential(3.1415, -1) -> "3.1415e0"
- // ToExponential(3.1415, 4) -> "3.1415e0"
- // ToExponential(3.1415, 3) -> "3.142e0"
- // ToExponential(123456789000000, 3) -> "1.235e14"
- // ToExponential(1000000000000000019884624838656.0, -1) -> "1e30"
- // ToExponential(1000000000000000019884624838656.0, 32) ->
- // "1.00000000000000001988462483865600e30"
- // ToExponential(1234, 0) -> "1e3"
- //
- // Returns true if the conversion succeeds. The conversion always succeeds
- // except for the following cases:
- // - the input value is special and no infinity_symbol or nan_symbol has
- // been provided to the constructor,
- // - 'requested_digits' > kMaxExponentialDigits.
- // The last condition implies that the result will never contain more than
- // kMaxExponentialDigits + 8 characters (the sign, the digit before the
- // decimal point, the decimal point, the exponent character, the
- // exponent's sign, and at most 3 exponent digits).
- bool ToExponential(double value,
- int requested_digits,
- StringBuilder* result_builder) const;
-
- // Computes 'precision' leading digits of the given 'value' and returns them
- // either in exponential or decimal format, depending on
- // max_{leading|trailing}_padding_zeroes_in_precision_mode (given to the
- // constructor).
- // The last computed digit is rounded.
- //
- // Example with max_leading_padding_zeroes_in_precision_mode = 6.
- // ToPrecision(0.0000012345, 2) -> "0.0000012"
- // ToPrecision(0.00000012345, 2) -> "1.2e-7"
- // Similarily the converter may add up to
- // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid
- // returning an exponential representation. A zero added by the
- // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit.
- // Examples for max_trailing_padding_zeroes_in_precision_mode = 1:
- // ToPrecision(230.0, 2) -> "230"
- // ToPrecision(230.0, 2) -> "230." with EMIT_TRAILING_DECIMAL_POINT.
- // ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT.
- // Examples for max_trailing_padding_zeroes_in_precision_mode = 3, and no
- // EMIT_TRAILING_ZERO_AFTER_POINT:
- // ToPrecision(123450.0, 6) -> "123450"
- // ToPrecision(123450.0, 5) -> "123450"
- // ToPrecision(123450.0, 4) -> "123500"
- // ToPrecision(123450.0, 3) -> "123000"
- // ToPrecision(123450.0, 2) -> "1.2e5"
- //
- // Returns true if the conversion succeeds. The conversion always succeeds
- // except for the following cases:
- // - the input value is special and no infinity_symbol or nan_symbol has
- // been provided to the constructor,
- // - precision < kMinPericisionDigits
- // - precision > kMaxPrecisionDigits
- // The last condition implies that the result will never contain more than
- // kMaxPrecisionDigits + 7 characters (the sign, the decimal point, the
- // exponent character, the exponent's sign, and at most 3 exponent digits).
- bool ToPrecision(double value,
- int precision,
- StringBuilder* result_builder) const;
-
- enum DtoaMode {
- // Produce the shortest correct representation.
- // For example the output of 0.299999999999999988897 is (the less accurate
- // but correct) 0.3.
- SHORTEST,
- // Same as SHORTEST, but for single-precision floats.
- SHORTEST_SINGLE,
- // Produce a fixed number of digits after the decimal point.
- // For instance fixed(0.1, 4) becomes 0.1000
- // If the input number is big, the output will be big.
- FIXED,
- // Fixed number of digits (independent of the decimal point).
- PRECISION
- };
-
- // The maximal number of digits that are needed to emit a double in base 10.
- // A higher precision can be achieved by using more digits, but the shortest
- // accurate representation of any double will never use more digits than
- // kBase10MaximalLength.
- // Note that DoubleToAscii null-terminates its input. So the given buffer
- // should be at least kBase10MaximalLength + 1 characters long.
- static const int kBase10MaximalLength = 17;
-
- // Converts the given double 'v' to ascii. 'v' must not be NaN, +Infinity, or
- // -Infinity. In SHORTEST_SINGLE-mode this restriction also applies to 'v'
- // after it has been casted to a single-precision float. That is, in this
- // mode static_cast<float>(v) must not be NaN, +Infinity or -Infinity.
- //
- // The result should be interpreted as buffer * 10^(point-length).
- //
- // The output depends on the given mode:
- // - SHORTEST: produce the least amount of digits for which the internal
- // identity requirement is still satisfied. If the digits are printed
- // (together with the correct exponent) then reading this number will give
- // 'v' again. The buffer will choose the representation that is closest to
- // 'v'. If there are two at the same distance, than the one farther away
- // from 0 is chosen (halfway cases - ending with 5 - are rounded up).
- // In this mode the 'requested_digits' parameter is ignored.
- // - SHORTEST_SINGLE: same as SHORTEST but with single-precision.
- // - FIXED: produces digits necessary to print a given number with
- // 'requested_digits' digits after the decimal point. The produced digits
- // might be too short in which case the caller has to fill the remainder
- // with '0's.
- // Example: toFixed(0.001, 5) is allowed to return buffer="1", point=-2.
- // Halfway cases are rounded towards +/-Infinity (away from 0). The call
- // toFixed(0.15, 2) thus returns buffer="2", point=0.
- // The returned buffer may contain digits that would be truncated from the
- // shortest representation of the input.
- // - PRECISION: produces 'requested_digits' where the first digit is not '0'.
- // Even though the length of produced digits usually equals
- // 'requested_digits', the function is allowed to return fewer digits, in
- // which case the caller has to fill the missing digits with '0's.
- // Halfway cases are again rounded away from 0.
- // DoubleToAscii expects the given buffer to be big enough to hold all
- // digits and a terminating null-character. In SHORTEST-mode it expects a
- // buffer of at least kBase10MaximalLength + 1. In all other modes the
- // requested_digits parameter and the padding-zeroes limit the size of the
- // output. Don't forget the decimal point, the exponent character and the
- // terminating null-character when computing the maximal output size.
- // The given length is only used in debug mode to ensure the buffer is big
- // enough.
- static void DoubleToAscii(double v,
- DtoaMode mode,
- int requested_digits,
- char* buffer,
- int buffer_length,
- bool* sign,
- int* length,
- int* point);
-
- private:
- // Implementation for ToShortest and ToShortestSingle.
- bool ToShortestIeeeNumber(double value,
- StringBuilder* result_builder,
- DtoaMode mode) const;
-
- // If the value is a special value (NaN or Infinity) constructs the
- // corresponding string using the configured infinity/nan-symbol.
- // If either of them is NULL or the value is not special then the
- // function returns false.
- bool HandleSpecialValues(double value, StringBuilder* result_builder) const;
- // Constructs an exponential representation (i.e. 1.234e56).
- // The given exponent assumes a decimal point after the first decimal digit.
- void CreateExponentialRepresentation(const char* decimal_digits,
- int length,
- int exponent,
- StringBuilder* result_builder) const;
- // Creates a decimal representation (i.e 1234.5678).
- void CreateDecimalRepresentation(const char* decimal_digits,
- int length,
- int decimal_point,
- int digits_after_point,
- StringBuilder* result_builder) const;
-
- const int flags_;
- const char* const infinity_symbol_;
- const char* const nan_symbol_;
- const char exponent_character_;
- const int decimal_in_shortest_low_;
- const int decimal_in_shortest_high_;
- const int max_leading_padding_zeroes_in_precision_mode_;
- const int max_trailing_padding_zeroes_in_precision_mode_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(DoubleToStringConverter);
-};
-
-
-class StringToDoubleConverter {
- public:
- // Enumeration for allowing octals and ignoring junk when converting
- // strings to numbers.
- enum Flags {
- NO_FLAGS = 0,
- ALLOW_HEX = 1,
- ALLOW_OCTALS = 2,
- ALLOW_TRAILING_JUNK = 4,
- ALLOW_LEADING_SPACES = 8,
- ALLOW_TRAILING_SPACES = 16,
- ALLOW_SPACES_AFTER_SIGN = 32
- };
-
- // Flags should be a bit-or combination of the possible Flags-enum.
- // - NO_FLAGS: no special flags.
- // - ALLOW_HEX: recognizes the prefix "0x". Hex numbers may only be integers.
- // Ex: StringToDouble("0x1234") -> 4660.0
- // In StringToDouble("0x1234.56") the characters ".56" are trailing
- // junk. The result of the call is hence dependent on
- // the ALLOW_TRAILING_JUNK flag and/or the junk value.
- // With this flag "0x" is a junk-string. Even with ALLOW_TRAILING_JUNK,
- // the string will not be parsed as "0" followed by junk.
- //
- // - ALLOW_OCTALS: recognizes the prefix "0" for octals:
- // If a sequence of octal digits starts with '0', then the number is
- // read as octal integer. Octal numbers may only be integers.
- // Ex: StringToDouble("01234") -> 668.0
- // StringToDouble("012349") -> 12349.0 // Not a sequence of octal
- // // digits.
- // In StringToDouble("01234.56") the characters ".56" are trailing
- // junk. The result of the call is hence dependent on
- // the ALLOW_TRAILING_JUNK flag and/or the junk value.
- // In StringToDouble("01234e56") the characters "e56" are trailing
- // junk, too.
- // - ALLOW_TRAILING_JUNK: ignore trailing characters that are not part of
- // a double literal.
- // - ALLOW_LEADING_SPACES: skip over leading whitespace, including spaces,
- // new-lines, and tabs.
- // - ALLOW_TRAILING_SPACES: ignore trailing whitespace.
- // - ALLOW_SPACES_AFTER_SIGN: ignore whitespace after the sign.
- // Ex: StringToDouble("- 123.2") -> -123.2.
- // StringToDouble("+ 123.2") -> 123.2
- //
- // empty_string_value is returned when an empty string is given as input.
- // If ALLOW_LEADING_SPACES or ALLOW_TRAILING_SPACES are set, then a string
- // containing only spaces is converted to the 'empty_string_value', too.
- //
- // junk_string_value is returned when
- // a) ALLOW_TRAILING_JUNK is not set, and a junk character (a character not
- // part of a double-literal) is found.
- // b) ALLOW_TRAILING_JUNK is set, but the string does not start with a
- // double literal.
- //
- // infinity_symbol and nan_symbol are strings that are used to detect
- // inputs that represent infinity and NaN. They can be null, in which case
- // they are ignored.
- // The conversion routine first reads any possible signs. Then it compares the
- // following character of the input-string with the first character of
- // the infinity, and nan-symbol. If either matches, the function assumes, that
- // a match has been found, and expects the following input characters to match
- // the remaining characters of the special-value symbol.
- // This means that the following restrictions apply to special-value symbols:
- // - they must not start with signs ('+', or '-'),
- // - they must not have the same first character.
- // - they must not start with digits.
- //
- // Examples:
- // flags = ALLOW_HEX | ALLOW_TRAILING_JUNK,
- // empty_string_value = 0.0,
- // junk_string_value = NaN,
- // infinity_symbol = "infinity",
- // nan_symbol = "nan":
- // StringToDouble("0x1234") -> 4660.0.
- // StringToDouble("0x1234K") -> 4660.0.
- // StringToDouble("") -> 0.0 // empty_string_value.
- // StringToDouble(" ") -> NaN // junk_string_value.
- // StringToDouble(" 1") -> NaN // junk_string_value.
- // StringToDouble("0x") -> NaN // junk_string_value.
- // StringToDouble("-123.45") -> -123.45.
- // StringToDouble("--123.45") -> NaN // junk_string_value.
- // StringToDouble("123e45") -> 123e45.
- // StringToDouble("123E45") -> 123e45.
- // StringToDouble("123e+45") -> 123e45.
- // StringToDouble("123E-45") -> 123e-45.
- // StringToDouble("123e") -> 123.0 // trailing junk ignored.
- // StringToDouble("123e-") -> 123.0 // trailing junk ignored.
- // StringToDouble("+NaN") -> NaN // NaN string literal.
- // StringToDouble("-infinity") -> -inf. // infinity literal.
- // StringToDouble("Infinity") -> NaN // junk_string_value.
- //
- // flags = ALLOW_OCTAL | ALLOW_LEADING_SPACES,
- // empty_string_value = 0.0,
- // junk_string_value = NaN,
- // infinity_symbol = NULL,
- // nan_symbol = NULL:
- // StringToDouble("0x1234") -> NaN // junk_string_value.
- // StringToDouble("01234") -> 668.0.
- // StringToDouble("") -> 0.0 // empty_string_value.
- // StringToDouble(" ") -> 0.0 // empty_string_value.
- // StringToDouble(" 1") -> 1.0
- // StringToDouble("0x") -> NaN // junk_string_value.
- // StringToDouble("0123e45") -> NaN // junk_string_value.
- // StringToDouble("01239E45") -> 1239e45.
- // StringToDouble("-infinity") -> NaN // junk_string_value.
- // StringToDouble("NaN") -> NaN // junk_string_value.
- StringToDoubleConverter(int flags,
- double empty_string_value,
- double junk_string_value,
- const char* infinity_symbol,
- const char* nan_symbol)
- : flags_(flags),
- empty_string_value_(empty_string_value),
- junk_string_value_(junk_string_value),
- infinity_symbol_(infinity_symbol),
- nan_symbol_(nan_symbol) {
- }
-
- // Performs the conversion.
- // The output parameter 'processed_characters_count' is set to the number
- // of characters that have been processed to read the number.
- // Spaces than are processed with ALLOW_{LEADING|TRAILING}_SPACES are included
- // in the 'processed_characters_count'. Trailing junk is never included.
- double StringToDouble(const char* buffer,
- int length,
- int* processed_characters_count) const;
-
- // Same as StringToDouble above but for 16 bit characters.
- double StringToDouble(const uc16* buffer,
- int length,
- int* processed_characters_count) const;
-
- // Same as StringToDouble but reads a float.
- // Note that this is not equivalent to static_cast<float>(StringToDouble(...))
- // due to potential double-rounding.
- float StringToFloat(const char* buffer,
- int length,
- int* processed_characters_count) const;
-
- // Same as StringToFloat above but for 16 bit characters.
- float StringToFloat(const uc16* buffer,
- int length,
- int* processed_characters_count) const;
-
- private:
- const int flags_;
- const double empty_string_value_;
- const double junk_string_value_;
- const char* const infinity_symbol_;
- const char* const nan_symbol_;
-
- template <class Iterator>
- double StringToIeee(Iterator start_pointer,
- int length,
- bool read_as_double,
- int* processed_characters_count) const;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(StringToDoubleConverter);
-};
-
-} // namespace double_conversion
-
-#endif // DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_
diff --git a/src/3rdparty/double-conversion/double-conversion.pri b/src/3rdparty/double-conversion/double-conversion.pri
deleted file mode 100644
index 1597aca33e..0000000000
--- a/src/3rdparty/double-conversion/double-conversion.pri
+++ /dev/null
@@ -1,24 +0,0 @@
-INCLUDEPATH += $$PWD
-VPATH += $$PWD
-SOURCES += \
- $$PWD/bignum.cc \
- $$PWD/bignum-dtoa.cc \
- $$PWD/cached-powers.cc \
- $$PWD/diy-fp.cc \
- $$PWD/double-conversion.cc \
- $$PWD/fast-dtoa.cc \
- $$PWD/fixed-dtoa.cc \
- $$PWD/strtod.cc
-
-HEADERS += \
- $$PWD/bignum-dtoa.h \
- $$PWD/bignum.h \
- $$PWD/cached-powers.h \
- $$PWD/diy-fp.h \
- $$PWD/double-conversion.h \
- $$PWD/fast-dtoa.h \
- $$PWD/fixed-dtoa.h \
- $$PWD/ieee.h \
- $$PWD/strtod.h \
- $$PWD/utils.h
-
diff --git a/src/3rdparty/double-conversion/fast-dtoa.cc b/src/3rdparty/double-conversion/fast-dtoa.cc
deleted file mode 100644
index 61350383a9..0000000000
--- a/src/3rdparty/double-conversion/fast-dtoa.cc
+++ /dev/null
@@ -1,665 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "fast-dtoa.h"
-
-#include "cached-powers.h"
-#include "diy-fp.h"
-#include "ieee.h"
-
-namespace double_conversion {
-
-// The minimal and maximal target exponent define the range of w's binary
-// exponent, where 'w' is the result of multiplying the input by a cached power
-// of ten.
-//
-// A different range might be chosen on a different platform, to optimize digit
-// generation, but a smaller range requires more powers of ten to be cached.
-static const int kMinimalTargetExponent = -60;
-static const int kMaximalTargetExponent = -32;
-
-
-// Adjusts the last digit of the generated number, and screens out generated
-// solutions that may be inaccurate. A solution may be inaccurate if it is
-// outside the safe interval, or if we cannot prove that it is closer to the
-// input than a neighboring representation of the same length.
-//
-// Input: * buffer containing the digits of too_high / 10^kappa
-// * the buffer's length
-// * distance_too_high_w == (too_high - w).f() * unit
-// * unsafe_interval == (too_high - too_low).f() * unit
-// * rest = (too_high - buffer * 10^kappa).f() * unit
-// * ten_kappa = 10^kappa * unit
-// * unit = the common multiplier
-// Output: returns true if the buffer is guaranteed to contain the closest
-// representable number to the input.
-// Modifies the generated digits in the buffer to approach (round towards) w.
-static bool RoundWeed(Vector<char> buffer,
- int length,
- uint64_t distance_too_high_w,
- uint64_t unsafe_interval,
- uint64_t rest,
- uint64_t ten_kappa,
- uint64_t unit) {
- uint64_t small_distance = distance_too_high_w - unit;
- uint64_t big_distance = distance_too_high_w + unit;
- // Let w_low = too_high - big_distance, and
- // w_high = too_high - small_distance.
- // Note: w_low < w < w_high
- //
- // The real w (* unit) must lie somewhere inside the interval
- // ]w_low; w_high[ (often written as "(w_low; w_high)")
-
- // Basically the buffer currently contains a number in the unsafe interval
- // ]too_low; too_high[ with too_low < w < too_high
- //
- // too_high - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // ^v 1 unit ^ ^ ^ ^
- // boundary_high --------------------- . . . .
- // ^v 1 unit . . . .
- // - - - - - - - - - - - - - - - - - - - + - - + - - - - - - . .
- // . . ^ . .
- // . big_distance . . .
- // . . . . rest
- // small_distance . . . .
- // v . . . .
- // w_high - - - - - - - - - - - - - - - - - - . . . .
- // ^v 1 unit . . . .
- // w ---------------------------------------- . . . .
- // ^v 1 unit v . . .
- // w_low - - - - - - - - - - - - - - - - - - - - - . . .
- // . . v
- // buffer --------------------------------------------------+-------+--------
- // . .
- // safe_interval .
- // v .
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .
- // ^v 1 unit .
- // boundary_low ------------------------- unsafe_interval
- // ^v 1 unit v
- // too_low - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- //
- //
- // Note that the value of buffer could lie anywhere inside the range too_low
- // to too_high.
- //
- // boundary_low, boundary_high and w are approximations of the real boundaries
- // and v (the input number). They are guaranteed to be precise up to one unit.
- // In fact the error is guaranteed to be strictly less than one unit.
- //
- // Anything that lies outside the unsafe interval is guaranteed not to round
- // to v when read again.
- // Anything that lies inside the safe interval is guaranteed to round to v
- // when read again.
- // If the number inside the buffer lies inside the unsafe interval but not
- // inside the safe interval then we simply do not know and bail out (returning
- // false).
- //
- // Similarly we have to take into account the imprecision of 'w' when finding
- // the closest representation of 'w'. If we have two potential
- // representations, and one is closer to both w_low and w_high, then we know
- // it is closer to the actual value v.
- //
- // By generating the digits of too_high we got the largest (closest to
- // too_high) buffer that is still in the unsafe interval. In the case where
- // w_high < buffer < too_high we try to decrement the buffer.
- // This way the buffer approaches (rounds towards) w.
- // There are 3 conditions that stop the decrementation process:
- // 1) the buffer is already below w_high
- // 2) decrementing the buffer would make it leave the unsafe interval
- // 3) decrementing the buffer would yield a number below w_high and farther
- // away than the current number. In other words:
- // (buffer{-1} < w_high) && w_high - buffer{-1} > buffer - w_high
- // Instead of using the buffer directly we use its distance to too_high.
- // Conceptually rest ~= too_high - buffer
- // We need to do the following tests in this order to avoid over- and
- // underflows.
- ASSERT(rest <= unsafe_interval);
- while (rest < small_distance && // Negated condition 1
- unsafe_interval - rest >= ten_kappa && // Negated condition 2
- (rest + ten_kappa < small_distance || // buffer{-1} > w_high
- small_distance - rest >= rest + ten_kappa - small_distance)) {
- buffer[length - 1]--;
- rest += ten_kappa;
- }
-
- // We have approached w+ as much as possible. We now test if approaching w-
- // would require changing the buffer. If yes, then we have two possible
- // representations close to w, but we cannot decide which one is closer.
- if (rest < big_distance &&
- unsafe_interval - rest >= ten_kappa &&
- (rest + ten_kappa < big_distance ||
- big_distance - rest > rest + ten_kappa - big_distance)) {
- return false;
- }
-
- // Weeding test.
- // The safe interval is [too_low + 2 ulp; too_high - 2 ulp]
- // Since too_low = too_high - unsafe_interval this is equivalent to
- // [too_high - unsafe_interval + 4 ulp; too_high - 2 ulp]
- // Conceptually we have: rest ~= too_high - buffer
- return (2 * unit <= rest) && (rest <= unsafe_interval - 4 * unit);
-}
-
-
-// Rounds the buffer upwards if the result is closer to v by possibly adding
-// 1 to the buffer. If the precision of the calculation is not sufficient to
-// round correctly, return false.
-// The rounding might shift the whole buffer in which case the kappa is
-// adjusted. For example "99", kappa = 3 might become "10", kappa = 4.
-//
-// If 2*rest > ten_kappa then the buffer needs to be round up.
-// rest can have an error of +/- 1 unit. This function accounts for the
-// imprecision and returns false, if the rounding direction cannot be
-// unambiguously determined.
-//
-// Precondition: rest < ten_kappa.
-static bool RoundWeedCounted(Vector<char> buffer,
- int length,
- uint64_t rest,
- uint64_t ten_kappa,
- uint64_t unit,
- int* kappa) {
- ASSERT(rest < ten_kappa);
- // The following tests are done in a specific order to avoid overflows. They
- // will work correctly with any uint64 values of rest < ten_kappa and unit.
- //
- // If the unit is too big, then we don't know which way to round. For example
- // a unit of 50 means that the real number lies within rest +/- 50. If
- // 10^kappa == 40 then there is no way to tell which way to round.
- if (unit >= ten_kappa) return false;
- // Even if unit is just half the size of 10^kappa we are already completely
- // lost. (And after the previous test we know that the expression will not
- // over/underflow.)
- if (ten_kappa - unit <= unit) return false;
- // If 2 * (rest + unit) <= 10^kappa we can safely round down.
- if ((ten_kappa - rest > rest) && (ten_kappa - 2 * rest >= 2 * unit)) {
- return true;
- }
- // If 2 * (rest - unit) >= 10^kappa, then we can safely round up.
- if ((rest > unit) && (ten_kappa - (rest - unit) <= (rest - unit))) {
- // Increment the last digit recursively until we find a non '9' digit.
- buffer[length - 1]++;
- for (int i = length - 1; i > 0; --i) {
- if (buffer[i] != '0' + 10) break;
- buffer[i] = '0';
- buffer[i - 1]++;
- }
- // If the first digit is now '0'+ 10 we had a buffer with all '9's. With the
- // exception of the first digit all digits are now '0'. Simply switch the
- // first digit to '1' and adjust the kappa. Example: "99" becomes "10" and
- // the power (the kappa) is increased.
- if (buffer[0] == '0' + 10) {
- buffer[0] = '1';
- (*kappa) += 1;
- }
- return true;
- }
- return false;
-}
-
-// Returns the biggest power of ten that is less than or equal to the given
-// number. We furthermore receive the maximum number of bits 'number' has.
-//
-// Returns power == 10^(exponent_plus_one-1) such that
-// power <= number < power * 10.
-// If number_bits == 0 then 0^(0-1) is returned.
-// The number of bits must be <= 32.
-// Precondition: number < (1 << (number_bits + 1)).
-
-// Inspired by the method for finding an integer log base 10 from here:
-// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
-static unsigned int const kSmallPowersOfTen[] =
- {0, 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000,
- 1000000000};
-
-static void BiggestPowerTen(uint32_t number,
- int number_bits,
- uint32_t* power,
- int* exponent_plus_one) {
- ASSERT(number < (1u << (number_bits + 1)));
- // 1233/4096 is approximately 1/lg(10).
- int exponent_plus_one_guess = ((number_bits + 1) * 1233 >> 12);
- // We increment to skip over the first entry in the kPowersOf10 table.
- // Note: kPowersOf10[i] == 10^(i-1).
- exponent_plus_one_guess++;
- // We don't have any guarantees that 2^number_bits <= number.
- if (number < kSmallPowersOfTen[exponent_plus_one_guess]) {
- exponent_plus_one_guess--;
- }
- *power = kSmallPowersOfTen[exponent_plus_one_guess];
- *exponent_plus_one = exponent_plus_one_guess;
-}
-
-// Generates the digits of input number w.
-// w is a floating-point number (DiyFp), consisting of a significand and an
-// exponent. Its exponent is bounded by kMinimalTargetExponent and
-// kMaximalTargetExponent.
-// Hence -60 <= w.e() <= -32.
-//
-// Returns false if it fails, in which case the generated digits in the buffer
-// should not be used.
-// Preconditions:
-// * low, w and high are correct up to 1 ulp (unit in the last place). That
-// is, their error must be less than a unit of their last digits.
-// * low.e() == w.e() == high.e()
-// * low < w < high, and taking into account their error: low~ <= high~
-// * kMinimalTargetExponent <= w.e() <= kMaximalTargetExponent
-// Postconditions: returns false if procedure fails.
-// otherwise:
-// * buffer is not null-terminated, but len contains the number of digits.
-// * buffer contains the shortest possible decimal digit-sequence
-// such that LOW < buffer * 10^kappa < HIGH, where LOW and HIGH are the
-// correct values of low and high (without their error).
-// * if more than one decimal representation gives the minimal number of
-// decimal digits then the one closest to W (where W is the correct value
-// of w) is chosen.
-// Remark: this procedure takes into account the imprecision of its input
-// numbers. If the precision is not enough to guarantee all the postconditions
-// then false is returned. This usually happens rarely (~0.5%).
-//
-// Say, for the sake of example, that
-// w.e() == -48, and w.f() == 0x1234567890abcdef
-// w's value can be computed by w.f() * 2^w.e()
-// We can obtain w's integral digits by simply shifting w.f() by -w.e().
-// -> w's integral part is 0x1234
-// w's fractional part is therefore 0x567890abcdef.
-// Printing w's integral part is easy (simply print 0x1234 in decimal).
-// In order to print its fraction we repeatedly multiply the fraction by 10 and
-// get each digit. Example the first digit after the point would be computed by
-// (0x567890abcdef * 10) >> 48. -> 3
-// The whole thing becomes slightly more complicated because we want to stop
-// once we have enough digits. That is, once the digits inside the buffer
-// represent 'w' we can stop. Everything inside the interval low - high
-// represents w. However we have to pay attention to low, high and w's
-// imprecision.
-static bool DigitGen(DiyFp low,
- DiyFp w,
- DiyFp high,
- Vector<char> buffer,
- int* length,
- int* kappa) {
- ASSERT(low.e() == w.e() && w.e() == high.e());
- ASSERT(low.f() + 1 <= high.f() - 1);
- ASSERT(kMinimalTargetExponent <= w.e() && w.e() <= kMaximalTargetExponent);
- // low, w and high are imprecise, but by less than one ulp (unit in the last
- // place).
- // If we remove (resp. add) 1 ulp from low (resp. high) we are certain that
- // the new numbers are outside of the interval we want the final
- // representation to lie in.
- // Inversely adding (resp. removing) 1 ulp from low (resp. high) would yield
- // numbers that are certain to lie in the interval. We will use this fact
- // later on.
- // We will now start by generating the digits within the uncertain
- // interval. Later we will weed out representations that lie outside the safe
- // interval and thus _might_ lie outside the correct interval.
- uint64_t unit = 1;
- DiyFp too_low = DiyFp(low.f() - unit, low.e());
- DiyFp too_high = DiyFp(high.f() + unit, high.e());
- // too_low and too_high are guaranteed to lie outside the interval we want the
- // generated number in.
- DiyFp unsafe_interval = DiyFp::Minus(too_high, too_low);
- // We now cut the input number into two parts: the integral digits and the
- // fractionals. We will not write any decimal separator though, but adapt
- // kappa instead.
- // Reminder: we are currently computing the digits (stored inside the buffer)
- // such that: too_low < buffer * 10^kappa < too_high
- // We use too_high for the digit_generation and stop as soon as possible.
- // If we stop early we effectively round down.
- DiyFp one = DiyFp(static_cast<uint64_t>(1) << -w.e(), w.e());
- // Division by one is a shift.
- uint32_t integrals = static_cast<uint32_t>(too_high.f() >> -one.e());
- // Modulo by one is an and.
- uint64_t fractionals = too_high.f() & (one.f() - 1);
- uint32_t divisor;
- int divisor_exponent_plus_one;
- BiggestPowerTen(integrals, DiyFp::kSignificandSize - (-one.e()),
- &divisor, &divisor_exponent_plus_one);
- *kappa = divisor_exponent_plus_one;
- *length = 0;
- // Loop invariant: buffer = too_high / 10^kappa (integer division)
- // The invariant holds for the first iteration: kappa has been initialized
- // with the divisor exponent + 1. And the divisor is the biggest power of ten
- // that is smaller than integrals.
- while (*kappa > 0) {
- int digit = integrals / divisor;
- ASSERT(digit <= 9);
- buffer[*length] = static_cast<char>('0' + digit);
- (*length)++;
- integrals %= divisor;
- (*kappa)--;
- // Note that kappa now equals the exponent of the divisor and that the
- // invariant thus holds again.
- uint64_t rest =
- (static_cast<uint64_t>(integrals) << -one.e()) + fractionals;
- // Invariant: too_high = buffer * 10^kappa + DiyFp(rest, one.e())
- // Reminder: unsafe_interval.e() == one.e()
- if (rest < unsafe_interval.f()) {
- // Rounding down (by not emitting the remaining digits) yields a number
- // that lies within the unsafe interval.
- return RoundWeed(buffer, *length, DiyFp::Minus(too_high, w).f(),
- unsafe_interval.f(), rest,
- static_cast<uint64_t>(divisor) << -one.e(), unit);
- }
- divisor /= 10;
- }
-
- // The integrals have been generated. We are at the point of the decimal
- // separator. In the following loop we simply multiply the remaining digits by
- // 10 and divide by one. We just need to pay attention to multiply associated
- // data (like the interval or 'unit'), too.
- // Note that the multiplication by 10 does not overflow, because w.e >= -60
- // and thus one.e >= -60.
- ASSERT(one.e() >= -60);
- ASSERT(fractionals < one.f());
- ASSERT(UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f());
- for (;;) {
- fractionals *= 10;
- unit *= 10;
- unsafe_interval.set_f(unsafe_interval.f() * 10);
- // Integer division by one.
- int digit = static_cast<int>(fractionals >> -one.e());
- ASSERT(digit <= 9);
- buffer[*length] = static_cast<char>('0' + digit);
- (*length)++;
- fractionals &= one.f() - 1; // Modulo by one.
- (*kappa)--;
- if (fractionals < unsafe_interval.f()) {
- return RoundWeed(buffer, *length, DiyFp::Minus(too_high, w).f() * unit,
- unsafe_interval.f(), fractionals, one.f(), unit);
- }
- }
-}
-
-
-
-// Generates (at most) requested_digits digits of input number w.
-// w is a floating-point number (DiyFp), consisting of a significand and an
-// exponent. Its exponent is bounded by kMinimalTargetExponent and
-// kMaximalTargetExponent.
-// Hence -60 <= w.e() <= -32.
-//
-// Returns false if it fails, in which case the generated digits in the buffer
-// should not be used.
-// Preconditions:
-// * w is correct up to 1 ulp (unit in the last place). That
-// is, its error must be strictly less than a unit of its last digit.
-// * kMinimalTargetExponent <= w.e() <= kMaximalTargetExponent
-//
-// Postconditions: returns false if procedure fails.
-// otherwise:
-// * buffer is not null-terminated, but length contains the number of
-// digits.
-// * the representation in buffer is the most precise representation of
-// requested_digits digits.
-// * buffer contains at most requested_digits digits of w. If there are less
-// than requested_digits digits then some trailing '0's have been removed.
-// * kappa is such that
-// w = buffer * 10^kappa + eps with |eps| < 10^kappa / 2.
-//
-// Remark: This procedure takes into account the imprecision of its input
-// numbers. If the precision is not enough to guarantee all the postconditions
-// then false is returned. This usually happens rarely, but the failure-rate
-// increases with higher requested_digits.
-static bool DigitGenCounted(DiyFp w,
- int requested_digits,
- Vector<char> buffer,
- int* length,
- int* kappa) {
- ASSERT(kMinimalTargetExponent <= w.e() && w.e() <= kMaximalTargetExponent);
- ASSERT(kMinimalTargetExponent >= -60);
- ASSERT(kMaximalTargetExponent <= -32);
- // w is assumed to have an error less than 1 unit. Whenever w is scaled we
- // also scale its error.
- uint64_t w_error = 1;
- // We cut the input number into two parts: the integral digits and the
- // fractional digits. We don't emit any decimal separator, but adapt kappa
- // instead. Example: instead of writing "1.2" we put "12" into the buffer and
- // increase kappa by 1.
- DiyFp one = DiyFp(static_cast<uint64_t>(1) << -w.e(), w.e());
- // Division by one is a shift.
- uint32_t integrals = static_cast<uint32_t>(w.f() >> -one.e());
- // Modulo by one is an and.
- uint64_t fractionals = w.f() & (one.f() - 1);
- uint32_t divisor;
- int divisor_exponent_plus_one;
- BiggestPowerTen(integrals, DiyFp::kSignificandSize - (-one.e()),
- &divisor, &divisor_exponent_plus_one);
- *kappa = divisor_exponent_plus_one;
- *length = 0;
-
- // Loop invariant: buffer = w / 10^kappa (integer division)
- // The invariant holds for the first iteration: kappa has been initialized
- // with the divisor exponent + 1. And the divisor is the biggest power of ten
- // that is smaller than 'integrals'.
- while (*kappa > 0) {
- int digit = integrals / divisor;
- ASSERT(digit <= 9);
- buffer[*length] = static_cast<char>('0' + digit);
- (*length)++;
- requested_digits--;
- integrals %= divisor;
- (*kappa)--;
- // Note that kappa now equals the exponent of the divisor and that the
- // invariant thus holds again.
- if (requested_digits == 0) break;
- divisor /= 10;
- }
-
- if (requested_digits == 0) {
- uint64_t rest =
- (static_cast<uint64_t>(integrals) << -one.e()) + fractionals;
- return RoundWeedCounted(buffer, *length, rest,
- static_cast<uint64_t>(divisor) << -one.e(), w_error,
- kappa);
- }
-
- // The integrals have been generated. We are at the point of the decimal
- // separator. In the following loop we simply multiply the remaining digits by
- // 10 and divide by one. We just need to pay attention to multiply associated
- // data (the 'unit'), too.
- // Note that the multiplication by 10 does not overflow, because w.e >= -60
- // and thus one.e >= -60.
- ASSERT(one.e() >= -60);
- ASSERT(fractionals < one.f());
- ASSERT(UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f());
- while (requested_digits > 0 && fractionals > w_error) {
- fractionals *= 10;
- w_error *= 10;
- // Integer division by one.
- int digit = static_cast<int>(fractionals >> -one.e());
- ASSERT(digit <= 9);
- buffer[*length] = static_cast<char>('0' + digit);
- (*length)++;
- requested_digits--;
- fractionals &= one.f() - 1; // Modulo by one.
- (*kappa)--;
- }
- if (requested_digits != 0) return false;
- return RoundWeedCounted(buffer, *length, fractionals, one.f(), w_error,
- kappa);
-}
-
-
-// Provides a decimal representation of v.
-// Returns true if it succeeds, otherwise the result cannot be trusted.
-// There will be *length digits inside the buffer (not null-terminated).
-// If the function returns true then
-// v == (double) (buffer * 10^decimal_exponent).
-// The digits in the buffer are the shortest representation possible: no
-// 0.09999999999999999 instead of 0.1. The shorter representation will even be
-// chosen even if the longer one would be closer to v.
-// The last digit will be closest to the actual v. That is, even if several
-// digits might correctly yield 'v' when read again, the closest will be
-// computed.
-static bool Grisu3(double v,
- FastDtoaMode mode,
- Vector<char> buffer,
- int* length,
- int* decimal_exponent) {
- DiyFp w = Double(v).AsNormalizedDiyFp();
- // boundary_minus and boundary_plus are the boundaries between v and its
- // closest floating-point neighbors. Any number strictly between
- // boundary_minus and boundary_plus will round to v when convert to a double.
- // Grisu3 will never output representations that lie exactly on a boundary.
- DiyFp boundary_minus, boundary_plus;
- if (mode == FAST_DTOA_SHORTEST) {
- Double(v).NormalizedBoundaries(&boundary_minus, &boundary_plus);
- } else {
- ASSERT(mode == FAST_DTOA_SHORTEST_SINGLE);
- float single_v = static_cast<float>(v);
- Single(single_v).NormalizedBoundaries(&boundary_minus, &boundary_plus);
- }
- ASSERT(boundary_plus.e() == w.e());
- DiyFp ten_mk; // Cached power of ten: 10^-k
- int mk; // -k
- int ten_mk_minimal_binary_exponent =
- kMinimalTargetExponent - (w.e() + DiyFp::kSignificandSize);
- int ten_mk_maximal_binary_exponent =
- kMaximalTargetExponent - (w.e() + DiyFp::kSignificandSize);
- PowersOfTenCache::GetCachedPowerForBinaryExponentRange(
- ten_mk_minimal_binary_exponent,
- ten_mk_maximal_binary_exponent,
- &ten_mk, &mk);
- ASSERT((kMinimalTargetExponent <= w.e() + ten_mk.e() +
- DiyFp::kSignificandSize) &&
- (kMaximalTargetExponent >= w.e() + ten_mk.e() +
- DiyFp::kSignificandSize));
- // Note that ten_mk is only an approximation of 10^-k. A DiyFp only contains a
- // 64 bit significand and ten_mk is thus only precise up to 64 bits.
-
- // The DiyFp::Times procedure rounds its result, and ten_mk is approximated
- // too. The variable scaled_w (as well as scaled_boundary_minus/plus) are now
- // off by a small amount.
- // In fact: scaled_w - w*10^k < 1ulp (unit in the last place) of scaled_w.
- // In other words: let f = scaled_w.f() and e = scaled_w.e(), then
- // (f-1) * 2^e < w*10^k < (f+1) * 2^e
- DiyFp scaled_w = DiyFp::Times(w, ten_mk);
- ASSERT(scaled_w.e() ==
- boundary_plus.e() + ten_mk.e() + DiyFp::kSignificandSize);
- // In theory it would be possible to avoid some recomputations by computing
- // the difference between w and boundary_minus/plus (a power of 2) and to
- // compute scaled_boundary_minus/plus by subtracting/adding from
- // scaled_w. However the code becomes much less readable and the speed
- // enhancements are not terriffic.
- DiyFp scaled_boundary_minus = DiyFp::Times(boundary_minus, ten_mk);
- DiyFp scaled_boundary_plus = DiyFp::Times(boundary_plus, ten_mk);
-
- // DigitGen will generate the digits of scaled_w. Therefore we have
- // v == (double) (scaled_w * 10^-mk).
- // Set decimal_exponent == -mk and pass it to DigitGen. If scaled_w is not an
- // integer than it will be updated. For instance if scaled_w == 1.23 then
- // the buffer will be filled with "123" und the decimal_exponent will be
- // decreased by 2.
- int kappa;
- bool result = DigitGen(scaled_boundary_minus, scaled_w, scaled_boundary_plus,
- buffer, length, &kappa);
- *decimal_exponent = -mk + kappa;
- return result;
-}
-
-
-// The "counted" version of grisu3 (see above) only generates requested_digits
-// number of digits. This version does not generate the shortest representation,
-// and with enough requested digits 0.1 will at some point print as 0.9999999...
-// Grisu3 is too imprecise for real halfway cases (1.5 will not work) and
-// therefore the rounding strategy for halfway cases is irrelevant.
-static bool Grisu3Counted(double v,
- int requested_digits,
- Vector<char> buffer,
- int* length,
- int* decimal_exponent) {
- DiyFp w = Double(v).AsNormalizedDiyFp();
- DiyFp ten_mk; // Cached power of ten: 10^-k
- int mk; // -k
- int ten_mk_minimal_binary_exponent =
- kMinimalTargetExponent - (w.e() + DiyFp::kSignificandSize);
- int ten_mk_maximal_binary_exponent =
- kMaximalTargetExponent - (w.e() + DiyFp::kSignificandSize);
- PowersOfTenCache::GetCachedPowerForBinaryExponentRange(
- ten_mk_minimal_binary_exponent,
- ten_mk_maximal_binary_exponent,
- &ten_mk, &mk);
- ASSERT((kMinimalTargetExponent <= w.e() + ten_mk.e() +
- DiyFp::kSignificandSize) &&
- (kMaximalTargetExponent >= w.e() + ten_mk.e() +
- DiyFp::kSignificandSize));
- // Note that ten_mk is only an approximation of 10^-k. A DiyFp only contains a
- // 64 bit significand and ten_mk is thus only precise up to 64 bits.
-
- // The DiyFp::Times procedure rounds its result, and ten_mk is approximated
- // too. The variable scaled_w (as well as scaled_boundary_minus/plus) are now
- // off by a small amount.
- // In fact: scaled_w - w*10^k < 1ulp (unit in the last place) of scaled_w.
- // In other words: let f = scaled_w.f() and e = scaled_w.e(), then
- // (f-1) * 2^e < w*10^k < (f+1) * 2^e
- DiyFp scaled_w = DiyFp::Times(w, ten_mk);
-
- // We now have (double) (scaled_w * 10^-mk).
- // DigitGen will generate the first requested_digits digits of scaled_w and
- // return together with a kappa such that scaled_w ~= buffer * 10^kappa. (It
- // will not always be exactly the same since DigitGenCounted only produces a
- // limited number of digits.)
- int kappa;
- bool result = DigitGenCounted(scaled_w, requested_digits,
- buffer, length, &kappa);
- *decimal_exponent = -mk + kappa;
- return result;
-}
-
-
-bool FastDtoa(double v,
- FastDtoaMode mode,
- int requested_digits,
- Vector<char> buffer,
- int* length,
- int* decimal_point) {
- ASSERT(v > 0);
- ASSERT(!Double(v).IsSpecial());
-
- bool result = false;
- int decimal_exponent = 0;
- switch (mode) {
- case FAST_DTOA_SHORTEST:
- case FAST_DTOA_SHORTEST_SINGLE:
- result = Grisu3(v, mode, buffer, length, &decimal_exponent);
- break;
- case FAST_DTOA_PRECISION:
- result = Grisu3Counted(v, requested_digits,
- buffer, length, &decimal_exponent);
- break;
- default:
- UNREACHABLE();
- }
- if (result) {
- *decimal_point = *length + decimal_exponent;
- buffer[*length] = '\0';
- }
- return result;
-}
-
-} // namespace double_conversion
diff --git a/src/3rdparty/double-conversion/fast-dtoa.h b/src/3rdparty/double-conversion/fast-dtoa.h
deleted file mode 100644
index 5f1e8eee5e..0000000000
--- a/src/3rdparty/double-conversion/fast-dtoa.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef DOUBLE_CONVERSION_FAST_DTOA_H_
-#define DOUBLE_CONVERSION_FAST_DTOA_H_
-
-#include "utils.h"
-
-namespace double_conversion {
-
-enum FastDtoaMode {
- // Computes the shortest representation of the given input. The returned
- // result will be the most accurate number of this length. Longer
- // representations might be more accurate.
- FAST_DTOA_SHORTEST,
- // Same as FAST_DTOA_SHORTEST but for single-precision floats.
- FAST_DTOA_SHORTEST_SINGLE,
- // Computes a representation where the precision (number of digits) is
- // given as input. The precision is independent of the decimal point.
- FAST_DTOA_PRECISION
-};
-
-// FastDtoa will produce at most kFastDtoaMaximalLength digits. This does not
-// include the terminating '\0' character.
-static const int kFastDtoaMaximalLength = 17;
-// Same for single-precision numbers.
-static const int kFastDtoaMaximalSingleLength = 9;
-
-// Provides a decimal representation of v.
-// The result should be interpreted as buffer * 10^(point - length).
-//
-// Precondition:
-// * v must be a strictly positive finite double.
-//
-// Returns true if it succeeds, otherwise the result can not be trusted.
-// There will be *length digits inside the buffer followed by a null terminator.
-// If the function returns true and mode equals
-// - FAST_DTOA_SHORTEST, then
-// the parameter requested_digits is ignored.
-// The result satisfies
-// v == (double) (buffer * 10^(point - length)).
-// The digits in the buffer are the shortest representation possible. E.g.
-// if 0.099999999999 and 0.1 represent the same double then "1" is returned
-// with point = 0.
-// The last digit will be closest to the actual v. That is, even if several
-// digits might correctly yield 'v' when read again, the buffer will contain
-// the one closest to v.
-// - FAST_DTOA_PRECISION, then
-// the buffer contains requested_digits digits.
-// the difference v - (buffer * 10^(point-length)) is closest to zero for
-// all possible representations of requested_digits digits.
-// If there are two values that are equally close, then FastDtoa returns
-// false.
-// For both modes the buffer must be large enough to hold the result.
-bool FastDtoa(double d,
- FastDtoaMode mode,
- int requested_digits,
- Vector<char> buffer,
- int* length,
- int* decimal_point);
-
-} // namespace double_conversion
-
-#endif // DOUBLE_CONVERSION_FAST_DTOA_H_
diff --git a/src/3rdparty/double-conversion/fixed-dtoa.cc b/src/3rdparty/double-conversion/fixed-dtoa.cc
deleted file mode 100644
index aef65fdc21..0000000000
--- a/src/3rdparty/double-conversion/fixed-dtoa.cc
+++ /dev/null
@@ -1,404 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include <math.h>
-
-#include "fixed-dtoa.h"
-#include "ieee.h"
-
-namespace double_conversion {
-
-// Represents a 128bit type. This class should be replaced by a native type on
-// platforms that support 128bit integers.
-class UInt128 {
- public:
- UInt128() : high_bits_(0), low_bits_(0) { }
- UInt128(uint64_t high, uint64_t low) : high_bits_(high), low_bits_(low) { }
-
- void Multiply(uint32_t multiplicand) {
- uint64_t accumulator;
-
- accumulator = (low_bits_ & kMask32) * multiplicand;
- uint32_t part = static_cast<uint32_t>(accumulator & kMask32);
- accumulator >>= 32;
- accumulator = accumulator + (low_bits_ >> 32) * multiplicand;
- low_bits_ = (accumulator << 32) + part;
- accumulator >>= 32;
- accumulator = accumulator + (high_bits_ & kMask32) * multiplicand;
- part = static_cast<uint32_t>(accumulator & kMask32);
- accumulator >>= 32;
- accumulator = accumulator + (high_bits_ >> 32) * multiplicand;
- high_bits_ = (accumulator << 32) + part;
- ASSERT((accumulator >> 32) == 0);
- }
-
- void Shift(int shift_amount) {
- ASSERT(-64 <= shift_amount && shift_amount <= 64);
- if (shift_amount == 0) {
- return;
- } else if (shift_amount == -64) {
- high_bits_ = low_bits_;
- low_bits_ = 0;
- } else if (shift_amount == 64) {
- low_bits_ = high_bits_;
- high_bits_ = 0;
- } else if (shift_amount <= 0) {
- high_bits_ <<= -shift_amount;
- high_bits_ += low_bits_ >> (64 + shift_amount);
- low_bits_ <<= -shift_amount;
- } else {
- low_bits_ >>= shift_amount;
- low_bits_ += high_bits_ << (64 - shift_amount);
- high_bits_ >>= shift_amount;
- }
- }
-
- // Modifies *this to *this MOD (2^power).
- // Returns *this DIV (2^power).
- int DivModPowerOf2(int power) {
- if (power >= 64) {
- int result = static_cast<int>(high_bits_ >> (power - 64));
- high_bits_ -= static_cast<uint64_t>(result) << (power - 64);
- return result;
- } else {
- uint64_t part_low = low_bits_ >> power;
- uint64_t part_high = high_bits_ << (64 - power);
- int result = static_cast<int>(part_low + part_high);
- high_bits_ = 0;
- low_bits_ -= part_low << power;
- return result;
- }
- }
-
- bool IsZero() const {
- return high_bits_ == 0 && low_bits_ == 0;
- }
-
- int BitAt(int position) {
- if (position >= 64) {
- return static_cast<int>(high_bits_ >> (position - 64)) & 1;
- } else {
- return static_cast<int>(low_bits_ >> position) & 1;
- }
- }
-
- private:
- static const uint64_t kMask32 = 0xFFFFFFFF;
- // Value == (high_bits_ << 64) + low_bits_
- uint64_t high_bits_;
- uint64_t low_bits_;
-};
-
-
-static const int kDoubleSignificandSize = 53; // Includes the hidden bit.
-
-
-static void FillDigits32FixedLength(uint32_t number, int requested_length,
- Vector<char> buffer, int* length) {
- for (int i = requested_length - 1; i >= 0; --i) {
- buffer[(*length) + i] = '0' + number % 10;
- number /= 10;
- }
- *length += requested_length;
-}
-
-
-static void FillDigits32(uint32_t number, Vector<char> buffer, int* length) {
- int number_length = 0;
- // We fill the digits in reverse order and exchange them afterwards.
- while (number != 0) {
- int digit = number % 10;
- number /= 10;
- buffer[(*length) + number_length] = static_cast<char>('0' + digit);
- number_length++;
- }
- // Exchange the digits.
- int i = *length;
- int j = *length + number_length - 1;
- while (i < j) {
- char tmp = buffer[i];
- buffer[i] = buffer[j];
- buffer[j] = tmp;
- i++;
- j--;
- }
- *length += number_length;
-}
-
-
-static void FillDigits64FixedLength(uint64_t number,
- Vector<char> buffer, int* length) {
- const uint32_t kTen7 = 10000000;
- // For efficiency cut the number into 3 uint32_t parts, and print those.
- uint32_t part2 = static_cast<uint32_t>(number % kTen7);
- number /= kTen7;
- uint32_t part1 = static_cast<uint32_t>(number % kTen7);
- uint32_t part0 = static_cast<uint32_t>(number / kTen7);
-
- FillDigits32FixedLength(part0, 3, buffer, length);
- FillDigits32FixedLength(part1, 7, buffer, length);
- FillDigits32FixedLength(part2, 7, buffer, length);
-}
-
-
-static void FillDigits64(uint64_t number, Vector<char> buffer, int* length) {
- const uint32_t kTen7 = 10000000;
- // For efficiency cut the number into 3 uint32_t parts, and print those.
- uint32_t part2 = static_cast<uint32_t>(number % kTen7);
- number /= kTen7;
- uint32_t part1 = static_cast<uint32_t>(number % kTen7);
- uint32_t part0 = static_cast<uint32_t>(number / kTen7);
-
- if (part0 != 0) {
- FillDigits32(part0, buffer, length);
- FillDigits32FixedLength(part1, 7, buffer, length);
- FillDigits32FixedLength(part2, 7, buffer, length);
- } else if (part1 != 0) {
- FillDigits32(part1, buffer, length);
- FillDigits32FixedLength(part2, 7, buffer, length);
- } else {
- FillDigits32(part2, buffer, length);
- }
-}
-
-
-static void RoundUp(Vector<char> buffer, int* length, int* decimal_point) {
- // An empty buffer represents 0.
- if (*length == 0) {
- buffer[0] = '1';
- *decimal_point = 1;
- *length = 1;
- return;
- }
- // Round the last digit until we either have a digit that was not '9' or until
- // we reached the first digit.
- buffer[(*length) - 1]++;
- for (int i = (*length) - 1; i > 0; --i) {
- if (buffer[i] != '0' + 10) {
- return;
- }
- buffer[i] = '0';
- buffer[i - 1]++;
- }
- // If the first digit is now '0' + 10, we would need to set it to '0' and add
- // a '1' in front. However we reach the first digit only if all following
- // digits had been '9' before rounding up. Now all trailing digits are '0' and
- // we simply switch the first digit to '1' and update the decimal-point
- // (indicating that the point is now one digit to the right).
- if (buffer[0] == '0' + 10) {
- buffer[0] = '1';
- (*decimal_point)++;
- }
-}
-
-
-// The given fractionals number represents a fixed-point number with binary
-// point at bit (-exponent).
-// Preconditions:
-// -128 <= exponent <= 0.
-// 0 <= fractionals * 2^exponent < 1
-// The buffer holds the result.
-// The function will round its result. During the rounding-process digits not
-// generated by this function might be updated, and the decimal-point variable
-// might be updated. If this function generates the digits 99 and the buffer
-// already contained "199" (thus yielding a buffer of "19999") then a
-// rounding-up will change the contents of the buffer to "20000".
-static void FillFractionals(uint64_t fractionals, int exponent,
- int fractional_count, Vector<char> buffer,
- int* length, int* decimal_point) {
- ASSERT(-128 <= exponent && exponent <= 0);
- // 'fractionals' is a fixed-point number, with binary point at bit
- // (-exponent). Inside the function the non-converted remainder of fractionals
- // is a fixed-point number, with binary point at bit 'point'.
- if (-exponent <= 64) {
- // One 64 bit number is sufficient.
- ASSERT(fractionals >> 56 == 0);
- int point = -exponent;
- for (int i = 0; i < fractional_count; ++i) {
- if (fractionals == 0) break;
- // Instead of multiplying by 10 we multiply by 5 and adjust the point
- // location. This way the fractionals variable will not overflow.
- // Invariant at the beginning of the loop: fractionals < 2^point.
- // Initially we have: point <= 64 and fractionals < 2^56
- // After each iteration the point is decremented by one.
- // Note that 5^3 = 125 < 128 = 2^7.
- // Therefore three iterations of this loop will not overflow fractionals
- // (even without the subtraction at the end of the loop body). At this
- // time point will satisfy point <= 61 and therefore fractionals < 2^point
- // and any further multiplication of fractionals by 5 will not overflow.
- fractionals *= 5;
- point--;
- int digit = static_cast<int>(fractionals >> point);
- ASSERT(digit <= 9);
- buffer[*length] = static_cast<char>('0' + digit);
- (*length)++;
- fractionals -= static_cast<uint64_t>(digit) << point;
- }
- // If the first bit after the point is set we have to round up.
- if (((fractionals >> (point - 1)) & 1) == 1) {
- RoundUp(buffer, length, decimal_point);
- }
- } else { // We need 128 bits.
- ASSERT(64 < -exponent && -exponent <= 128);
- UInt128 fractionals128 = UInt128(fractionals, 0);
- fractionals128.Shift(-exponent - 64);
- int point = 128;
- for (int i = 0; i < fractional_count; ++i) {
- if (fractionals128.IsZero()) break;
- // As before: instead of multiplying by 10 we multiply by 5 and adjust the
- // point location.
- // This multiplication will not overflow for the same reasons as before.
- fractionals128.Multiply(5);
- point--;
- int digit = fractionals128.DivModPowerOf2(point);
- ASSERT(digit <= 9);
- buffer[*length] = static_cast<char>('0' + digit);
- (*length)++;
- }
- if (fractionals128.BitAt(point - 1) == 1) {
- RoundUp(buffer, length, decimal_point);
- }
- }
-}
-
-
-// Removes leading and trailing zeros.
-// If leading zeros are removed then the decimal point position is adjusted.
-static void TrimZeros(Vector<char> buffer, int* length, int* decimal_point) {
- while (*length > 0 && buffer[(*length) - 1] == '0') {
- (*length)--;
- }
- int first_non_zero = 0;
- while (first_non_zero < *length && buffer[first_non_zero] == '0') {
- first_non_zero++;
- }
- if (first_non_zero != 0) {
- for (int i = first_non_zero; i < *length; ++i) {
- buffer[i - first_non_zero] = buffer[i];
- }
- *length -= first_non_zero;
- *decimal_point -= first_non_zero;
- }
-}
-
-
-bool FastFixedDtoa(double v,
- int fractional_count,
- Vector<char> buffer,
- int* length,
- int* decimal_point) {
- const uint32_t kMaxUInt32 = 0xFFFFFFFF;
- uint64_t significand = Double(v).Significand();
- int exponent = Double(v).Exponent();
- // v = significand * 2^exponent (with significand a 53bit integer).
- // If the exponent is larger than 20 (i.e. we may have a 73bit number) then we
- // don't know how to compute the representation. 2^73 ~= 9.5*10^21.
- // If necessary this limit could probably be increased, but we don't need
- // more.
- if (exponent > 20) return false;
- if (fractional_count > 20) return false;
- *length = 0;
- // At most kDoubleSignificandSize bits of the significand are non-zero.
- // Given a 64 bit integer we have 11 0s followed by 53 potentially non-zero
- // bits: 0..11*..0xxx..53*..xx
- if (exponent + kDoubleSignificandSize > 64) {
- // The exponent must be > 11.
- //
- // We know that v = significand * 2^exponent.
- // And the exponent > 11.
- // We simplify the task by dividing v by 10^17.
- // The quotient delivers the first digits, and the remainder fits into a 64
- // bit number.
- // Dividing by 10^17 is equivalent to dividing by 5^17*2^17.
- const uint64_t kFive17 = UINT64_2PART_C(0xB1, A2BC2EC5); // 5^17
- uint64_t divisor = kFive17;
- int divisor_power = 17;
- uint64_t dividend = significand;
- uint32_t quotient;
- uint64_t remainder;
- // Let v = f * 2^e with f == significand and e == exponent.
- // Then need q (quotient) and r (remainder) as follows:
- // v = q * 10^17 + r
- // f * 2^e = q * 10^17 + r
- // f * 2^e = q * 5^17 * 2^17 + r
- // If e > 17 then
- // f * 2^(e-17) = q * 5^17 + r/2^17
- // else
- // f = q * 5^17 * 2^(17-e) + r/2^e
- if (exponent > divisor_power) {
- // We only allow exponents of up to 20 and therefore (17 - e) <= 3
- dividend <<= exponent - divisor_power;
- quotient = static_cast<uint32_t>(dividend / divisor);
- remainder = (dividend % divisor) << divisor_power;
- } else {
- divisor <<= divisor_power - exponent;
- quotient = static_cast<uint32_t>(dividend / divisor);
- remainder = (dividend % divisor) << exponent;
- }
- FillDigits32(quotient, buffer, length);
- FillDigits64FixedLength(remainder, buffer, length);
- *decimal_point = *length;
- } else if (exponent >= 0) {
- // 0 <= exponent <= 11
- significand <<= exponent;
- FillDigits64(significand, buffer, length);
- *decimal_point = *length;
- } else if (exponent > -kDoubleSignificandSize) {
- // We have to cut the number.
- uint64_t integrals = significand >> -exponent;
- uint64_t fractionals = significand - (integrals << -exponent);
- if (integrals > kMaxUInt32) {
- FillDigits64(integrals, buffer, length);
- } else {
- FillDigits32(static_cast<uint32_t>(integrals), buffer, length);
- }
- *decimal_point = *length;
- FillFractionals(fractionals, exponent, fractional_count,
- buffer, length, decimal_point);
- } else if (exponent < -128) {
- // This configuration (with at most 20 digits) means that all digits must be
- // 0.
- ASSERT(fractional_count <= 20);
- buffer[0] = '\0';
- *length = 0;
- *decimal_point = -fractional_count;
- } else {
- *decimal_point = 0;
- FillFractionals(significand, exponent, fractional_count,
- buffer, length, decimal_point);
- }
- TrimZeros(buffer, length, decimal_point);
- buffer[*length] = '\0';
- if ((*length) == 0) {
- // The string is empty and the decimal_point thus has no importance. Mimick
- // Gay's dtoa and and set it to -fractional_count.
- *decimal_point = -fractional_count;
- }
- return true;
-}
-
-} // namespace double_conversion
diff --git a/src/3rdparty/double-conversion/fixed-dtoa.h b/src/3rdparty/double-conversion/fixed-dtoa.h
deleted file mode 100644
index 3bdd08e21f..0000000000
--- a/src/3rdparty/double-conversion/fixed-dtoa.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef DOUBLE_CONVERSION_FIXED_DTOA_H_
-#define DOUBLE_CONVERSION_FIXED_DTOA_H_
-
-#include "utils.h"
-
-namespace double_conversion {
-
-// Produces digits necessary to print a given number with
-// 'fractional_count' digits after the decimal point.
-// The buffer must be big enough to hold the result plus one terminating null
-// character.
-//
-// The produced digits might be too short in which case the caller has to fill
-// the gaps with '0's.
-// Example: FastFixedDtoa(0.001, 5, ...) is allowed to return buffer = "1", and
-// decimal_point = -2.
-// Halfway cases are rounded towards +/-Infinity (away from 0). The call
-// FastFixedDtoa(0.15, 2, ...) thus returns buffer = "2", decimal_point = 0.
-// The returned buffer may contain digits that would be truncated from the
-// shortest representation of the input.
-//
-// This method only works for some parameters. If it can't handle the input it
-// returns false. The output is null-terminated when the function succeeds.
-bool FastFixedDtoa(double v, int fractional_count,
- Vector<char> buffer, int* length, int* decimal_point);
-
-} // namespace double_conversion
-
-#endif // DOUBLE_CONVERSION_FIXED_DTOA_H_
diff --git a/src/3rdparty/double-conversion/ieee.h b/src/3rdparty/double-conversion/ieee.h
deleted file mode 100644
index 661141d1a8..0000000000
--- a/src/3rdparty/double-conversion/ieee.h
+++ /dev/null
@@ -1,402 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef DOUBLE_CONVERSION_DOUBLE_H_
-#define DOUBLE_CONVERSION_DOUBLE_H_
-
-#include "diy-fp.h"
-
-namespace double_conversion {
-
-// We assume that doubles and uint64_t have the same endianness.
-static uint64_t double_to_uint64(double d) { return BitCast<uint64_t>(d); }
-static double uint64_to_double(uint64_t d64) { return BitCast<double>(d64); }
-static uint32_t float_to_uint32(float f) { return BitCast<uint32_t>(f); }
-static float uint32_to_float(uint32_t d32) { return BitCast<float>(d32); }
-
-// Helper functions for doubles.
-class Double {
- public:
- static const uint64_t kSignMask = UINT64_2PART_C(0x80000000, 00000000);
- static const uint64_t kExponentMask = UINT64_2PART_C(0x7FF00000, 00000000);
- static const uint64_t kSignificandMask = UINT64_2PART_C(0x000FFFFF, FFFFFFFF);
- static const uint64_t kHiddenBit = UINT64_2PART_C(0x00100000, 00000000);
- static const int kPhysicalSignificandSize = 52; // Excludes the hidden bit.
- static const int kSignificandSize = 53;
-
- Double() : d64_(0) {}
- explicit Double(double d) : d64_(double_to_uint64(d)) {}
- explicit Double(uint64_t d64) : d64_(d64) {}
- explicit Double(DiyFp diy_fp)
- : d64_(DiyFpToUint64(diy_fp)) {}
-
- // The value encoded by this Double must be greater or equal to +0.0.
- // It must not be special (infinity, or NaN).
- DiyFp AsDiyFp() const {
- ASSERT(Sign() > 0);
- ASSERT(!IsSpecial());
- return DiyFp(Significand(), Exponent());
- }
-
- // The value encoded by this Double must be strictly greater than 0.
- DiyFp AsNormalizedDiyFp() const {
- ASSERT(value() > 0.0);
- uint64_t f = Significand();
- int e = Exponent();
-
- // The current double could be a denormal.
- while ((f & kHiddenBit) == 0) {
- f <<= 1;
- e--;
- }
- // Do the final shifts in one go.
- f <<= DiyFp::kSignificandSize - kSignificandSize;
- e -= DiyFp::kSignificandSize - kSignificandSize;
- return DiyFp(f, e);
- }
-
- // Returns the double's bit as uint64.
- uint64_t AsUint64() const {
- return d64_;
- }
-
- // Returns the next greater double. Returns +infinity on input +infinity.
- double NextDouble() const {
- if (d64_ == kInfinity) return Double(kInfinity).value();
- if (Sign() < 0 && Significand() == 0) {
- // -0.0
- return 0.0;
- }
- if (Sign() < 0) {
- return Double(d64_ - 1).value();
- } else {
- return Double(d64_ + 1).value();
- }
- }
-
- double PreviousDouble() const {
- if (d64_ == (kInfinity | kSignMask)) return -Double::Infinity();
- if (Sign() < 0) {
- return Double(d64_ + 1).value();
- } else {
- if (Significand() == 0) return -0.0;
- return Double(d64_ - 1).value();
- }
- }
-
- int Exponent() const {
- if (IsDenormal()) return kDenormalExponent;
-
- uint64_t d64 = AsUint64();
- int biased_e =
- static_cast<int>((d64 & kExponentMask) >> kPhysicalSignificandSize);
- return biased_e - kExponentBias;
- }
-
- uint64_t Significand() const {
- uint64_t d64 = AsUint64();
- uint64_t significand = d64 & kSignificandMask;
- if (!IsDenormal()) {
- return significand + kHiddenBit;
- } else {
- return significand;
- }
- }
-
- // Returns true if the double is a denormal.
- bool IsDenormal() const {
- uint64_t d64 = AsUint64();
- return (d64 & kExponentMask) == 0;
- }
-
- // We consider denormals not to be special.
- // Hence only Infinity and NaN are special.
- bool IsSpecial() const {
- uint64_t d64 = AsUint64();
- return (d64 & kExponentMask) == kExponentMask;
- }
-
- bool IsNan() const {
- uint64_t d64 = AsUint64();
- return ((d64 & kExponentMask) == kExponentMask) &&
- ((d64 & kSignificandMask) != 0);
- }
-
- bool IsInfinite() const {
- uint64_t d64 = AsUint64();
- return ((d64 & kExponentMask) == kExponentMask) &&
- ((d64 & kSignificandMask) == 0);
- }
-
- int Sign() const {
- uint64_t d64 = AsUint64();
- return (d64 & kSignMask) == 0? 1: -1;
- }
-
- // Precondition: the value encoded by this Double must be greater or equal
- // than +0.0.
- DiyFp UpperBoundary() const {
- ASSERT(Sign() > 0);
- return DiyFp(Significand() * 2 + 1, Exponent() - 1);
- }
-
- // Computes the two boundaries of this.
- // The bigger boundary (m_plus) is normalized. The lower boundary has the same
- // exponent as m_plus.
- // Precondition: the value encoded by this Double must be greater than 0.
- void NormalizedBoundaries(DiyFp* out_m_minus, DiyFp* out_m_plus) const {
- ASSERT(value() > 0.0);
- DiyFp v = this->AsDiyFp();
- DiyFp m_plus = DiyFp::Normalize(DiyFp((v.f() << 1) + 1, v.e() - 1));
- DiyFp m_minus;
- if (LowerBoundaryIsCloser()) {
- m_minus = DiyFp((v.f() << 2) - 1, v.e() - 2);
- } else {
- m_minus = DiyFp((v.f() << 1) - 1, v.e() - 1);
- }
- m_minus.set_f(m_minus.f() << (m_minus.e() - m_plus.e()));
- m_minus.set_e(m_plus.e());
- *out_m_plus = m_plus;
- *out_m_minus = m_minus;
- }
-
- bool LowerBoundaryIsCloser() const {
- // The boundary is closer if the significand is of the form f == 2^p-1 then
- // the lower boundary is closer.
- // Think of v = 1000e10 and v- = 9999e9.
- // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but
- // at a distance of 1e8.
- // The only exception is for the smallest normal: the largest denormal is
- // at the same distance as its successor.
- // Note: denormals have the same exponent as the smallest normals.
- bool physical_significand_is_zero = ((AsUint64() & kSignificandMask) == 0);
- return physical_significand_is_zero && (Exponent() != kDenormalExponent);
- }
-
- double value() const { return uint64_to_double(d64_); }
-
- // Returns the significand size for a given order of magnitude.
- // If v = f*2^e with 2^p-1 <= f <= 2^p then p+e is v's order of magnitude.
- // This function returns the number of significant binary digits v will have
- // once it's encoded into a double. In almost all cases this is equal to
- // kSignificandSize. The only exceptions are denormals. They start with
- // leading zeroes and their effective significand-size is hence smaller.
- static int SignificandSizeForOrderOfMagnitude(int order) {
- if (order >= (kDenormalExponent + kSignificandSize)) {
- return kSignificandSize;
- }
- if (order <= kDenormalExponent) return 0;
- return order - kDenormalExponent;
- }
-
- static double Infinity() {
- return Double(kInfinity).value();
- }
-
- static double NaN() {
- return Double(kNaN).value();
- }
-
- private:
- static const int kExponentBias = 0x3FF + kPhysicalSignificandSize;
- static const int kDenormalExponent = -kExponentBias + 1;
- static const int kMaxExponent = 0x7FF - kExponentBias;
- static const uint64_t kInfinity = UINT64_2PART_C(0x7FF00000, 00000000);
- static const uint64_t kNaN = UINT64_2PART_C(0x7FF80000, 00000000);
-
- const uint64_t d64_;
-
- static uint64_t DiyFpToUint64(DiyFp diy_fp) {
- uint64_t significand = diy_fp.f();
- int exponent = diy_fp.e();
- while (significand > kHiddenBit + kSignificandMask) {
- significand >>= 1;
- exponent++;
- }
- if (exponent >= kMaxExponent) {
- return kInfinity;
- }
- if (exponent < kDenormalExponent) {
- return 0;
- }
- while (exponent > kDenormalExponent && (significand & kHiddenBit) == 0) {
- significand <<= 1;
- exponent--;
- }
- uint64_t biased_exponent;
- if (exponent == kDenormalExponent && (significand & kHiddenBit) == 0) {
- biased_exponent = 0;
- } else {
- biased_exponent = static_cast<uint64_t>(exponent + kExponentBias);
- }
- return (significand & kSignificandMask) |
- (biased_exponent << kPhysicalSignificandSize);
- }
-
- DISALLOW_COPY_AND_ASSIGN(Double);
-};
-
-class Single {
- public:
- static const uint32_t kSignMask = 0x80000000;
- static const uint32_t kExponentMask = 0x7F800000;
- static const uint32_t kSignificandMask = 0x007FFFFF;
- static const uint32_t kHiddenBit = 0x00800000;
- static const int kPhysicalSignificandSize = 23; // Excludes the hidden bit.
- static const int kSignificandSize = 24;
-
- Single() : d32_(0) {}
- explicit Single(float f) : d32_(float_to_uint32(f)) {}
- explicit Single(uint32_t d32) : d32_(d32) {}
-
- // The value encoded by this Single must be greater or equal to +0.0.
- // It must not be special (infinity, or NaN).
- DiyFp AsDiyFp() const {
- ASSERT(Sign() > 0);
- ASSERT(!IsSpecial());
- return DiyFp(Significand(), Exponent());
- }
-
- // Returns the single's bit as uint64.
- uint32_t AsUint32() const {
- return d32_;
- }
-
- int Exponent() const {
- if (IsDenormal()) return kDenormalExponent;
-
- uint32_t d32 = AsUint32();
- int biased_e =
- static_cast<int>((d32 & kExponentMask) >> kPhysicalSignificandSize);
- return biased_e - kExponentBias;
- }
-
- uint32_t Significand() const {
- uint32_t d32 = AsUint32();
- uint32_t significand = d32 & kSignificandMask;
- if (!IsDenormal()) {
- return significand + kHiddenBit;
- } else {
- return significand;
- }
- }
-
- // Returns true if the single is a denormal.
- bool IsDenormal() const {
- uint32_t d32 = AsUint32();
- return (d32 & kExponentMask) == 0;
- }
-
- // We consider denormals not to be special.
- // Hence only Infinity and NaN are special.
- bool IsSpecial() const {
- uint32_t d32 = AsUint32();
- return (d32 & kExponentMask) == kExponentMask;
- }
-
- bool IsNan() const {
- uint32_t d32 = AsUint32();
- return ((d32 & kExponentMask) == kExponentMask) &&
- ((d32 & kSignificandMask) != 0);
- }
-
- bool IsInfinite() const {
- uint32_t d32 = AsUint32();
- return ((d32 & kExponentMask) == kExponentMask) &&
- ((d32 & kSignificandMask) == 0);
- }
-
- int Sign() const {
- uint32_t d32 = AsUint32();
- return (d32 & kSignMask) == 0? 1: -1;
- }
-
- // Computes the two boundaries of this.
- // The bigger boundary (m_plus) is normalized. The lower boundary has the same
- // exponent as m_plus.
- // Precondition: the value encoded by this Single must be greater than 0.
- void NormalizedBoundaries(DiyFp* out_m_minus, DiyFp* out_m_plus) const {
- ASSERT(value() > 0.0);
- DiyFp v = this->AsDiyFp();
- DiyFp m_plus = DiyFp::Normalize(DiyFp((v.f() << 1) + 1, v.e() - 1));
- DiyFp m_minus;
- if (LowerBoundaryIsCloser()) {
- m_minus = DiyFp((v.f() << 2) - 1, v.e() - 2);
- } else {
- m_minus = DiyFp((v.f() << 1) - 1, v.e() - 1);
- }
- m_minus.set_f(m_minus.f() << (m_minus.e() - m_plus.e()));
- m_minus.set_e(m_plus.e());
- *out_m_plus = m_plus;
- *out_m_minus = m_minus;
- }
-
- // Precondition: the value encoded by this Single must be greater or equal
- // than +0.0.
- DiyFp UpperBoundary() const {
- ASSERT(Sign() > 0);
- return DiyFp(Significand() * 2 + 1, Exponent() - 1);
- }
-
- bool LowerBoundaryIsCloser() const {
- // The boundary is closer if the significand is of the form f == 2^p-1 then
- // the lower boundary is closer.
- // Think of v = 1000e10 and v- = 9999e9.
- // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but
- // at a distance of 1e8.
- // The only exception is for the smallest normal: the largest denormal is
- // at the same distance as its successor.
- // Note: denormals have the same exponent as the smallest normals.
- bool physical_significand_is_zero = ((AsUint32() & kSignificandMask) == 0);
- return physical_significand_is_zero && (Exponent() != kDenormalExponent);
- }
-
- float value() const { return uint32_to_float(d32_); }
-
- static float Infinity() {
- return Single(kInfinity).value();
- }
-
- static float NaN() {
- return Single(kNaN).value();
- }
-
- private:
- static const int kExponentBias = 0x7F + kPhysicalSignificandSize;
- static const int kDenormalExponent = -kExponentBias + 1;
- static const int kMaxExponent = 0xFF - kExponentBias;
- static const uint32_t kInfinity = 0x7F800000;
- static const uint32_t kNaN = 0x7FC00000;
-
- const uint32_t d32_;
-
- DISALLOW_COPY_AND_ASSIGN(Single);
-};
-
-} // namespace double_conversion
-
-#endif // DOUBLE_CONVERSION_DOUBLE_H_
diff --git a/src/3rdparty/double-conversion/strtod.cc b/src/3rdparty/double-conversion/strtod.cc
deleted file mode 100644
index 34717562bd..0000000000
--- a/src/3rdparty/double-conversion/strtod.cc
+++ /dev/null
@@ -1,555 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include <stdarg.h>
-#include <limits.h>
-
-#include "strtod.h"
-#include "bignum.h"
-#include "cached-powers.h"
-#include "ieee.h"
-
-namespace double_conversion {
-
-// 2^53 = 9007199254740992.
-// Any integer with at most 15 decimal digits will hence fit into a double
-// (which has a 53bit significand) without loss of precision.
-static const int kMaxExactDoubleIntegerDecimalDigits = 15;
-// 2^64 = 18446744073709551616 > 10^19
-static const int kMaxUint64DecimalDigits = 19;
-
-// Max double: 1.7976931348623157 x 10^308
-// Min non-zero double: 4.9406564584124654 x 10^-324
-// Any x >= 10^309 is interpreted as +infinity.
-// Any x <= 10^-324 is interpreted as 0.
-// Note that 2.5e-324 (despite being smaller than the min double) will be read
-// as non-zero (equal to the min non-zero double).
-static const int kMaxDecimalPower = 309;
-static const int kMinDecimalPower = -324;
-
-// 2^64 = 18446744073709551616
-static const uint64_t kMaxUint64 = UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF);
-
-
-static const double exact_powers_of_ten[] = {
- 1.0, // 10^0
- 10.0,
- 100.0,
- 1000.0,
- 10000.0,
- 100000.0,
- 1000000.0,
- 10000000.0,
- 100000000.0,
- 1000000000.0,
- 10000000000.0, // 10^10
- 100000000000.0,
- 1000000000000.0,
- 10000000000000.0,
- 100000000000000.0,
- 1000000000000000.0,
- 10000000000000000.0,
- 100000000000000000.0,
- 1000000000000000000.0,
- 10000000000000000000.0,
- 100000000000000000000.0, // 10^20
- 1000000000000000000000.0,
- // 10^22 = 0x21e19e0c9bab2400000 = 0x878678326eac9 * 2^22
- 10000000000000000000000.0
-};
-static const int kExactPowersOfTenSize = ARRAY_SIZE(exact_powers_of_ten);
-
-// Maximum number of significant digits in the decimal representation.
-// In fact the value is 772 (see conversions.cc), but to give us some margin
-// we round up to 780.
-static const int kMaxSignificantDecimalDigits = 780;
-
-static Vector<const char> TrimLeadingZeros(Vector<const char> buffer) {
- for (int i = 0; i < buffer.length(); i++) {
- if (buffer[i] != '0') {
- return buffer.SubVector(i, buffer.length());
- }
- }
- return Vector<const char>(buffer.start(), 0);
-}
-
-
-static Vector<const char> TrimTrailingZeros(Vector<const char> buffer) {
- for (int i = buffer.length() - 1; i >= 0; --i) {
- if (buffer[i] != '0') {
- return buffer.SubVector(0, i + 1);
- }
- }
- return Vector<const char>(buffer.start(), 0);
-}
-
-
-static void CutToMaxSignificantDigits(Vector<const char> buffer,
- int exponent,
- char* significant_buffer,
- int* significant_exponent) {
- for (int i = 0; i < kMaxSignificantDecimalDigits - 1; ++i) {
- significant_buffer[i] = buffer[i];
- }
- // The input buffer has been trimmed. Therefore the last digit must be
- // different from '0'.
- ASSERT(buffer[buffer.length() - 1] != '0');
- // Set the last digit to be non-zero. This is sufficient to guarantee
- // correct rounding.
- significant_buffer[kMaxSignificantDecimalDigits - 1] = '1';
- *significant_exponent =
- exponent + (buffer.length() - kMaxSignificantDecimalDigits);
-}
-
-
-// Trims the buffer and cuts it to at most kMaxSignificantDecimalDigits.
-// If possible the input-buffer is reused, but if the buffer needs to be
-// modified (due to cutting), then the input needs to be copied into the
-// buffer_copy_space.
-static void TrimAndCut(Vector<const char> buffer, int exponent,
- char* buffer_copy_space, int space_size,
- Vector<const char>* trimmed, int* updated_exponent) {
- Vector<const char> left_trimmed = TrimLeadingZeros(buffer);
- Vector<const char> right_trimmed = TrimTrailingZeros(left_trimmed);
- exponent += left_trimmed.length() - right_trimmed.length();
- if (right_trimmed.length() > kMaxSignificantDecimalDigits) {
- (void) space_size; // Mark variable as used.
- ASSERT(space_size >= kMaxSignificantDecimalDigits);
- CutToMaxSignificantDigits(right_trimmed, exponent,
- buffer_copy_space, updated_exponent);
- *trimmed = Vector<const char>(buffer_copy_space,
- kMaxSignificantDecimalDigits);
- } else {
- *trimmed = right_trimmed;
- *updated_exponent = exponent;
- }
-}
-
-
-// Reads digits from the buffer and converts them to a uint64.
-// Reads in as many digits as fit into a uint64.
-// When the string starts with "1844674407370955161" no further digit is read.
-// Since 2^64 = 18446744073709551616 it would still be possible read another
-// digit if it was less or equal than 6, but this would complicate the code.
-static uint64_t ReadUint64(Vector<const char> buffer,
- int* number_of_read_digits) {
- uint64_t result = 0;
- int i = 0;
- while (i < buffer.length() && result <= (kMaxUint64 / 10 - 1)) {
- int digit = buffer[i++] - '0';
- ASSERT(0 <= digit && digit <= 9);
- result = 10 * result + digit;
- }
- *number_of_read_digits = i;
- return result;
-}
-
-
-// Reads a DiyFp from the buffer.
-// The returned DiyFp is not necessarily normalized.
-// If remaining_decimals is zero then the returned DiyFp is accurate.
-// Otherwise it has been rounded and has error of at most 1/2 ulp.
-static void ReadDiyFp(Vector<const char> buffer,
- DiyFp* result,
- int* remaining_decimals) {
- int read_digits;
- uint64_t significand = ReadUint64(buffer, &read_digits);
- if (buffer.length() == read_digits) {
- *result = DiyFp(significand, 0);
- *remaining_decimals = 0;
- } else {
- // Round the significand.
- if (buffer[read_digits] >= '5') {
- significand++;
- }
- // Compute the binary exponent.
- int exponent = 0;
- *result = DiyFp(significand, exponent);
- *remaining_decimals = buffer.length() - read_digits;
- }
-}
-
-
-static bool DoubleStrtod(Vector<const char> trimmed,
- int exponent,
- double* result) {
-#if !defined(DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS)
- // On x86 the floating-point stack can be 64 or 80 bits wide. If it is
- // 80 bits wide (as is the case on Linux) then double-rounding occurs and the
- // result is not accurate.
- // We know that Windows32 uses 64 bits and is therefore accurate.
- // Note that the ARM simulator is compiled for 32bits. It therefore exhibits
- // the same problem.
- return false;
-#endif
- if (trimmed.length() <= kMaxExactDoubleIntegerDecimalDigits) {
- int read_digits;
- // The trimmed input fits into a double.
- // If the 10^exponent (resp. 10^-exponent) fits into a double too then we
- // can compute the result-double simply by multiplying (resp. dividing) the
- // two numbers.
- // This is possible because IEEE guarantees that floating-point operations
- // return the best possible approximation.
- if (exponent < 0 && -exponent < kExactPowersOfTenSize) {
- // 10^-exponent fits into a double.
- *result = static_cast<double>(ReadUint64(trimmed, &read_digits));
- ASSERT(read_digits == trimmed.length());
- *result /= exact_powers_of_ten[-exponent];
- return true;
- }
- if (0 <= exponent && exponent < kExactPowersOfTenSize) {
- // 10^exponent fits into a double.
- *result = static_cast<double>(ReadUint64(trimmed, &read_digits));
- ASSERT(read_digits == trimmed.length());
- *result *= exact_powers_of_ten[exponent];
- return true;
- }
- int remaining_digits =
- kMaxExactDoubleIntegerDecimalDigits - trimmed.length();
- if ((0 <= exponent) &&
- (exponent - remaining_digits < kExactPowersOfTenSize)) {
- // The trimmed string was short and we can multiply it with
- // 10^remaining_digits. As a result the remaining exponent now fits
- // into a double too.
- *result = static_cast<double>(ReadUint64(trimmed, &read_digits));
- ASSERT(read_digits == trimmed.length());
- *result *= exact_powers_of_ten[remaining_digits];
- *result *= exact_powers_of_ten[exponent - remaining_digits];
- return true;
- }
- }
- return false;
-}
-
-
-// Returns 10^exponent as an exact DiyFp.
-// The given exponent must be in the range [1; kDecimalExponentDistance[.
-static DiyFp AdjustmentPowerOfTen(int exponent) {
- ASSERT(0 < exponent);
- ASSERT(exponent < PowersOfTenCache::kDecimalExponentDistance);
- // Simply hardcode the remaining powers for the given decimal exponent
- // distance.
- ASSERT(PowersOfTenCache::kDecimalExponentDistance == 8);
- switch (exponent) {
- case 1: return DiyFp(UINT64_2PART_C(0xa0000000, 00000000), -60);
- case 2: return DiyFp(UINT64_2PART_C(0xc8000000, 00000000), -57);
- case 3: return DiyFp(UINT64_2PART_C(0xfa000000, 00000000), -54);
- case 4: return DiyFp(UINT64_2PART_C(0x9c400000, 00000000), -50);
- case 5: return DiyFp(UINT64_2PART_C(0xc3500000, 00000000), -47);
- case 6: return DiyFp(UINT64_2PART_C(0xf4240000, 00000000), -44);
- case 7: return DiyFp(UINT64_2PART_C(0x98968000, 00000000), -40);
- default:
- UNREACHABLE();
- }
-}
-
-
-// If the function returns true then the result is the correct double.
-// Otherwise it is either the correct double or the double that is just below
-// the correct double.
-static bool DiyFpStrtod(Vector<const char> buffer,
- int exponent,
- double* result) {
- DiyFp input;
- int remaining_decimals;
- ReadDiyFp(buffer, &input, &remaining_decimals);
- // Since we may have dropped some digits the input is not accurate.
- // If remaining_decimals is different than 0 than the error is at most
- // .5 ulp (unit in the last place).
- // We don't want to deal with fractions and therefore keep a common
- // denominator.
- const int kDenominatorLog = 3;
- const int kDenominator = 1 << kDenominatorLog;
- // Move the remaining decimals into the exponent.
- exponent += remaining_decimals;
- int error = (remaining_decimals == 0 ? 0 : kDenominator / 2);
-
- int old_e = input.e();
- input.Normalize();
- error <<= old_e - input.e();
-
- ASSERT(exponent <= PowersOfTenCache::kMaxDecimalExponent);
- if (exponent < PowersOfTenCache::kMinDecimalExponent) {
- *result = 0.0;
- return true;
- }
- DiyFp cached_power;
- int cached_decimal_exponent;
- PowersOfTenCache::GetCachedPowerForDecimalExponent(exponent,
- &cached_power,
- &cached_decimal_exponent);
-
- if (cached_decimal_exponent != exponent) {
- int adjustment_exponent = exponent - cached_decimal_exponent;
- DiyFp adjustment_power = AdjustmentPowerOfTen(adjustment_exponent);
- input.Multiply(adjustment_power);
- if (kMaxUint64DecimalDigits - buffer.length() >= adjustment_exponent) {
- // The product of input with the adjustment power fits into a 64 bit
- // integer.
- ASSERT(DiyFp::kSignificandSize == 64);
- } else {
- // The adjustment power is exact. There is hence only an error of 0.5.
- error += kDenominator / 2;
- }
- }
-
- input.Multiply(cached_power);
- // The error introduced by a multiplication of a*b equals
- // error_a + error_b + error_a*error_b/2^64 + 0.5
- // Substituting a with 'input' and b with 'cached_power' we have
- // error_b = 0.5 (all cached powers have an error of less than 0.5 ulp),
- // error_ab = 0 or 1 / kDenominator > error_a*error_b/ 2^64
- int error_b = kDenominator / 2;
- int error_ab = (error == 0 ? 0 : 1); // We round up to 1.
- int fixed_error = kDenominator / 2;
- error += error_b + error_ab + fixed_error;
-
- old_e = input.e();
- input.Normalize();
- error <<= old_e - input.e();
-
- // See if the double's significand changes if we add/subtract the error.
- int order_of_magnitude = DiyFp::kSignificandSize + input.e();
- int effective_significand_size =
- Double::SignificandSizeForOrderOfMagnitude(order_of_magnitude);
- int precision_digits_count =
- DiyFp::kSignificandSize - effective_significand_size;
- if (precision_digits_count + kDenominatorLog >= DiyFp::kSignificandSize) {
- // This can only happen for very small denormals. In this case the
- // half-way multiplied by the denominator exceeds the range of an uint64.
- // Simply shift everything to the right.
- int shift_amount = (precision_digits_count + kDenominatorLog) -
- DiyFp::kSignificandSize + 1;
- input.set_f(input.f() >> shift_amount);
- input.set_e(input.e() + shift_amount);
- // We add 1 for the lost precision of error, and kDenominator for
- // the lost precision of input.f().
- error = (error >> shift_amount) + 1 + kDenominator;
- precision_digits_count -= shift_amount;
- }
- // We use uint64_ts now. This only works if the DiyFp uses uint64_ts too.
- ASSERT(DiyFp::kSignificandSize == 64);
- ASSERT(precision_digits_count < 64);
- uint64_t one64 = 1;
- uint64_t precision_bits_mask = (one64 << precision_digits_count) - 1;
- uint64_t precision_bits = input.f() & precision_bits_mask;
- uint64_t half_way = one64 << (precision_digits_count - 1);
- precision_bits *= kDenominator;
- half_way *= kDenominator;
- DiyFp rounded_input(input.f() >> precision_digits_count,
- input.e() + precision_digits_count);
- if (precision_bits >= half_way + error) {
- rounded_input.set_f(rounded_input.f() + 1);
- }
- // If the last_bits are too close to the half-way case than we are too
- // inaccurate and round down. In this case we return false so that we can
- // fall back to a more precise algorithm.
-
- *result = Double(rounded_input).value();
- if (half_way - error < precision_bits && precision_bits < half_way + error) {
- // Too imprecise. The caller will have to fall back to a slower version.
- // However the returned number is guaranteed to be either the correct
- // double, or the next-lower double.
- return false;
- } else {
- return true;
- }
-}
-
-
-// Returns
-// - -1 if buffer*10^exponent < diy_fp.
-// - 0 if buffer*10^exponent == diy_fp.
-// - +1 if buffer*10^exponent > diy_fp.
-// Preconditions:
-// buffer.length() + exponent <= kMaxDecimalPower + 1
-// buffer.length() + exponent > kMinDecimalPower
-// buffer.length() <= kMaxDecimalSignificantDigits
-static int CompareBufferWithDiyFp(Vector<const char> buffer,
- int exponent,
- DiyFp diy_fp) {
- ASSERT(buffer.length() + exponent <= kMaxDecimalPower + 1);
- ASSERT(buffer.length() + exponent > kMinDecimalPower);
- ASSERT(buffer.length() <= kMaxSignificantDecimalDigits);
- // Make sure that the Bignum will be able to hold all our numbers.
- // Our Bignum implementation has a separate field for exponents. Shifts will
- // consume at most one bigit (< 64 bits).
- // ln(10) == 3.3219...
- ASSERT(((kMaxDecimalPower + 1) * 333 / 100) < Bignum::kMaxSignificantBits);
- Bignum buffer_bignum;
- Bignum diy_fp_bignum;
- buffer_bignum.AssignDecimalString(buffer);
- diy_fp_bignum.AssignUInt64(diy_fp.f());
- if (exponent >= 0) {
- buffer_bignum.MultiplyByPowerOfTen(exponent);
- } else {
- diy_fp_bignum.MultiplyByPowerOfTen(-exponent);
- }
- if (diy_fp.e() > 0) {
- diy_fp_bignum.ShiftLeft(diy_fp.e());
- } else {
- buffer_bignum.ShiftLeft(-diy_fp.e());
- }
- return Bignum::Compare(buffer_bignum, diy_fp_bignum);
-}
-
-
-// Returns true if the guess is the correct double.
-// Returns false, when guess is either correct or the next-lower double.
-static bool ComputeGuess(Vector<const char> trimmed, int exponent,
- double* guess) {
- if (trimmed.length() == 0) {
- *guess = 0.0;
- return true;
- }
- if (exponent + trimmed.length() - 1 >= kMaxDecimalPower) {
- *guess = Double::Infinity();
- return true;
- }
- if (exponent + trimmed.length() <= kMinDecimalPower) {
- *guess = 0.0;
- return true;
- }
-
- if (DoubleStrtod(trimmed, exponent, guess) ||
- DiyFpStrtod(trimmed, exponent, guess)) {
- return true;
- }
- if (*guess == Double::Infinity()) {
- return true;
- }
- return false;
-}
-
-double Strtod(Vector<const char> buffer, int exponent) {
- char copy_buffer[kMaxSignificantDecimalDigits];
- Vector<const char> trimmed;
- int updated_exponent;
- TrimAndCut(buffer, exponent, copy_buffer, kMaxSignificantDecimalDigits,
- &trimmed, &updated_exponent);
- exponent = updated_exponent;
-
- double guess;
- bool is_correct = ComputeGuess(trimmed, exponent, &guess);
- if (is_correct) return guess;
-
- DiyFp upper_boundary = Double(guess).UpperBoundary();
- int comparison = CompareBufferWithDiyFp(trimmed, exponent, upper_boundary);
- if (comparison < 0) {
- return guess;
- } else if (comparison > 0) {
- return Double(guess).NextDouble();
- } else if ((Double(guess).Significand() & 1) == 0) {
- // Round towards even.
- return guess;
- } else {
- return Double(guess).NextDouble();
- }
-}
-
-float Strtof(Vector<const char> buffer, int exponent) {
- char copy_buffer[kMaxSignificantDecimalDigits];
- Vector<const char> trimmed;
- int updated_exponent;
- TrimAndCut(buffer, exponent, copy_buffer, kMaxSignificantDecimalDigits,
- &trimmed, &updated_exponent);
- exponent = updated_exponent;
-
- double double_guess;
- bool is_correct = ComputeGuess(trimmed, exponent, &double_guess);
-
- float float_guess = static_cast<float>(double_guess);
- if (float_guess == double_guess) {
- // This shortcut triggers for integer values.
- return float_guess;
- }
-
- // We must catch double-rounding. Say the double has been rounded up, and is
- // now a boundary of a float, and rounds up again. This is why we have to
- // look at previous too.
- // Example (in decimal numbers):
- // input: 12349
- // high-precision (4 digits): 1235
- // low-precision (3 digits):
- // when read from input: 123
- // when rounded from high precision: 124.
- // To do this we simply look at the neigbors of the correct result and see
- // if they would round to the same float. If the guess is not correct we have
- // to look at four values (since two different doubles could be the correct
- // double).
-
- double double_next = Double(double_guess).NextDouble();
- double double_previous = Double(double_guess).PreviousDouble();
-
- float f1 = static_cast<float>(double_previous);
- float f2 = float_guess;
- float f3 = static_cast<float>(double_next);
- float f4;
- if (is_correct) {
- f4 = f3;
- } else {
- double double_next2 = Double(double_next).NextDouble();
- f4 = static_cast<float>(double_next2);
- }
- (void) f2; // Mark variable as used.
- ASSERT(f1 <= f2 && f2 <= f3 && f3 <= f4);
-
- // If the guess doesn't lie near a single-precision boundary we can simply
- // return its float-value.
- if (f1 == f4) {
- return float_guess;
- }
-
- ASSERT((f1 != f2 && f2 == f3 && f3 == f4) ||
- (f1 == f2 && f2 != f3 && f3 == f4) ||
- (f1 == f2 && f2 == f3 && f3 != f4));
-
- // guess and next are the two possible canditates (in the same way that
- // double_guess was the lower candidate for a double-precision guess).
- float guess = f1;
- float next = f4;
- DiyFp upper_boundary;
- if (guess == 0.0f) {
- float min_float = 1e-45f;
- upper_boundary = Double(static_cast<double>(min_float) / 2).AsDiyFp();
- } else {
- upper_boundary = Single(guess).UpperBoundary();
- }
- int comparison = CompareBufferWithDiyFp(trimmed, exponent, upper_boundary);
- if (comparison < 0) {
- return guess;
- } else if (comparison > 0) {
- return next;
- } else if ((Single(guess).Significand() & 1) == 0) {
- // Round towards even.
- return guess;
- } else {
- return next;
- }
-}
-
-} // namespace double_conversion
diff --git a/src/3rdparty/double-conversion/strtod.h b/src/3rdparty/double-conversion/strtod.h
deleted file mode 100644
index ed0293b8f5..0000000000
--- a/src/3rdparty/double-conversion/strtod.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef DOUBLE_CONVERSION_STRTOD_H_
-#define DOUBLE_CONVERSION_STRTOD_H_
-
-#include "utils.h"
-
-namespace double_conversion {
-
-// The buffer must only contain digits in the range [0-9]. It must not
-// contain a dot or a sign. It must not start with '0', and must not be empty.
-double Strtod(Vector<const char> buffer, int exponent);
-
-// The buffer must only contain digits in the range [0-9]. It must not
-// contain a dot or a sign. It must not start with '0', and must not be empty.
-float Strtof(Vector<const char> buffer, int exponent);
-
-} // namespace double_conversion
-
-#endif // DOUBLE_CONVERSION_STRTOD_H_
diff --git a/src/3rdparty/double-conversion/utils.h b/src/3rdparty/double-conversion/utils.h
deleted file mode 100644
index 53eec64282..0000000000
--- a/src/3rdparty/double-conversion/utils.h
+++ /dev/null
@@ -1,330 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef DOUBLE_CONVERSION_UTILS_H_
-#define DOUBLE_CONVERSION_UTILS_H_
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <assert.h>
-#ifndef ASSERT
-# if defined(WINCE) || defined(_WIN32_WCE)
-# define ASSERT(condition)
-# else
-# define ASSERT(condition) \
- assert(condition);
-# endif
-#endif
-#ifndef UNIMPLEMENTED
-# define UNIMPLEMENTED() (exit(-1))
-#endif
-#ifndef UNREACHABLE
-# define UNREACHABLE() (exit(-1))
-#endif
-
-// Double operations detection based on target architecture.
-// Linux uses a 80bit wide floating point stack on x86. This induces double
-// rounding, which in turn leads to wrong results.
-// An easy way to test if the floating-point operations are correct is to
-// evaluate: 89255.0/1e22. If the floating-point stack is 64 bits wide then
-// the result is equal to 89255e-22.
-// The best way to test this, is to create a division-function and to compare
-// the output of the division with the expected result. (Inlining must be
-// disabled.)
-// On Linux,x86 89255e-22 != Div_double(89255.0/1e22)
-#if defined(_M_X64) || defined(__x86_64__) || \
- defined(__ARMEL__) || defined(__avr32__) || _M_ARM_FP || \
- defined(__hppa__) || defined(__ia64__) || \
- defined(__mips__) || \
- defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || \
- defined(__sparc__) || defined(__sparc) || defined(__s390__) || \
- defined(__SH4__) || defined(__alpha__) || \
- defined(_MIPS_ARCH_MIPS32R2) || \
- defined(__AARCH64EL__)
-#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
-#elif defined(_M_IX86) || defined(__i386__) || defined(__i386)
-#if defined(_WIN32)
-// Windows uses a 64bit wide floating point stack.
-#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
-#else
-#undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS
-#endif // _WIN32
-#elif defined(WINCE) || defined(_WIN32_WCE)
-#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
-#else
-#error Target architecture was not detected as supported by Double-Conversion.
-#endif
-
-#if defined(__GNUC__)
-#define DOUBLE_CONVERSION_UNUSED __attribute__((unused))
-#else
-#define DOUBLE_CONVERSION_UNUSED
-#endif
-
-#if defined(_WIN32) && !defined(__MINGW32__)
-
-typedef signed char int8_t;
-typedef unsigned char uint8_t;
-typedef short int16_t; // NOLINT
-typedef unsigned short uint16_t; // NOLINT
-typedef int int32_t;
-typedef unsigned int uint32_t;
-typedef __int64 int64_t;
-typedef unsigned __int64 uint64_t;
-// intptr_t and friends are defined in crtdefs.h through stdio.h.
-
-#else
-
-#include <stdint.h>
-
-#endif
-
-typedef uint16_t uc16;
-
-// The following macro works on both 32 and 64-bit platforms.
-// Usage: instead of writing 0x1234567890123456
-// write UINT64_2PART_C(0x12345678,90123456);
-#define UINT64_2PART_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u))
-
-
-// The expression ARRAY_SIZE(a) is a compile-time constant of type
-// size_t which represents the number of elements of the given
-// array. You should only use ARRAY_SIZE on statically allocated
-// arrays.
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(a) \
- ((sizeof(a) / sizeof(*(a))) / \
- static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
-#endif
-
-// A macro to disallow the evil copy constructor and operator= functions
-// This should be used in the private: declarations for a class
-#ifndef DISALLOW_COPY_AND_ASSIGN
-#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
- TypeName(const TypeName&); \
- void operator=(const TypeName&)
-#endif
-
-// A macro to disallow all the implicit constructors, namely the
-// default constructor, copy constructor and operator= functions.
-//
-// This should be used in the private: declarations for a class
-// that wants to prevent anyone from instantiating it. This is
-// especially useful for classes containing only static methods.
-#ifndef DISALLOW_IMPLICIT_CONSTRUCTORS
-#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
- TypeName(); \
- DISALLOW_COPY_AND_ASSIGN(TypeName)
-#endif
-
-namespace double_conversion {
-
-static const int kCharSize = sizeof(char);
-
-// Returns the maximum of the two parameters.
-template <typename T>
-static T Max(T a, T b) {
- return a < b ? b : a;
-}
-
-
-// Returns the minimum of the two parameters.
-template <typename T>
-static T Min(T a, T b) {
- return a < b ? a : b;
-}
-
-
-inline int StrLength(const char* string) {
- size_t length = strlen(string);
- ASSERT(length == static_cast<size_t>(static_cast<int>(length)));
- return static_cast<int>(length);
-}
-
-// This is a simplified version of V8's Vector class.
-template <typename T>
-class Vector {
- public:
- Vector() : start_(NULL), length_(0) {}
- Vector(T* data, int length) : start_(data), length_(length) {
- ASSERT(length == 0 || (length > 0 && data != NULL));
- }
-
- // Returns a vector using the same backing storage as this one,
- // spanning from and including 'from', to but not including 'to'.
- Vector<T> SubVector(int from, int to) {
- ASSERT(to <= length_);
- ASSERT(from < to);
- ASSERT(0 <= from);
- return Vector<T>(start() + from, to - from);
- }
-
- // Returns the length of the vector.
- int length() const { return length_; }
-
- // Returns whether or not the vector is empty.
- bool is_empty() const { return length_ == 0; }
-
- // Returns the pointer to the start of the data in the vector.
- T* start() const { return start_; }
-
- // Access individual vector elements - checks bounds in debug mode.
- T& operator[](int index) const {
- ASSERT(0 <= index && index < length_);
- return start_[index];
- }
-
- T& first() { return start_[0]; }
-
- T& last() { return start_[length_ - 1]; }
-
- private:
- T* start_;
- int length_;
-};
-
-
-// Helper class for building result strings in a character buffer. The
-// purpose of the class is to use safe operations that checks the
-// buffer bounds on all operations in debug mode.
-class StringBuilder {
- public:
- StringBuilder(char* buffer, int size)
- : buffer_(buffer, size), position_(0) { }
-
- ~StringBuilder() { if (!is_finalized()) Finalize(); }
-
- int size() const { return buffer_.length(); }
-
- // Get the current position in the builder.
- int position() const {
- ASSERT(!is_finalized());
- return position_;
- }
-
- // Reset the position.
- void Reset() { position_ = 0; }
-
- // Add a single character to the builder. It is not allowed to add
- // 0-characters; use the Finalize() method to terminate the string
- // instead.
- void AddCharacter(char c) {
- ASSERT(c != '\0');
- ASSERT(!is_finalized() && position_ < buffer_.length());
- buffer_[position_++] = c;
- }
-
- // Add an entire string to the builder. Uses strlen() internally to
- // compute the length of the input string.
- void AddString(const char* s) {
- AddSubstring(s, StrLength(s));
- }
-
- // Add the first 'n' characters of the given string 's' to the
- // builder. The input string must have enough characters.
- void AddSubstring(const char* s, int n) {
- ASSERT(!is_finalized() && position_ + n < buffer_.length());
- ASSERT(static_cast<size_t>(n) <= strlen(s));
- memmove(&buffer_[position_], s, n * kCharSize);
- position_ += n;
- }
-
-
- // Add character padding to the builder. If count is non-positive,
- // nothing is added to the builder.
- void AddPadding(char c, int count) {
- for (int i = 0; i < count; i++) {
- AddCharacter(c);
- }
- }
-
- // Finalize the string by 0-terminating it and returning the buffer.
- char* Finalize() {
- ASSERT(!is_finalized() && position_ < buffer_.length());
- buffer_[position_] = '\0';
- // Make sure nobody managed to add a 0-character to the
- // buffer while building the string.
- ASSERT(strlen(buffer_.start()) == static_cast<size_t>(position_));
- position_ = -1;
- ASSERT(is_finalized());
- return buffer_.start();
- }
-
- private:
- Vector<char> buffer_;
- int position_;
-
- bool is_finalized() const { return position_ < 0; }
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
-};
-
-// The type-based aliasing rule allows the compiler to assume that pointers of
-// different types (for some definition of different) never alias each other.
-// Thus the following code does not work:
-//
-// float f = foo();
-// int fbits = *(int*)(&f);
-//
-// The compiler 'knows' that the int pointer can't refer to f since the types
-// don't match, so the compiler may cache f in a register, leaving random data
-// in fbits. Using C++ style casts makes no difference, however a pointer to
-// char data is assumed to alias any other pointer. This is the 'memcpy
-// exception'.
-//
-// Bit_cast uses the memcpy exception to move the bits from a variable of one
-// type of a variable of another type. Of course the end result is likely to
-// be implementation dependent. Most compilers (gcc-4.2 and MSVC 2005)
-// will completely optimize BitCast away.
-//
-// There is an additional use for BitCast.
-// Recent gccs will warn when they see casts that may result in breakage due to
-// the type-based aliasing rule. If you have checked that there is no breakage
-// you can use BitCast to cast one pointer type to another. This confuses gcc
-// enough that it can no longer see that you have cast one pointer type to
-// another thus avoiding the warning.
-template <class Dest, class Source>
-inline Dest BitCast(const Source& source) {
- // Compile time assertion: sizeof(Dest) == sizeof(Source)
- // A compile error here means your Dest and Source have different sizes.
- DOUBLE_CONVERSION_UNUSED
- typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];
-
- Dest dest;
- memmove(&dest, &source, sizeof(dest));
- return dest;
-}
-
-template <class Dest, class Source>
-inline Dest BitCast(Source* source) {
- return BitCast<Dest>(reinterpret_cast<uintptr_t>(source));
-}
-
-} // namespace double_conversion
-
-#endif // DOUBLE_CONVERSION_UTILS_H_
diff --git a/src/3rdparty/masm/wtf/Platform.h b/src/3rdparty/masm/wtf/Platform.h
index f0612fe50e..2a2b8abc61 100644
--- a/src/3rdparty/masm/wtf/Platform.h
+++ b/src/3rdparty/masm/wtf/Platform.h
@@ -348,6 +348,11 @@
|| (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) \
|| (defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR))
#define WTF_OS_IOS 1
+#elif OS(DARWIN) && ((defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED) \
+ || (defined(TARGET_OS_APPLETV) && TARGET_OS_APPLETV) \
+ || (defined(TARGET_APPLETV_SIMULATOR) && TARGET_APPLETV_SIMULATOR))
+#define WTF_OS_IOS 1
+#define WTF_OS_TVOS 1
#elif OS(DARWIN) && defined(TARGET_OS_MAC) && TARGET_OS_MAC
#define WTF_OS_MAC_OS_X 1
diff --git a/src/imports/folderlistmodel/fileinfothread.cpp b/src/imports/folderlistmodel/fileinfothread.cpp
index ebdfba42a8..731eb45460 100644
--- a/src/imports/folderlistmodel/fileinfothread.cpp
+++ b/src/imports/folderlistmodel/fileinfothread.cpp
@@ -52,7 +52,8 @@ FileInfoThread::FileInfoThread(QObject *parent)
showDirsFirst(false),
showDotAndDotDot(false),
showHidden(false),
- showOnlyReadable(false)
+ showOnlyReadable(false),
+ caseSensitive(true)
{
#ifndef QT_NO_FILESYSTEMWATCHER
watcher = new QFileSystemWatcher(this);
@@ -190,6 +191,14 @@ void FileInfoThread::setShowOnlyReadable(bool on)
condition.wakeAll();
}
+void FileInfoThread::setCaseSensitive(bool on)
+{
+ QMutexLocker locker(&mutex);
+ caseSensitive = on;
+ folderUpdate = true;
+ condition.wakeAll();
+}
+
#ifndef QT_NO_FILESYSTEMWATCHER
void FileInfoThread::updateFile(const QString &path)
{
@@ -228,7 +237,8 @@ void FileInfoThread::run()
void FileInfoThread::getFileInfos(const QString &path)
{
QDir::Filters filter;
- filter = QDir::CaseSensitive;
+ if (caseSensitive)
+ filter = QDir::CaseSensitive;
if (showFiles)
filter = filter | QDir::Files;
if (showDirs)
diff --git a/src/imports/folderlistmodel/fileinfothread_p.h b/src/imports/folderlistmodel/fileinfothread_p.h
index b375584ff8..5f62f39a20 100644
--- a/src/imports/folderlistmodel/fileinfothread_p.h
+++ b/src/imports/folderlistmodel/fileinfothread_p.h
@@ -79,6 +79,7 @@ public:
void setShowDotAndDotDot(bool on);
void setShowHidden(bool on);
void setShowOnlyReadable(bool on);
+ void setCaseSensitive(bool on);
public Q_SLOTS:
#ifndef QT_NO_FILESYSTEMWATCHER
@@ -113,6 +114,7 @@ private:
bool showDotAndDotDot;
bool showHidden;
bool showOnlyReadable;
+ bool caseSensitive;
};
#endif // FILEINFOTHREAD_P_H
diff --git a/src/imports/folderlistmodel/plugin.cpp b/src/imports/folderlistmodel/plugin.cpp
index a2536bdc7d..33c1167719 100644
--- a/src/imports/folderlistmodel/plugin.cpp
+++ b/src/imports/folderlistmodel/plugin.cpp
@@ -36,6 +36,13 @@
#include "qquickfolderlistmodel.h"
+static void initResources()
+{
+#ifdef QT_STATIC
+ Q_INIT_RESOURCE(qmake_Qt_labs_folderlistmodel);
+#endif
+}
+
QT_BEGIN_NAMESPACE
//![class decl]
@@ -45,6 +52,7 @@ class QmlFolderListModelPlugin : public QQmlExtensionPlugin
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
public:
+ QmlFolderListModelPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); }
virtual void registerTypes(const char *uri)
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.folderlistmodel"));
@@ -52,6 +60,7 @@ public:
qmlRegisterType<QQuickFolderListModel>(uri,1,0,"FolderListModel");
qmlRegisterType<QQuickFolderListModel>(uri,2,0,"FolderListModel");
qmlRegisterType<QQuickFolderListModel,1>(uri,2,1,"FolderListModel");
+ qmlRegisterType<QQuickFolderListModel,2>(uri,2,2,"FolderListModel");
#endif
}
};
diff --git a/src/imports/folderlistmodel/qquickfolderlistmodel.cpp b/src/imports/folderlistmodel/qquickfolderlistmodel.cpp
index 8bfbf09769..839e0f42c7 100644
--- a/src/imports/folderlistmodel/qquickfolderlistmodel.cpp
+++ b/src/imports/folderlistmodel/qquickfolderlistmodel.cpp
@@ -49,7 +49,7 @@ public:
: q_ptr(q),
sortField(QQuickFolderListModel::Name), sortReversed(false), showFiles(true),
showDirs(true), showDirsFirst(false), showDotAndDotDot(false), showOnlyReadable(false),
- showHidden(false)
+ showHidden(false), caseSensitive(true)
{
nameFilters << QLatin1String("*");
}
@@ -70,6 +70,7 @@ public:
bool showDotAndDotDot;
bool showOnlyReadable;
bool showHidden;
+ bool caseSensitive;
~QQuickFolderListModelPrivate() {}
void init();
@@ -762,6 +763,30 @@ void QQuickFolderListModel::setShowOnlyReadable(bool on)
}
/*!
+ * \qmlproperty bool FolderListModel::caseSensitive
+ * \since 5.7
+ *
+ * Use case sensitive pattern matching.
+ *
+ * By default, this property is true.
+ *
+ */
+bool QQuickFolderListModel::caseSensitive() const
+{
+ Q_D(const QQuickFolderListModel);
+ return d->caseSensitive;
+}
+
+void QQuickFolderListModel::setCaseSensitive(bool on)
+{
+ Q_D(QQuickFolderListModel);
+
+ if (on != d->caseSensitive) {
+ d->fileInfoThread.setCaseSensitive(on);
+ }
+}
+
+/*!
\qmlmethod var FolderListModel::get(int index, string property)
Get the folder property for the given index. The following properties
diff --git a/src/imports/folderlistmodel/qquickfolderlistmodel.h b/src/imports/folderlistmodel/qquickfolderlistmodel.h
index fcfec56c87..4b540742b4 100644
--- a/src/imports/folderlistmodel/qquickfolderlistmodel.h
+++ b/src/imports/folderlistmodel/qquickfolderlistmodel.h
@@ -67,6 +67,7 @@ class QQuickFolderListModel : public QAbstractListModel, public QQmlParserStatus
Q_PROPERTY(bool showDotAndDotDot READ showDotAndDotDot WRITE setShowDotAndDotDot)
Q_PROPERTY(bool showHidden READ showHidden WRITE setShowHidden REVISION 1)
Q_PROPERTY(bool showOnlyReadable READ showOnlyReadable WRITE setShowOnlyReadable)
+ Q_PROPERTY(bool caseSensitive READ caseSensitive WRITE setCaseSensitive REVISION 2)
Q_PROPERTY(int count READ count NOTIFY countChanged)
//![class props]
@@ -128,6 +129,8 @@ public:
void setShowHidden(bool on);
bool showOnlyReadable() const;
void setShowOnlyReadable(bool on);
+ bool caseSensitive() const;
+ void setCaseSensitive(bool on);
//![prop funcs]
Q_INVOKABLE bool isFolder(int index) const;
diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp
index ada50774a7..5b55a2711f 100644
--- a/src/imports/localstorage/plugin.cpp
+++ b/src/imports/localstorage/plugin.cpp
@@ -54,6 +54,13 @@
#include <private/qv4scopedvalue_p.h>
#include <private/qv4objectiterator_p.h>
+static void initResources()
+{
+#ifdef QT_STATIC
+ Q_INIT_RESOURCE(qmake_QtQuick_LocalStorage);
+#endif
+}
+
QT_BEGIN_NAMESPACE
#define V4THROW_SQL(error, desc) { \
@@ -744,10 +751,10 @@ class QQmlLocalStoragePlugin : public QQmlExtensionPlugin
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
public:
- QQmlLocalStoragePlugin()
+ QQmlLocalStoragePlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent)
{
+ initResources();
}
-
void registerTypes(const char *uri)
{
Q_ASSERT(QLatin1String(uri) == "QtQuick.LocalStorage");
diff --git a/src/imports/models/plugin.cpp b/src/imports/models/plugin.cpp
index c2b0d2ae94..4ba1ddea14 100644
--- a/src/imports/models/plugin.cpp
+++ b/src/imports/models/plugin.cpp
@@ -35,6 +35,13 @@
#include <private/qqmlmodelsmodule_p.h>
+static void initResources()
+{
+#ifdef QT_STATIC
+ Q_INIT_RESOURCE(qmake_QtQml_Models_2);
+#endif
+}
+
QT_BEGIN_NAMESPACE
/*!
@@ -64,6 +71,7 @@ class QtQmlModelsPlugin : public QQmlExtensionPlugin
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0")
public:
+ QtQmlModelsPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); }
virtual void registerTypes(const char *uri)
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQml.Models"));
diff --git a/src/imports/particles/plugin.cpp b/src/imports/particles/plugin.cpp
index 56b611a408..609efd0bad 100644
--- a/src/imports/particles/plugin.cpp
+++ b/src/imports/particles/plugin.cpp
@@ -35,6 +35,13 @@
#include <private/qquickparticlesmodule_p.h>
+static void initResources()
+{
+#ifdef QT_STATIC
+ Q_INIT_RESOURCE(qmake_QtQuick_Particles_2);
+#endif
+}
+
QT_BEGIN_NAMESPACE
//![class decl]
@@ -43,6 +50,7 @@ class QtQuick2ParticlesPlugin : public QQmlExtensionPlugin
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0")
public:
+ QtQuick2ParticlesPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); }
virtual void registerTypes(const char *uri)
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.Particles"));
diff --git a/src/imports/qtquick2/plugin.cpp b/src/imports/qtquick2/plugin.cpp
index 36a57112b2..4cb77dcd4b 100644
--- a/src/imports/qtquick2/plugin.cpp
+++ b/src/imports/qtquick2/plugin.cpp
@@ -35,6 +35,13 @@
#include <private/qtquick2_p.h>
+static void initResources()
+{
+#ifdef QT_STATIC
+ Q_INIT_RESOURCE(qmake_QtQuick_2);
+#endif
+}
+
QT_BEGIN_NAMESPACE
//![class decl]
@@ -43,6 +50,7 @@ class QtQuick2Plugin : public QQmlExtensionPlugin
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0")
public:
+ QtQuick2Plugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); }
virtual void registerTypes(const char *uri)
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick"));
diff --git a/src/imports/settings/plugin.cpp b/src/imports/settings/plugin.cpp
index c32d370537..49ee8ab9bf 100644
--- a/src/imports/settings/plugin.cpp
+++ b/src/imports/settings/plugin.cpp
@@ -36,6 +36,13 @@
#include "qqmlsettings_p.h"
+static void initResources()
+{
+#ifdef QT_STATIC
+ Q_INIT_RESOURCE(qmake_Qt_labs_settings);
+#endif
+}
+
QT_BEGIN_NAMESPACE
class QmlSettingsPlugin : public QQmlExtensionPlugin
@@ -44,6 +51,7 @@ class QmlSettingsPlugin : public QQmlExtensionPlugin
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
public:
+ QmlSettingsPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); }
virtual void registerTypes(const char *uri)
{
Q_ASSERT(QByteArray(uri) == QByteArray("Qt.labs.settings"));
diff --git a/src/imports/statemachine/plugin.cpp b/src/imports/statemachine/plugin.cpp
index 4a711a3278..e0fea01d8f 100644
--- a/src/imports/statemachine/plugin.cpp
+++ b/src/imports/statemachine/plugin.cpp
@@ -41,6 +41,13 @@
#include <QQmlExtensionPlugin>
#include <qqml.h>
+static void initResources()
+{
+#ifdef QT_STATIC
+ Q_INIT_RESOURCE(qmake_QtQml_StateMachine);
+#endif
+}
+
QT_BEGIN_NAMESPACE
class QtQmlStateMachinePlugin : public QQmlExtensionPlugin
@@ -49,6 +56,7 @@ class QtQmlStateMachinePlugin : public QQmlExtensionPlugin
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtQml.StateMachine/1.0")
public:
+ QtQmlStateMachinePlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); }
void registerTypes(const char *uri)
{
qmlRegisterType<State>(uri, 1, 0, "State");
diff --git a/src/imports/testlib/main.cpp b/src/imports/testlib/main.cpp
index c42ece5da5..b2ea10fa38 100644
--- a/src/imports/testlib/main.cpp
+++ b/src/imports/testlib/main.cpp
@@ -48,6 +48,13 @@ QML_DECLARE_TYPE(QuickTestEvent)
#include <QtDebug>
+static void initResources()
+{
+#ifdef QT_STATIC
+ Q_INIT_RESOURCE(qmake_QtTest);
+#endif
+}
+
QT_BEGIN_NAMESPACE
class QuickTestUtil : public QObject
@@ -137,6 +144,7 @@ class QTestQmlModule : public QQmlExtensionPlugin
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
public:
+ QTestQmlModule(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); }
virtual void registerTypes(const char *uri)
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("QtTest"));
diff --git a/src/imports/window/plugin.cpp b/src/imports/window/plugin.cpp
index 010e9b3eed..2946cae679 100644
--- a/src/imports/window/plugin.cpp
+++ b/src/imports/window/plugin.cpp
@@ -35,6 +35,13 @@
#include <private/qquickwindowmodule_p.h>
+static void initResources()
+{
+#ifdef QT_STATIC
+ Q_INIT_RESOURCE(qmake_QtQuick_Window_2);
+#endif
+}
+
QT_BEGIN_NAMESPACE
/*!
@@ -53,13 +60,13 @@ QT_BEGIN_NAMESPACE
*/
-
//![class decl]
class QtQuick2WindowPlugin : public QQmlExtensionPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0")
public:
+ QtQuick2WindowPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); }
virtual void registerTypes(const char *uri)
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.Window"));
diff --git a/src/imports/xmllistmodel/plugin.cpp b/src/imports/xmllistmodel/plugin.cpp
index 8a9d4379c4..514a44fe14 100644
--- a/src/imports/xmllistmodel/plugin.cpp
+++ b/src/imports/xmllistmodel/plugin.cpp
@@ -36,6 +36,13 @@
#include "qqmlxmllistmodel_p.h"
+static void initResources()
+{
+#ifdef QT_STATIC
+ Q_INIT_RESOURCE(qmake_QtQuick_XmlListModel);
+#endif
+}
+
QT_BEGIN_NAMESPACE
class QmlXmlListModelPlugin : public QQmlExtensionPlugin
@@ -44,6 +51,7 @@ class QmlXmlListModelPlugin : public QQmlExtensionPlugin
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
public:
+ QmlXmlListModelPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); }
virtual void registerTypes(const char *uri)
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.XmlListModel"));
diff --git a/src/particles/qquickparticleaffector_p.h b/src/particles/qquickparticleaffector_p.h
index 4646c839d9..f71097fda9 100644
--- a/src/particles/qquickparticleaffector_p.h
+++ b/src/particles/qquickparticleaffector_p.h
@@ -48,10 +48,11 @@
#include <QObject>
#include "qquickparticlesystem_p.h"
#include "qquickparticleextruder_p.h"
+#include "qtquickparticlesglobal_p.h"
QT_BEGIN_NAMESPACE
-class QQuickParticleAffector : public QQuickItem
+class Q_QUICKPARTICLES_PRIVATE_EXPORT QQuickParticleAffector : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(QQuickParticleSystem* system READ system WRITE setSystem NOTIFY systemChanged)
diff --git a/src/particles/qquickparticlesystem_p.h b/src/particles/qquickparticlesystem_p.h
index 96bd655793..7ad066cdfa 100644
--- a/src/particles/qquickparticlesystem_p.h
+++ b/src/particles/qquickparticlesystem_p.h
@@ -55,6 +55,7 @@
#include <QAbstractAnimation>
#include <QtQml/qqml.h>
#include <private/qv8engine_p.h> //For QQmlV4Handle
+#include "qtquickparticlesglobal_p.h"
QT_BEGIN_NAMESPACE
@@ -75,7 +76,7 @@ struct QQuickParticleDataHeapNode{
QSet<QQuickParticleData*> data;//Set ptrs instead?
};
-class QQuickParticleDataHeap {
+class Q_QUICKPARTICLES_PRIVATE_EXPORT QQuickParticleDataHeap {
//Idea is to do a binary heap, but which also stores a set of int,Node* so that if the int already exists, you can
//add it to the data* list. Pops return the whole list at once.
public:
@@ -102,7 +103,7 @@ private:
QHash<int,int> m_lookups;
};
-class Q_AUTOTEST_EXPORT QQuickParticleGroupData {
+class Q_QUICKPARTICLES_PRIVATE_EXPORT QQuickParticleGroupData {
public:
QQuickParticleGroupData(int id, QQuickParticleSystem* sys);
~QQuickParticleGroupData();
@@ -142,7 +143,7 @@ struct Color4ub {
uchar a;
};
-class Q_AUTOTEST_EXPORT QQuickParticleData {
+class Q_QUICKPARTICLES_PRIVATE_EXPORT QQuickParticleData {
public:
//TODO: QObject like memory management (without the cost, just attached to system)
QQuickParticleData(QQuickParticleSystem* sys);
@@ -245,7 +246,7 @@ private:
QQuickV4ParticleData* v8Datum;
};
-class Q_AUTOTEST_EXPORT QQuickParticleSystem : public QQuickItem
+class Q_QUICKPARTICLES_PRIVATE_EXPORT QQuickParticleSystem : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged)
diff --git a/src/particles/qquickv4particledata.cpp b/src/particles/qquickv4particledata.cpp
index 876c7214b0..41e8c8e94a 100644
--- a/src/particles/qquickv4particledata.cpp
+++ b/src/particles/qquickv4particledata.cpp
@@ -380,7 +380,7 @@ static QV4::ReturnedValue particleData_set_ ## VARIABLE (QV4::CallContext *ctx)\
if (!r || !r->d()->datum)\
ctx->engine()->throwError(QStringLiteral("Not a valid ParticleData object"));\
\
- r->d()->datum-> VARIABLE = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();\
+ r->d()->datum-> VARIABLE = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN();\
return QV4::Encode::undefined(); \
}
@@ -401,7 +401,7 @@ static QV4::ReturnedValue particleData_set_ ## VARIABLE (QV4::CallContext *ctx)\
if (!r || !r->d()->datum)\
ctx->engine()->throwError(QStringLiteral("Not a valid ParticleData object"));\
\
- r->d()->datum-> SETTER (ctx->argc() ? ctx->args()[0].toNumber() : qSNaN());\
+ r->d()->datum-> SETTER (ctx->argc() ? ctx->args()[0].toNumber() : qQNaN());\
return QV4::Encode::undefined(); \
}
diff --git a/src/particles/qquickwander.cpp b/src/particles/qquickwander.cpp
index da0f2ef85b..30fa69a126 100644
--- a/src/particles/qquickwander.cpp
+++ b/src/particles/qquickwander.cpp
@@ -83,7 +83,7 @@ QQuickWanderAffector::QQuickWanderAffector(QQuickItem *parent) :
QQuickWanderAffector::~QQuickWanderAffector()
{
for (QHash<int, WanderData*>::const_iterator iter=m_wanderData.constBegin();
- iter != m_wanderData.constEnd(); iter++)
+ iter != m_wanderData.constEnd(); ++iter)
delete (*iter);
}
diff --git a/src/plugins/qmltooling/packetprotocol/packetprotocol.pro b/src/plugins/qmltooling/packetprotocol/packetprotocol.pro
new file mode 100644
index 0000000000..383e32b54e
--- /dev/null
+++ b/src/plugins/qmltooling/packetprotocol/packetprotocol.pro
@@ -0,0 +1,13 @@
+TARGET = QtPacketProtocol
+QT = core-private qml-private
+CONFIG += static internal_module
+
+HEADERS = \
+ qpacketprotocol_p.h \
+ qpacket_p.h
+
+SOURCES = \
+ qpacketprotocol.cpp \
+ qpacket.cpp
+
+load(qt_module)
diff --git a/src/plugins/qmltooling/packetprotocol/qpacket.cpp b/src/plugins/qmltooling/packetprotocol/qpacket.cpp
new file mode 100644
index 0000000000..1bb611ab25
--- /dev/null
+++ b/src/plugins/qmltooling/packetprotocol/qpacket.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpacket_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QPacket
+ \internal
+
+ \brief The QPacket class encapsulates an unfragmentable packet of data to be
+ transmitted by QPacketProtocol.
+
+ The QPacket class works together with QPacketProtocol to make it simple to
+ send arbitrary sized data "packets" across fragmented transports such as TCP
+ and UDP.
+
+ QPacket provides a QDataStream interface to an unfragmentable packet.
+ Applications should construct a QPacket, propagate it with data and then
+ transmit it over a QPacketProtocol instance. For example:
+ \code
+ int version = QDataStream::Qt_DefaultCompiledVersion;
+ QPacketProtocol protocol(...);
+
+ QPacket myPacket(version);
+ myPacket << "Hello world!" << 123;
+ protocol.send(myPacket.data());
+ \endcode
+
+ As long as both ends of the connection are using the QPacketProtocol class
+ and the same data stream version, the data within this packet will be
+ delivered unfragmented at the other end, ready for extraction.
+
+ \code
+ QByteArray greeting;
+ int count;
+
+ QPacket myPacket(version, protocol.read());
+
+ myPacket >> greeting >> count;
+ \endcode
+
+ Only packets constructed from raw byte arrays may be read from. Empty QPacket
+ instances are for transmission only and are considered "write only". Attempting
+ to read data from them will result in undefined behavior.
+
+ \ingroup io
+ \sa QPacketProtocol
+ */
+
+
+/*!
+ Constructs an empty write-only packet.
+ */
+QPacket::QPacket(int version)
+{
+ buf.open(QIODevice::WriteOnly);
+ setDevice(&buf);
+ setVersion(version);
+}
+
+/*!
+ Constructs a read-only packet.
+ */
+QPacket::QPacket(int version, const QByteArray &data)
+{
+ buf.setData(data);
+ buf.open(QIODevice::ReadOnly);
+ setDevice(&buf);
+ setVersion(version);
+}
+
+/*!
+ Returns raw packet data.
+ */
+QByteArray QPacket::data() const
+{
+ return buf.data();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/packetprotocol/qpacket_p.h b/src/plugins/qmltooling/packetprotocol/qpacket_p.h
new file mode 100644
index 0000000000..dda152dfd1
--- /dev/null
+++ b/src/plugins/qmltooling/packetprotocol/qpacket_p.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPACKET_H
+#define QPACKET_H
+
+#include <QtCore/qdatastream.h>
+#include <QtCore/qbuffer.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+class QPacket : public QDataStream
+{
+public:
+ QPacket(int version);
+ explicit QPacket(int version, const QByteArray &ba);
+ QByteArray data() const;
+
+private:
+ void init(QIODevice::OpenMode mode);
+ QBuffer buf;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPACKET_H
diff --git a/src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp b/src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp
new file mode 100644
index 0000000000..d576e74e53
--- /dev/null
+++ b/src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp
@@ -0,0 +1,293 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpacketprotocol_p.h"
+
+#include <QtCore/QElapsedTimer>
+#include <private/qiodevice_p.h>
+#include <private/qobject_p.h>
+
+QT_BEGIN_NAMESPACE
+
+static const int MAX_PACKET_SIZE = 0x7FFFFFFF;
+
+/*!
+ \class QPacketProtocol
+ \internal
+
+ \brief The QPacketProtocol class encapsulates communicating discrete packets
+ across fragmented IO channels, such as TCP sockets.
+
+ QPacketProtocol makes it simple to send arbitrary sized data "packets" across
+ fragmented transports such as TCP and UDP.
+
+ As transmission boundaries are not respected, sending packets over protocols
+ like TCP frequently involves "stitching" them back together at the receiver.
+ QPacketProtocol makes this easier by performing this task for you. Packet
+ data sent using QPacketProtocol is prepended with a 4-byte size header
+ allowing the receiving QPacketProtocol to buffer the packet internally until
+ it has all been received. QPacketProtocol does not perform any sanity
+ checking on the size or on the data, so this class should only be used in
+ prototyping or trusted situations where DOS attacks are unlikely.
+
+ QPacketProtocol does not perform any communications itself. Instead it can
+ operate on any QIODevice that supports the QIODevice::readyRead() signal. A
+ logical "packet" is simply a QByteArray. The following example how to send
+ data using QPacketProtocol.
+
+ \code
+ QTcpSocket socket;
+ // ... connect socket ...
+
+ QPacketProtocol protocol(&socket);
+
+ // Send a packet
+ QDataStream packet;
+ packet << "Hello world" << 123;
+ protocol.send(packet.data());
+ \endcode
+
+ Likewise, the following shows how to read data from QPacketProtocol, assuming
+ that the QPacketProtocol::readyRead() signal has been emitted.
+
+ \code
+ // ... QPacketProtocol::readyRead() is emitted ...
+
+ int a;
+ QByteArray b;
+
+ // Receive packet
+ QDataStream packet(protocol.read());
+ p >> a >> b;
+ \endcode
+
+ \ingroup io
+*/
+
+class QPacketProtocolPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QPacketProtocol)
+public:
+ QPacketProtocolPrivate(QIODevice *dev);
+
+ QList<qint64> sendingPackets;
+ QList<QByteArray> packets;
+ QByteArray inProgress;
+ qint32 inProgressSize;
+ bool waitingForPacket;
+ QIODevice *dev;
+};
+
+/*!
+ Construct a QPacketProtocol instance that works on \a dev with the
+ specified \a parent.
+ */
+QPacketProtocol::QPacketProtocol(QIODevice *dev, QObject *parent)
+ : QObject(*(new QPacketProtocolPrivate(dev)), parent)
+{
+ Q_ASSERT(4 == sizeof(qint32));
+ Q_ASSERT(dev);
+
+ QObject::connect(dev, SIGNAL(readyRead()),
+ this, SLOT(readyToRead()));
+ QObject::connect(dev, SIGNAL(aboutToClose()),
+ this, SLOT(aboutToClose()));
+ QObject::connect(dev, SIGNAL(bytesWritten(qint64)),
+ this, SLOT(bytesWritten(qint64)));
+}
+
+/*!
+ \fn void QPacketProtocol::send(const QByteArray &data)
+
+ Transmit the \a packet.
+ */
+void QPacketProtocol::send(const QByteArray &data)
+{
+ Q_D(QPacketProtocol);
+
+ if (data.isEmpty())
+ return; // We don't send empty packets
+ qint64 sendSize = data.size() + sizeof(qint32);
+
+ d->sendingPackets.append(sendSize);
+ qint32 sendSize32 = sendSize;
+ qint64 writeBytes = d->dev->write((char *)&sendSize32, sizeof(qint32));
+ Q_UNUSED(writeBytes);
+ Q_ASSERT(writeBytes == sizeof(qint32));
+ writeBytes = d->dev->write(data);
+ Q_ASSERT(writeBytes == data.size());
+}
+
+/*!
+ Returns the number of received packets yet to be read.
+ */
+qint64 QPacketProtocol::packetsAvailable() const
+{
+ Q_D(const QPacketProtocol);
+ return d->packets.count();
+}
+
+/*!
+ Return the next unread packet, or an empty QByteArray if no packets
+ are available. This method does NOT block.
+ */
+QByteArray QPacketProtocol::read()
+{
+ Q_D(QPacketProtocol);
+ return d->packets.isEmpty() ? QByteArray() : d->packets.takeFirst();
+}
+
+/*!
+ This function locks until a new packet is available for reading and the
+ \l{QIODevice::}{readyRead()} signal has been emitted. The function
+ will timeout after \a msecs milliseconds; the default timeout is
+ 30000 milliseconds.
+
+ The function returns true if the readyRead() signal is emitted and
+ there is new data available for reading; otherwise it returns false
+ (if an error occurred or the operation timed out).
+ */
+
+bool QPacketProtocol::waitForReadyRead(int msecs)
+{
+ Q_D(QPacketProtocol);
+ if (!d->packets.isEmpty())
+ return true;
+
+ QElapsedTimer stopWatch;
+ stopWatch.start();
+
+ d->waitingForPacket = true;
+ do {
+ if (!d->dev->waitForReadyRead(msecs))
+ return false;
+ if (!d->waitingForPacket)
+ return true;
+ msecs = qt_subtract_from_timeout(msecs, stopWatch.elapsed());
+ } while (true);
+}
+
+/*!
+ Return the QIODevice passed to the QPacketProtocol constructor.
+*/
+void QPacketProtocol::aboutToClose()
+{
+ Q_D(QPacketProtocol);
+ d->inProgress.clear();
+ d->sendingPackets.clear();
+ d->inProgressSize = -1;
+}
+
+void QPacketProtocol::bytesWritten(qint64 bytes)
+{
+ Q_D(QPacketProtocol);
+ Q_ASSERT(!d->sendingPackets.isEmpty());
+
+ while (bytes) {
+ if (d->sendingPackets.at(0) > bytes) {
+ d->sendingPackets[0] -= bytes;
+ bytes = 0;
+ } else {
+ bytes -= d->sendingPackets.at(0);
+ d->sendingPackets.removeFirst();
+ }
+ }
+}
+
+void QPacketProtocol::readyToRead()
+{
+ Q_D(QPacketProtocol);
+ while (true) {
+ // Need to get trailing data
+ if (-1 == d->inProgressSize) {
+ // We need a size header of sizeof(qint32)
+ if (sizeof(qint32) > (uint)d->dev->bytesAvailable())
+ return;
+
+ // Read size header
+ int read = d->dev->read((char *)&d->inProgressSize, sizeof(qint32));
+ Q_ASSERT(read == sizeof(qint32));
+ Q_UNUSED(read);
+
+ // Check sizing constraints
+ if (d->inProgressSize > MAX_PACKET_SIZE) {
+ QObject::disconnect(d->dev, SIGNAL(readyRead()),
+ this, SLOT(readyToRead()));
+ QObject::disconnect(d->dev, SIGNAL(aboutToClose()),
+ this, SLOT(aboutToClose()));
+ QObject::disconnect(d->dev, SIGNAL(bytesWritten(qint64)),
+ this, SLOT(bytesWritten(qint64)));
+ d->dev = 0;
+ emit invalidPacket();
+ return;
+ }
+
+ d->inProgressSize -= sizeof(qint32);
+ } else {
+ d->inProgress.append(d->dev->read(d->inProgressSize - d->inProgress.size()));
+
+ if (d->inProgressSize == d->inProgress.size()) {
+ // Packet has arrived!
+ d->packets.append(d->inProgress);
+ d->inProgressSize = -1;
+ d->inProgress.clear();
+
+ d->waitingForPacket = false;
+ emit readyRead();
+ } else
+ return;
+ }
+ }
+}
+
+QPacketProtocolPrivate::QPacketProtocolPrivate(QIODevice *dev) :
+ inProgressSize(-1), waitingForPacket(false), dev(dev)
+{
+}
+
+/*!
+ \fn void QPacketProtocol::readyRead()
+
+ Emitted whenever a new packet is received. Applications may use
+ QPacketProtocol::read() to retrieve this packet.
+ */
+
+/*!
+ \fn void QPacketProtocol::invalidPacket()
+
+ A packet larger than the maximum allowable packet size was received. The
+ packet will be discarded and, as it indicates corruption in the protocol, no
+ further packets will be received.
+ */
+
+QT_END_NAMESPACE
diff --git a/tools/qmlprofiler/qpacketprotocol.h b/src/plugins/qmltooling/packetprotocol/qpacketprotocol_p.h
index 17608033f4..20bbc66418 100644
--- a/tools/qmlprofiler/qpacketprotocol.h
+++ b/src/plugins/qmltooling/packetprotocol/qpacketprotocol_p.h
@@ -31,79 +31,49 @@
**
****************************************************************************/
-#ifndef QPACKETPROTOCOL_H
-#define QPACKETPROTOCOL_H
+#ifndef QPACKETPROTOCOL_P_H
+#define QPACKETPROTOCOL_P_H
#include <QtCore/qobject.h>
-#include <QtCore/qdatastream.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
QT_BEGIN_NAMESPACE
+
class QIODevice;
-class QBuffer;
-QT_END_NAMESPACE
-class QPacket;
-class QPacketAutoSend;
-class QPacketProtocolPrivate;
+class QPacketProtocolPrivate;
class QPacketProtocol : public QObject
{
Q_OBJECT
+ Q_DECLARE_PRIVATE(QPacketProtocol)
public:
explicit QPacketProtocol(QIODevice *dev, QObject *parent = 0);
- virtual ~QPacketProtocol();
-
- qint32 maximumPacketSize() const;
- qint32 setMaximumPacketSize(qint32);
-
- QPacketAutoSend send();
- void send(const QPacket &);
+ void send(const QByteArray &data);
qint64 packetsAvailable() const;
- QPacket read();
-
+ QByteArray read();
bool waitForReadyRead(int msecs = 3000);
- void clear();
-
- QIODevice *device();
-
Q_SIGNALS:
void readyRead();
void invalidPacket();
- void packetWritten();
-
-private:
- QPacketProtocolPrivate *d;
-};
-
-
-class QPacket : public QDataStream
-{
-public:
- QPacket();
- QPacket(const QPacket &);
- virtual ~QPacket();
-
- void clear();
- bool isEmpty() const;
- QByteArray data() const;
-protected:
- friend class QPacketProtocol;
- QPacket(const QByteArray &ba);
- QByteArray b;
- QBuffer *buf;
+private Q_SLOTS:
+ void aboutToClose();
+ void bytesWritten(qint64 bytes);
+ void readyToRead();
};
-class QPacketAutoSend : public QPacket
-{
-public:
- virtual ~QPacketAutoSend();
-
-private:
- friend class QPacketProtocol;
- QPacketAutoSend(QPacketProtocol *);
- QPacketProtocol *p;
-};
+QT_END_NAMESPACE
-#endif
+#endif // QPACKETPROTOCOL_P_H
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.cpp
index 6bccec08b1..6880417f1d 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.cpp
@@ -32,51 +32,48 @@
****************************************************************************/
#include "qdebugmessageservice.h"
+#include "qqmldebugpacket.h"
#include <private/qqmldebugconnector_p.h>
-#include <QDataStream>
-
QT_BEGIN_NAMESPACE
-const QString QDebugMessageService::s_key = QStringLiteral("DebugMessages");
-
void DebugMessageHandler(QtMsgType type, const QMessageLogContext &ctxt,
const QString &buf)
{
- QQmlDebugConnector::service<QDebugMessageService>()->sendDebugMessage(type, ctxt, buf);
+ QQmlDebugConnector::service<QDebugMessageServiceImpl>()->sendDebugMessage(type, ctxt, buf);
}
-QDebugMessageService::QDebugMessageService(QObject *parent) :
- QQmlDebugService(s_key, 2, parent), oldMsgHandler(0),
+QDebugMessageServiceImpl::QDebugMessageServiceImpl(QObject *parent) :
+ QDebugMessageService(2, parent), oldMsgHandler(0),
prevState(QQmlDebugService::NotConnected)
{
// don't execute stateChanged() in parallel
QMutexLocker lock(&initMutex);
+ timer.start();
if (state() == Enabled) {
oldMsgHandler = qInstallMessageHandler(DebugMessageHandler);
prevState = Enabled;
}
}
-void QDebugMessageService::sendDebugMessage(QtMsgType type,
+void QDebugMessageServiceImpl::sendDebugMessage(QtMsgType type,
const QMessageLogContext &ctxt,
const QString &buf)
{
//We do not want to alter the message handling mechanism
//We just eavesdrop and forward the messages to a port
//only if a client is connected to it.
- QByteArray message;
- QQmlDebugStream ws(&message, QIODevice::WriteOnly);
+ QQmlDebugPacket ws;
ws << QByteArray("MESSAGE") << type << buf.toUtf8();
- ws << QString::fromLatin1(ctxt.file).toUtf8();
- ws << ctxt.line << QString::fromLatin1(ctxt.function).toUtf8();
+ ws << QByteArray(ctxt.file) << ctxt.line << QByteArray(ctxt.function);
+ ws << QByteArray(ctxt.category) << timer.nsecsElapsed();
- emit messageToClient(name(), message);
+ emit messageToClient(name(), ws.data());
if (oldMsgHandler)
(*oldMsgHandler)(type, ctxt, buf);
}
-void QDebugMessageService::stateChanged(State state)
+void QDebugMessageServiceImpl::stateChanged(State state)
{
QMutexLocker lock(&initMutex);
@@ -93,4 +90,10 @@ void QDebugMessageService::stateChanged(State state)
prevState = state;
}
+void QDebugMessageServiceImpl::synchronizeTime(const QElapsedTimer &otherTimer)
+{
+ QMutexLocker lock(&initMutex);
+ timer = otherTimer;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.h b/src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.h
index c0dc41bcd0..a5ff1fc3d7 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.h
+++ b/src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.h
@@ -45,36 +45,35 @@
// We mean it.
//
-#include <private/qqmldebugservice_p.h>
+#include <private/qqmldebugserviceinterfaces_p.h>
#include <QtCore/qlogging.h>
#include <QtCore/qmutex.h>
+#include <QtCore/qelapsedtimer.h>
QT_BEGIN_NAMESPACE
class QDebugMessageServicePrivate;
-class QDebugMessageService : public QQmlDebugService
+class QDebugMessageServiceImpl : public QDebugMessageService
{
Q_OBJECT
public:
- QDebugMessageService(QObject *parent = 0);
+ QDebugMessageServiceImpl(QObject *parent = 0);
- void sendDebugMessage(QtMsgType type, const QMessageLogContext &ctxt,
- const QString &buf);
+ void sendDebugMessage(QtMsgType type, const QMessageLogContext &ctxt, const QString &buf);
+ void synchronizeTime(const QElapsedTimer &otherTimer);
protected:
- static const QString s_key;
-
void stateChanged(State);
private:
- friend class QQmlDebugConnector;
friend class QQmlDebuggerServiceFactory;
QtMessageHandler oldMsgHandler;
QQmlDebugService::State prevState;
QMutex initMutex;
+ QElapsedTimer timer;
};
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qmldbg_debugger.pro b/src/plugins/qmltooling/qmldbg_debugger/qmldbg_debugger.pro
index 8d1a54e9e4..9db38d2dfe 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qmldbg_debugger.pro
+++ b/src/plugins/qmltooling/qmldbg_debugger/qmldbg_debugger.pro
@@ -1,5 +1,5 @@
TARGET = qmldbg_debugger
-QT = qml-private core-private
+QT = qml-private core-private packetprotocol-private
PLUGIN_TYPE = qmltooling
PLUGIN_CLASS_NAME = QQmlDebuggerServiceFactory
@@ -12,17 +12,21 @@ SOURCES += \
$$PWD/qqmlnativedebugservice.cpp \
$$PWD/qqmlwatcher.cpp \
$$PWD/qv4debugservice.cpp \
+ $$PWD/qv4debugger.cpp \
$$PWD/qv4debuggeragent.cpp \
$$PWD/qv4datacollector.cpp
+
HEADERS += \
$$PWD/../shared/qqmlconfigurabledebugservice.h \
+ $$PWD/../shared/qqmldebugpacket.h \
$$PWD/qdebugmessageservice.h \
$$PWD/qqmldebuggerservicefactory.h \
$$PWD/qqmlenginedebugservice.h \
$$PWD/qqmlnativedebugservice.h \
$$PWD/qqmlwatcher.h \
$$PWD/qv4debugservice.h \
+ $$PWD/qv4debugger.h \
$$PWD/qv4debuggeragent.h \
$$PWD/qv4datacollector.h
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservicefactory.cpp b/src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservicefactory.cpp
index f379352cfa..4690da04d1 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservicefactory.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservicefactory.cpp
@@ -42,8 +42,8 @@ QT_BEGIN_NAMESPACE
QQmlDebugService *QQmlDebuggerServiceFactory::create(const QString &key)
{
- if (key == QDebugMessageService::s_key)
- return new QDebugMessageService(this);
+ if (key == QDebugMessageServiceImpl::s_key)
+ return new QDebugMessageServiceImpl(this);
if (key == QQmlEngineDebugServiceImpl::s_key)
return new QQmlEngineDebugServiceImpl(this);
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
index 8f53dc6d50..6860915606 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
@@ -33,6 +33,7 @@
#include "qqmlenginedebugservice.h"
#include "qqmlwatcher.h"
+#include "qqmldebugpacket.h"
#include <private/qqmldebugstatesdelegate_p.h>
#include <private/qqmlboundsignal_p.h>
@@ -89,8 +90,7 @@ QDataStream &operator<<(QDataStream &ds,
ds << (int)data.type << data.name;
// check first whether the data can be saved
// (otherwise we assert in QVariant::operator<<)
- QByteArray buffer;
- QDataStream fakeStream(&buffer, QIODevice::WriteOnly);
+ QQmlDebugPacket fakeStream;
if (QMetaType::save(fakeStream, data.value.type(), data.value.constData()))
ds << data.value;
else
@@ -427,7 +427,7 @@ QList<QObject*> QQmlEngineDebugServiceImpl::objectForLocationInfo(const QString
const QHash<int, QObject *> &hash = objectsForIds();
for (QHash<int, QObject *>::ConstIterator i = hash.constBegin(); i != hash.constEnd(); ++i) {
QQmlData *ddata = QQmlData::get(i.value());
- if (ddata && ddata->outerContext) {
+ if (ddata && ddata->outerContext && ddata->outerContext->isValid()) {
if (QFileInfo(ddata->outerContext->urlString()).fileName() == filename &&
ddata->lineNumber == lineNumber &&
ddata->columnNumber >= columnNumber) {
@@ -440,21 +440,20 @@ QList<QObject*> QQmlEngineDebugServiceImpl::objectForLocationInfo(const QString
void QQmlEngineDebugServiceImpl::processMessage(const QByteArray &message)
{
- QQmlDebugStream ds(message);
+ QQmlDebugPacket ds(message);
QByteArray type;
int queryId;
ds >> type >> queryId;
- QByteArray reply;
- QQmlDebugStream rs(&reply, QIODevice::WriteOnly);
+ QQmlDebugPacket rs;
if (type == "LIST_ENGINES") {
rs << QByteArray("LIST_ENGINES_R");
rs << queryId << m_engines.count();
for (int ii = 0; ii < m_engines.count(); ++ii) {
- QQmlEngine *engine = m_engines.at(ii);
+ QJSEngine *engine = m_engines.at(ii);
QString engineName = engine->objectName();
int engineId = QQmlDebugService::idForObject(engine);
@@ -617,7 +616,7 @@ void QQmlEngineDebugServiceImpl::processMessage(const QByteArray &message)
rs << QByteArray("SET_METHOD_BODY_R") << queryId << ok;
}
- emit messageToClient(name(), reply);
+ emit messageToClient(name(), rs.data());
}
bool QQmlEngineDebugServiceImpl::setBinding(int objectId,
@@ -769,15 +768,12 @@ bool QQmlEngineDebugServiceImpl::setMethodBody(int objectId, const QString &meth
void QQmlEngineDebugServiceImpl::propertyChanged(int id, int objectId, const QMetaProperty &property, const QVariant &value)
{
- QByteArray reply;
- QQmlDebugStream rs(&reply, QIODevice::WriteOnly);
-
+ QQmlDebugPacket rs;
rs << QByteArray("UPDATE_WATCH") << id << objectId << QByteArray(property.name()) << valueContents(value);
-
- emit messageToClient(name(), reply);
+ emit messageToClient(name(), rs.data());
}
-void QQmlEngineDebugServiceImpl::engineAboutToBeAdded(QQmlEngine *engine)
+void QQmlEngineDebugServiceImpl::engineAboutToBeAdded(QJSEngine *engine)
{
Q_ASSERT(engine);
Q_ASSERT(!m_engines.contains(engine));
@@ -786,7 +782,7 @@ void QQmlEngineDebugServiceImpl::engineAboutToBeAdded(QQmlEngine *engine)
emit attachedToEngine(engine);
}
-void QQmlEngineDebugServiceImpl::engineAboutToBeRemoved(QQmlEngine *engine)
+void QQmlEngineDebugServiceImpl::engineAboutToBeRemoved(QJSEngine *engine)
{
Q_ASSERT(engine);
Q_ASSERT(m_engines.contains(engine));
@@ -795,7 +791,7 @@ void QQmlEngineDebugServiceImpl::engineAboutToBeRemoved(QQmlEngine *engine)
emit detachedFromEngine(engine);
}
-void QQmlEngineDebugServiceImpl::objectCreated(QQmlEngine *engine, QObject *object)
+void QQmlEngineDebugServiceImpl::objectCreated(QJSEngine *engine, QObject *object)
{
Q_ASSERT(engine);
Q_ASSERT(m_engines.contains(engine));
@@ -804,12 +800,11 @@ void QQmlEngineDebugServiceImpl::objectCreated(QQmlEngine *engine, QObject *obje
int objectId = QQmlDebugService::idForObject(object);
int parentId = QQmlDebugService::idForObject(object->parent());
- QByteArray reply;
- QQmlDebugStream rs(&reply, QIODevice::WriteOnly);
+ QQmlDebugPacket rs;
//unique queryId -1
rs << QByteArray("OBJECT_CREATED") << -1 << engineId << objectId << parentId;
- emit messageToClient(name(), reply);
+ emit messageToClient(name(), rs.data());
}
void QQmlEngineDebugServiceImpl::setStatesDelegate(QQmlDebugStatesDelegate *delegate)
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.h b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.h
index 68cb420cc0..e6c832b9bc 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.h
+++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.h
@@ -89,9 +89,9 @@ public:
bool hasNotifySignal;
};
- void engineAboutToBeAdded(QQmlEngine *) Q_DECL_OVERRIDE;
- void engineAboutToBeRemoved(QQmlEngine *) Q_DECL_OVERRIDE;
- void objectCreated(QQmlEngine *, QObject *) Q_DECL_OVERRIDE;
+ void engineAboutToBeAdded(QJSEngine *) Q_DECL_OVERRIDE;
+ void engineAboutToBeRemoved(QJSEngine *) Q_DECL_OVERRIDE;
+ void objectCreated(QJSEngine *, QObject *) Q_DECL_OVERRIDE;
void setStatesDelegate(QQmlDebugStatesDelegate *) Q_DECL_OVERRIDE;
@@ -120,7 +120,7 @@ private:
QList<QObject *> objectForLocationInfo(const QString &filename, int lineNumber,
int columnNumber);
- QList<QQmlEngine *> m_engines;
+ QList<QJSEngine *> m_engines;
QQmlWatcher *m_watch;
QQmlDebugStatesDelegate *m_statesDelegate;
};
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlnativedebugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qqmlnativedebugservice.cpp
index f5cc78e77f..a57ef56a84 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qqmlnativedebugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlnativedebugservice.cpp
@@ -32,6 +32,7 @@
****************************************************************************/
#include "qqmlnativedebugservice.h"
+#include "qqmldebugpacket.h"
#include <private/qqmldebugconnector_p.h>
#include <private/qv4debugging_p.h>
@@ -46,8 +47,7 @@
#include <private/qv4isel_moth_p.h>
#include <private/qqmldebugserviceinterfaces_p.h>
-#include <qqmlengine.h>
-
+#include <QtQml/qjsengine.h>
#include <QtCore/qjsonarray.h>
#include <QtCore/qjsondocument.h>
#include <QtCore/qjsonobject.h>
@@ -313,16 +313,15 @@ void NativeDebugger::handleCommand(QJsonObject *response, const QString &cmd,
static QString encodeContext(QV4::ExecutionContext *executionContext)
{
- QByteArray ba;
- QDataStream ds(&ba, QIODevice::WriteOnly);
+ QQmlDebugPacket ds;
ds << quintptr(executionContext);
- return QString::fromLatin1(ba.toHex());
+ return QString::fromLatin1(ds.data().toHex());
}
static void decodeContext(const QString &context, QV4::ExecutionContext **executionContext)
{
quintptr rawContext;
- QDataStream ds(QByteArray::fromHex(context.toLatin1()));
+ QQmlDebugPacket ds(QByteArray::fromHex(context.toLatin1()));
ds >> rawContext;
*executionContext = reinterpret_cast<QV4::ExecutionContext *>(rawContext);
}
@@ -724,7 +723,7 @@ QQmlNativeDebugServiceImpl::~QQmlNativeDebugServiceImpl()
delete m_breakHandler;
}
-void QQmlNativeDebugServiceImpl::engineAboutToBeAdded(QQmlEngine *engine)
+void QQmlNativeDebugServiceImpl::engineAboutToBeAdded(QJSEngine *engine)
{
TRACE_PROTOCOL("Adding engine" << engine);
if (engine) {
@@ -741,7 +740,7 @@ void QQmlNativeDebugServiceImpl::engineAboutToBeAdded(QQmlEngine *engine)
QQmlDebugService::engineAboutToBeAdded(engine);
}
-void QQmlNativeDebugServiceImpl::engineAboutToBeRemoved(QQmlEngine *engine)
+void QQmlNativeDebugServiceImpl::engineAboutToBeRemoved(QJSEngine *engine)
{
TRACE_PROTOCOL("Removing engine" << engine);
if (engine) {
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlnativedebugservice.h b/src/plugins/qmltooling/qmldbg_debugger/qqmlnativedebugservice.h
index 9d0780a203..5ebf0a7f54 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qqmlnativedebugservice.h
+++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlnativedebugservice.h
@@ -68,14 +68,14 @@ class QQmlNativeDebugServiceImpl : public QQmlNativeDebugService
public:
QQmlNativeDebugServiceImpl(QObject *parent);
- ~QQmlNativeDebugServiceImpl();
+ ~QQmlNativeDebugServiceImpl() Q_DECL_OVERRIDE;
- void engineAboutToBeAdded(QQmlEngine *engine);
- void engineAboutToBeRemoved(QQmlEngine *engine);
+ void engineAboutToBeAdded(QJSEngine *engine) Q_DECL_OVERRIDE;
+ void engineAboutToBeRemoved(QJSEngine *engine) Q_DECL_OVERRIDE;
- void stateAboutToBeChanged(State state);
+ void stateAboutToBeChanged(State state) Q_DECL_OVERRIDE;
- void messageReceived(const QByteArray &message);
+ void messageReceived(const QByteArray &message) Q_DECL_OVERRIDE;
void emitAsynchronousMessageToClient(const QJsonObject &message);
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
index 4cca1900de..78cb2be8d3 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
@@ -39,10 +39,17 @@
#include <private/qv4identifier_p.h>
#include <private/qv4runtime_p.h>
+#include <private/qqmlcontext_p.h>
+#include <private/qqmlengine_p.h>
+
#include <QtCore/qjsonarray.h>
+#include <QtCore/qjsonobject.h>
QT_BEGIN_NAMESPACE
+const QV4DataCollector::Ref QV4DataCollector::s_invalidRef =
+ std::numeric_limits<QV4DataCollector::Ref>::max();
+
QV4::CallContext *QV4DataCollector::findContext(QV4::ExecutionEngine *engine, int frame)
{
QV4::ExecutionContext *ctx = engine->currentContext;
@@ -89,21 +96,16 @@ QVector<QV4::Heap::ExecutionContext::ContextType> QV4DataCollector::getScopeType
return types;
}
-
-QV4DataCollector::QV4DataCollector(QV4::ExecutionEngine *engine)
- : m_engine(engine), m_collectedRefs(Q_NULLPTR)
-{
- values.set(engine, engine->newArrayObject());
-}
-
-QV4DataCollector::~QV4DataCollector()
+QV4DataCollector::QV4DataCollector(QV4::ExecutionEngine *engine) : m_engine(engine)
{
+ m_values.set(engine, engine->newArrayObject());
}
-void QV4DataCollector::collect(const QV4::ScopedValue &value)
+QV4DataCollector::Ref QV4DataCollector::collect(const QV4::ScopedValue &value)
{
- if (m_collectedRefs)
- m_collectedRefs->append(addRef(value));
+ Ref ref = addRef(value);
+ m_collectedRefs.append(ref);
+ return ref;
}
const QV4::Object *collectProperty(const QV4::ScopedValue &value, QV4::ExecutionEngine *engine,
@@ -190,7 +192,8 @@ QV4DataCollector::Ref QV4DataCollector::addFunctionRef(const QString &functionNa
dict.insert(QStringLiteral("handle"), qint64(ref));
dict.insert(QStringLiteral("type"), QStringLiteral("function"));
dict.insert(QStringLiteral("name"), functionName);
- specialRefs.insert(ref, dict);
+ m_specialRefs.insert(ref, dict);
+ m_collectedRefs.append(ref);
return ref;
}
@@ -203,19 +206,25 @@ QV4DataCollector::Ref QV4DataCollector::addScriptRef(const QString &scriptName)
dict.insert(QStringLiteral("handle"), qint64(ref));
dict.insert(QStringLiteral("type"), QStringLiteral("script"));
dict.insert(QStringLiteral("name"), scriptName);
- specialRefs.insert(ref, dict);
+ m_specialRefs.insert(ref, dict);
+ m_collectedRefs.append(ref);
return ref;
}
-void QV4DataCollector::collectScope(QJsonObject *dict, QV4::Debugging::V4Debugger *debugger,
- int frameNr, int scopeNr)
+bool QV4DataCollector::isValidRef(QV4DataCollector::Ref ref) const
+{
+ QV4::Scope scope(engine());
+ QV4::ScopedObject array(scope, m_values.value());
+ return ref < array->getLength();
+}
+
+void QV4DataCollector::collectScope(QJsonObject *dict, QV4Debugger *debugger, int frameNr,
+ int scopeNr)
{
QStringList names;
- Refs refs;
- if (debugger->state() == QV4::Debugging::V4Debugger::Paused) {
- RefHolder holder(this, &refs);
+ if (debugger->state() == QV4Debugger::Paused) {
ArgumentCollectJob argumentsJob(m_engine, this, &names, frameNr, scopeNr);
debugger->runInEngine(&argumentsJob);
LocalCollectJob localsJob(m_engine, this, &names, frameNr, scopeNr);
@@ -225,15 +234,36 @@ void QV4DataCollector::collectScope(QJsonObject *dict, QV4::Debugging::V4Debugge
QV4::Scope scope(engine());
QV4::ScopedObject scopeObject(scope, engine()->newObject());
- Q_ASSERT(names.size() == refs.size());
- for (int i = 0, ei = refs.size(); i != ei; ++i)
+ Q_ASSERT(names.size() == m_collectedRefs.size());
+ for (int i = 0, ei = m_collectedRefs.size(); i != ei; ++i)
scopeObject->put(engine(), names.at(i),
- QV4::Value::fromReturnedValue(getValue(refs.at(i))));
+ QV4::Value::fromReturnedValue(getValue(m_collectedRefs.at(i))));
Ref scopeObjectRef = addRef(scopeObject);
dict->insert(QStringLiteral("ref"), qint64(scopeObjectRef));
- if (m_collectedRefs)
- m_collectedRefs->append(scopeObjectRef);
+ m_collectedRefs.append(scopeObjectRef);
+}
+
+QJsonArray QV4DataCollector::flushCollectedRefs()
+{
+ QJsonArray refs;
+ std::sort(m_collectedRefs.begin(), m_collectedRefs.end());
+ for (int i = 0, ei = m_collectedRefs.size(); i != ei; ++i) {
+ QV4DataCollector::Ref ref = m_collectedRefs.at(i);
+ if (i > 0 && ref == m_collectedRefs.at(i - 1))
+ continue;
+ refs.append(lookupRef(ref));
+ }
+
+ m_collectedRefs.clear();
+ return refs;
+}
+
+void QV4DataCollector::clear()
+{
+ m_values.set(engine(), engine()->newArrayObject());
+ m_collectedRefs.clear();
+ m_specialRefs.clear();
}
QV4DataCollector::Ref QV4DataCollector::addRef(QV4::Value value, bool deduplicate)
@@ -256,10 +286,10 @@ QV4DataCollector::Ref QV4DataCollector::addRef(QV4::Value value, bool deduplicat
// if we wouldn't do this, the putIndexed won't work.
ExceptionStateSaver resetExceptionState(engine());
QV4::Scope scope(engine());
- QV4::ScopedObject array(scope, values.value());
+ QV4::ScopedObject array(scope, m_values.value());
if (deduplicate) {
for (Ref i = 0; i < array->getLength(); ++i) {
- if (array->getIndexed(i) == value.rawValue() && !specialRefs.contains(i))
+ if (array->getIndexed(i) == value.rawValue() && !m_specialRefs.contains(i))
return i;
}
}
@@ -272,15 +302,15 @@ QV4DataCollector::Ref QV4DataCollector::addRef(QV4::Value value, bool deduplicat
QV4::ReturnedValue QV4DataCollector::getValue(Ref ref)
{
QV4::Scope scope(engine());
- QV4::ScopedObject array(scope, values.value());
+ QV4::ScopedObject array(scope, m_values.value());
Q_ASSERT(ref < array->getLength());
return array->getIndexed(ref, Q_NULLPTR);
}
bool QV4DataCollector::lookupSpecialRef(Ref ref, QJsonObject *dict)
{
- SpecialRefs::const_iterator it = specialRefs.find(ref);
- if (it == specialRefs.end())
+ SpecialRefs::const_iterator it = m_specialRefs.constFind(ref);
+ if (it == m_specialRefs.cend())
return false;
*dict = it.value();
@@ -316,14 +346,54 @@ QJsonObject QV4DataCollector::collectAsJson(const QString &name, const QV4::Scop
if (value->isManaged() && !value->isString()) {
Ref ref = addRef(value);
dict.insert(QStringLiteral("ref"), qint64(ref));
- if (m_collectedRefs)
- m_collectedRefs->append(ref);
+ m_collectedRefs.append(ref);
}
collectProperty(value, engine(), dict);
return dict;
}
+void ValueLookupJob::run()
+{
+ // Open a QML context if we don't have one, yet. We might run into QML objects when looking up
+ // refs and that will crash without a valid QML context. Mind that engine->qmlContext() is only
+ // set if the engine is currently executing QML code.
+ QScopedPointer<QObject> scopeObject;
+ QV4::ExecutionEngine *engine = collector->engine();
+ if (engine->qmlEngine() && !engine->qmlContext()) {
+ scopeObject.reset(new QObject);
+ engine->pushContext(engine->currentContext->newQmlContext(
+ QQmlContextData::get(engine->qmlEngine()->rootContext()),
+ scopeObject.data()));
+ }
+ foreach (const QJsonValue &handle, handles) {
+ QV4DataCollector::Ref ref = handle.toInt();
+ if (!collector->isValidRef(ref)) {
+ exception = QString::fromLatin1("Invalid Ref: %1").arg(ref);
+ break;
+ }
+ result[QString::number(ref)] = collector->lookupRef(ref);
+ }
+ collectedRefs = collector->flushCollectedRefs();
+ if (scopeObject)
+ engine->popContext();
+}
+
+const QString &ValueLookupJob::exceptionMessage() const
+{
+ return exception;
+}
+
+const QJsonObject &ValueLookupJob::returnValue() const
+{
+ return result;
+}
+
+const QJsonArray &ValueLookupJob::refs() const
+{
+ return collectedRefs;
+}
+
ExpressionEvalJob::ExpressionEvalJob(QV4::ExecutionEngine *engine, int frameNr,
const QString &expression,
QV4DataCollector *collector)
@@ -332,11 +402,12 @@ ExpressionEvalJob::ExpressionEvalJob(QV4::ExecutionEngine *engine, int frameNr,
{
}
-void ExpressionEvalJob::handleResult(QV4::ScopedValue &result)
+void ExpressionEvalJob::handleResult(QV4::ScopedValue &value)
{
if (hasExeption())
- exception = result->toQStringNoThrow();
- collector->collect(result);
+ exception = value->toQStringNoThrow();
+ result = collector->lookupRef(collector->collect(value));
+ collectedRefs = collector->flushCollectedRefs();
}
const QString &ExpressionEvalJob::exceptionMessage() const
@@ -344,24 +415,32 @@ const QString &ExpressionEvalJob::exceptionMessage() const
return exception;
}
-GatherSourcesJob::GatherSourcesJob(QV4::ExecutionEngine *engine, int seq)
+const QJsonObject &ExpressionEvalJob::returnValue() const
+{
+ return result;
+}
+
+const QJsonArray &ExpressionEvalJob::refs() const
+{
+ return collectedRefs;
+}
+
+GatherSourcesJob::GatherSourcesJob(QV4::ExecutionEngine *engine)
: engine(engine)
- , seq(seq)
{}
void GatherSourcesJob::run()
{
- QStringList sources;
-
foreach (QV4::CompiledData::CompilationUnit *unit, engine->compilationUnits) {
QString fileName = unit->fileName();
if (!fileName.isEmpty())
sources.append(fileName);
}
+}
- QV4::Debugging::V4Debugger *debugger
- = static_cast<QV4::Debugging::V4Debugger *>(engine->debugger);
- emit debugger->sourcesCollected(debugger, sources, seq);
+const QStringList &GatherSourcesJob::result() const
+{
+ return sources;
}
ArgumentCollectJob::ArgumentCollectJob(QV4::ExecutionEngine *engine, QV4DataCollector *collector,
@@ -428,20 +507,15 @@ void LocalCollectJob::run()
}
ThisCollectJob::ThisCollectJob(QV4::ExecutionEngine *engine, QV4DataCollector *collector,
- int frameNr, bool *foundThis)
+ int frameNr)
: engine(engine)
, collector(collector)
, frameNr(frameNr)
- , foundThis(foundThis)
+ , thisRef(QV4DataCollector::s_invalidRef)
{}
void ThisCollectJob::run()
{
- *foundThis = myRun();
-}
-
-bool ThisCollectJob::myRun()
-{
QV4::Scope scope(engine);
QV4::ScopedContext ctxt(scope, QV4DataCollector::findContext(engine, frameNr));
while (ctxt) {
@@ -452,23 +526,33 @@ bool ThisCollectJob::myRun()
}
if (!ctxt)
- return false;
+ return;
QV4::ScopedValue o(scope, ctxt->asCallContext()->d()->activation);
- collector->collect(o);
- return true;
+ thisRef = collector->collect(o);
+}
+
+QV4DataCollector::Ref ThisCollectJob::foundRef() const
+{
+ return thisRef;
}
ExceptionCollectJob::ExceptionCollectJob(QV4::ExecutionEngine *engine, QV4DataCollector *collector)
: engine(engine)
, collector(collector)
+ , exception(QV4DataCollector::s_invalidRef)
{}
void ExceptionCollectJob::run()
{
QV4::Scope scope(engine);
QV4::ScopedValue v(scope, *engine->exceptionValue);
- collector->collect(v);
+ exception = collector->collect(v);
+}
+
+QV4DataCollector::Ref ExceptionCollectJob::exceptionValue() const
+{
+ return exception;
}
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
index d0e4a4ad18..d1ff98f9b0 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
@@ -34,8 +34,12 @@
#ifndef QV4DATACOLLECTOR_H
#define QV4DATACOLLECTOR_H
+#include "qv4debugger.h"
#include <private/qv4engine_p.h>
-#include <private/qv4debugging_p.h>
+#include <private/qv4persistent_p.h>
+
+#include <QtCore/QJsonObject>
+#include <QtCore/QJsonArray>
QT_BEGIN_NAMESPACE
@@ -44,6 +48,7 @@ class QV4DataCollector
public:
typedef uint Ref;
typedef QVector<uint> Refs;
+ static const Ref s_invalidRef;
static QV4::CallContext *findContext(QV4::ExecutionEngine *engine, int frame);
static QV4::Heap::CallContext *findScope(QV4::ExecutionContext *ctxt, int scope);
@@ -51,23 +56,21 @@ public:
QV4::ExecutionEngine *engine, int frame);
QV4DataCollector(QV4::ExecutionEngine *engine);
- ~QV4DataCollector();
-
- void collect(const QV4::ScopedValue &value);
-
- QJsonObject lookupRef(Ref ref);
+ Ref collect(const QV4::ScopedValue &value);
Ref addFunctionRef(const QString &functionName);
Ref addScriptRef(const QString &scriptName);
- void collectScope(QJsonObject *dict, QV4::Debugging::V4Debugger *debugger, int frameNr,
- int scopeNr);
+ bool isValidRef(Ref ref) const;
+ QJsonObject lookupRef(Ref ref);
+
+ void collectScope(QJsonObject *dict, QV4Debugger *debugger, int frameNr, int scopeNr);
QV4::ExecutionEngine *engine() const { return m_engine; }
+ QJsonArray flushCollectedRefs();
+ void clear();
private:
- friend class RefHolder;
-
Ref addRef(QV4::Value value, bool deduplicate = true);
QV4::ReturnedValue getValue(Ref ref);
bool lookupSpecialRef(Ref ref, QJsonObject *dict);
@@ -77,53 +80,57 @@ private:
void collectArgumentsInContext();
QV4::ExecutionEngine *m_engine;
- Refs *m_collectedRefs;
- QV4::PersistentValue values;
+ Refs m_collectedRefs;
+ QV4::PersistentValue m_values;
typedef QHash<Ref, QJsonObject> SpecialRefs;
- SpecialRefs specialRefs;
+ SpecialRefs m_specialRefs;
};
-class RefHolder {
-public:
- RefHolder(QV4DataCollector *collector, QV4DataCollector::Refs *target) :
- m_collector(collector), m_previousRefs(collector->m_collectedRefs)
- {
- m_collector->m_collectedRefs = target;
- }
-
- ~RefHolder()
- {
- std::swap(m_collector->m_collectedRefs, m_previousRefs);
- }
+class ValueLookupJob: public QV4Debugger::Job
+{
+ QV4DataCollector *collector;
+ const QJsonArray handles;
+ QJsonObject result;
+ QJsonArray collectedRefs;
+ QString exception;
-private:
- QV4DataCollector *m_collector;
- QV4DataCollector::Refs *m_previousRefs;
+public:
+ ValueLookupJob(const QJsonArray &handles, QV4DataCollector *collector) :
+ collector(collector), handles(handles) {}
+ void run();
+ const QString &exceptionMessage() const;
+ const QJsonObject &returnValue() const;
+ const QJsonArray &refs() const;
};
-class ExpressionEvalJob: public QV4::Debugging::V4Debugger::JavaScriptJob
+class ExpressionEvalJob: public QV4Debugger::JavaScriptJob
{
QV4DataCollector *collector;
QString exception;
+ QJsonObject result;
+ QJsonArray collectedRefs;
public:
ExpressionEvalJob(QV4::ExecutionEngine *engine, int frameNr, const QString &expression,
QV4DataCollector *collector);
- virtual void handleResult(QV4::ScopedValue &result);
+ virtual void handleResult(QV4::ScopedValue &value);
const QString &exceptionMessage() const;
+ const QJsonObject &returnValue() const;
+ const QJsonArray &refs() const;
};
-class GatherSourcesJob: public QV4::Debugging::V4Debugger::Job
+class GatherSourcesJob: public QV4Debugger::Job
{
QV4::ExecutionEngine *engine;
- const int seq;
+ QStringList sources;
public:
- GatherSourcesJob(QV4::ExecutionEngine *engine, int seq);
+ GatherSourcesJob(QV4::ExecutionEngine *engine);
void run();
+ const QStringList &result() const;
};
-class ArgumentCollectJob: public QV4::Debugging::V4Debugger::Job
+class ArgumentCollectJob: public QV4Debugger::Job
{
QV4::ExecutionEngine *engine;
QV4DataCollector *collector;
@@ -137,7 +144,7 @@ public:
void run();
};
-class LocalCollectJob: public QV4::Debugging::V4Debugger::Job
+class LocalCollectJob: public QV4Debugger::Job
{
QV4::ExecutionEngine *engine;
QV4DataCollector *collector;
@@ -151,28 +158,29 @@ public:
void run();
};
-class ThisCollectJob: public QV4::Debugging::V4Debugger::Job
+class ThisCollectJob: public QV4Debugger::Job
{
QV4::ExecutionEngine *engine;
QV4DataCollector *collector;
int frameNr;
- bool *foundThis;
+ QV4DataCollector::Ref thisRef;
public:
- ThisCollectJob(QV4::ExecutionEngine *engine, QV4DataCollector *collector, int frameNr,
- bool *foundThis);
+ ThisCollectJob(QV4::ExecutionEngine *engine, QV4DataCollector *collector, int frameNr);
void run();
- bool myRun();
+ QV4DataCollector::Ref foundRef() const;
};
-class ExceptionCollectJob: public QV4::Debugging::V4Debugger::Job
+class ExceptionCollectJob: public QV4Debugger::Job
{
QV4::ExecutionEngine *engine;
QV4DataCollector *collector;
+ QV4DataCollector::Ref exception;
public:
ExceptionCollectJob(QV4::ExecutionEngine *engine, QV4DataCollector *collector);
void run();
+ QV4DataCollector::Ref exceptionValue() const;
};
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp
new file mode 100644
index 0000000000..b7c310edd8
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp
@@ -0,0 +1,416 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qv4debugger.h"
+#include "qv4datacollector.h"
+
+#include <private/qv4scopedvalue_p.h>
+#include <private/qv4script_p.h>
+#include <private/qqmlcontext_p.h>
+#include <private/qqmlengine_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QV4Debugger::BreakPoint::BreakPoint(const QString &fileName, int line)
+ : fileName(fileName), lineNumber(line)
+{}
+
+inline uint qHash(const QV4Debugger::BreakPoint &b, uint seed = 0) Q_DECL_NOTHROW
+{
+ return qHash(b.fileName, seed) ^ b.lineNumber;
+}
+
+inline bool operator==(const QV4Debugger::BreakPoint &a,
+ const QV4Debugger::BreakPoint &b)
+{
+ return a.lineNumber == b.lineNumber && a.fileName == b.fileName;
+}
+
+QV4Debugger::JavaScriptJob::JavaScriptJob(QV4::ExecutionEngine *engine, int frameNr,
+ const QString &script)
+ : engine(engine)
+ , frameNr(frameNr)
+ , script(script)
+ , resultIsException(false)
+{}
+
+void QV4Debugger::JavaScriptJob::run()
+{
+ QV4::Scope scope(engine);
+
+ QV4::ExecutionContextSaver saver(scope);
+
+ QV4::ExecutionContext *ctx = engine->currentContext;
+ QObject scopeObject;
+ if (frameNr < 0) { // Use QML context if available
+ QQmlEngine *qmlEngine = engine->qmlEngine();
+ if (qmlEngine) {
+ QQmlContext *qmlRootContext = qmlEngine->rootContext();
+ QQmlContextPrivate *ctxtPriv = QQmlContextPrivate::get(qmlRootContext);
+
+ QV4::ScopedObject withContext(scope, engine->newObject());
+ for (int ii = 0; ii < ctxtPriv->instances.count(); ++ii) {
+ QObject *object = ctxtPriv->instances.at(ii);
+ if (QQmlContext *context = qmlContext(object)) {
+ if (QQmlContextData *cdata = QQmlContextData::get(context)) {
+ QV4::ScopedValue v(scope, QV4::QObjectWrapper::wrap(engine, object));
+ withContext->put(engine, cdata->findObjectId(object), v);
+ }
+ }
+ }
+ if (!engine->qmlContext()) {
+ engine->pushContext(ctx->newQmlContext(QQmlContextData::get(qmlRootContext),
+ &scopeObject));
+ ctx = engine->currentContext;
+ }
+ engine->pushContext(ctx->newWithContext(withContext->toObject(engine)));
+ ctx = engine->currentContext;
+ }
+ } else {
+ if (frameNr > 0) {
+ for (int i = 0; i < frameNr; ++i) {
+ ctx = engine->parentContext(ctx);
+ }
+ engine->pushContext(ctx);
+ }
+ }
+
+ QV4::Script script(ctx, this->script);
+ script.strictMode = ctx->d()->strictMode;
+ // In order for property lookups in QML to work, we need to disable fast v4 lookups. That
+ // is a side-effect of inheritContext.
+ script.inheritContext = true;
+ script.parse();
+ QV4::ScopedValue result(scope);
+ if (!scope.engine->hasException)
+ result = script.run();
+ if (scope.engine->hasException) {
+ result = scope.engine->catchException();
+ resultIsException = true;
+ }
+ handleResult(result);
+}
+
+bool QV4Debugger::JavaScriptJob::hasExeption() const
+{
+ return resultIsException;
+}
+
+class EvalJob: public QV4Debugger::JavaScriptJob
+{
+ bool result;
+
+public:
+ EvalJob(QV4::ExecutionEngine *engine, const QString &script)
+ : QV4Debugger::JavaScriptJob(engine, /*frameNr*/-1, script)
+ , result(false)
+ {}
+
+ virtual void handleResult(QV4::ScopedValue &result)
+ {
+ this->result = result->toBoolean();
+ }
+
+ bool resultAsBoolean() const
+ {
+ return result;
+ }
+};
+
+QV4Debugger::QV4Debugger(QV4::ExecutionEngine *engine)
+ : m_engine(engine)
+ , m_state(Running)
+ , m_stepping(NotStepping)
+ , m_pauseRequested(false)
+ , m_haveBreakPoints(false)
+ , m_breakOnThrow(false)
+ , m_returnedValue(engine, QV4::Primitive::undefinedValue())
+ , m_gatherSources(0)
+ , m_runningJob(0)
+ , m_collector(new QV4DataCollector(engine))
+{
+ static int debuggerId = qRegisterMetaType<QV4Debugger*>();
+ static int pauseReasonId = qRegisterMetaType<QV4Debugger::PauseReason>();
+ Q_UNUSED(debuggerId);
+ Q_UNUSED(pauseReasonId);
+}
+
+QV4Debugger::~QV4Debugger()
+{
+ delete m_collector;
+}
+
+QV4::ExecutionEngine *QV4Debugger::engine() const
+{
+ return m_engine;
+}
+
+QV4DataCollector *QV4Debugger::collector() const
+{
+ return m_collector;
+}
+
+void QV4Debugger::pause()
+{
+ QMutexLocker locker(&m_lock);
+ if (m_state == Paused)
+ return;
+ m_pauseRequested = true;
+}
+
+void QV4Debugger::resume(Speed speed)
+{
+ QMutexLocker locker(&m_lock);
+ if (m_state != Paused)
+ return;
+
+ if (!m_returnedValue.isUndefined())
+ m_returnedValue.set(m_engine, QV4::Encode::undefined());
+
+ m_currentContext.set(m_engine, *m_engine->currentContext);
+ m_stepping = speed;
+ m_runningCondition.wakeAll();
+}
+
+QV4Debugger::State QV4Debugger::state() const
+{
+ return m_state;
+}
+
+void QV4Debugger::addBreakPoint(const QString &fileName, int lineNumber, const QString &condition)
+{
+ QMutexLocker locker(&m_lock);
+ m_breakPoints.insert(BreakPoint(fileName.mid(fileName.lastIndexOf('/') + 1),
+ lineNumber), condition);
+ m_haveBreakPoints = true;
+}
+
+void QV4Debugger::removeBreakPoint(const QString &fileName, int lineNumber)
+{
+ QMutexLocker locker(&m_lock);
+ m_breakPoints.remove(BreakPoint(fileName.mid(fileName.lastIndexOf('/') + 1),
+ lineNumber));
+ m_haveBreakPoints = !m_breakPoints.isEmpty();
+}
+
+void QV4Debugger::setBreakOnThrow(bool onoff)
+{
+ QMutexLocker locker(&m_lock);
+
+ m_breakOnThrow = onoff;
+}
+
+void QV4Debugger::clearPauseRequest()
+{
+ QMutexLocker locker(&m_lock);
+ m_pauseRequested = false;
+}
+
+QV4Debugger::ExecutionState QV4Debugger::currentExecutionState() const
+{
+ ExecutionState state;
+ state.fileName = getFunction()->sourceFile();
+ state.lineNumber = engine()->current->lineNumber;
+
+ return state;
+}
+
+bool QV4Debugger::pauseAtNextOpportunity() const {
+ return m_pauseRequested || m_haveBreakPoints || m_gatherSources || m_stepping >= StepOver;
+}
+
+QVector<QV4::StackFrame> QV4Debugger::stackTrace(int frameLimit) const
+{
+ return m_engine->stackTrace(frameLimit);
+}
+
+void QV4Debugger::maybeBreakAtInstruction()
+{
+ if (m_runningJob) // do not re-enter when we're doing a job for the debugger.
+ return;
+
+ QMutexLocker locker(&m_lock);
+
+ if (m_gatherSources) {
+ m_gatherSources->run();
+ delete m_gatherSources;
+ m_gatherSources = 0;
+ }
+
+ switch (m_stepping) {
+ case StepOver:
+ if (m_currentContext.asManaged()->d() != m_engine->current)
+ break;
+ // fall through
+ case StepIn:
+ pauseAndWait(Step);
+ return;
+ case StepOut:
+ case NotStepping:
+ break;
+ }
+
+ if (m_pauseRequested) { // Serve debugging requests from the agent
+ m_pauseRequested = false;
+ pauseAndWait(PauseRequest);
+ } else if (m_haveBreakPoints) {
+ if (QV4::Function *f = getFunction()) {
+ const int lineNumber = engine()->current->lineNumber;
+ if (reallyHitTheBreakPoint(f->sourceFile(), lineNumber))
+ pauseAndWait(BreakPointHit);
+ }
+ }
+}
+
+void QV4Debugger::enteringFunction()
+{
+ if (m_runningJob)
+ return;
+ QMutexLocker locker(&m_lock);
+
+ if (m_stepping == StepIn) {
+ m_currentContext.set(m_engine, *m_engine->currentContext);
+ }
+}
+
+void QV4Debugger::leavingFunction(const QV4::ReturnedValue &retVal)
+{
+ if (m_runningJob)
+ return;
+ Q_UNUSED(retVal); // TODO
+
+ QMutexLocker locker(&m_lock);
+
+ if (m_stepping != NotStepping && m_currentContext.asManaged()->d() == m_engine->current) {
+ m_currentContext.set(m_engine, *m_engine->parentContext(m_engine->currentContext));
+ m_stepping = StepOver;
+ m_returnedValue.set(m_engine, retVal);
+ }
+}
+
+void QV4Debugger::aboutToThrow()
+{
+ if (!m_breakOnThrow)
+ return;
+
+ if (m_runningJob) // do not re-enter when we're doing a job for the debugger.
+ return;
+
+ QMutexLocker locker(&m_lock);
+ pauseAndWait(Throwing);
+}
+
+QV4::Function *QV4Debugger::getFunction() const
+{
+ QV4::Scope scope(m_engine);
+ QV4::ExecutionContext *context = m_engine->currentContext;
+ QV4::ScopedFunctionObject function(scope, context->getFunctionObject());
+ if (function)
+ return function->function();
+ else
+ return context->d()->engine->globalCode;
+}
+
+void QV4Debugger::runJobUnpaused()
+{
+ QMutexLocker locker(&m_lock);
+ if (m_runningJob)
+ m_runningJob->run();
+ m_jobIsRunning.wakeAll();
+}
+
+void QV4Debugger::pauseAndWait(PauseReason reason)
+{
+ if (m_runningJob)
+ return;
+
+ m_state = Paused;
+ emit debuggerPaused(this, reason);
+
+ while (true) {
+ m_runningCondition.wait(&m_lock);
+ if (m_runningJob) {
+ m_runningJob->run();
+ m_jobIsRunning.wakeAll();
+ } else {
+ break;
+ }
+ }
+
+ m_state = Running;
+}
+
+bool QV4Debugger::reallyHitTheBreakPoint(const QString &filename, int linenr)
+{
+ QHash<BreakPoint, QString>::iterator it = m_breakPoints.find(
+ BreakPoint(filename.mid(filename.lastIndexOf('/') + 1), linenr));
+ if (it == m_breakPoints.end())
+ return false;
+ QString condition = it.value();
+ if (condition.isEmpty())
+ return true;
+
+ Q_ASSERT(m_runningJob == 0);
+ EvalJob evilJob(m_engine, condition);
+ m_runningJob = &evilJob;
+ m_runningJob->run();
+ m_runningJob = 0;
+
+ return evilJob.resultAsBoolean();
+}
+
+void QV4Debugger::runInEngine(QV4Debugger::Job *job)
+{
+ QMutexLocker locker(&m_lock);
+ runInEngine_havingLock(job);
+}
+
+void QV4Debugger::runInEngine_havingLock(QV4Debugger::Job *job)
+{
+ Q_ASSERT(job);
+ Q_ASSERT(m_runningJob == 0);
+
+ m_runningJob = job;
+ if (state() == Paused)
+ m_runningCondition.wakeAll();
+ else
+ QMetaObject::invokeMethod(this, "runJobUnpaused", Qt::QueuedConnection);
+ m_jobIsRunning.wait(&m_lock);
+ m_runningJob = 0;
+}
+
+QV4Debugger::Job::~Job()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.h b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.h
new file mode 100644
index 0000000000..abb43f82f3
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.h
@@ -0,0 +1,192 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QV4DEBUGGER_H
+#define QV4DEBUGGER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qv4debugging_p.h>
+#include <private/qv4function_p.h>
+#include <private/qv4context_p.h>
+#include <private/qv4persistent_p.h>
+
+#include <QtCore/qmutex.h>
+#include <QtCore/qwaitcondition.h>
+
+QT_BEGIN_NAMESPACE
+
+class QV4DataCollector;
+class QV4Debugger : public QV4::Debugging::Debugger
+{
+ Q_OBJECT
+public:
+ struct BreakPoint {
+ BreakPoint(const QString &fileName, int line);
+ QString fileName;
+ int lineNumber;
+ };
+
+ class Job
+ {
+ public:
+ virtual ~Job();
+ virtual void run() = 0;
+ };
+
+ class JavaScriptJob: public Job
+ {
+ QV4::ExecutionEngine *engine;
+ int frameNr;
+ const QString &script;
+ bool resultIsException;
+
+ public:
+ JavaScriptJob(QV4::ExecutionEngine *engine, int frameNr, const QString &script);
+ void run();
+ bool hasExeption() const;
+
+ protected:
+ virtual void handleResult(QV4::ScopedValue &result) = 0;
+ };
+
+ enum State {
+ Running,
+ Paused
+ };
+
+ enum Speed {
+ FullThrottle = 0,
+ StepOut,
+ StepOver,
+ StepIn,
+
+ NotStepping = FullThrottle
+ };
+
+ enum PauseReason {
+ PauseRequest,
+ BreakPointHit,
+ Throwing,
+ Step
+ };
+
+ QV4Debugger(QV4::ExecutionEngine *engine);
+ ~QV4Debugger();
+
+ QV4::ExecutionEngine *engine() const;
+ QV4DataCollector *collector() const;
+
+ void pause();
+ void resume(Speed speed);
+
+ State state() const;
+
+ void addBreakPoint(const QString &fileName, int lineNumber,
+ const QString &condition = QString());
+ void removeBreakPoint(const QString &fileName, int lineNumber);
+
+ void setBreakOnThrow(bool onoff);
+
+ void clearPauseRequest();
+
+ // used for testing
+ struct ExecutionState
+ {
+ QString fileName;
+ int lineNumber;
+ };
+ ExecutionState currentExecutionState() const;
+
+ QVector<QV4::StackFrame> stackTrace(int frameLimit = -1) const;
+ QVector<QV4::Heap::ExecutionContext::ContextType> getScopeTypes(int frame = 0) const;
+
+ QV4::Function *getFunction() const;
+ void runInEngine(Job *job);
+
+ // compile-time interface
+ void maybeBreakAtInstruction() Q_DECL_OVERRIDE;
+
+ // execution hooks
+ void enteringFunction() Q_DECL_OVERRIDE;
+ void leavingFunction(const QV4::ReturnedValue &retVal) Q_DECL_OVERRIDE;
+ void aboutToThrow() Q_DECL_OVERRIDE;
+
+ bool pauseAtNextOpportunity() const Q_DECL_OVERRIDE;
+
+signals:
+ void debuggerPaused(QV4Debugger *self, QV4Debugger::PauseReason reason);
+
+private slots:
+ void runJobUnpaused();
+
+private:
+ // requires lock to be held
+ void pauseAndWait(PauseReason reason);
+ bool reallyHitTheBreakPoint(const QString &filename, int linenr);
+ void runInEngine_havingLock(QV4Debugger::Job *job);
+
+ QV4::ExecutionEngine *m_engine;
+ QV4::PersistentValue m_currentContext;
+ QMutex m_lock;
+ QWaitCondition m_runningCondition;
+ State m_state;
+ Speed m_stepping;
+ bool m_pauseRequested;
+ bool m_haveBreakPoints;
+ bool m_breakOnThrow;
+
+ QHash<BreakPoint, QString> m_breakPoints;
+ QV4::PersistentValue m_returnedValue;
+
+ Job *m_gatherSources;
+ Job *m_runningJob;
+ QV4DataCollector *m_collector;
+ QWaitCondition m_jobIsRunning;
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QV4Debugger::PauseReason)
+Q_DECLARE_METATYPE(QV4Debugger*)
+
+#endif // QV4DEBUGGER_H
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp
index e33595c629..c563a97fe2 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp
@@ -44,38 +44,34 @@ QV4DebuggerAgent::QV4DebuggerAgent(QV4DebugServiceImpl *debugService)
: m_breakOnThrow(false), m_debugService(debugService)
{}
-QV4::Debugging::V4Debugger *QV4DebuggerAgent::firstDebugger() const
+QV4Debugger *QV4DebuggerAgent::pausedDebugger() const
{
- // Currently only 1 single engine is supported, so:
- if (m_debuggers.isEmpty())
- return 0;
- else
- return m_debuggers.first();
+ foreach (QV4Debugger *debugger, m_debuggers) {
+ if (debugger->state() == QV4Debugger::Paused)
+ return debugger;
+ }
+ return 0;
}
bool QV4DebuggerAgent::isRunning() const
{
- // Currently only 1 single engine is supported, so:
- if (QV4::Debugging::V4Debugger *debugger = firstDebugger())
- return debugger->state() == QV4::Debugging::V4Debugger::Running;
- else
- return false;
+ // "running" means none of the engines are paused.
+ return pausedDebugger() == 0;
}
-void QV4DebuggerAgent::debuggerPaused(QV4::Debugging::V4Debugger *debugger,
- QV4::Debugging::PauseReason reason)
+void QV4DebuggerAgent::debuggerPaused(QV4Debugger *debugger, QV4Debugger::PauseReason reason)
{
Q_UNUSED(reason);
- m_debugService->clearHandles(debugger->engine());
+ debugger->collector()->clear();
QJsonObject event, body, script;
event.insert(QStringLiteral("type"), QStringLiteral("event"));
switch (reason) {
- case QV4::Debugging::Step:
- case QV4::Debugging::PauseRequest:
- case QV4::Debugging::BreakPoint: {
+ case QV4Debugger::Step:
+ case QV4Debugger::PauseRequest:
+ case QV4Debugger::BreakPointHit: {
event.insert(QStringLiteral("event"), QStringLiteral("break"));
QVector<QV4::StackFrame> frames = debugger->stackTrace(1);
if (frames.isEmpty())
@@ -92,7 +88,7 @@ void QV4DebuggerAgent::debuggerPaused(QV4::Debugging::V4Debugger *debugger,
body.insert(QStringLiteral("breakpoints"), breakPoints);
script.insert(QStringLiteral("name"), topFrame.source);
} break;
- case QV4::Debugging::Throwing:
+ case QV4Debugger::Throwing:
// TODO: complete this!
event.insert(QStringLiteral("event"), QStringLiteral("exception"));
break;
@@ -105,28 +101,7 @@ void QV4DebuggerAgent::debuggerPaused(QV4::Debugging::V4Debugger *debugger,
m_debugService->send(event);
}
-void QV4DebuggerAgent::sourcesCollected(QV4::Debugging::V4Debugger *debugger,
- const QStringList &sources, int requestSequenceNr)
-{
- QJsonArray body;
- foreach (const QString &source, sources) {
- QJsonObject src;
- src[QLatin1String("name")] = source;
- src[QLatin1String("scriptType")] = 4;
- body.append(src);
- }
-
- QJsonObject response;
- response[QLatin1String("success")] = true;
- response[QLatin1String("running")] = debugger->state() == QV4::Debugging::V4Debugger::Running;
- response[QLatin1String("body")] = body;
- response[QLatin1String("command")] = QStringLiteral("scripts");
- response[QLatin1String("request_seq")] = requestSequenceNr;
- response[QLatin1String("type")] = QStringLiteral("response");
- m_debugService->send(response);
-}
-
-void QV4DebuggerAgent::addDebugger(QV4::Debugging::V4Debugger *debugger)
+void QV4DebuggerAgent::addDebugger(QV4Debugger *debugger)
{
Q_ASSERT(!m_debuggers.contains(debugger));
m_debuggers << debugger;
@@ -137,57 +112,50 @@ void QV4DebuggerAgent::addDebugger(QV4::Debugging::V4Debugger *debugger)
if (breakPoint.enabled)
debugger->addBreakPoint(breakPoint.fileName, breakPoint.lineNr, breakPoint.condition);
- connect(debugger, SIGNAL(destroyed(QObject*)),
- this, SLOT(handleDebuggerDeleted(QObject*)));
- connect(debugger, SIGNAL(sourcesCollected(QV4::Debugging::V4Debugger*,QStringList,int)),
- this, SLOT(sourcesCollected(QV4::Debugging::V4Debugger*,QStringList,int)),
- Qt::QueuedConnection);
- connect(debugger,
- SIGNAL(debuggerPaused(QV4::Debugging::V4Debugger*,QV4::Debugging::PauseReason)),
- this, SLOT(debuggerPaused(QV4::Debugging::V4Debugger*,QV4::Debugging::PauseReason)),
+ connect(debugger, &QObject::destroyed, this, &QV4DebuggerAgent::handleDebuggerDeleted);
+ connect(debugger, &QV4Debugger::debuggerPaused, this, &QV4DebuggerAgent::debuggerPaused,
Qt::QueuedConnection);
}
-void QV4DebuggerAgent::removeDebugger(QV4::Debugging::V4Debugger *debugger)
+void QV4DebuggerAgent::removeDebugger(QV4Debugger *debugger)
{
m_debuggers.removeAll(debugger);
- disconnect(debugger, SIGNAL(destroyed(QObject*)),
- this, SLOT(handleDebuggerDeleted(QObject*)));
- disconnect(debugger, SIGNAL(sourcesCollected(QV4::Debugging::V4Debugger*,QStringList,int)),
- this, SLOT(sourcesCollected(QV4::Debugging::V4Debugger*,QStringList,int)));
- disconnect(debugger,
- SIGNAL(debuggerPaused(QV4::Debugging::V4Debugger*,QV4::Debugging::PauseReason)),
- this,
- SLOT(debuggerPaused(QV4::Debugging::V4Debugger*,QV4::Debugging::PauseReason)));
+ disconnect(debugger, &QObject::destroyed, this, &QV4DebuggerAgent::handleDebuggerDeleted);
+ disconnect(debugger, &QV4Debugger::debuggerPaused, this, &QV4DebuggerAgent::debuggerPaused);
+}
+
+const QList<QV4Debugger *> &QV4DebuggerAgent::debuggers()
+{
+ return m_debuggers;
}
void QV4DebuggerAgent::handleDebuggerDeleted(QObject *debugger)
{
- m_debuggers.removeAll(static_cast<QV4::Debugging::V4Debugger *>(debugger));
+ m_debuggers.removeAll(static_cast<QV4Debugger *>(debugger));
}
-void QV4DebuggerAgent::pause(QV4::Debugging::V4Debugger *debugger) const
+void QV4DebuggerAgent::pause(QV4Debugger *debugger) const
{
debugger->pause();
}
void QV4DebuggerAgent::pauseAll() const
{
- foreach (QV4::Debugging::V4Debugger *debugger, m_debuggers)
+ foreach (QV4Debugger *debugger, m_debuggers)
pause(debugger);
}
void QV4DebuggerAgent::resumeAll() const
{
- foreach (QV4::Debugging::V4Debugger *debugger, m_debuggers)
- if (debugger->state() == QV4::Debugging::V4Debugger::Paused)
- debugger->resume(QV4::Debugging::V4Debugger::FullThrottle);
+ foreach (QV4Debugger *debugger, m_debuggers)
+ if (debugger->state() == QV4Debugger::Paused)
+ debugger->resume(QV4Debugger::FullThrottle);
}
int QV4DebuggerAgent::addBreakPoint(const QString &fileName, int lineNumber, bool enabled, const QString &condition)
{
if (enabled)
- foreach (QV4::Debugging::V4Debugger *debugger, m_debuggers)
+ foreach (QV4Debugger *debugger, m_debuggers)
debugger->addBreakPoint(fileName, lineNumber, condition);
int id = m_breakPoints.size();
@@ -204,7 +172,7 @@ void QV4DebuggerAgent::removeBreakPoint(int id)
m_breakPoints.remove(id);
if (breakPoint.enabled)
- foreach (QV4::Debugging::V4Debugger *debugger, m_debuggers)
+ foreach (QV4Debugger *debugger, m_debuggers)
debugger->removeBreakPoint(breakPoint.fileName, breakPoint.lineNr);
}
@@ -222,7 +190,7 @@ void QV4DebuggerAgent::enableBreakPoint(int id, bool onoff)
return;
breakPoint.enabled = onoff;
- foreach (QV4::Debugging::V4Debugger *debugger, m_debuggers) {
+ foreach (QV4Debugger *debugger, m_debuggers) {
if (onoff)
debugger->addBreakPoint(breakPoint.fileName, breakPoint.lineNr, breakPoint.condition);
else
@@ -245,9 +213,15 @@ void QV4DebuggerAgent::setBreakOnThrow(bool onoff)
{
if (onoff != m_breakOnThrow) {
m_breakOnThrow = onoff;
- foreach (QV4::Debugging::V4Debugger *debugger, m_debuggers)
+ foreach (QV4Debugger *debugger, m_debuggers)
debugger->setBreakOnThrow(onoff);
}
}
+void QV4DebuggerAgent::clearAllPauseRequests()
+{
+ foreach (QV4Debugger *debugger, m_debuggers)
+ debugger->clearPauseRequest();
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.h b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.h
index eafb408e7a..dea9d74088 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.h
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.h
@@ -34,7 +34,7 @@
#ifndef QV4DEBUGGERAGENT_H
#define QV4DEBUGGERAGENT_H
-#include <private/qv4debugging_p.h>
+#include "qv4debugger.h"
QT_BEGIN_NAMESPACE
@@ -46,13 +46,14 @@ class QV4DebuggerAgent : public QObject
public:
QV4DebuggerAgent(QV4DebugServiceImpl *m_debugService);
- QV4::Debugging::V4Debugger *firstDebugger() const;
+ QV4Debugger *pausedDebugger() const;
bool isRunning() const;
- void addDebugger(QV4::Debugging::V4Debugger *debugger);
- void removeDebugger(QV4::Debugging::V4Debugger *debugger);
+ void addDebugger(QV4Debugger *debugger);
+ void removeDebugger(QV4Debugger *debugger);
+ const QList<QV4Debugger *> &debuggers();
- void pause(QV4::Debugging::V4Debugger *debugger) const;
+ void pause(QV4Debugger *debugger) const;
void pauseAll() const;
void resumeAll() const;
int addBreakPoint(const QString &fileName, int lineNumber, bool enabled = true, const QString &condition = QString());
@@ -63,15 +64,14 @@ public:
bool breakOnThrow() const { return m_breakOnThrow; }
void setBreakOnThrow(bool onoff);
+ void clearAllPauseRequests();
public slots:
- void debuggerPaused(QV4::Debugging::V4Debugger *debugger, QV4::Debugging::PauseReason reason);
- void sourcesCollected(QV4::Debugging::V4Debugger *debugger, const QStringList &sources,
- int requestSequenceNr);
+ void debuggerPaused(QV4Debugger *debugger, QV4Debugger::PauseReason reason);
void handleDebuggerDeleted(QObject *debugger);
private:
- QList<QV4::Debugging::V4Debugger *> m_debuggers;
+ QList<QV4Debugger *> m_debuggers;
struct BreakPoint {
QString fileName;
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
index 5233a09992..dcf1fe8335 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
@@ -33,11 +33,12 @@
#include "qv4debugservice.h"
#include "qqmlengine.h"
+#include "qqmldebugpacket.h"
+
#include <private/qv4engine_p.h>
#include <private/qv4isel_moth_p.h>
#include <private/qv4function_p.h>
#include <private/qqmldebugconnector_p.h>
-
#include <private/qv8engine_p.h>
#include <QtCore/QJsonArray>
@@ -63,7 +64,6 @@ QT_BEGIN_NAMESPACE
class V8CommandHandler;
class UnknownV8CommandHandler;
-int QV4DebugServiceImpl::debuggerIndex = 0;
int QV4DebugServiceImpl::sequence = 0;
class V8CommandHandler
@@ -104,7 +104,7 @@ protected:
void addCommand() { response.insert(QStringLiteral("command"), cmd); }
void addRequestSequence() { response.insert(QStringLiteral("request_seq"), seq); }
void addSuccess(bool success) { response.insert(QStringLiteral("success"), success); }
- void addBody(const QJsonObject &body)
+ void addBody(const QJsonValue &body)
{
response.insert(QStringLiteral("body"), body);
}
@@ -114,9 +114,9 @@ protected:
response.insert(QStringLiteral("running"), debugService->debuggerAgent.isRunning());
}
- void addRefs()
+ void addRefs(const QJsonArray &refs)
{
- response.insert(QStringLiteral("refs"), debugService->buildRefs());
+ response.insert(QStringLiteral("refs"), refs);
}
void createErrorResponse(const QString &msg)
@@ -169,6 +169,7 @@ public:
QJsonObject body;
body.insert(QStringLiteral("V8Version"),
QLatin1String("this is not V8, this is V4 in Qt " QT_VERSION_STR));
+ body.insert(QStringLiteral("UnpausedEvaluate"), true);
addBody(body);
}
};
@@ -271,7 +272,11 @@ public:
int toFrame = arguments.value(QStringLiteral("toFrame")).toInt(fromFrame + 10);
// no idea what the bottom property is for, so we'll ignore it.
- QV4::Debugging::V4Debugger *debugger = debugService->debuggerAgent.firstDebugger();
+ QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
+ if (!debugger) {
+ createErrorResponse(QStringLiteral("Debugger has to be paused to retrieve backtraces."));
+ return;
+ }
QJsonArray frameArray;
QVector<QV4::StackFrame> frames = debugger->stackTrace(toFrame);
@@ -292,7 +297,7 @@ public:
body.insert(QStringLiteral("frames"), frameArray);
}
addBody(body);
- addRefs();
+ addRefs(debugger->collector()->flushCollectedRefs());
}
};
@@ -308,7 +313,12 @@ public:
const int frameNr = arguments.value(QStringLiteral("number")).toInt(
debugService->selectedFrame());
- QV4::Debugging::V4Debugger *debugger = debugService->debuggerAgent.firstDebugger();
+ QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
+ if (!debugger) {
+ createErrorResponse(QStringLiteral("Debugger has to be paused to retrieve frames."));
+ return;
+ }
+
QVector<QV4::StackFrame> frames = debugger->stackTrace(frameNr + 1);
if (frameNr < 0 || frameNr >= frames.size()) {
createErrorResponse(QStringLiteral("frame command has invalid frame number"));
@@ -324,7 +334,7 @@ public:
addSuccess(true);
addRunning();
addBody(frame);
- addRefs();
+ addRefs(debugger->collector()->flushCollectedRefs());
}
};
@@ -341,7 +351,12 @@ public:
debugService->selectedFrame());
const int scopeNr = arguments.value(QStringLiteral("number")).toInt(0);
- QV4::Debugging::V4Debugger *debugger = debugService->debuggerAgent.firstDebugger();
+ QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
+ if (!debugger) {
+ createErrorResponse(QStringLiteral("Debugger has to be paused to retrieve scope."));
+ return;
+ }
+
QVector<QV4::StackFrame> frames = debugger->stackTrace(frameNr + 1);
if (frameNr < 0 || frameNr >= frames.size()) {
createErrorResponse(QStringLiteral("scope command has invalid frame number"));
@@ -360,7 +375,7 @@ public:
addSuccess(true);
addRunning();
addBody(scope);
- addRefs();
+ addRefs(debugger->collector()->flushCollectedRefs());
}
};
@@ -375,17 +390,32 @@ public:
QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
QJsonArray handles = arguments.value(QStringLiteral("handles")).toArray();
- QJsonObject body;
- foreach (const QJsonValue &handle, handles)
- body[QString::number(handle.toInt())] = debugService->lookup(handle.toInt());
+ QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
+ if (!debugger) {
+ const QList<QV4Debugger *> &debuggers = debugService->debuggerAgent.debuggers();
+ if (debuggers.count() > 1) {
+ createErrorResponse(QStringLiteral("Cannot lookup values if multiple debuggers are running and none is paused"));
+ return;
+ } else if (debuggers.count() == 0) {
+ createErrorResponse(QStringLiteral("No debuggers available to lookup values"));
+ return;
+ }
+ debugger = debuggers.first();
+ }
- // response:
- addCommand();
- addRequestSequence();
- addSuccess(true);
- addRunning();
- addBody(body);
- addRefs();
+ ValueLookupJob job(handles, debugger->collector());
+ debugger->runInEngine(&job);
+ if (!job.exceptionMessage().isEmpty()) {
+ createErrorResponse(job.exceptionMessage());
+ } else {
+ // response:
+ addCommand();
+ addRequestSequence();
+ addSuccess(true);
+ addRunning();
+ addBody(job.returnValue());
+ addRefs(job.refs());
+ }
}
};
@@ -399,10 +429,15 @@ public:
// decypher the payload:
QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
- QV4::Debugging::V4Debugger *debugger = debugService->debuggerAgent.firstDebugger();
+ QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
+ if (!debugger) {
+ createErrorResponse(QStringLiteral("Debugger has to be paused in order to continue."));
+ return;
+ }
+ debugService->debuggerAgent.clearAllPauseRequests();
if (arguments.empty()) {
- debugger->resume(QV4::Debugging::V4Debugger::FullThrottle);
+ debugger->resume(QV4Debugger::FullThrottle);
} else {
QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
QString stepAction = arguments.value(QStringLiteral("stepaction")).toString();
@@ -411,11 +446,11 @@ public:
qWarning() << "Step count other than 1 is not supported.";
if (stepAction == QStringLiteral("in")) {
- debugger->resume(QV4::Debugging::V4Debugger::StepIn);
+ debugger->resume(QV4Debugger::StepIn);
} else if (stepAction == QStringLiteral("out")) {
- debugger->resume(QV4::Debugging::V4Debugger::StepOut);
+ debugger->resume(QV4Debugger::StepOut);
} else if (stepAction == QStringLiteral("next")) {
- debugger->resume(QV4::Debugging::V4Debugger::StepOver);
+ debugger->resume(QV4Debugger::StepOver);
} else {
createErrorResponse(QStringLiteral("continue command has invalid stepaction"));
return;
@@ -507,11 +542,28 @@ public:
}
// do it:
- QV4::Debugging::V4Debugger *debugger = debugService->debuggerAgent.firstDebugger();
- GatherSourcesJob job(debugger->engine(), requestSequenceNr());
+ QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
+ if (!debugger) {
+ createErrorResponse(QStringLiteral("Debugger has to be paused to retrieve scripts."));
+ return;
+ }
+
+ GatherSourcesJob job(debugger->engine());
debugger->runInEngine(&job);
- // response will be send by
+ QJsonArray body;
+ foreach (const QString &source, job.result()) {
+ QJsonObject src;
+ src[QLatin1String("name")] = source;
+ src[QLatin1String("scriptType")] = 4;
+ body.append(src);
+ }
+
+ addSuccess(true);
+ addRunning();
+ addBody(body);
+ addCommand();
+ addRequestSequence();
}
};
@@ -550,28 +602,36 @@ public:
virtual void handleRequest()
{
- QV4::Debugging::V4Debugger *debugger = debugService->debuggerAgent.firstDebugger();
- if (debugger->state() == QV4::Debugging::V4Debugger::Paused) {
- QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
- QString expression = arguments.value(QStringLiteral("expression")).toString();
- const int frame = arguments.value(QStringLiteral("frame")).toInt(0);
-
- QV4DataCollector *collector = debugService->collector();
- RefHolder holder(collector, debugService->refs());
- ExpressionEvalJob job(debugger->engine(), frame, expression, collector);
- debugger->runInEngine(&job);
- if (job.hasExeption()) {
- createErrorResponse(job.exceptionMessage());
- } else {
- addCommand();
- addRequestSequence();
- addSuccess(true);
- addRunning();
- addBody(collector->lookupRef(debugService->refs()->last()));
- addRefs();
+ QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
+ QString expression = arguments.value(QStringLiteral("expression")).toString();
+ int frame = -1;
+
+ QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
+ if (!debugger) {
+ const QList<QV4Debugger *> &debuggers = debugService->debuggerAgent.debuggers();
+ if (debuggers.count() > 1) {
+ createErrorResponse(QStringLiteral("Cannot evaluate expressions if multiple debuggers are running and none is paused"));
+ return;
+ } else if (debuggers.count() == 0) {
+ createErrorResponse(QStringLiteral("No debuggers available to evaluate expressions"));
+ return;
}
+ debugger = debuggers.first();
} else {
- createErrorResponse(QStringLiteral("Debugger has to be paused for evaluate to work."));
+ frame = arguments.value(QStringLiteral("frame")).toInt(0);
+ }
+
+ ExpressionEvalJob job(debugger->engine(), frame, expression, debugger->collector());
+ debugger->runInEngine(&job);
+ if (job.hasExeption()) {
+ createErrorResponse(job.exceptionMessage());
+ } else {
+ addCommand();
+ addRequestSequence();
+ addSuccess(true);
+ addRunning();
+ addBody(job.returnValue());
+ addRefs(job.refs());
}
}
};
@@ -593,7 +653,7 @@ V8CommandHandler *QV4DebugServiceImpl::v8CommandHandler(const QString &command)
QV4DebugServiceImpl::QV4DebugServiceImpl(QObject *parent) :
QQmlConfigurableDebugService<QV4DebugService>(1, parent),
- debuggerAgent(this), version(1), theSelectedFrame(0),
+ debuggerAgent(this), theSelectedFrame(0),
unknownV8CommandHandler(new UnknownV8CommandHandler)
{
addHandler(new V8VersionRequest);
@@ -615,7 +675,7 @@ QV4DebugServiceImpl::~QV4DebugServiceImpl()
qDeleteAll(handlers);
}
-void QV4DebugServiceImpl::engineAboutToBeAdded(QQmlEngine *engine)
+void QV4DebugServiceImpl::engineAdded(QJSEngine *engine)
{
QMutexLocker lock(&m_configMutex);
if (engine) {
@@ -623,37 +683,26 @@ void QV4DebugServiceImpl::engineAboutToBeAdded(QQmlEngine *engine)
if (QQmlDebugConnector *server = QQmlDebugConnector::instance()) {
if (ee) {
ee->iselFactory.reset(new QV4::Moth::ISelFactory);
- QV4::Debugging::V4Debugger *debugger = new QV4::Debugging::V4Debugger(ee);
+ QV4Debugger *debugger = new QV4Debugger(ee);
if (state() == Enabled)
ee->setDebugger(debugger);
- debuggerMap.insert(debuggerIndex++, debugger);
debuggerAgent.addDebugger(debugger);
debuggerAgent.moveToThread(server->thread());
}
}
}
- QQmlConfigurableDebugService<QV4DebugService>::engineAboutToBeAdded(engine);
+ QQmlConfigurableDebugService<QV4DebugService>::engineAdded(engine);
}
-void QV4DebugServiceImpl::engineAboutToBeRemoved(QQmlEngine *engine)
+void QV4DebugServiceImpl::engineAboutToBeRemoved(QJSEngine *engine)
{
QMutexLocker lock(&m_configMutex);
if (engine){
const QV4::ExecutionEngine *ee = QV8Engine::getV4(engine->handle());
if (ee) {
- QV4::Debugging::V4Debugger *debugger
- = qobject_cast<QV4::Debugging::V4Debugger *>(ee->debugger);
- if (debugger) {
- typedef QMap<int, QV4::Debugging::V4Debugger *>::const_iterator DebuggerMapIterator;
- const DebuggerMapIterator end = debuggerMap.constEnd();
- for (DebuggerMapIterator i = debuggerMap.constBegin(); i != end; ++i) {
- if (i.value() == debugger) {
- debuggerMap.remove(i.key());
- break;
- }
- }
+ QV4Debugger *debugger = qobject_cast<QV4Debugger *>(ee->debugger);
+ if (debugger)
debuggerAgent.removeDebugger(debugger);
- }
}
}
QQmlConfigurableDebugService<QV4DebugService>::engineAboutToBeRemoved(engine);
@@ -663,12 +712,10 @@ void QV4DebugServiceImpl::stateAboutToBeChanged(State state)
{
QMutexLocker lock(&m_configMutex);
if (state == Enabled) {
- typedef QMap<int, QV4::Debugging::V4Debugger *>::const_iterator DebuggerMapIterator;
- const DebuggerMapIterator end = debuggerMap.constEnd();
- for (DebuggerMapIterator i = debuggerMap.constBegin(); i != end; ++i) {
- QV4::ExecutionEngine *ee = i.value()->engine();
+ foreach (QV4Debugger *debugger, debuggerAgent.debuggers()) {
+ QV4::ExecutionEngine *ee = debugger->engine();
if (!ee->debugger)
- ee->setDebugger(i.value());
+ ee->setDebugger(debugger);
}
}
QQmlConfigurableDebugService<QV4DebugService>::stateAboutToBeChanged(state);
@@ -696,7 +743,7 @@ void QV4DebugServiceImpl::messageReceived(const QByteArray &message)
{
QMutexLocker lock(&m_configMutex);
- QQmlDebugStream ms(message);
+ QQmlDebugPacket ms(message);
QByteArray header;
ms >> header;
@@ -737,11 +784,10 @@ void QV4DebugServiceImpl::messageReceived(const QByteArray &message)
void QV4DebugServiceImpl::sendSomethingToSomebody(const char *type, int magicNumber)
{
- QByteArray response;
- QQmlDebugStream rs(&response, QIODevice::WriteOnly);
+ QQmlDebugPacket rs;
rs << QByteArray(type)
- << QByteArray::number(version) << QByteArray::number(magicNumber);
- emit messageToClient(name(), packMessage(type, response));
+ << QByteArray::number(int(version())) << QByteArray::number(magicNumber);
+ emit messageToClient(name(), packMessage(type, rs.data()));
}
void QV4DebugServiceImpl::handleV8Request(const QByteArray &payload)
@@ -761,11 +807,10 @@ void QV4DebugServiceImpl::handleV8Request(const QByteArray &payload)
QByteArray QV4DebugServiceImpl::packMessage(const QByteArray &command, const QByteArray &message)
{
- QByteArray reply;
- QQmlDebugStream rs(&reply, QIODevice::WriteOnly);
+ QQmlDebugPacket rs;
static const QByteArray cmd("V8DEBUG");
rs << cmd << command << message;
- return reply;
+ return rs.data();
}
void QV4DebugServiceImpl::send(QJsonObject v8Payload)
@@ -784,51 +829,42 @@ void QV4DebugServiceImpl::send(QJsonObject v8Payload)
emit messageToClient(name(), packMessage("v8message", responseData));
}
-void QV4DebugServiceImpl::clearHandles(QV4::ExecutionEngine *engine)
-{
- theCollector.reset(new QV4DataCollector(engine));
-}
-
QJsonObject QV4DebugServiceImpl::buildFrame(const QV4::StackFrame &stackFrame, int frameNr,
- QV4::Debugging::V4Debugger *debugger)
+ QV4Debugger *debugger)
{
QV4DataCollector::Ref ref;
QJsonObject frame;
frame[QLatin1String("index")] = frameNr;
frame[QLatin1String("debuggerFrame")] = false;
- ref = theCollector->addFunctionRef(stackFrame.function);
- collectedRefs.append(ref);
+ ref = debugger->collector()->addFunctionRef(stackFrame.function);
frame[QLatin1String("func")] = toRef(ref);
- ref = theCollector->addScriptRef(stackFrame.source);
- collectedRefs.append(ref);
+ ref = debugger->collector()->addScriptRef(stackFrame.source);
frame[QLatin1String("script")] = toRef(ref);
frame[QLatin1String("line")] = stackFrame.line - 1;
if (stackFrame.column >= 0)
frame[QLatin1String("column")] = stackFrame.column;
QJsonArray scopes;
- if (debugger->state() == QV4::Debugging::V4Debugger::Paused) {
- RefHolder holder(theCollector.data(), &collectedRefs);
- bool foundThis = false;
- ThisCollectJob job(debugger->engine(), theCollector.data(), frameNr, &foundThis);
- debugger->runInEngine(&job);
- if (foundThis)
- frame[QLatin1String("receiver")] = toRef(collectedRefs.last());
+ Q_ASSERT (debugger->state() == QV4Debugger::Paused);
+
+ ThisCollectJob job(debugger->engine(), debugger->collector(), frameNr);
+ debugger->runInEngine(&job);
+ if (job.foundRef() != QV4DataCollector::s_invalidRef)
+ frame[QLatin1String("receiver")] = toRef(job.foundRef());
+
+ // Only type and index are used by Qt Creator, so we keep it easy:
+ QVector<QV4::Heap::ExecutionContext::ContextType> scopeTypes =
+ QV4DataCollector::getScopeTypes(debugger->engine(), frameNr);
+ for (int i = 0, ei = scopeTypes.count(); i != ei; ++i) {
+ int type = encodeScopeType(scopeTypes[i]);
+ if (type == -1)
+ continue;
- // Only type and index are used by Qt Creator, so we keep it easy:
- QVector<QV4::Heap::ExecutionContext::ContextType> scopeTypes =
- QV4DataCollector::getScopeTypes(debugger->engine(), frameNr);
- for (int i = 0, ei = scopeTypes.count(); i != ei; ++i) {
- int type = encodeScopeType(scopeTypes[i]);
- if (type == -1)
- continue;
-
- QJsonObject scope;
- scope[QLatin1String("index")] = i;
- scope[QLatin1String("type")] = type;
- scopes.push_back(scope);
- }
+ QJsonObject scope;
+ scope[QLatin1String("index")] = i;
+ scope[QLatin1String("type")] = type;
+ scopes.push_back(scope);
}
frame[QLatin1String("scopes")] = scopes;
@@ -857,16 +893,14 @@ int QV4DebugServiceImpl::encodeScopeType(QV4::Heap::ExecutionContext::ContextTyp
}
}
-QJsonObject QV4DebugServiceImpl::buildScope(int frameNr, int scopeNr,
- QV4::Debugging::V4Debugger *debugger)
+QJsonObject QV4DebugServiceImpl::buildScope(int frameNr, int scopeNr, QV4Debugger *debugger)
{
QJsonObject scope;
QJsonObject object;
- RefHolder holder(theCollector.data(), &collectedRefs);
- theCollector->collectScope(&object, debugger, frameNr, scopeNr);
+ debugger->collector()->collectScope(&object, debugger, frameNr, scopeNr);
- if (debugger->state() == QV4::Debugging::V4Debugger::Paused) {
+ if (debugger->state() == QV4Debugger::Paused) {
QVector<QV4::Heap::ExecutionContext::ContextType> scopeTypes =
QV4DataCollector::getScopeTypes(debugger->engine(), frameNr);
scope[QLatin1String("type")] = encodeScopeType(scopeTypes[scopeNr]);
@@ -880,27 +914,6 @@ QJsonObject QV4DebugServiceImpl::buildScope(int frameNr, int scopeNr,
return scope;
}
-QJsonValue QV4DebugServiceImpl::lookup(QV4DataCollector::Ref refId)
-{
- RefHolder holder(theCollector.data(), &collectedRefs);
- return theCollector->lookupRef(refId);
-}
-
-QJsonArray QV4DebugServiceImpl::buildRefs()
-{
- QJsonArray refs;
- std::sort(collectedRefs.begin(), collectedRefs.end());
- for (int i = 0, ei = collectedRefs.size(); i != ei; ++i) {
- QV4DataCollector::Ref ref = collectedRefs.at(i);
- if (i > 0 && ref == collectedRefs.at(i - 1))
- continue;
- refs.append(lookup(ref));
- }
-
- collectedRefs.clear();
- return refs;
-}
-
QJsonValue QV4DebugServiceImpl::toRef(QV4DataCollector::Ref ref)
{
QJsonObject dict;
@@ -908,16 +921,6 @@ QJsonValue QV4DebugServiceImpl::toRef(QV4DataCollector::Ref ref)
return dict;
}
-QV4DataCollector *QV4DebugServiceImpl::collector() const
-{
- return theCollector.data();
-}
-
-QV4DataCollector::Refs *QV4DebugServiceImpl::refs()
-{
- return &collectedRefs;
-}
-
void QV4DebugServiceImpl::selectFrame(int frameNr)
{
theSelectedFrame = frameNr;
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h
index 273e5ffd62..2d9932b838 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h
@@ -57,7 +57,6 @@ QT_BEGIN_NAMESPACE
namespace QV4 { struct ExecutionEngine; }
-class QQmlEngine;
class VariableCollector;
class V8CommandHandler;
class UnknownV8CommandHandler;
@@ -68,34 +67,27 @@ class QV4DebugServiceImpl : public QQmlConfigurableDebugService<QV4DebugService>
Q_OBJECT
public:
explicit QV4DebugServiceImpl(QObject *parent = 0);
- ~QV4DebugServiceImpl();
+ ~QV4DebugServiceImpl() Q_DECL_OVERRIDE;
- void engineAboutToBeAdded(QQmlEngine *engine);
- void engineAboutToBeRemoved(QQmlEngine *engine);
+ void engineAdded(QJSEngine *engine) Q_DECL_OVERRIDE;
+ void engineAboutToBeRemoved(QJSEngine *engine) Q_DECL_OVERRIDE;
- void stateAboutToBeChanged(State state);
+ void stateAboutToBeChanged(State state) Q_DECL_OVERRIDE;
- void signalEmitted(const QString &signal);
+ void signalEmitted(const QString &signal) Q_DECL_OVERRIDE;
void send(QJsonObject v8Payload);
- QJsonObject buildScope(int frameNr, int scopeNr, QV4::Debugging::V4Debugger *debugger);
- QJsonArray buildRefs();
- QJsonValue lookup(QV4DataCollector::Ref refId);
+ QJsonObject buildScope(int frameNr, int scopeNr, QV4Debugger *debugger);
QJsonValue toRef(QV4DataCollector::Ref ref);
- QJsonObject buildFrame(const QV4::StackFrame &stackFrame, int frameNr,
- QV4::Debugging::V4Debugger *debugger);
+ QJsonObject buildFrame(const QV4::StackFrame &stackFrame, int frameNr, QV4Debugger *debugger);
int selectedFrame() const;
void selectFrame(int frameNr);
- void clearHandles(QV4::ExecutionEngine *engine);
-
- QV4DataCollector *collector() const;
QV4DebuggerAgent debuggerAgent;
- QV4DataCollector::Refs *refs();
protected:
- void messageReceived(const QByteArray &);
+ void messageReceived(const QByteArray &) Q_DECL_OVERRIDE;
void sendSomethingToSomebody(const char *type, int magicNumber = 1);
private:
@@ -109,13 +101,8 @@ private:
int encodeScopeType(QV4::Heap::ExecutionContext::ContextType scopeType);
QStringList breakOnSignals;
- QMap<int, QV4::Debugging::V4Debugger *> debuggerMap;
- static int debuggerIndex;
static int sequence;
- const int version;
- QV4DataCollector::Refs collectedRefs;
- QScopedPointer<QV4DataCollector> theCollector;
int theSelectedFrame;
void addHandler(V8CommandHandler* handler);
diff --git a/src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.cpp b/src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.cpp
index fa6dca7aca..daf620805f 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.cpp
+++ b/src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.cpp
@@ -33,6 +33,7 @@
#include "abstractviewinspector.h"
#include "abstracttool.h"
+#include "qqmldebugpacket.h"
#include <QtCore/QDebug>
#include <QtQml/QQmlEngine>
@@ -262,18 +263,16 @@ void AbstractViewInspector::onQmlObjectDestroyed(QObject *object)
QPair<int, int> ids = m_hashObjectsTobeDestroyed.take(object);
- QByteArray response;
-
- QQmlDebugStream rs(&response, QIODevice::WriteOnly);
+ QQmlDebugPacket rs;
rs << QByteArray(RESPONSE) << ids.first << true << ids.second;
- emit m_debugService->messageToClient(m_debugService->name(), response);
+ emit m_debugService->messageToClient(m_debugService->name(), rs.data());
}
void AbstractViewInspector::handleMessage(const QByteArray &message)
{
bool success = true;
- QQmlDebugStream ds(message);
+ QQmlDebugPacket ds(message);
QByteArray type;
ds >> type;
@@ -358,16 +357,14 @@ void AbstractViewInspector::handleMessage(const QByteArray &message)
}
- QByteArray response;
- QQmlDebugStream rs(&response, QIODevice::WriteOnly);
+ QQmlDebugPacket rs;
rs << QByteArray(RESPONSE) << requestId << success;
- emit m_debugService->messageToClient(m_debugService->name(), response);
+ emit m_debugService->messageToClient(m_debugService->name(), rs.data());
}
void AbstractViewInspector::sendCurrentObjects(const QList<QObject*> &objects)
{
- QByteArray message;
- QQmlDebugStream ds(&message, QIODevice::WriteOnly);
+ QQmlDebugPacket ds;
ds << QByteArray(EVENT) << m_eventId++ << QByteArray(SELECT);
@@ -377,7 +374,7 @@ void AbstractViewInspector::sendCurrentObjects(const QList<QObject*> &objects)
debugIds << QQmlDebugService::idForObject(object);
ds << debugIds;
- emit m_debugService->messageToClient(m_debugService->name(), message);
+ emit m_debugService->messageToClient(m_debugService->name(), ds.data());
}
void AbstractViewInspector::sendQmlFileReloaded(bool success)
@@ -387,10 +384,10 @@ void AbstractViewInspector::sendQmlFileReloaded(bool success)
QByteArray response;
- QQmlDebugStream rs(&response, QIODevice::WriteOnly);
+ QQmlDebugPacket rs;
rs << QByteArray(RESPONSE) << m_reloadEventId << success;
- emit m_debugService->messageToClient(m_debugService->name(), response);
+ emit m_debugService->messageToClient(m_debugService->name(), rs.data());
}
QString AbstractViewInspector::idStringForObject(QObject *obj) const
diff --git a/src/plugins/qmltooling/qmldbg_inspector/inspecttool.cpp b/src/plugins/qmltooling/qmldbg_inspector/inspecttool.cpp
index cc6b4ffb8c..0e12f29869 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/inspecttool.cpp
+++ b/src/plugins/qmltooling/qmldbg_inspector/inspecttool.cpp
@@ -347,8 +347,6 @@ qreal InspectTool::nextZoomScale(ZoomDirection direction)
}
return zoomScales.first();
}
-
- return 1.0f;
}
void InspectTool::initializeDrag(const QPointF &pos)
diff --git a/src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro b/src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro
index 1c3e5f387b..dd5cc8ceef 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro
+++ b/src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro
@@ -1,5 +1,5 @@
TARGET = qmldbg_inspector
-QT += qml-private quick-private core-private gui-private
+QT += qml-private quick-private core-private gui-private packetprotocol-private
PLUGIN_TYPE = qmltooling
PLUGIN_CLASS_NAME = QQmlInspectorServiceFactory
@@ -16,6 +16,7 @@ SOURCES += \
$$PWD/qqmlinspectorservice.cpp
HEADERS += \
+ $$PWD/../shared/qqmldebugpacket.h \
$$PWD/highlight.h \
$$PWD/qquickviewinspector.h \
$$PWD/qqmlinspectorservicefactory.h \
diff --git a/src/plugins/qmltooling/qmldbg_inspector/qqmlinspectorservice.cpp b/src/plugins/qmltooling/qmldbg_inspector/qqmlinspectorservice.cpp
index 1707091df3..6b786024f8 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/qqmlinspectorservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_inspector/qqmlinspectorservice.cpp
@@ -50,12 +50,12 @@ class QQmlInspectorServiceImpl : public QQmlInspectorService
public:
QQmlInspectorServiceImpl(QObject *parent = 0);
- void addView(QObject *);
- void removeView(QObject *);
+ void addView(QObject *) Q_DECL_OVERRIDE;
+ void removeView(QObject *) Q_DECL_OVERRIDE;
protected:
- virtual void stateChanged(State state);
- virtual void messageReceived(const QByteArray &);
+ virtual void stateChanged(State state) Q_DECL_OVERRIDE;
+ virtual void messageReceived(const QByteArray &) Q_DECL_OVERRIDE;
private Q_SLOTS:
void processMessage(const QByteArray &message);
diff --git a/src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp b/src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp
index 057bf9523e..478cbf5514 100644
--- a/src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp
+++ b/src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp
@@ -32,7 +32,6 @@
****************************************************************************/
#include "qlocalclientconnectionfactory.h"
-#include "qpacketprotocol.h"
#include "qqmldebugserver.h"
#include <QtCore/qplugin.h>
diff --git a/src/plugins/qmltooling/qmldbg_native/qmldbg_native.pro b/src/plugins/qmltooling/qmldbg_native/qmldbg_native.pro
index 7dc16b8c44..d490d77e50 100644
--- a/src/plugins/qmltooling/qmldbg_native/qmldbg_native.pro
+++ b/src/plugins/qmltooling/qmldbg_native/qmldbg_native.pro
@@ -1,12 +1,19 @@
TARGET = qmldbg_native
-QT += qml-private core-private
+QT += qml-private core-private packetprotocol-private
PLUGIN_TYPE = qmltooling
PLUGIN_CLASS_NAME = QQmlNativeDebugConnectorFactory
load(qt_plugin)
+HEADERS += \
+ $$PWD/../shared/qqmldebugpacket.h \
+ $$PWD/qqmlnativedebugconnector.h
+
SOURCES += \
$$PWD/qqmlnativedebugconnector.cpp
+INCLUDEPATH += $$PWD \
+ $$PWD/../shared
+
OTHER_FILES += \
$$PWD/qqmlnativedebugconnector.json
diff --git a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp
index 6621eafb27..fe94610496 100644
--- a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp
+++ b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp
@@ -31,18 +31,18 @@
**
****************************************************************************/
-#include <private/qqmldebugconnector_p.h>
-#include <private/qhooks_p.h>
+#include "qqmlnativedebugconnector.h"
+#include "qqmldebugpacket.h"
-#include <qqmlengine.h>
+#include <private/qhooks_p.h>
+#include <QtQml/qjsengine.h>
#include <QtCore/qdebug.h>
#include <QtCore/qjsonarray.h>
#include <QtCore/qjsondocument.h>
#include <QtCore/qjsonobject.h>
#include <QtCore/qjsonvalue.h>
#include <QtCore/qpointer.h>
-#include <QtCore/qvector.h>
//#define TRACE_PROTOCOL(s) qDebug() << s
#define TRACE_PROTOCOL(s)
@@ -65,7 +65,7 @@ Q_DECL_EXPORT void qt_qmlDebugConnectorOpen();
// member to some other place.
Q_DECL_EXPORT void qt_qmlDebugSetStreamVersion(int version)
{
- QQmlDebugStream::s_dataStreamVersion = version;
+ QQmlNativeDebugConnector::setDataStreamVersion(version);
}
@@ -172,33 +172,6 @@ Q_DECL_EXPORT void qt_qmlDebugConnectorOpen()
QT_BEGIN_NAMESPACE
-class QQmlNativeDebugConnector : public QQmlDebugConnector
-{
- Q_OBJECT
-
-public:
- QQmlNativeDebugConnector();
- ~QQmlNativeDebugConnector();
-
- bool blockingMode() const;
- QQmlDebugService *service(const QString &name) const;
- void addEngine(QQmlEngine *engine);
- void removeEngine(QQmlEngine *engine);
- bool addService(const QString &name, QQmlDebugService *service);
- bool removeService(const QString &name);
- bool open(const QVariantHash &configuration);
-
-private slots:
- void sendMessage(const QString &name, const QByteArray &message);
- void sendMessages(const QString &name, const QList<QByteArray> &messages);
-
-private:
- void announceObjectAvailability(const QString &objectType, QObject *object, bool available);
-
- QVector<QQmlDebugService *> m_services;
- bool m_blockingMode;
-};
-
QQmlNativeDebugConnector::QQmlNativeDebugConnector()
: m_blockingMode(false)
{
@@ -250,8 +223,10 @@ QQmlDebugService *QQmlNativeDebugConnector::service(const QString &name) const
return 0;
}
-void QQmlNativeDebugConnector::addEngine(QQmlEngine *engine)
+void QQmlNativeDebugConnector::addEngine(QJSEngine *engine)
{
+ Q_ASSERT(!m_engines.contains(engine));
+
TRACE_PROTOCOL("Add engine to connector:" << engine);
foreach (QQmlDebugService *service, m_services)
service->engineAboutToBeAdded(engine);
@@ -260,10 +235,14 @@ void QQmlNativeDebugConnector::addEngine(QQmlEngine *engine)
foreach (QQmlDebugService *service, m_services)
service->engineAdded(engine);
+
+ m_engines.append(engine);
}
-void QQmlNativeDebugConnector::removeEngine(QQmlEngine *engine)
+void QQmlNativeDebugConnector::removeEngine(QJSEngine *engine)
{
+ Q_ASSERT(m_engines.contains(engine));
+
TRACE_PROTOCOL("Remove engine from connector:" << engine);
foreach (QQmlDebugService *service, m_services)
service->engineAboutToBeRemoved(engine);
@@ -272,6 +251,13 @@ void QQmlNativeDebugConnector::removeEngine(QQmlEngine *engine)
foreach (QQmlDebugService *service, m_services)
service->engineRemoved(engine);
+
+ m_engines.removeOne(engine);
+}
+
+bool QQmlNativeDebugConnector::hasEngine(QJSEngine *engine) const
+{
+ return m_engines.contains(engine);
}
void QQmlNativeDebugConnector::announceObjectAvailability(const QString &objectType,
@@ -294,9 +280,8 @@ void QQmlNativeDebugConnector::announceObjectAvailability(const QString &objectT
bool QQmlNativeDebugConnector::addService(const QString &name, QQmlDebugService *service)
{
TRACE_PROTOCOL("Add service to connector: " << qPrintable(name) << service);
- for (QVector<QQmlDebugService *>::ConstIterator i = m_services.begin(); i != m_services.end();
- ++i) {
- if ((*i)->name() == name)
+ for (auto it = m_services.cbegin(), end = m_services.cend(); it != end; ++it) {
+ if ((*it)->name() == name)
return false;
}
@@ -338,6 +323,12 @@ bool QQmlNativeDebugConnector::open(const QVariantHash &configuration)
return true;
}
+void QQmlNativeDebugConnector::setDataStreamVersion(int version)
+{
+ Q_ASSERT(version <= QDataStream::Qt_DefaultCompiledVersion);
+ s_dataStreamVersion = version;
+}
+
void QQmlNativeDebugConnector::sendMessage(const QString &name, const QByteArray &message)
{
(*responseBuffer) += name.toUtf8() + ' ' + QByteArray::number(message.size()) + ' ' + message;
@@ -363,21 +354,9 @@ void QQmlNativeDebugConnector::sendMessages(const QString &name, const QList<QBy
sendMessage(name, messages.at(i));
}
-class QQmlNativeDebugConnectorFactory : public QQmlDebugConnectorFactory
+QQmlDebugConnector *QQmlNativeDebugConnectorFactory::create(const QString &key)
{
- Q_OBJECT
-
- Q_PLUGIN_METADATA(IID QQmlDebugConnectorFactory_iid FILE "qqmlnativedebugconnector.json")
-
-public:
- QQmlNativeDebugConnectorFactory() {}
-
- QQmlDebugConnector *create(const QString &key)
- {
- return key == QLatin1String("QQmlNativeDebugConnector") ? new QQmlNativeDebugConnector : 0;
- }
-};
+ return key == QLatin1String("QQmlNativeDebugConnector") ? new QQmlNativeDebugConnector : 0;
+}
QT_END_NAMESPACE
-
-#include "qqmlnativedebugconnector.moc"
diff --git a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.h b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.h
new file mode 100644
index 0000000000..c2eba9dfc4
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLNATIVEDEBUGCONNECTOR_H
+#define QQMLNATIVEDEBUGCONNECTOR_H
+
+#include <private/qqmldebugconnector_p.h>
+#include <QtCore/qvector.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQmlNativeDebugConnector : public QQmlDebugConnector
+{
+ Q_OBJECT
+
+public:
+ QQmlNativeDebugConnector();
+ ~QQmlNativeDebugConnector() Q_DECL_OVERRIDE;
+
+ bool blockingMode() const Q_DECL_OVERRIDE;
+ QQmlDebugService *service(const QString &name) const Q_DECL_OVERRIDE;
+ void addEngine(QJSEngine *engine) Q_DECL_OVERRIDE;
+ void removeEngine(QJSEngine *engine) Q_DECL_OVERRIDE;
+ bool hasEngine(QJSEngine *engine) const Q_DECL_OVERRIDE;
+ bool addService(const QString &name, QQmlDebugService *service) Q_DECL_OVERRIDE;
+ bool removeService(const QString &name) Q_DECL_OVERRIDE;
+ bool open(const QVariantHash &configuration) Q_DECL_OVERRIDE;
+ static void setDataStreamVersion(int version);
+
+private slots:
+ void sendMessage(const QString &name, const QByteArray &message);
+ void sendMessages(const QString &name, const QList<QByteArray> &messages);
+
+private:
+ void announceObjectAvailability(const QString &objectType, QObject *object, bool available);
+
+ QVector<QQmlDebugService *> m_services;
+ QVector<QJSEngine *> m_engines;
+ bool m_blockingMode;
+};
+
+class QQmlNativeDebugConnectorFactory : public QQmlDebugConnectorFactory
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID QQmlDebugConnectorFactory_iid FILE "qqmlnativedebugconnector.json")
+public:
+ QQmlDebugConnector *create(const QString &key);
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLNATIVEDEBUGCONNECTOR_H
+
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qmldbg_profiler.pro b/src/plugins/qmltooling/qmldbg_profiler/qmldbg_profiler.pro
index e1c4095d88..6efe9eacad 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qmldbg_profiler.pro
+++ b/src/plugins/qmltooling/qmldbg_profiler/qmldbg_profiler.pro
@@ -1,5 +1,5 @@
TARGET = qmldbg_profiler
-QT = qml-private core-private
+QT = qml-private core-private packetprotocol-private
PLUGIN_TYPE = qmltooling
PLUGIN_CLASS_NAME = QQmlProfilerServiceFactory
@@ -14,6 +14,7 @@ SOURCES += \
HEADERS += \
$$PWD/../shared/qqmlconfigurabledebugservice.h \
+ $$PWD/../shared/qqmldebugpacket.h \
$$PWD/qqmlenginecontrolservice.h \
$$PWD/qqmlprofileradapter.h \
$$PWD/qqmlprofilerservice.h \
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp
index 4f131ac481..4da279bb42 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp
@@ -32,25 +32,24 @@
****************************************************************************/
#include "qqmlenginecontrolservice.h"
-#include <QQmlEngine>
+#include "qqmldebugpacket.h"
+#include <QJSEngine>
QT_BEGIN_NAMESPACE
-const QString QQmlEngineControlService::s_key = QStringLiteral("EngineControl");
-
-QQmlEngineControlService::QQmlEngineControlService(QObject *parent) :
- QQmlDebugService(s_key, 1, parent)
+QQmlEngineControlServiceImpl::QQmlEngineControlServiceImpl(QObject *parent) :
+ QQmlEngineControlService(1, parent)
{
}
-void QQmlEngineControlService::messageReceived(const QByteArray &message)
+void QQmlEngineControlServiceImpl::messageReceived(const QByteArray &message)
{
QMutexLocker lock(&dataMutex);
- QQmlDebugStream d(message);
+ QQmlDebugPacket d(message);
int command;
int engineId;
d >> command >> engineId;
- QQmlEngine *engine = qobject_cast<QQmlEngine *>(objectForId(engineId));
+ QJSEngine *engine = qobject_cast<QJSEngine *>(objectForId(engineId));
if (command == StartWaitingEngine && startingEngines.contains(engine)) {
startingEngines.removeOne(engine);
emit attachedToEngine(engine);
@@ -60,7 +59,7 @@ void QQmlEngineControlService::messageReceived(const QByteArray &message)
}
}
-void QQmlEngineControlService::engineAboutToBeAdded(QQmlEngine *engine)
+void QQmlEngineControlServiceImpl::engineAboutToBeAdded(QJSEngine *engine)
{
QMutexLocker lock(&dataMutex);
if (state() == Enabled) {
@@ -73,7 +72,7 @@ void QQmlEngineControlService::engineAboutToBeAdded(QQmlEngine *engine)
}
}
-void QQmlEngineControlService::engineAboutToBeRemoved(QQmlEngine *engine)
+void QQmlEngineControlServiceImpl::engineAboutToBeRemoved(QJSEngine *engine)
{
QMutexLocker lock(&dataMutex);
if (state() == Enabled) {
@@ -86,7 +85,7 @@ void QQmlEngineControlService::engineAboutToBeRemoved(QQmlEngine *engine)
}
}
-void QQmlEngineControlService::engineAdded(QQmlEngine *engine)
+void QQmlEngineControlServiceImpl::engineAdded(QJSEngine *engine)
{
if (state() == Enabled) {
QMutexLocker lock(&dataMutex);
@@ -96,7 +95,7 @@ void QQmlEngineControlService::engineAdded(QQmlEngine *engine)
}
}
-void QQmlEngineControlService::engineRemoved(QQmlEngine *engine)
+void QQmlEngineControlServiceImpl::engineRemoved(QJSEngine *engine)
{
if (state() == Enabled) {
QMutexLocker lock(&dataMutex);
@@ -106,22 +105,21 @@ void QQmlEngineControlService::engineRemoved(QQmlEngine *engine)
}
}
-void QQmlEngineControlService::sendMessage(QQmlEngineControlService::MessageType type, QQmlEngine *engine)
+void QQmlEngineControlServiceImpl::sendMessage(QQmlEngineControlServiceImpl::MessageType type, QJSEngine *engine)
{
- QByteArray message;
- QQmlDebugStream d(&message, QIODevice::WriteOnly);
- d << type << idForObject(engine);
- emit messageToClient(name(), message);
+ QQmlDebugPacket d;
+ d << int(type) << idForObject(engine);
+ emit messageToClient(name(), d.data());
}
-void QQmlEngineControlService::stateChanged(State)
+void QQmlEngineControlServiceImpl::stateChanged(State)
{
// We flush everything for any kind of state change, to avoid complicated timing issues.
QMutexLocker lock(&dataMutex);
- foreach (QQmlEngine *engine, startingEngines)
+ foreach (QJSEngine *engine, startingEngines)
emit attachedToEngine(engine);
startingEngines.clear();
- foreach (QQmlEngine *engine, stoppingEngines)
+ foreach (QJSEngine *engine, stoppingEngines)
emit detachedFromEngine(engine);
stoppingEngines.clear();
}
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.h b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.h
index e2a93e562a..028852e964 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.h
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.h
@@ -35,7 +35,7 @@
#define QQMLENGINECONTROLSERVICE_H
#include <QMutex>
-#include <private/qqmldebugservice_p.h>
+#include <private/qqmldebugserviceinterfaces_p.h>
//
// W A R N I N G
@@ -50,11 +50,9 @@
QT_BEGIN_NAMESPACE
-class QQmlEngineControlService : public QQmlDebugService
+class QQmlEngineControlServiceImpl : public QQmlEngineControlService
{
public:
- static const QString s_key;
-
enum MessageType {
EngineAboutToBeAdded,
EngineAdded,
@@ -67,22 +65,24 @@ public:
StopWaitingEngine
};
- QQmlEngineControlService(QObject *parent = 0);
+ QQmlEngineControlServiceImpl(QObject *parent = 0);
protected:
+ friend class QQmlProfilerServiceFactory;
+
QMutex dataMutex;
- QList<QQmlEngine *> startingEngines;
- QList<QQmlEngine *> stoppingEngines;
+ QList<QJSEngine *> startingEngines;
+ QList<QJSEngine *> stoppingEngines;
- void messageReceived(const QByteArray &);
- void engineAboutToBeAdded(QQmlEngine *);
- void engineAboutToBeRemoved(QQmlEngine *);
- void engineAdded(QQmlEngine *);
- void engineRemoved(QQmlEngine *);
+ void messageReceived(const QByteArray &) Q_DECL_OVERRIDE;
+ void engineAboutToBeAdded(QJSEngine *) Q_DECL_OVERRIDE;
+ void engineAboutToBeRemoved(QJSEngine *) Q_DECL_OVERRIDE;
+ void engineAdded(QJSEngine *) Q_DECL_OVERRIDE;
+ void engineRemoved(QJSEngine *) Q_DECL_OVERRIDE;
- void sendMessage(MessageType type, QQmlEngine *engine);
+ void sendMessage(MessageType type, QJSEngine *engine);
- void stateChanged(State);
+ void stateChanged(State) Q_DECL_OVERRIDE;
};
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp
index 245900abae..faa1726637 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp
@@ -32,13 +32,16 @@
****************************************************************************/
#include "qqmlprofileradapter.h"
+#include "qqmldebugpacket.h"
+
#include <private/qqmldebugserviceinterfaces_p.h>
QT_BEGIN_NAMESPACE
QQmlProfilerAdapter::QQmlProfilerAdapter(QQmlProfilerService *service, QQmlEnginePrivate *engine) :
- QQmlAbstractProfilerAdapter(service), next(0)
+ next(0)
{
+ setService(service);
engine->enableProfiler();
connect(this, SIGNAL(profilingEnabled(quint64)), engine->profiler, SLOT(startProfiling(quint64)));
connect(this, SIGNAL(profilingEnabledWhileWaiting(quint64)),
@@ -72,13 +75,12 @@ static void qQmlProfilerDataToByteArrays(const QQmlProfilerData *d, QList<QByteA
continue;
//### using QDataStream is relatively expensive
- QQmlDebugStream ds(&data, QIODevice::WriteOnly);
+ QQmlDebugPacket ds;
ds << d->time << decodedMessageType << decodedDetailType;
switch (decodedMessageType) {
case QQmlProfilerDefinitions::RangeStart:
- if (decodedDetailType == (int)QQmlProfilerDefinitions::Binding)
- ds << QQmlProfilerDefinitions::QmlBinding;
+ case QQmlProfilerDefinitions::RangeEnd:
break;
case QQmlProfilerDefinitions::RangeData:
ds << (d->detailString.isEmpty() ? d->detailUrl.toString() : d->detailString);
@@ -87,13 +89,11 @@ static void qQmlProfilerDataToByteArrays(const QQmlProfilerData *d, QList<QByteA
ds << (d->detailUrl.isEmpty() ? d->detailString : d->detailUrl.toString()) << d->x
<< d->y;
break;
- case QQmlProfilerDefinitions::RangeEnd: break;
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid message type.");
break;
}
- messages << data;
- data.clear();
+ messages << ds.data();
}
}
}
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.h b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.h
index eceb58ce3a..b15c2febda 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.h
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.h
@@ -54,7 +54,7 @@ class QQmlProfilerAdapter : public QQmlAbstractProfilerAdapter {
Q_OBJECT
public:
QQmlProfilerAdapter(QQmlProfilerService *service, QQmlEnginePrivate *engine);
- qint64 sendMessages(qint64 until, QList<QByteArray> &messages);
+ qint64 sendMessages(qint64 until, QList<QByteArray> &messages) Q_DECL_OVERRIDE;
public slots:
void receiveData(const QVector<QQmlProfilerData> &new_data);
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp
index 2654cf662b..462bd5e394 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp
@@ -35,9 +35,11 @@
#include "qv4profileradapter.h"
#include "qqmlprofileradapter.h"
#include "qqmlprofilerservicefactory.h"
-#include <private/qqmlengine_p.h>
+#include "qqmldebugpacket.h"
+
+#include <private/qjsengine_p.h>
+#include <private/qqmldebugpluginmanager_p.h>
-#include <QtCore/qdatastream.h>
#include <QtCore/qurl.h>
#include <QtCore/qtimer.h>
#include <QtCore/qthread.h>
@@ -45,11 +47,20 @@
QT_BEGIN_NAMESPACE
+Q_QML_DEBUG_PLUGIN_LOADER(QQmlAbstractProfilerAdapter)
+Q_QML_IMPORT_DEBUG_PLUGIN(QQuickProfilerAdapterFactory)
+
QQmlProfilerServiceImpl::QQmlProfilerServiceImpl(QObject *parent) :
QQmlConfigurableDebugService<QQmlProfilerService>(1, parent),
m_waitingForStop(false)
{
m_timer.start();
+ QQmlAbstractProfilerAdapter *quickAdapter =
+ loadQQmlAbstractProfilerAdapter(QLatin1String("QQuickProfilerAdapter"));
+ if (quickAdapter) {
+ addGlobalProfiler(quickAdapter);
+ quickAdapter->setService(this);
+ }
}
QQmlProfilerServiceImpl::~QQmlProfilerServiceImpl()
@@ -75,8 +86,8 @@ void QQmlProfilerServiceImpl::dataReady(QQmlAbstractProfilerAdapter *profiler)
}
m_startTimes.insert(0, profiler);
if (dataComplete) {
- QList<QQmlEngine *> enginesToRelease;
- foreach (QQmlEngine *engine, m_stoppingEngines) {
+ QList<QJSEngine *> enginesToRelease;
+ foreach (QJSEngine *engine, m_stoppingEngines) {
foreach (QQmlAbstractProfilerAdapter *engineProfiler, m_engineProfilers.values(engine)) {
if (m_startTimes.values().contains(engineProfiler)) {
enginesToRelease.append(engine);
@@ -85,27 +96,30 @@ void QQmlProfilerServiceImpl::dataReady(QQmlAbstractProfilerAdapter *profiler)
}
}
sendMessages();
- foreach (QQmlEngine *engine, enginesToRelease) {
+ foreach (QJSEngine *engine, enginesToRelease) {
m_stoppingEngines.removeOne(engine);
emit detachedFromEngine(engine);
}
}
}
-void QQmlProfilerServiceImpl::engineAboutToBeAdded(QQmlEngine *engine)
+void QQmlProfilerServiceImpl::engineAboutToBeAdded(QJSEngine *engine)
{
Q_ASSERT_X(QThread::currentThread() == engine->thread(), Q_FUNC_INFO,
"QML profilers have to be added from the engine thread");
QMutexLocker lock(&m_configMutex);
- QQmlProfilerAdapter *qmlAdapter = new QQmlProfilerAdapter(this, QQmlEnginePrivate::get(engine));
+ if (QQmlEngine *qmlEngine = qobject_cast<QQmlEngine *>(engine)) {
+ QQmlProfilerAdapter *qmlAdapter =
+ new QQmlProfilerAdapter(this, QQmlEnginePrivate::get(qmlEngine));
+ addEngineProfiler(qmlAdapter, engine);
+ }
QV4ProfilerAdapter *v4Adapter = new QV4ProfilerAdapter(this, QV8Engine::getV4(engine->handle()));
- addEngineProfiler(qmlAdapter, engine);
addEngineProfiler(v4Adapter, engine);
QQmlConfigurableDebugService<QQmlProfilerService>::engineAboutToBeAdded(engine);
}
-void QQmlProfilerServiceImpl::engineAdded(QQmlEngine *engine)
+void QQmlProfilerServiceImpl::engineAdded(QJSEngine *engine)
{
Q_ASSERT_X(QThread::currentThread() == engine->thread(), Q_FUNC_INFO,
"QML profilers have to be added from the engine thread");
@@ -115,7 +129,7 @@ void QQmlProfilerServiceImpl::engineAdded(QQmlEngine *engine)
profiler->stopWaiting();
}
-void QQmlProfilerServiceImpl::engineAboutToBeRemoved(QQmlEngine *engine)
+void QQmlProfilerServiceImpl::engineAboutToBeRemoved(QJSEngine *engine)
{
Q_ASSERT_X(QThread::currentThread() == engine->thread(), Q_FUNC_INFO,
"QML profilers have to be removed from the engine thread");
@@ -135,7 +149,7 @@ void QQmlProfilerServiceImpl::engineAboutToBeRemoved(QQmlEngine *engine)
}
}
-void QQmlProfilerServiceImpl::engineRemoved(QQmlEngine *engine)
+void QQmlProfilerServiceImpl::engineRemoved(QJSEngine *engine)
{
Q_ASSERT_X(QThread::currentThread() == engine->thread(), Q_FUNC_INFO,
"QML profilers have to be removed from the engine thread");
@@ -148,7 +162,7 @@ void QQmlProfilerServiceImpl::engineRemoved(QQmlEngine *engine)
m_engineProfilers.remove(engine);
}
-void QQmlProfilerServiceImpl::addEngineProfiler(QQmlAbstractProfilerAdapter *profiler, QQmlEngine *engine)
+void QQmlProfilerServiceImpl::addEngineProfiler(QQmlAbstractProfilerAdapter *profiler, QJSEngine *engine)
{
profiler->moveToThread(thread());
profiler->synchronize(m_timer);
@@ -176,7 +190,6 @@ void QQmlProfilerServiceImpl::removeGlobalProfiler(QQmlAbstractProfilerAdapter *
QMutexLocker lock(&m_configMutex);
removeProfilerFromStartTimes(profiler);
m_globalProfilers.removeOne(profiler);
- delete profiler;
}
void QQmlProfilerServiceImpl::removeProfilerFromStartTimes(const QQmlAbstractProfilerAdapter *profiler)
@@ -198,12 +211,17 @@ void QQmlProfilerServiceImpl::removeProfilerFromStartTimes(const QQmlAbstractPro
*
* If any engine profiler is started like that also start all global profilers.
*/
-void QQmlProfilerServiceImpl::startProfiling(QQmlEngine *engine, quint64 features)
+void QQmlProfilerServiceImpl::startProfiling(QJSEngine *engine, quint64 features)
{
QMutexLocker lock(&m_configMutex);
- QByteArray message;
- QQmlDebugStream d(&message, QIODevice::WriteOnly);
+ if (features & static_cast<quint64>(1) << ProfileDebugMessages) {
+ if (QDebugMessageService *messageService =
+ QQmlDebugConnector::instance()->service<QDebugMessageService>())
+ messageService->synchronizeTime(m_timer);
+ }
+
+ QQmlDebugPacket d;
d << m_timer.nsecsElapsed() << (int)Event << (int)StartTrace;
bool startedAny = false;
@@ -217,8 +235,8 @@ void QQmlProfilerServiceImpl::startProfiling(QQmlEngine *engine, quint64 feature
if (startedAny)
d << idForObject(engine);
} else {
- QSet<QQmlEngine *> engines;
- for (QMultiHash<QQmlEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin());
+ QSet<QJSEngine *> engines;
+ for (QMultiHash<QJSEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin());
i != m_engineProfilers.end(); ++i) {
if (!i.value()->isRunning()) {
engines << i.key();
@@ -226,7 +244,7 @@ void QQmlProfilerServiceImpl::startProfiling(QQmlEngine *engine, quint64 feature
startedAny = true;
}
}
- foreach (QQmlEngine *profiledEngine, engines)
+ foreach (QJSEngine *profiledEngine, engines)
d << idForObject(profiledEngine);
}
@@ -239,7 +257,7 @@ void QQmlProfilerServiceImpl::startProfiling(QQmlEngine *engine, quint64 feature
emit startFlushTimer();
}
- emit messageToClient(name(), message);
+ emit messageToClient(name(), d.data());
}
/*!
@@ -249,14 +267,14 @@ void QQmlProfilerServiceImpl::startProfiling(QQmlEngine *engine, quint64 feature
* If afterwards no more engine profilers are running, also stop all global profilers. Otherwise
* only make them report their data.
*/
-void QQmlProfilerServiceImpl::stopProfiling(QQmlEngine *engine)
+void QQmlProfilerServiceImpl::stopProfiling(QJSEngine *engine)
{
QMutexLocker lock(&m_configMutex);
QList<QQmlAbstractProfilerAdapter *> stopping;
QList<QQmlAbstractProfilerAdapter *> reporting;
bool stillRunning = false;
- for (QMultiHash<QQmlEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin());
+ for (QMultiHash<QJSEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin());
i != m_engineProfilers.end(); ++i) {
if (i.value()->isRunning()) {
if (engine == 0 || i.key() == engine) {
@@ -299,15 +317,13 @@ void QQmlProfilerServiceImpl::sendMessages()
{
QList<QByteArray> messages;
- QByteArray data;
-
+ QQmlDebugPacket traceEnd;
if (m_waitingForStop) {
- QQmlDebugStream traceEnd(&data, QIODevice::WriteOnly);
traceEnd << m_timer.nsecsElapsed() << (int)Event << (int)EndTrace;
- QSet<QQmlEngine *> seen;
+ QSet<QJSEngine *> seen;
foreach (QQmlAbstractProfilerAdapter *profiler, m_startTimes) {
- for (QMultiHash<QQmlEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin());
+ for (QMultiHash<QJSEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin());
i != m_engineProfilers.end(); ++i) {
if (i.value() == profiler && !seen.contains(i.key())) {
seen << i.key();
@@ -331,12 +347,11 @@ void QQmlProfilerServiceImpl::sendMessages()
if (m_waitingForStop) {
//indicate completion
- messages << data;
- data.clear();
+ messages << traceEnd.data();
- QQmlDebugStream ds(&data, QIODevice::WriteOnly);
+ QQmlDebugPacket ds;
ds << (qint64)-1 << (int)Complete;
- messages << data;
+ messages << ds.data();
m_waitingForStop = false;
}
@@ -360,7 +375,7 @@ void QQmlProfilerServiceImpl::stateAboutToBeChanged(QQmlDebugService::State newS
// Stop all profiling and send the data before we get disabled.
if (newState != Enabled) {
- foreach (QQmlEngine *engine, m_engineProfilers.keys())
+ foreach (QJSEngine *engine, m_engineProfilers.keys())
stopProfiling(engine);
}
}
@@ -369,8 +384,7 @@ void QQmlProfilerServiceImpl::messageReceived(const QByteArray &message)
{
QMutexLocker lock(&m_configMutex);
- QByteArray rwData = message;
- QQmlDebugStream stream(&rwData, QIODevice::ReadOnly);
+ QQmlDebugPacket stream(message);
int engineId = -1;
quint64 features = std::numeric_limits<quint64>::max();
@@ -397,9 +411,9 @@ void QQmlProfilerServiceImpl::messageReceived(const QByteArray &message)
// If engineId == -1 objectForId() and then the cast will return 0.
if (enabled)
- startProfiling(qobject_cast<QQmlEngine *>(objectForId(engineId)), features);
+ startProfiling(qobject_cast<QJSEngine *>(objectForId(engineId)), features);
else
- stopProfiling(qobject_cast<QQmlEngine *>(objectForId(engineId)));
+ stopProfiling(qobject_cast<QJSEngine *>(objectForId(engineId)));
stopWaiting();
}
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h
index 9b139ffabb..299d170339 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h
@@ -64,8 +64,6 @@
QT_BEGIN_NAMESPACE
class QUrl;
-class QQmlEngine;
-
class QQmlProfilerServiceImpl :
public QQmlConfigurableDebugService<QQmlProfilerService>,
@@ -74,21 +72,22 @@ class QQmlProfilerServiceImpl :
Q_OBJECT
public:
- void engineAboutToBeAdded(QQmlEngine *engine);
- void engineAboutToBeRemoved(QQmlEngine *engine);
- void engineAdded(QQmlEngine *engine);
- void engineRemoved(QQmlEngine *engine);
+ void engineAboutToBeAdded(QJSEngine *engine) Q_DECL_OVERRIDE;
+ void engineAboutToBeRemoved(QJSEngine *engine) Q_DECL_OVERRIDE;
+ void engineAdded(QJSEngine *engine) Q_DECL_OVERRIDE;
+ void engineRemoved(QJSEngine *engine) Q_DECL_OVERRIDE;
- void addGlobalProfiler(QQmlAbstractProfilerAdapter *profiler);
- void removeGlobalProfiler(QQmlAbstractProfilerAdapter *profiler);
+ void addGlobalProfiler(QQmlAbstractProfilerAdapter *profiler) Q_DECL_OVERRIDE;
+ void removeGlobalProfiler(QQmlAbstractProfilerAdapter *profiler) Q_DECL_OVERRIDE;
- void startProfiling(QQmlEngine *engine, quint64 features = std::numeric_limits<quint64>::max());
- void stopProfiling(QQmlEngine *engine);
+ void startProfiling(QJSEngine *engine,
+ quint64 features = std::numeric_limits<quint64>::max()) Q_DECL_OVERRIDE;
+ void stopProfiling(QJSEngine *engine) Q_DECL_OVERRIDE;
QQmlProfilerServiceImpl(QObject *parent = 0);
- ~QQmlProfilerServiceImpl();
+ ~QQmlProfilerServiceImpl() Q_DECL_OVERRIDE;
- void dataReady(QQmlAbstractProfilerAdapter *profiler);
+ void dataReady(QQmlAbstractProfilerAdapter *profiler) Q_DECL_OVERRIDE;
signals:
void startFlushTimer();
@@ -98,14 +97,14 @@ private slots:
void flush();
protected:
- virtual void stateAboutToBeChanged(State state);
- virtual void messageReceived(const QByteArray &);
+ virtual void stateAboutToBeChanged(State state) Q_DECL_OVERRIDE;
+ virtual void messageReceived(const QByteArray &) Q_DECL_OVERRIDE;
private:
friend class QQmlProfilerServiceFactory;
void sendMessages();
- void addEngineProfiler(QQmlAbstractProfilerAdapter *profiler, QQmlEngine *engine);
+ void addEngineProfiler(QQmlAbstractProfilerAdapter *profiler, QJSEngine *engine);
void removeProfilerFromStartTimes(const QQmlAbstractProfilerAdapter *profiler);
QElapsedTimer m_timer;
@@ -113,8 +112,8 @@ private:
bool m_waitingForStop;
QList<QQmlAbstractProfilerAdapter *> m_globalProfilers;
- QMultiHash<QQmlEngine *, QQmlAbstractProfilerAdapter *> m_engineProfilers;
- QList<QQmlEngine *> m_stoppingEngines;
+ QMultiHash<QJSEngine *, QQmlAbstractProfilerAdapter *> m_engineProfilers;
+ QList<QJSEngine *> m_stoppingEngines;
QMultiMap<qint64, QQmlAbstractProfilerAdapter *> m_startTimes;
};
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.cpp
index 83c2075246..c1b8e6a817 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.cpp
@@ -42,8 +42,8 @@ QQmlDebugService *QQmlProfilerServiceFactory::create(const QString &key)
if (key == QQmlProfilerServiceImpl::s_key)
return new QQmlProfilerServiceImpl(this);
- if (key == QQmlEngineControlService::s_key)
- return new QQmlEngineControlService(this);
+ if (key == QQmlEngineControlServiceImpl::s_key)
+ return new QQmlEngineControlServiceImpl(this);
return 0;
}
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp
index 24e01f4c68..2e7051b912 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp
@@ -33,16 +33,22 @@
#include "qv4profileradapter.h"
#include "qqmlprofilerservice.h"
+#include "qqmldebugpacket.h"
QT_BEGIN_NAMESPACE
QV4ProfilerAdapter::QV4ProfilerAdapter(QQmlProfilerService *service, QV4::ExecutionEngine *engine) :
- QQmlAbstractProfilerAdapter(service), dataPos(0), memoryPos(0)
+ m_functionCallPos(0), m_memoryPos(0)
{
+ setService(service);
engine->enableProfiler();
connect(this, SIGNAL(profilingEnabled(quint64)),
- engine->profiler, SLOT(startProfiling(quint64)));
+ this, SLOT(forwardEnabled(quint64)));
connect(this, SIGNAL(profilingEnabledWhileWaiting(quint64)),
+ this, SLOT(forwardEnabledWhileWaiting(quint64)), Qt::DirectConnection);
+ connect(this, SIGNAL(v4ProfilingEnabled(quint64)),
+ engine->profiler, SLOT(startProfiling(quint64)));
+ connect(this, SIGNAL(v4ProfilingEnabledWhileWaiting(quint64)),
engine->profiler, SLOT(startProfiling(quint64)), Qt::DirectConnection);
connect(this, SIGNAL(profilingDisabled()), engine->profiler, SLOT(stopProfiling()));
connect(this, SIGNAL(profilingDisabledWhileWaiting()), engine->profiler, SLOT(stopProfiling()),
@@ -58,30 +64,29 @@ QV4ProfilerAdapter::QV4ProfilerAdapter(QQmlProfilerService *service, QV4::Execut
qint64 QV4ProfilerAdapter::appendMemoryEvents(qint64 until, QList<QByteArray> &messages)
{
- QByteArray message;
- while (memory_data.length() > memoryPos && memory_data[memoryPos].timestamp <= until) {
- QQmlDebugStream d(&message, QIODevice::WriteOnly);
- QV4::Profiling::MemoryAllocationProperties &props = memory_data[memoryPos];
+ while (m_memoryData.length() > m_memoryPos && m_memoryData[m_memoryPos].timestamp <= until) {
+ QQmlDebugPacket d;
+ QV4::Profiling::MemoryAllocationProperties &props = m_memoryData[m_memoryPos];
d << props.timestamp << MemoryAllocation << props.type << props.size;
- ++memoryPos;
- messages.append(message);
+ ++m_memoryPos;
+ messages.append(d.data());
}
- return memory_data.length() == memoryPos ? -1 : memory_data[memoryPos].timestamp;
+ return m_memoryData.length() == m_memoryPos ? -1 : m_memoryData[m_memoryPos].timestamp;
}
qint64 QV4ProfilerAdapter::finalizeMessages(qint64 until, QList<QByteArray> &messages,
qint64 callNext)
{
if (callNext == -1) {
- data.clear();
- dataPos = 0;
+ m_functionCallData.clear();
+ m_functionCallPos = 0;
}
qint64 memoryNext = appendMemoryEvents(until, messages);
if (memoryNext == -1) {
- memory_data.clear();
- memoryPos = 0;
+ m_memoryData.clear();
+ m_memoryPos = 0;
return callNext;
}
@@ -90,64 +95,84 @@ qint64 QV4ProfilerAdapter::finalizeMessages(qint64 until, QList<QByteArray> &mes
qint64 QV4ProfilerAdapter::sendMessages(qint64 until, QList<QByteArray> &messages)
{
- QByteArray message;
while (true) {
- while (!stack.isEmpty() && (dataPos == data.length() ||
- stack.top() <= data[dataPos].start)) {
- if (stack.top() > until)
- return finalizeMessages(until, messages, stack.top());
-
- appendMemoryEvents(stack.top(), messages);
- QQmlDebugStream d(&message, QIODevice::WriteOnly);
- d << stack.pop() << RangeEnd << Javascript;
- messages.append(message);
+ while (!m_stack.isEmpty() &&
+ (m_functionCallPos == m_functionCallData.length() ||
+ m_stack.top() <= m_functionCallData[m_functionCallPos].start)) {
+ if (m_stack.top() > until)
+ return finalizeMessages(until, messages, m_stack.top());
+
+ appendMemoryEvents(m_stack.top(), messages);
+ QQmlDebugPacket d;
+ d << m_stack.pop() << RangeEnd << Javascript;
+ messages.append(d.data());
}
- while (dataPos != data.length() && (stack.empty() || data[dataPos].start < stack.top())) {
- const QV4::Profiling::FunctionCallProperties &props = data[dataPos];
+ while (m_functionCallPos != m_functionCallData.length() &&
+ (m_stack.empty() || m_functionCallData[m_functionCallPos].start < m_stack.top())) {
+ const QV4::Profiling::FunctionCallProperties &props =
+ m_functionCallData[m_functionCallPos];
if (props.start > until)
return finalizeMessages(until, messages, props.start);
appendMemoryEvents(props.start, messages);
- QQmlDebugStream d_start(&message, QIODevice::WriteOnly);
+ QQmlDebugPacket d_start;
d_start << props.start << RangeStart << Javascript;
- messages.push_back(message);
- message.clear();
- QQmlDebugStream d_location(&message, QIODevice::WriteOnly);
+ messages.push_back(d_start.data());
+ QQmlDebugPacket d_location;
d_location << props.start << RangeLocation << Javascript << props.file << props.line
<< props.column;
- messages.push_back(message);
- message.clear();
- QQmlDebugStream d_data(&message, QIODevice::WriteOnly);
+ messages.push_back(d_location.data());
+ QQmlDebugPacket d_data;
d_data << props.start << RangeData << Javascript << props.name;
- messages.push_back(message);
- message.clear();
- stack.push(props.end);
- ++dataPos;
+ messages.push_back(d_data.data());
+ m_stack.push(props.end);
+ ++m_functionCallPos;
}
- if (stack.empty() && dataPos == data.length())
+ if (m_stack.empty() && m_functionCallPos == m_functionCallData.length())
return finalizeMessages(until, messages, -1);
}
}
void QV4ProfilerAdapter::receiveData(
- const QVector<QV4::Profiling::FunctionCallProperties> &new_data,
- const QVector<QV4::Profiling::MemoryAllocationProperties> &new_memory_data)
+ const QVector<QV4::Profiling::FunctionCallProperties> &functionCallData,
+ const QVector<QV4::Profiling::MemoryAllocationProperties> &memoryData)
{
// In rare cases it could be that another flush or stop event is processed while data from
// the previous one is still pending. In that case we just append the data.
- if (data.isEmpty())
- data = new_data;
+ if (m_functionCallData.isEmpty())
+ m_functionCallData = functionCallData;
else
- data.append(new_data);
+ m_functionCallData.append(functionCallData);
- if (memory_data.isEmpty())
- memory_data = new_memory_data;
+ if (m_memoryData.isEmpty())
+ m_memoryData = memoryData;
else
- memory_data.append(new_memory_data);
+ m_memoryData.append(memoryData);
service->dataReady(this);
}
+quint64 QV4ProfilerAdapter::translateFeatures(quint64 qmlFeatures)
+{
+ quint64 v4Features = 0;
+ const quint64 one = 1;
+ if (qmlFeatures & (one << ProfileJavaScript))
+ v4Features |= (one << QV4::Profiling::FeatureFunctionCall);
+ if (qmlFeatures & (one << ProfileMemory))
+ v4Features |= (one << QV4::Profiling::FeatureMemoryAllocation);
+ return v4Features;
+}
+
+void QV4ProfilerAdapter::forwardEnabled(quint64 features)
+{
+ emit v4ProfilingEnabled(translateFeatures(features));
+}
+
+void QV4ProfilerAdapter::forwardEnabledWhileWaiting(quint64 features)
+{
+ emit v4ProfilingEnabledWhileWaiting(translateFeatures(features));
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h
index cea3da72e3..c07fc4dc96 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h
+++ b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h
@@ -62,18 +62,28 @@ public:
virtual qint64 sendMessages(qint64 until, QList<QByteArray> &messages);
+signals:
+ void v4ProfilingEnabled(quint64 v4Features);
+ void v4ProfilingEnabledWhileWaiting(quint64 v4Features);
+
public slots:
void receiveData(const QVector<QV4::Profiling::FunctionCallProperties> &,
const QVector<QV4::Profiling::MemoryAllocationProperties> &);
+private slots:
+ void forwardEnabled(quint64 features);
+ void forwardEnabledWhileWaiting(quint64 features);
+
private:
- QVector<QV4::Profiling::FunctionCallProperties> data;
- QVector<QV4::Profiling::MemoryAllocationProperties> memory_data;
- int dataPos;
- int memoryPos;
- QStack<qint64> stack;
+ QVector<QV4::Profiling::FunctionCallProperties> m_functionCallData;
+ QVector<QV4::Profiling::MemoryAllocationProperties> m_memoryData;
+ int m_functionCallPos;
+ int m_memoryPos;
+ QStack<qint64> m_stack;
qint64 appendMemoryEvents(qint64 until, QList<QByteArray> &messages);
qint64 finalizeMessages(qint64 until, QList<QByteArray> &messages, qint64 callNext);
+
+ static quint64 translateFeatures(quint64 qmlFeatures);
};
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_quickprofiler/qmldbg_quickprofiler.pro b/src/plugins/qmltooling/qmldbg_quickprofiler/qmldbg_quickprofiler.pro
new file mode 100644
index 0000000000..6ca0a184ca
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_quickprofiler/qmldbg_quickprofiler.pro
@@ -0,0 +1,20 @@
+TARGET = qmldbg_quickprofiler
+QT += qml-private quick-private core-private packetprotocol-private
+
+PLUGIN_TYPE = qmltooling
+PLUGIN_CLASS_NAME = QQuickProfilerAdapterFactory
+load(qt_plugin)
+
+INCLUDEPATH += $$PWD/../shared
+
+SOURCES += \
+ $$PWD/qquickprofileradapter.cpp \
+ $$PWD/qquickprofileradapterfactory.cpp
+
+HEADERS += \
+ $$PWD/qquickprofileradapter.h \
+ $$PWD/qquickprofileradapterfactory.h \
+ $$PWD/../shared/qqmldebugpacket.h
+
+OTHER_FILES += \
+ qquickprofileradapter.json
diff --git a/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp
new file mode 100644
index 0000000000..8438a6fb3a
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickprofileradapter.h"
+#include "qqmldebugpacket.h"
+#include <QCoreApplication>
+#include <private/qqmldebugserviceinterfaces_p.h>
+#include <private/qquickprofiler_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QQuickProfilerAdapter::QQuickProfilerAdapter(QObject *parent) :
+ QQmlAbstractProfilerAdapter(parent), next(0)
+{
+ QQuickProfiler::initialize(this);
+
+ // We can always do DirectConnection here as all methods are protected by mutexes
+ connect(this, SIGNAL(profilingEnabled(quint64)),
+ QQuickProfiler::s_instance, SLOT(startProfilingImpl(quint64)), Qt::DirectConnection);
+ connect(this, SIGNAL(profilingEnabledWhileWaiting(quint64)),
+ QQuickProfiler::s_instance, SLOT(startProfilingImpl(quint64)), Qt::DirectConnection);
+ connect(this, SIGNAL(referenceTimeKnown(QElapsedTimer)),
+ QQuickProfiler::s_instance, SLOT(setTimer(QElapsedTimer)), Qt::DirectConnection);
+ connect(this, SIGNAL(profilingDisabled()),
+ QQuickProfiler::s_instance, SLOT(stopProfilingImpl()), Qt::DirectConnection);
+ connect(this, SIGNAL(profilingDisabledWhileWaiting()),
+ QQuickProfiler::s_instance, SLOT(stopProfilingImpl()), Qt::DirectConnection);
+ connect(this, SIGNAL(dataRequested()),
+ QQuickProfiler::s_instance, SLOT(reportDataImpl()), Qt::DirectConnection);
+ connect(QQuickProfiler::s_instance, SIGNAL(dataReady(QVector<QQuickProfilerData>)),
+ this, SLOT(receiveData(QVector<QQuickProfilerData>)), Qt::DirectConnection);
+}
+
+QQuickProfilerAdapter::~QQuickProfilerAdapter()
+{
+ if (service)
+ service->removeGlobalProfiler(this);
+}
+
+// convert to QByteArrays that can be sent to the debug client
+// use of QDataStream can skew results
+// (see tst_qqmldebugtrace::trace() benchmark)
+static void qQuickProfilerDataToByteArrays(const QQuickProfilerData &data,
+ QList<QByteArray> &messages)
+{
+ Q_ASSERT_X(((data.messageType | data.detailType) & (1 << 31)) == 0, Q_FUNC_INFO,
+ "You can use at most 31 message types and 31 detail types.");
+ for (uint decodedMessageType = 0; (data.messageType >> decodedMessageType) != 0;
+ ++decodedMessageType) {
+ if ((data.messageType & (1 << decodedMessageType)) == 0)
+ continue;
+
+ for (uint decodedDetailType = 0; (data.detailType >> decodedDetailType) != 0;
+ ++decodedDetailType) {
+ if ((data.detailType & (1 << decodedDetailType)) == 0)
+ continue;
+
+ //### using QDataStream is relatively expensive
+ QQmlDebugPacket ds;
+ ds << data.time << decodedMessageType << decodedDetailType;
+
+ switch (decodedMessageType) {
+ case QQuickProfiler::Event:
+ switch (decodedDetailType) {
+ case QQuickProfiler::AnimationFrame:
+ ds << data.framerate << data.count << data.threadId;
+ break;
+ case QQuickProfiler::Key:
+ case QQuickProfiler::Mouse:
+ ds << data.inputType << data.inputA << data.inputB;
+ break;
+ }
+ break;
+ case QQuickProfiler::PixmapCacheEvent:
+ ds << data.detailUrl.toString();
+ switch (decodedDetailType) {
+ case QQuickProfiler::PixmapSizeKnown: ds << data.x << data.y; break;
+ case QQuickProfiler::PixmapReferenceCountChanged: ds << data.count; break;
+ case QQuickProfiler::PixmapCacheCountChanged: ds << data.count; break;
+ default: break;
+ }
+ break;
+ case QQuickProfiler::SceneGraphFrame:
+ switch (decodedDetailType) {
+ // RendererFrame: preprocessTime, updateTime, bindingTime, renderTime
+ case QQuickProfiler::SceneGraphRendererFrame: ds << data.subtime_1 << data.subtime_2 << data.subtime_3 << data.subtime_4; break;
+ // AdaptationLayerFrame: glyphCount (which is an integer), glyphRenderTime, glyphStoreTime
+ case QQuickProfiler::SceneGraphAdaptationLayerFrame: ds << data.subtime_3 << data.subtime_1 << data.subtime_2; break;
+ // ContextFrame: compiling material time
+ case QQuickProfiler::SceneGraphContextFrame: ds << data.subtime_1; break;
+ // RenderLoop: syncTime, renderTime, swapTime
+ case QQuickProfiler::SceneGraphRenderLoopFrame: ds << data.subtime_1 << data.subtime_2 << data.subtime_3; break;
+ // TexturePrepare: bind, convert, swizzle, upload, mipmap
+ case QQuickProfiler::SceneGraphTexturePrepare: ds << data.subtime_1 << data.subtime_2 << data.subtime_3 << data.subtime_4 << data.subtime_5; break;
+ // TextureDeletion: deletionTime
+ case QQuickProfiler::SceneGraphTextureDeletion: ds << data.subtime_1; break;
+ // PolishAndSync: polishTime, waitTime, syncTime, animationsTime,
+ case QQuickProfiler::SceneGraphPolishAndSync: ds << data.subtime_1 << data.subtime_2 << data.subtime_3 << data.subtime_4; break;
+ // WindowsRenderLoop: GL time, make current time, SceneGraph time
+ case QQuickProfiler::SceneGraphWindowsRenderShow: ds << data.subtime_1 << data.subtime_2 << data.subtime_3; break;
+ // WindowsAnimations: update time
+ case QQuickProfiler::SceneGraphWindowsAnimations: ds << data.subtime_1; break;
+ // non-threaded rendering: polish time
+ case QQuickProfiler::SceneGraphPolishFrame: ds << data.subtime_1; break;
+ default:break;
+ }
+ break;
+ default:
+ Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid message type.");
+ break;
+ }
+ messages << ds.data();
+ }
+ }
+}
+
+qint64 QQuickProfilerAdapter::sendMessages(qint64 until, QList<QByteArray> &messages)
+{
+ while (next < m_data.size()) {
+ if (m_data[next].time <= until)
+ qQuickProfilerDataToByteArrays(m_data[next++], messages);
+ else
+ return m_data[next].time;
+ }
+ m_data.clear();
+ next = 0;
+ return -1;
+}
+
+void QQuickProfilerAdapter::receiveData(const QVector<QQuickProfilerData> &new_data)
+{
+ if (m_data.isEmpty())
+ m_data = new_data;
+ else
+ m_data.append(new_data);
+ service->dataReady(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.h b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.h
new file mode 100644
index 0000000000..7a3a25f049
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKPROFILERADAPTER_H
+#define QQUICKPROFILERADAPTER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtQml/private/qqmlabstractprofileradapter_p.h>
+#include <QtQuick/private/qquickprofiler_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickProfilerAdapter : public QQmlAbstractProfilerAdapter {
+ Q_OBJECT
+public:
+ QQuickProfilerAdapter(QObject *parent = 0);
+ ~QQuickProfilerAdapter();
+ qint64 sendMessages(qint64 until, QList<QByteArray> &messages);
+
+public slots:
+ void receiveData(const QVector<QQuickProfilerData> &new_data);
+
+private:
+ int next;
+ QVector<QQuickProfilerData> m_data;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKPROFILERADAPTER_H
diff --git a/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.json b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.json
new file mode 100644
index 0000000000..76b08fbcab
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "QQuickProfilerAdapter" ]
+}
diff --git a/tools/qmlprofiler/qmlprofilereventlocation.h b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapterfactory.cpp
index ebf9f2eed6..9fae5e3a4d 100644
--- a/tools/qmlprofiler/qmlprofilereventlocation.h
+++ b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapterfactory.cpp
@@ -31,23 +31,18 @@
**
****************************************************************************/
-#ifndef QMLPROFILEREVENTLOCATION_H
-#define QMLPROFILEREVENTLOCATION_H
+#include "qquickprofileradapterfactory.h"
+#include "qquickprofileradapter.h"
+#include <private/qqmldebugconnector_p.h>
+#include <private/qqmldebugserviceinterfaces_p.h>
-#include <QString>
+QT_BEGIN_NAMESPACE
-struct QmlEventLocation
+QQmlAbstractProfilerAdapter *QQuickProfilerAdapterFactory::create(const QString &key)
{
- QmlEventLocation() : line(-1), column(-1) {}
- QmlEventLocation(const QString &file, int lineNumber, int columnNumber)
- : filename(file), line(lineNumber), column(columnNumber) {}
- QString filename;
- int line;
- int column;
-};
+ if (key != QLatin1String("QQuickProfilerAdapter"))
+ return 0;
+ return new QQuickProfilerAdapter(this);
+}
-QT_BEGIN_NAMESPACE
-Q_DECLARE_TYPEINFO(QmlEventLocation, Q_MOVABLE_TYPE);
QT_END_NAMESPACE
-
-#endif // QMLPROFILEREVENTLOCATION_H
diff --git a/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapterfactory.h b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapterfactory.h
new file mode 100644
index 0000000000..dee77747ef
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapterfactory.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKPROFILERADAPTERFACTORY_H
+#define QQUICKPROFILERADAPTERFACTORY_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtQml/private/qqmlabstractprofileradapter_p.h>
+#include <QtQuick/private/qquickprofiler_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickProfilerAdapterFactory : public QQmlAbstractProfilerAdapterFactory
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID QQmlAbstractProfilerAdapterFactory_iid FILE "qquickprofileradapter.json")
+public:
+ QQmlAbstractProfilerAdapter *create(const QString &key);
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKPROFILERADAPTERFACTORY_H
diff --git a/src/plugins/qmltooling/qmldbg_server/qmldbg_server.pro b/src/plugins/qmltooling/qmldbg_server/qmldbg_server.pro
index 5e2d0874df..923faa01f3 100644
--- a/src/plugins/qmltooling/qmldbg_server/qmldbg_server.pro
+++ b/src/plugins/qmltooling/qmldbg_server/qmldbg_server.pro
@@ -1,19 +1,18 @@
TARGET = qmldbg_server
-QT = qml-private core-private
+QT = qml-private packetprotocol-private
PLUGIN_TYPE = qmltooling
PLUGIN_CLASS_NAME = QQmlDebugServerFactory
load(qt_plugin)
SOURCES += \
- $$PWD/qqmldebugserver.cpp \
- $$PWD/../shared/qpacketprotocol.cpp
+ $$PWD/qqmldebugserver.cpp
HEADERS += \
$$PWD/qqmldebugserverfactory.h \
$$PWD/../shared/qqmldebugserver.h \
- $$PWD/../shared/qpacketprotocol.h \
- $$PWD/../shared/qqmldebugserverconnection.h
+ $$PWD/../shared/qqmldebugserverconnection.h \
+ $$PWD/../shared/qqmldebugpacket.h
INCLUDEPATH += $$PWD \
$$PWD/../shared
diff --git a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
index 69d36beaca..a2182c2baf 100644
--- a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
+++ b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
@@ -33,13 +33,15 @@
#include "qqmldebugserver.h"
#include "qqmldebugserverfactory.h"
-#include "qpacketprotocol.h"
#include "qqmldebugserverconnection.h"
+#include "qqmldebugpacket.h"
#include <private/qqmldebugservice_p.h>
-#include <private/qqmlengine_p.h>
+#include <private/qjsengine_p.h>
#include <private/qqmlglobal_p.h>
#include <private/qqmldebugpluginmanager_p.h>
+#include <private/qqmldebugserviceinterfaces_p.h>
+#include <private/qpacketprotocol_p.h>
#include <QtCore/QAtomicInt>
#include <QtCore/QDir>
@@ -47,9 +49,6 @@
#include <QtCore/QStringList>
#include <QtCore/qwaitcondition.h>
-#include <private/qobject_p.h>
-#include <private/qcoreapplication_p.h>
-
QT_BEGIN_NAMESPACE
/*
@@ -105,6 +104,11 @@ public:
m_fileName = fileName;
}
+ const QString &pluginName() const
+ {
+ return m_pluginName;
+ }
+
void run();
private:
@@ -122,25 +126,26 @@ class QQmlDebugServerImpl : public QQmlDebugServer
public:
QQmlDebugServerImpl();
- bool blockingMode() const;
+ bool blockingMode() const Q_DECL_OVERRIDE;
- QQmlDebugService *service(const QString &name) const;
+ QQmlDebugService *service(const QString &name) const Q_DECL_OVERRIDE;
- void addEngine(QQmlEngine *engine);
- void removeEngine(QQmlEngine *engine);
+ void addEngine(QJSEngine *engine) Q_DECL_OVERRIDE;
+ void removeEngine(QJSEngine *engine) Q_DECL_OVERRIDE;
+ bool hasEngine(QJSEngine *engine) const Q_DECL_OVERRIDE;
- bool addService(const QString &name, QQmlDebugService *service);
- bool removeService(const QString &name);
+ bool addService(const QString &name, QQmlDebugService *service) Q_DECL_OVERRIDE;
+ bool removeService(const QString &name) Q_DECL_OVERRIDE;
- bool open(const QVariantHash &configuration);
- void setDevice(QIODevice *socket);
+ bool open(const QVariantHash &configuration) Q_DECL_OVERRIDE;
+ void setDevice(QIODevice *socket) Q_DECL_OVERRIDE;
void parseArguments();
static void cleanup();
private slots:
- void wakeEngine(QQmlEngine *engine);
+ void wakeEngine(QJSEngine *engine);
void sendMessage(const QString &name, const QByteArray &message);
void sendMessages(const QString &name, const QList<QByteArray> &messages);
void changeServiceState(const QString &serviceName, QQmlDebugService::State state);
@@ -157,6 +162,7 @@ private:
EngineCondition() : numServices(0), condition(new QWaitCondition) {}
bool waitForServices(QMutex *locked, int numEngines);
+ bool isWaiting() const { return numServices > 0; }
void wake();
private:
@@ -175,9 +181,9 @@ private:
bool m_gotHello;
bool m_blockingMode;
- QHash<QQmlEngine *, EngineCondition> m_engineConditions;
+ QHash<QJSEngine *, EngineCondition> m_engineConditions;
- QMutex m_helloMutex;
+ mutable QMutex m_helloMutex;
QWaitCondition m_helloCondition;
QQmlDebugServerThread m_thread;
QPacketProtocol *m_protocol;
@@ -304,6 +310,9 @@ bool QQmlDebugServerImpl::open(const QVariantHash &configuration = QVariantHash(
}
}
+ if (m_thread.pluginName().isEmpty())
+ return false;
+
QMutexLocker locker(&m_helloMutex);
m_thread.start();
m_helloCondition.wait(&m_helloMutex); // wait for connection
@@ -312,6 +321,7 @@ bool QQmlDebugServerImpl::open(const QVariantHash &configuration = QVariantHash(
return true;
}
+#define qUsage qWarning().noquote().nospace
void QQmlDebugServerImpl::parseArguments()
{
// format: qmljsdebugger=port:<port_from>[,port_to],host:<ip address>][,block]
@@ -334,7 +344,7 @@ void QQmlDebugServerImpl::parseArguments()
for (; argsIt != argsItEnd; ++argsIt) {
const QString strArgument = *argsIt;
if (strArgument.startsWith(QLatin1String("port:"))) {
- portFrom = strArgument.mid(5).toInt(&ok);
+ portFrom = strArgument.midRef(5).toInt(&ok);
portTo = portFrom;
QStringList::const_iterator argsNext = argsIt + 1;
if (argsNext == argsItEnd)
@@ -360,9 +370,8 @@ void QQmlDebugServerImpl::parseArguments()
} else if (!services.isEmpty()) {
services.append(strArgument);
} else {
- qWarning() << QString::fromLatin1("QML Debugger: Invalid argument '%1' "
- "detected. Ignoring the same.")
- .arg(strArgument);
+ qUsage() << tr("QML Debugger: Invalid argument \"%1\" detected. Ignoring the same.")
+ .arg(strArgument);
}
}
@@ -374,11 +383,43 @@ void QQmlDebugServerImpl::parseArguments()
else
m_thread.setPortRange(portFrom, portTo, hostAddress);
} else {
- qWarning() << QString::fromLatin1("QML Debugger: Ignoring \"-qmljsdebugger=%1\". "
- "Format is qmljsdebugger=port:<port_from>[,port_to],host:"
- "<ip address>][,block]").arg(args);
+ qUsage() << tr("QML Debugger: Ignoring \"-qmljsdebugger=%1\".").arg(args);
+ qUsage() << tr("The format is \"-qmljsdebugger=[file:<file>|port:<port_from>][,<port_to>]"
+ "[,host:<ip address>][,block][,services:<service>][,<service>]*\"\n");
+ qUsage() << tr("\"file:\" can be used to specify the name of a file the debugger will try "
+ "to connect to using a QLocalSocket. If \"file:\" is given any \"host:\" and"
+ "\"port:\" arguments will be ignored.\n");
+ qUsage() << tr("\"host:\" and \"port:\" can be used to specify an address and a single "
+ "port or a range of ports the debugger will try to bind to with a "
+ "QTcpServer.\n");
+ qUsage() << tr("\"block\" makes the debugger and some services wait for clients to be "
+ "connected and ready before the first QML engine starts.\n");
+ qUsage() << tr("\"services:\" can be used to specify which debug services the debugger "
+ "should load. Some debug services interact badly with others. The V4 "
+ "debugger should not be loaded when using the QML profiler as it will force "
+ "any V4 engines to use the JavaScript interpreter rather than the JIT. The "
+ "following debug services are available by default:");
+ qUsage() << QQmlEngineDebugService::s_key << tr("\t- The QML debugger");
+ qUsage() << QV4DebugService::s_key << tr("\t- The V4 debugger");
+ qUsage() << QQmlInspectorService::s_key << tr("\t- The QML inspector");
+ qUsage() << QQmlProfilerService::s_key << tr("\t- The QML profiler");
+ qUsage() << QQmlEngineControlService::s_key
+ << tr("\t- Allows the client to delay the starting and stopping of\n"
+ "\t\t QML engines until other services are ready. QtCreator\n"
+ "\t\t uses this service with the QML profiler in order to\n"
+ "\t\t profile multiple QML engines at the same time.");
+ qUsage() << QDebugMessageService::s_key
+ << tr("\t- Sends qDebug() and similar messages over the QML debug\n"
+ "\t\t connection. QtCreator uses this for showing debug\n"
+ "\t\t messages in the JavaScript console.");
+ qUsage() << tr("Other services offered by qmltooling plugins that implement "
+ "QQmlDebugServiceFactory and which can be found in the standard plugin "
+ "paths will also be available and can be specified. If no \"services\" "
+ "argument is given, all services found this way, including the default "
+ "ones, are loaded.");
}
}
+#undef qUsage
void QQmlDebugServerImpl::receiveMessage()
{
@@ -390,7 +431,7 @@ void QQmlDebugServerImpl::receiveMessage()
if (!m_protocol)
return;
- QQmlDebugStream in(m_protocol->read().data());
+ QQmlDebugPacket in(m_protocol->read());
QString name;
@@ -404,16 +445,15 @@ void QQmlDebugServerImpl::receiveMessage()
//Get the supported QDataStream version
if (!in.atEnd()) {
- in >> QQmlDebugStream::s_dataStreamVersion;
- if (QQmlDebugStream::s_dataStreamVersion > QDataStream().version())
- QQmlDebugStream::s_dataStreamVersion = QDataStream().version();
+ in >> s_dataStreamVersion;
+ if (s_dataStreamVersion > QDataStream::Qt_DefaultCompiledVersion)
+ s_dataStreamVersion = QDataStream::Qt_DefaultCompiledVersion;
}
// Send the hello answer immediately, since it needs to arrive before
// the plugins below start sending messages.
- QByteArray helloAnswer;
- QQmlDebugStream out(&helloAnswer, QIODevice::WriteOnly);
+ QQmlDebugPacket out;
QStringList pluginNames;
QList<float> pluginVersions;
const int count = m_plugins.count();
@@ -426,11 +466,9 @@ void QQmlDebugServerImpl::receiveMessage()
}
out << QString(QStringLiteral("QDeclarativeDebugClient")) << 0 << protocolVersion
- << pluginNames << pluginVersions << QQmlDebugStream::s_dataStreamVersion;
+ << pluginNames << pluginVersions << dataStreamVersion();
- QPacket pack;
- pack.writeRawData(helloAnswer.data(), helloAnswer.length());
- m_protocol->send(pack);
+ m_protocol->send(out.data());
m_connection->flush();
QMutexLocker helloLock(&m_helloMutex);
@@ -523,12 +561,14 @@ QQmlDebugService *QQmlDebugServerImpl::service(const QString &name) const
return m_plugins.value(name);
}
-void QQmlDebugServerImpl::addEngine(QQmlEngine *engine)
+void QQmlDebugServerImpl::addEngine(QJSEngine *engine)
{
// to be executed outside of debugger thread
Q_ASSERT(QThread::currentThread() != &m_thread);
QMutexLocker locker(&m_helloMutex);
+ Q_ASSERT(!m_engineConditions.contains(engine));
+
foreach (QQmlDebugService *service, m_plugins)
service->engineAboutToBeAdded(engine);
@@ -538,12 +578,14 @@ void QQmlDebugServerImpl::addEngine(QQmlEngine *engine)
service->engineAdded(engine);
}
-void QQmlDebugServerImpl::removeEngine(QQmlEngine *engine)
+void QQmlDebugServerImpl::removeEngine(QJSEngine *engine)
{
// to be executed outside of debugger thread
Q_ASSERT(QThread::currentThread() != &m_thread);
QMutexLocker locker(&m_helloMutex);
+ Q_ASSERT(m_engineConditions.contains(engine));
+
foreach (QQmlDebugService *service, m_plugins)
service->engineAboutToBeRemoved(engine);
@@ -551,6 +593,16 @@ void QQmlDebugServerImpl::removeEngine(QQmlEngine *engine)
foreach (QQmlDebugService *service, m_plugins)
service->engineRemoved(engine);
+
+ m_engineConditions.remove(engine);
+}
+
+bool QQmlDebugServerImpl::hasEngine(QJSEngine *engine) const
+{
+ QMutexLocker locker(&m_helloMutex);
+ QHash<QJSEngine *, EngineCondition>::ConstIterator i = m_engineConditions.constFind(engine);
+ // if we're still waiting the engine isn't fully "there", yet, nor fully removed.
+ return i != m_engineConditions.constEnd() && !i.value().isWaiting();
}
bool QQmlDebugServerImpl::addService(const QString &name, QQmlDebugService *service)
@@ -566,10 +618,10 @@ bool QQmlDebugServerImpl::addService(const QString &name, QQmlDebugService *serv
connect(service, SIGNAL(messagesToClient(QString,QList<QByteArray>)),
this, SLOT(sendMessages(QString,QList<QByteArray>)));
- connect(service, SIGNAL(attachedToEngine(QQmlEngine*)),
- this, SLOT(wakeEngine(QQmlEngine*)), Qt::QueuedConnection);
- connect(service, SIGNAL(detachedFromEngine(QQmlEngine*)),
- this, SLOT(wakeEngine(QQmlEngine*)), Qt::QueuedConnection);
+ connect(service, SIGNAL(attachedToEngine(QJSEngine*)),
+ this, SLOT(wakeEngine(QJSEngine*)), Qt::QueuedConnection);
+ connect(service, SIGNAL(detachedFromEngine(QJSEngine*)),
+ this, SLOT(wakeEngine(QJSEngine*)), Qt::QueuedConnection);
service->setState(QQmlDebugService::Unavailable);
m_plugins.insert(name, service);
@@ -589,18 +641,16 @@ bool QQmlDebugServerImpl::removeService(const QString &name)
m_plugins.remove(name);
service->setState(QQmlDebugService::NotConnected);
- disconnect(service, SIGNAL(detachedFromEngine(QQmlEngine*)),
- this, SLOT(wakeEngine(QQmlEngine*)));
- disconnect(service, SIGNAL(attachedToEngine(QQmlEngine*)),
- this, SLOT(wakeEngine(QQmlEngine*)));
+ disconnect(service, SIGNAL(detachedFromEngine(QJSEngine*)),
+ this, SLOT(wakeEngine(QJSEngine*)));
+ disconnect(service, SIGNAL(attachedToEngine(QJSEngine*)),
+ this, SLOT(wakeEngine(QJSEngine*)));
disconnect(service, SIGNAL(messagesToClient(QString,QList<QByteArray>)),
this, SLOT(sendMessages(QString,QList<QByteArray>)));
disconnect(service, SIGNAL(messageToClient(QString,QByteArray)),
this, SLOT(sendMessage(QString,QByteArray)));
- m_plugins.remove(service->name());
-
return true;
}
@@ -614,13 +664,9 @@ bool QQmlDebugServerImpl::canSendMessage(const QString &name)
void QQmlDebugServerImpl::doSendMessage(const QString &name, const QByteArray &message)
{
- QByteArray prefixed;
- QQmlDebugStream out(&prefixed, QIODevice::WriteOnly);
+ QQmlDebugPacket out;
out << name << message;
-
- QPacket pack;
- pack.writeRawData(prefixed.data(), prefixed.length());
- m_protocol->send(pack);
+ m_protocol->send(out.data());
}
void QQmlDebugServerImpl::sendMessage(const QString &name, const QByteArray &message)
@@ -640,7 +686,7 @@ void QQmlDebugServerImpl::sendMessages(const QString &name, const QList<QByteArr
}
}
-void QQmlDebugServerImpl::wakeEngine(QQmlEngine *engine)
+void QQmlDebugServerImpl::wakeEngine(QJSEngine *engine)
{
// to be executed in debugger thread
Q_ASSERT(QThread::currentThread() == thread());
diff --git a/src/plugins/qmltooling/qmltooling.pro b/src/plugins/qmltooling/qmltooling.pro
index 263e76e016..3728126dd9 100644
--- a/src/plugins/qmltooling/qmltooling.pro
+++ b/src/plugins/qmltooling/qmltooling.pro
@@ -1,5 +1,9 @@
TEMPLATE = subdirs
+# Utilities
+SUBDIRS += \
+ packetprotocol
+
# Connectors
SUBDIRS += \
qmldbg_native \
@@ -12,4 +16,15 @@ SUBDIRS += \
qmldbg_debugger \
qmldbg_profiler
-qtHaveModule(quick): SUBDIRS += qmldbg_inspector
+qmldbg_server.depends = packetprotocol
+qmldbg_native.depends = packetprotocol
+qmldbg_debugger.depends = packetprotocol
+qmldbg_profiler.depends = packetprotocol
+
+qtHaveModule(quick) {
+ SUBDIRS += \
+ qmldbg_inspector \
+ qmldbg_quickprofiler
+ qmldbg_inspector.depends = packetprotocol
+ qmldbg_quickprofiler.depends = packetprotocol
+}
diff --git a/src/plugins/qmltooling/shared/qpacketprotocol.cpp b/src/plugins/qmltooling/shared/qpacketprotocol.cpp
deleted file mode 100644
index 9a58f803c1..0000000000
--- a/src/plugins/qmltooling/shared/qpacketprotocol.cpp
+++ /dev/null
@@ -1,531 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpacketprotocol.h"
-
-#include <QtCore/QBuffer>
-#include <QtCore/QElapsedTimer>
-#include <private/qiodevice_p.h>
-
-QT_BEGIN_NAMESPACE
-
-static const unsigned int MAX_PACKET_SIZE = 0x7FFFFFFF;
-
-/*!
- \class QPacketProtocol
- \internal
-
- \brief The QPacketProtocol class encapsulates communicating discrete packets
- across fragmented IO channels, such as TCP sockets.
-
- QPacketProtocol makes it simple to send arbitrary sized data "packets" across
- fragmented transports such as TCP and UDP.
-
- As transmission boundaries are not respected, sending packets over protocols
- like TCP frequently involves "stitching" them back together at the receiver.
- QPacketProtocol makes this easier by performing this task for you. Packet
- data sent using QPacketProtocol is prepended with a 4-byte size header
- allowing the receiving QPacketProtocol to buffer the packet internally until
- it has all been received. QPacketProtocol does not perform any sanity
- checking on the size or on the data, so this class should only be used in
- prototyping or trusted situations where DOS attacks are unlikely.
-
- QPacketProtocol does not perform any communications itself. Instead it can
- operate on any QIODevice that supports the QIODevice::readyRead() signal. A
- logical "packet" is encapsulated by the companion QPacket class. The
- following example shows two ways to send data using QPacketProtocol. The
- transmitted data is equivalent in both.
-
- \code
- QTcpSocket socket;
- // ... connect socket ...
-
- QPacketProtocol protocol(&socket);
-
- // Send packet the quick way
- protocol.send() << "Hello world" << 123;
-
- // Send packet the longer way
- QPacket packet;
- packet << "Hello world" << 123;
- protocol.send(packet);
- \endcode
-
- Likewise, the following shows how to read data from QPacketProtocol, assuming
- that the QPacketProtocol::readyRead() signal has been emitted.
-
- \code
- // ... QPacketProtocol::readyRead() is emitted ...
-
- int a;
- QByteArray b;
-
- // Receive packet the quick way
- protocol.read() >> a >> b;
-
- // Receive packet the longer way
- QPacket packet = protocol.read();
- p >> a >> b;
- \endcode
-
- \ingroup io
- \sa QPacket
-*/
-
-class QPacketProtocolPrivate : public QObject
-{
- Q_OBJECT
-public:
- QPacketProtocolPrivate(QPacketProtocol *parent, QIODevice *_dev)
- : QObject(parent), inProgressSize(-1), maxPacketSize(MAX_PACKET_SIZE),
- waitingForPacket(false), dev(_dev)
- {
- Q_ASSERT(4 == sizeof(qint32));
-
- QObject::connect(this, SIGNAL(readyRead()),
- parent, SIGNAL(readyRead()));
- QObject::connect(this, SIGNAL(packetWritten()),
- parent, SIGNAL(packetWritten()));
- QObject::connect(this, SIGNAL(invalidPacket()),
- parent, SIGNAL(invalidPacket()));
- QObject::connect(dev, SIGNAL(readyRead()),
- this, SLOT(readyToRead()));
- QObject::connect(dev, SIGNAL(aboutToClose()),
- this, SLOT(aboutToClose()));
- QObject::connect(dev, SIGNAL(bytesWritten(qint64)),
- this, SLOT(bytesWritten(qint64)));
- }
-
-Q_SIGNALS:
- void readyRead();
- void packetWritten();
- void invalidPacket();
-
-public Q_SLOTS:
- void aboutToClose()
- {
- inProgress.clear();
- sendingPackets.clear();
- inProgressSize = -1;
- }
-
- void bytesWritten(qint64 bytes)
- {
- Q_ASSERT(!sendingPackets.isEmpty());
-
- while (bytes) {
- if (sendingPackets.at(0) > bytes) {
- sendingPackets[0] -= bytes;
- bytes = 0;
- } else {
- bytes -= sendingPackets.at(0);
- sendingPackets.removeFirst();
- emit packetWritten();
- }
- }
- }
-
- void readyToRead()
- {
- while (true) {
- // Need to get trailing data
- if (-1 == inProgressSize) {
- // We need a size header of sizeof(qint32)
- if (sizeof(qint32) > (uint)dev->bytesAvailable())
- return;
-
- // Read size header
- int read = dev->read((char *)&inProgressSize, sizeof(qint32));
- Q_ASSERT(read == sizeof(qint32));
- Q_UNUSED(read);
-
- // Check sizing constraints
- if (inProgressSize > maxPacketSize) {
- QObject::disconnect(dev, SIGNAL(readyRead()),
- this, SLOT(readyToRead()));
- QObject::disconnect(dev, SIGNAL(aboutToClose()),
- this, SLOT(aboutToClose()));
- QObject::disconnect(dev, SIGNAL(bytesWritten(qint64)),
- this, SLOT(bytesWritten(qint64)));
- dev = 0;
- emit invalidPacket();
- return;
- }
-
- inProgressSize -= sizeof(qint32);
- } else {
- inProgress.append(dev->read(inProgressSize - inProgress.size()));
-
- if (inProgressSize == inProgress.size()) {
- // Packet has arrived!
- packets.append(inProgress);
- inProgressSize = -1;
- inProgress.clear();
-
- waitingForPacket = false;
- emit readyRead();
- } else
- return;
- }
- }
- }
-
-public:
- QList<qint64> sendingPackets;
- QList<QByteArray> packets;
- QByteArray inProgress;
- qint32 inProgressSize;
- qint32 maxPacketSize;
- bool waitingForPacket;
- QIODevice *dev;
-};
-
-/*!
- Construct a QPacketProtocol instance that works on \a dev with the
- specified \a parent.
- */
-QPacketProtocol::QPacketProtocol(QIODevice *dev, QObject *parent)
- : QObject(parent), d(new QPacketProtocolPrivate(this, dev))
-{
- Q_ASSERT(dev);
-}
-
-/*!
- Destroys the QPacketProtocol instance.
- */
-QPacketProtocol::~QPacketProtocol()
-{
-}
-
-/*!
- Returns the maximum packet size allowed. By default this is
- 2,147,483,647 bytes.
-
- If a packet claiming to be larger than the maximum packet size is received,
- the QPacketProtocol::invalidPacket() signal is emitted.
-
- \sa QPacketProtocol::setMaximumPacketSize()
- */
-qint32 QPacketProtocol::maximumPacketSize() const
-{
- return d->maxPacketSize;
-}
-
-/*!
- Sets the maximum allowable packet size to \a max.
-
- \sa QPacketProtocol::maximumPacketSize()
- */
-qint32 QPacketProtocol::setMaximumPacketSize(qint32 max)
-{
- if (max > (signed)sizeof(qint32))
- d->maxPacketSize = max;
- return d->maxPacketSize;
-}
-
-/*!
- Returns a streamable object that is transmitted on destruction. For example
-
- \code
- protocol.send() << "Hello world" << 123;
- \endcode
-
- will send a packet containing "Hello world" and 123. To construct more
- complex packets, explicitly construct a QPacket instance.
- */
-QPacketAutoSend QPacketProtocol::send()
-{
- return QPacketAutoSend(this);
-}
-
-/*!
- \fn void QPacketProtocol::send(const QPacket & packet)
-
- Transmit the \a packet.
- */
-void QPacketProtocol::send(const QPacket & p)
-{
- if (p.b.isEmpty())
- return; // We don't send empty packets
-
- qint64 sendSize = p.b.size() + sizeof(qint32);
-
- d->sendingPackets.append(sendSize);
- qint32 sendSize32 = sendSize;
- qint64 writeBytes = d->dev->write((char *)&sendSize32, sizeof(qint32));
- Q_UNUSED(writeBytes);
- Q_ASSERT(writeBytes == sizeof(qint32));
- writeBytes = d->dev->write(p.b);
- Q_ASSERT(writeBytes == p.b.size());
-}
-
-/*!
- Returns the number of received packets yet to be read.
- */
-qint64 QPacketProtocol::packetsAvailable() const
-{
- return d->packets.count();
-}
-
-/*!
- Discard any unread packets.
- */
-void QPacketProtocol::clear()
-{
- d->packets.clear();
-}
-
-/*!
- Return the next unread packet, or an invalid QPacket instance if no packets
- are available. This method does NOT block.
- */
-QPacket QPacketProtocol::read()
-{
- if (0 == d->packets.count())
- return QPacket();
-
- QPacket rv(d->packets.at(0));
- d->packets.removeFirst();
- return rv;
-}
-
-/*!
- This function locks until a new packet is available for reading and the
- \l{QIODevice::}{readyRead()} signal has been emitted. The function
- will timeout after \a msecs milliseconds; the default timeout is
- 30000 milliseconds.
-
- The function returns true if the readyRead() signal is emitted and
- there is new data available for reading; otherwise it returns false
- (if an error occurred or the operation timed out).
- */
-
-bool QPacketProtocol::waitForReadyRead(int msecs)
-{
- if (!d->packets.isEmpty())
- return true;
-
- QElapsedTimer stopWatch;
- stopWatch.start();
-
- d->waitingForPacket = true;
- do {
- if (!d->dev->waitForReadyRead(msecs))
- return false;
- if (!d->waitingForPacket)
- return true;
- msecs = qt_subtract_from_timeout(msecs, stopWatch.elapsed());
- } while (true);
-}
-
-/*!
- Return the QIODevice passed to the QPacketProtocol constructor.
-*/
-QIODevice *QPacketProtocol::device()
-{
- return d->dev;
-}
-
-/*!
- \fn void QPacketProtocol::readyRead()
-
- Emitted whenever a new packet is received. Applications may use
- QPacketProtocol::read() to retrieve this packet.
- */
-
-/*!
- \fn void QPacketProtocol::invalidPacket()
-
- A packet larger than the maximum allowable packet size was received. The
- packet will be discarded and, as it indicates corruption in the protocol, no
- further packets will be received.
- */
-
-/*!
- \fn void QPacketProtocol::packetWritten()
-
- Emitted each time a packet is completing written to the device. This signal
- may be used for communications flow control.
- */
-
-/*!
- \class QPacket
- \internal
-
- \brief The QPacket class encapsulates an unfragmentable packet of data to be
- transmitted by QPacketProtocol.
-
- The QPacket class works together with QPacketProtocol to make it simple to
- send arbitrary sized data "packets" across fragmented transports such as TCP
- and UDP.
-
- QPacket provides a QDataStream interface to an unfragmentable packet.
- Applications should construct a QPacket, propagate it with data and then
- transmit it over a QPacketProtocol instance. For example:
- \code
- QPacketProtocol protocol(...);
-
- QPacket myPacket;
- myPacket << "Hello world!" << 123;
- protocol.send(myPacket);
- \endcode
-
- As long as both ends of the connection are using the QPacketProtocol class,
- the data within this packet will be delivered unfragmented at the other end,
- ready for extraction.
-
- \code
- QByteArray greeting;
- int count;
-
- QPacket myPacket = protocol.read();
-
- myPacket >> greeting >> count;
- \endcode
-
- Only packets returned from QPacketProtocol::read() may be read from. QPacket
- instances constructed by directly by applications are for transmission only
- and are considered "write only". Attempting to read data from them will
- result in undefined behavior.
-
- \ingroup io
- \sa QPacketProtocol
- */
-
-/*!
- Constructs an empty write-only packet.
- */
-QPacket::QPacket()
- : QDataStream(), buf(0)
-{
- buf = new QBuffer(&b);
- buf->open(QIODevice::WriteOnly);
- setDevice(buf);
- setVersion(QDataStream::Qt_4_7);
-}
-
-/*!
- Destroys the QPacket instance.
- */
-QPacket::~QPacket()
-{
- if (buf) {
- delete buf;
- buf = 0;
- }
-}
-
-/*!
- Creates a copy of \a other. The initial stream positions are shared, but the
- two packets are otherwise independent.
- */
-QPacket::QPacket(const QPacket & other)
- : QDataStream(), b(other.b), buf(0)
-{
- buf = new QBuffer(&b);
- buf->open(other.buf->openMode());
- setDevice(buf);
-}
-
-/*!
- \internal
- */
-QPacket::QPacket(const QByteArray & ba)
- : QDataStream(), b(ba), buf(0)
-{
- buf = new QBuffer(&b);
- buf->open(QIODevice::ReadOnly);
- setDevice(buf);
-}
-
-/*!
- Returns true if this packet is empty - that is, contains no data.
- */
-bool QPacket::isEmpty() const
-{
- return b.isEmpty();
-}
-
-/*!
- Returns raw packet data.
- */
-QByteArray QPacket::data() const
-{
- return b;
-}
-
-/*!
- Clears data in the packet. This is useful for reusing one writable packet.
- For example
- \code
- QPacketProtocol protocol(...);
-
- QPacket packet;
-
- packet << "Hello world!" << 123;
- protocol.send(packet);
-
- packet.clear();
- packet << "Goodbyte world!" << 789;
- protocol.send(packet);
- \endcode
- */
-void QPacket::clear()
-{
- QBuffer::OpenMode oldMode = buf->openMode();
- buf->close();
- b.clear();
- buf->setBuffer(&b); // reset QBuffer internals with new size of b.
- buf->open(oldMode);
-}
-
-/*!
- \class QPacketAutoSend
- \internal
-
- \internal
- */
-QPacketAutoSend::QPacketAutoSend(QPacketProtocol *_p)
- : QPacket(), p(_p)
-{
-}
-
-QPacketAutoSend::~QPacketAutoSend()
-{
- if (!b.isEmpty())
- p->send(*this);
-}
-
-QT_END_NAMESPACE
-
-#include <qpacketprotocol.moc>
diff --git a/src/plugins/qmltooling/shared/qqmlconfigurabledebugservice.h b/src/plugins/qmltooling/shared/qqmlconfigurabledebugservice.h
index 9aa4531428..52021379bc 100644
--- a/src/plugins/qmltooling/shared/qqmlconfigurabledebugservice.h
+++ b/src/plugins/qmltooling/shared/qqmlconfigurabledebugservice.h
@@ -66,7 +66,7 @@ protected:
{
QMutexLocker lock(&m_configMutex);
m_waitingForConfiguration = false;
- foreach (QQmlEngine *engine, m_waitingEngines)
+ foreach (QJSEngine *engine, m_waitingEngines)
emit Base::attachedToEngine(engine);
m_waitingEngines.clear();
}
@@ -79,7 +79,7 @@ protected:
QQmlDebugConnector::instance()->blockingMode());
}
- void stateChanged(QQmlDebugService::State newState)
+ void stateChanged(QQmlDebugService::State newState) Q_DECL_OVERRIDE
{
if (newState != QQmlDebugService::Enabled)
stopWaiting();
@@ -87,7 +87,7 @@ protected:
init();
}
- void engineAboutToBeAdded(QQmlEngine *engine)
+ void engineAboutToBeAdded(QJSEngine *engine) Q_DECL_OVERRIDE
{
QMutexLocker lock(&m_configMutex);
if (m_waitingForConfiguration)
@@ -97,7 +97,7 @@ protected:
}
QMutex m_configMutex;
- QList<QQmlEngine *> m_waitingEngines;
+ QList<QJSEngine *> m_waitingEngines;
bool m_waitingForConfiguration;
};
diff --git a/src/plugins/qmltooling/shared/qqmldebugpacket.h b/src/plugins/qmltooling/shared/qqmldebugpacket.h
new file mode 100644
index 0000000000..459937f411
--- /dev/null
+++ b/src/plugins/qmltooling/shared/qqmldebugpacket.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLDEBUGPACKET_P_H
+#define QQMLDEBUGPACKET_P_H
+
+#include <QtCore/qbuffer.h>
+#include <QtQml/private/qqmldebugconnector_p.h>
+#include <QtPacketProtocol/private/qpacket_p.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+// QPacket with a fixed data stream version, centrally set by QQmlDebugServer
+class QQmlDebugPacket : public QPacket
+{
+public:
+ QQmlDebugPacket() : QPacket(QQmlDebugConnector::dataStreamVersion()) {}
+ QQmlDebugPacket(const QByteArray &ba) : QPacket(QQmlDebugConnector::dataStreamVersion(), ba) {}
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLDEBUGPACKET_P_H
diff --git a/src/plugins/qmltooling/shared/qqmldebugserver.h b/src/plugins/qmltooling/shared/qqmldebugserver.h
index a7c17075d9..3807f12214 100644
--- a/src/plugins/qmltooling/shared/qqmldebugserver.h
+++ b/src/plugins/qmltooling/shared/qqmldebugserver.h
@@ -37,6 +37,8 @@
#include <private/qqmldebugconnector_p.h>
#include <private/qtqmlglobal_p.h>
+#include <QtCore/QIODevice>
+
//
// W A R N I N G
// -------------
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index 16c4cb28ed..d871a9add5 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -339,6 +339,7 @@ IRBuilder::IRBuilder(const QSet<QString> &illegalNames)
: illegalNames(illegalNames)
, _object(0)
, _propertyDeclaration(0)
+ , pool(0)
, jsGenerator(0)
{
}
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index cde7a2acb4..3ce3e04969 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -1244,7 +1244,7 @@ int QQmlEnumTypeResolver::evaluateEnum(const QString &scope, const QByteArray &e
imports->resolveType(scope, &type, 0, 0, 0);
if (!type)
return -1;
- return type ? type->enumValue(compiler->enginePrivate(), QHashedCStringRef(enumValue.constData(), enumValue.length()), ok) : -1;
+ return type->enumValue(compiler->enginePrivate(), QHashedCStringRef(enumValue.constData(), enumValue.length()), ok);
}
const QMetaObject *mo = StaticQtMetaObject::get();
diff --git a/src/qml/compiler/qv4jsir.cpp b/src/qml/compiler/qv4jsir.cpp
index 685825e8ea..f8cfe7da2c 100644
--- a/src/qml/compiler/qv4jsir.cpp
+++ b/src/qml/compiler/qv4jsir.cpp
@@ -164,12 +164,12 @@ struct RemoveSharedExpressions: IR::StmtVisitor, IR::ExprVisitor
subexpressions.clear();
subexpressions.reserve(function->basicBlockCount() * 8);
- foreach (BasicBlock *block, function->basicBlocks()) {
+ for (BasicBlock *block : function->basicBlocks()) {
if (block->isRemoved())
continue;
clone.setBasicBlock(block);
- foreach (Stmt *s, block->statements()) {
+ for (Stmt *s : block->statements()) {
s->accept(this);
}
}
@@ -451,7 +451,7 @@ void Function::removeBasicBlock(BasicBlock *block)
int Function::liveBasicBlocksCount() const
{
int count = 0;
- foreach (BasicBlock *bb, basicBlocks())
+ for (BasicBlock *bb : basicBlocks())
if (!bb->isRemoved())
++count;
return count;
@@ -507,7 +507,7 @@ void Function::setStatementCount(int cnt)
BasicBlock::~BasicBlock()
{
- foreach (Stmt *s, _statements) {
+ for (Stmt *s : qAsConst(_statements)) {
Phi *p = s->asPhi();
if (p)
p->destroyData();
@@ -558,7 +558,7 @@ Expr *BasicBlock::CONST(Type type, double value)
} else if (type == NullType) {
value = 0;
} else if (type == UndefinedType) {
- value = qSNaN();
+ value = qQNaN();
}
e->init(type, value);
@@ -764,7 +764,7 @@ void BasicBlock::setStatements(const QVector<Stmt *> &newStatements)
Q_ASSERT(!isRemoved());
Q_ASSERT(newStatements.size() >= _statements.size());
// FIXME: this gets quite inefficient for large basic-blocks, so this function/case should be re-worked.
- foreach (Stmt *s, _statements) {
+ for (Stmt *s : qAsConst(_statements)) {
Phi *p = s->asPhi();
if (!p)
continue;
@@ -978,11 +978,11 @@ void IRPrinter::print(Function *f)
*out << ')' << endl
<< '{' << endl;
- foreach (const QString *local, f->locals)
+ for (const QString *local : qAsConst(f->locals))
*out << " local var " << *local << endl;
bool needsSeperator = !f->locals.isEmpty();
- foreach (BasicBlock *bb, f->basicBlocks()) {
+ for (BasicBlock *bb : f->basicBlocks()) {
if (bb->isRemoved())
continue;
@@ -1000,7 +1000,7 @@ void IRPrinter::print(BasicBlock *bb)
std::swap(currentBB, bb);
printBlockStart();
- foreach (Stmt *s, currentBB->statements()) {
+ for (Stmt *s : currentBB->statements()) {
if (!s)
continue;
@@ -1315,7 +1315,7 @@ void IRPrinter::printBlockStart()
*out << str;
*out << "; predecessors:";
- foreach (BasicBlock *in, currentBB->in)
+ for (BasicBlock *in : qAsConst(currentBB->in))
*out << " L" << in->index();
if (currentBB->in.isEmpty())
*out << " none";
diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp
index f20dbbf4fe..de4ab8dae5 100644
--- a/src/qml/compiler/qv4ssa.cpp
+++ b/src/qml/compiler/qv4ssa.cpp
@@ -2771,7 +2771,7 @@ void convertConst(Const *c, Type targetType)
break;
case NullType:
case UndefinedType:
- c->value = qSNaN();
+ c->value = qQNaN();
c->type = targetType;
default:
Q_UNIMPLEMENTED();
diff --git a/src/qml/debugger/qqmlabstractprofileradapter_p.h b/src/qml/debugger/qqmlabstractprofileradapter_p.h
index bfd1561d3d..c723224985 100644
--- a/src/qml/debugger/qqmlabstractprofileradapter_p.h
+++ b/src/qml/debugger/qqmlabstractprofileradapter_p.h
@@ -58,9 +58,10 @@ class Q_QML_PRIVATE_EXPORT QQmlAbstractProfilerAdapter : public QObject, public
Q_OBJECT
public:
- QQmlAbstractProfilerAdapter(QQmlProfilerService *service) :
- service(service), waiting(true), featuresEnabled(0) {}
+ QQmlAbstractProfilerAdapter(QObject *parent = 0) :
+ QObject(parent), service(0), waiting(true), featuresEnabled(0) {}
virtual ~QQmlAbstractProfilerAdapter() {}
+ void setService(QQmlProfilerService *new_service) { service = new_service; }
virtual qint64 sendMessages(qint64 until, QList<QByteArray> &messages) = 0;
@@ -96,6 +97,15 @@ private:
quint64 featuresEnabled;
};
+class Q_QML_PRIVATE_EXPORT QQmlAbstractProfilerAdapterFactory : public QObject
+{
+ Q_OBJECT
+public:
+ virtual QQmlAbstractProfilerAdapter *create(const QString &key) = 0;
+};
+
+#define QQmlAbstractProfilerAdapterFactory_iid "org.qt-project.Qt.QQmlAbstractProfilerAdapterFactory"
+
QT_END_NAMESPACE
#endif // QQMLABSTRACTPROFILERADAPTER_P_H
diff --git a/src/qml/debugger/qqmldebug.cpp b/src/qml/debugger/qqmldebug.cpp
index 35dc110e9a..b308f5aa29 100644
--- a/src/qml/debugger/qqmldebug.cpp
+++ b/src/qml/debugger/qqmldebug.cpp
@@ -33,6 +33,7 @@
#include "qqmldebug.h"
#include "qqmldebugconnector_p.h"
+#include "qqmldebugserviceinterfaces_p.h"
#include <private/qqmlengine_p.h>
@@ -52,10 +53,64 @@ QQmlDebuggingEnabler::QQmlDebuggingEnabler(bool printWarning)
}
/*!
+ * Retrieves the plugin keys of the debugger services provided by default. The debugger services
+ * enable a debug client to use a Qml/JavaScript debugger, in order to set breakpoints, pause
+ * execution, evaluate expressions and similar debugging tasks.
+ * \return List of plugin keys of default debugger services.
+ */
+QStringList QQmlDebuggingEnabler::debuggerServices()
+{
+ return QStringList() << QV4DebugService::s_key << QQmlEngineDebugService::s_key
+ << QDebugMessageService::s_key;
+}
+
+/*!
+ * Retrieves the plugin keys of the inspector services provided by default. The inspector services
+ * enable a debug client to use a visual inspector tool for Qt Quick.
+ * \return List of plugin keys of default inspector services.
+ */
+QStringList QQmlDebuggingEnabler::inspectorServices()
+{
+ return QStringList() << QQmlInspectorService::s_key;
+}
+
+/*!
+ * Retrieves the names of the profiler services provided by default. The profiler services enable a
+ * debug client to use a profiler and track the time taken by various QML and JavaScript constructs,
+ * as well as the QtQuick SceneGraph.
+ * \return List of plugin keys of default profiler services.
+ */
+QStringList QQmlDebuggingEnabler::profilerServices()
+{
+ return QStringList() << QQmlProfilerService::s_key << QQmlEngineControlService::s_key;
+}
+
+/*!
+ * Restricts the services available from the debug connector. The connector will scan plugins in the
+ * "qmltooling" subdirectory of the default plugin path. If this function is not called before the
+ * debug connector is enabled, all services found that way will be available to any client. If this
+ * function is called, only the services with plugin keys given in \a services will be available.
+ *
+ * Use this method to disable debugger and inspector services when profiling to get better
+ * performance and more realistic profiles. The debugger service will put any JavaScript engine it
+ * connects to into interpreted mode, disabling the JIT compiler.
+ *
+ * \sa debuggerServices(), profilerServices(), inspectorServices()
+ */
+void QQmlDebuggingEnabler::setServices(const QStringList &services)
+{
+#ifndef QQML_NO_DEBUG_PROTOCOL
+ QQmlDebugConnector::setServices(services);
+#else
+ Q_UNUSED(services);
+#endif
+}
+
+/*!
* \enum QQmlDebuggingEnabler::StartMode
*
- * Defines the debug server's start behavior. You can interrupt QML engines starting while a debug
- * client is connecting, in order to set breakpoints in or profile startup code.
+ * Defines the debug connector's start behavior. You can interrupt QML engines starting while a
+ * debug client is connecting, in order to set breakpoints in or profile startup code.
*
* \value DoNotWaitForClient Run any QML engines as usual while the debug services are connecting.
* \value WaitForClient If a QML engine starts while the debug services are connecting,
@@ -63,13 +118,13 @@ QQmlDebuggingEnabler::QQmlDebuggingEnabler(bool printWarning)
*/
/*!
- * Enables debugging for QML engines created after calling this function. The debug server will
+ * Enables debugging for QML engines created after calling this function. The debug connector will
* listen on \a port at \a hostName and block the QML engine until it receives a connection if
* \a mode is \c WaitForClient. If \a mode is not specified it won't block and if \a hostName is not
- * specified it will listen on all available interfaces. You can only start one debug server at a
- * time. A debug server may have already been started if the -qmljsdebugger= command line argument
- * was given. This method returns \c true if a new debug server was successfully started, or
- * \c false otherwise.
+ * specified it will listen on all available interfaces. You can only start one debug connector at a
+ * time. A debug connector may have already been started if the -qmljsdebugger= command line
+ * argument was given. This method returns \c true if a new debug connector was successfully
+ * started, or \c false otherwise.
*/
bool QQmlDebuggingEnabler::startTcpDebugServer(int port, StartMode mode, const QString &hostName)
{
@@ -85,7 +140,7 @@ bool QQmlDebuggingEnabler::startTcpDebugServer(int port, StartMode mode, const Q
}
#else
Q_UNUSED(port);
- Q_UNUSED(block);
+ Q_UNUSED(mode);
Q_UNUSED(hostName);
#endif
return false;
@@ -94,12 +149,12 @@ bool QQmlDebuggingEnabler::startTcpDebugServer(int port, StartMode mode, const Q
/*!
* \since 5.6
*
- * Enables debugging for QML engines created after calling this function. The debug server will
+ * Enables debugging for QML engines created after calling this function. The debug connector will
* connect to a debugger waiting on a local socket at the given \a socketFileName and block the QML
* engine until the connection is established if \a mode is \c WaitForClient. If \a mode is not
- * specified it will not block. You can only start one debug server at a time. A debug server may
- * have already been started if the -qmljsdebugger= command line argument was given. This method
- * returns \c true if a new debug server was successfully started, or \c false otherwise.
+ * specified it will not block. You can only start one debug connector at a time. A debug connector
+ * may have already been started if the -qmljsdebugger= command line argument was given. This method
+ * returns \c true if a new debug connector was successfully started, or \c false otherwise.
*/
bool QQmlDebuggingEnabler::connectToLocalDebugger(const QString &socketFileName, StartMode mode)
{
@@ -114,7 +169,7 @@ bool QQmlDebuggingEnabler::connectToLocalDebugger(const QString &socketFileName,
}
#else
Q_UNUSED(fileName);
- Q_UNUSED(block);
+ Q_UNUSED(mode);
#endif
return false;
}
diff --git a/src/qml/debugger/qqmldebug.h b/src/qml/debugger/qqmldebug.h
index 5d65982a49..6316ebd195 100644
--- a/src/qml/debugger/qqmldebug.h
+++ b/src/qml/debugger/qqmldebug.h
@@ -48,6 +48,13 @@ struct Q_QML_EXPORT QQmlDebuggingEnabler
};
QQmlDebuggingEnabler(bool printWarning = true);
+
+ static QStringList debuggerServices();
+ static QStringList inspectorServices();
+ static QStringList profilerServices();
+
+ static void setServices(const QStringList &services);
+
static bool startTcpDebugServer(int port, StartMode mode = DoNotWaitForClient,
const QString &hostName = QString());
static bool connectToLocalDebugger(const QString &socketFileName,
diff --git a/src/qml/debugger/qqmldebugconnector.cpp b/src/qml/debugger/qqmldebugconnector.cpp
index 64a8a49bb9..7d9f462fe2 100644
--- a/src/qml/debugger/qqmldebugconnector.cpp
+++ b/src/qml/debugger/qqmldebugconnector.cpp
@@ -39,6 +39,7 @@
#include <QtCore/QDir>
#include <QtCore/QDebug>
#include <QtCore/QJsonArray>
+#include <QtCore/QDataStream>
#include <private/qcoreapplication_p.h>
#include <private/qqmlengine_p.h>
@@ -56,6 +57,8 @@ Q_QML_IMPORT_DEBUG_PLUGIN(QQmlInspectorServiceFactory)
Q_QML_IMPORT_DEBUG_PLUGIN(QQmlProfilerServiceFactory)
Q_QML_IMPORT_DEBUG_PLUGIN(QQmlDebuggerServiceFactory)
+int QQmlDebugConnector::s_dataStreamVersion = QDataStream::Qt_4_7;
+
struct QQmlDebugConnectorParams {
QString pluginKey;
QStringList services;
diff --git a/src/qml/debugger/qqmldebugconnector_p.h b/src/qml/debugger/qqmldebugconnector_p.h
index f5f5a87b56..b64e873328 100644
--- a/src/qml/debugger/qqmldebugconnector_p.h
+++ b/src/qml/debugger/qqmldebugconnector_p.h
@@ -35,6 +35,7 @@
#define QQMLDEBUGCONNECTOR_H
#include <QtQml/qtqmlglobal.h>
+#include <QtQml/qjsengine.h>
#include <QtCore/QVariantList>
#include <private/qqmldebugservice_p.h>
@@ -60,13 +61,18 @@ public:
static void setPluginKey(const QString &key);
static void setServices(const QStringList &services);
static QQmlDebugConnector *instance();
+ static int dataStreamVersion()
+ {
+ return s_dataStreamVersion;
+ }
virtual bool blockingMode() const = 0;
virtual QQmlDebugService *service(const QString &name) const = 0;
- virtual void addEngine(QQmlEngine *engine) = 0;
- virtual void removeEngine(QQmlEngine *engine) = 0;
+ virtual void addEngine(QJSEngine *engine) = 0;
+ virtual void removeEngine(QJSEngine *engine) = 0;
+ virtual bool hasEngine(QJSEngine *engine) const = 0;
virtual bool addService(const QString &name, QQmlDebugService *service) = 0;
virtual bool removeService(const QString &name) = 0;
@@ -82,6 +88,7 @@ public:
protected:
static QString commandLineArguments();
+ static int s_dataStreamVersion;
};
class Q_QML_PRIVATE_EXPORT QQmlDebugConnectorFactory : public QObject {
diff --git a/src/qml/debugger/qqmldebugservice.cpp b/src/qml/debugger/qqmldebugservice.cpp
index 0b07f320ec..f46a924d5e 100644
--- a/src/qml/debugger/qqmldebugservice.cpp
+++ b/src/qml/debugger/qqmldebugservice.cpp
@@ -182,50 +182,24 @@ void QQmlDebugService::messageReceived(const QByteArray &)
{
}
-void QQmlDebugService::engineAboutToBeAdded(QQmlEngine *engine)
+void QQmlDebugService::engineAboutToBeAdded(QJSEngine *engine)
{
emit attachedToEngine(engine);
}
-void QQmlDebugService::engineAboutToBeRemoved(QQmlEngine *engine)
+void QQmlDebugService::engineAboutToBeRemoved(QJSEngine *engine)
{
emit detachedFromEngine(engine);
}
-void QQmlDebugService::engineAdded(QQmlEngine *)
+void QQmlDebugService::engineAdded(QJSEngine *)
{
}
-void QQmlDebugService::engineRemoved(QQmlEngine *)
+void QQmlDebugService::engineRemoved(QJSEngine *)
{
}
-int QQmlDebugStream::s_dataStreamVersion = QDataStream::Qt_4_7;
-
-QQmlDebugStream::QQmlDebugStream()
- : QDataStream()
-{
- setVersion(s_dataStreamVersion);
-}
-
-QQmlDebugStream::QQmlDebugStream(QIODevice *d)
- : QDataStream(d)
-{
- setVersion(s_dataStreamVersion);
-}
-
-QQmlDebugStream::QQmlDebugStream(QByteArray *ba, QIODevice::OpenMode flags)
- : QDataStream(ba, flags)
-{
- setVersion(s_dataStreamVersion);
-}
-
-QQmlDebugStream::QQmlDebugStream(const QByteArray &ba)
- : QDataStream(ba)
-{
- setVersion(s_dataStreamVersion);
-}
-
QT_END_NAMESPACE
#include "qqmldebugservice.moc"
diff --git a/src/qml/debugger/qqmldebugservice_p.h b/src/qml/debugger/qqmldebugservice_p.h
index 3d692133cc..0fcf5459ef 100644
--- a/src/qml/debugger/qqmldebugservice_p.h
+++ b/src/qml/debugger/qqmldebugservice_p.h
@@ -35,7 +35,6 @@
#define QQMLDEBUGSERVICE_H
#include <QtCore/qobject.h>
-#include <QtCore/qdatastream.h>
#include <QtCore/qhash.h>
#include <private/qtqmlglobal_p.h>
@@ -53,7 +52,7 @@
QT_BEGIN_NAMESPACE
-class QQmlEngine;
+class QJSEngine;
class QQmlDebugServicePrivate;
class Q_QML_PRIVATE_EXPORT QQmlDebugService : public QObject
@@ -76,10 +75,10 @@ public:
virtual void stateChanged(State);
virtual void messageReceived(const QByteArray &);
- virtual void engineAboutToBeAdded(QQmlEngine *);
- virtual void engineAboutToBeRemoved(QQmlEngine *);
- virtual void engineAdded(QQmlEngine *);
- virtual void engineRemoved(QQmlEngine *);
+ virtual void engineAboutToBeAdded(QJSEngine *);
+ virtual void engineAboutToBeRemoved(QJSEngine *);
+ virtual void engineAdded(QJSEngine *);
+ virtual void engineRemoved(QJSEngine *);
static const QHash<int, QObject *> &objectsForIds();
static int idForObject(QObject *);
@@ -89,24 +88,13 @@ protected:
explicit QQmlDebugService(const QString &, float version, QObject *parent = 0);
signals:
- void attachedToEngine(QQmlEngine *);
- void detachedFromEngine(QQmlEngine *);
+ void attachedToEngine(QJSEngine *);
+ void detachedFromEngine(QJSEngine *);
void messageToClient(const QString &name, const QByteArray &message);
void messagesToClient(const QString &name, const QList<QByteArray> &messages);
};
-class Q_QML_PRIVATE_EXPORT QQmlDebugStream : public QDataStream
-{
-public:
- static int s_dataStreamVersion;
-
- QQmlDebugStream();
- explicit QQmlDebugStream(QIODevice *d);
- QQmlDebugStream(QByteArray *ba, QIODevice::OpenMode flags);
- QQmlDebugStream(const QByteArray &ba);
-};
-
QT_END_NAMESPACE
#endif // QQMLDEBUGSERVICE_H
diff --git a/src/qml/debugger/qqmldebugserviceinterfaces.cpp b/src/qml/debugger/qqmldebugserviceinterfaces.cpp
index 199c682748..e0968b2656 100644
--- a/src/qml/debugger/qqmldebugserviceinterfaces.cpp
+++ b/src/qml/debugger/qqmldebugserviceinterfaces.cpp
@@ -39,6 +39,8 @@ const QString QV4DebugService::s_key = QStringLiteral("V8Debugger");
const QString QQmlEngineDebugService::s_key = QStringLiteral("QmlDebugger");
const QString QQmlInspectorService::s_key = QStringLiteral("QmlInspector");
const QString QQmlProfilerService::s_key = QStringLiteral("CanvasFrameRate");
+const QString QDebugMessageService::s_key = QStringLiteral("DebugMessages");
+const QString QQmlEngineControlService::s_key = QStringLiteral("EngineControl");
const QString QQmlNativeDebugService::s_key = QStringLiteral("NativeQmlDebugger");
QT_END_NAMESPACE
diff --git a/src/qml/debugger/qqmldebugserviceinterfaces_p.h b/src/qml/debugger/qqmldebugserviceinterfaces_p.h
index 6391bc6218..1b45392680 100644
--- a/src/qml/debugger/qqmldebugserviceinterfaces_p.h
+++ b/src/qml/debugger/qqmldebugserviceinterfaces_p.h
@@ -60,6 +60,8 @@ class Q_QML_PRIVATE_EXPORT QV4DebugService : protected QQmlDebugService
{
Q_OBJECT
public:
+ static const QString s_key;
+
virtual void signalEmitted(const QString &signal) = 0;
protected:
@@ -67,20 +69,20 @@ protected:
QV4DebugService(float version, QObject *parent = 0) :
QQmlDebugService(s_key, version, parent) {}
-
- static const QString s_key;
};
class Q_QML_PRIVATE_EXPORT QQmlProfilerService : protected QQmlDebugService
{
Q_OBJECT
public:
+ static const QString s_key;
+
virtual void addGlobalProfiler(QQmlAbstractProfilerAdapter *profiler) = 0;
virtual void removeGlobalProfiler(QQmlAbstractProfilerAdapter *profiler) = 0;
- virtual void startProfiling(QQmlEngine *engine,
+ virtual void startProfiling(QJSEngine *engine,
quint64 features = std::numeric_limits<quint64>::max()) = 0;
- virtual void stopProfiling(QQmlEngine *engine) = 0;
+ virtual void stopProfiling(QJSEngine *engine) = 0;
virtual void dataReady(QQmlAbstractProfilerAdapter *profiler) = 0;
@@ -89,15 +91,15 @@ protected:
QQmlProfilerService(float version, QObject *parent = 0) :
QQmlDebugService(s_key, version, parent) {}
-
- static const QString s_key;
};
class Q_QML_PRIVATE_EXPORT QQmlEngineDebugService : protected QQmlDebugService
{
Q_OBJECT
public:
- virtual void objectCreated(QQmlEngine *engine, QObject *object) = 0;
+ static const QString s_key;
+
+ virtual void objectCreated(QJSEngine *engine, QObject *object) = 0;
virtual void setStatesDelegate(QQmlDebugStatesDelegate *) = 0;
protected:
@@ -107,14 +109,14 @@ protected:
QQmlDebugService(s_key, version, parent) {}
QQmlBoundSignal *nextSignal(QQmlBoundSignal *prev) { return prev->m_nextSignal; }
-
- static const QString s_key;
};
class Q_QML_PRIVATE_EXPORT QQmlInspectorService : protected QQmlDebugService
{
Q_OBJECT
public:
+ static const QString s_key;
+
virtual void addView(QObject *) = 0;
virtual void removeView(QObject *) = 0;
@@ -123,8 +125,35 @@ protected:
QQmlInspectorService(float version, QObject *parent = 0) :
QQmlDebugService(s_key, version, parent) {}
+};
+
+class Q_QML_PRIVATE_EXPORT QDebugMessageService : protected QQmlDebugService
+{
+ Q_OBJECT
+public:
+ static const QString s_key;
+
+ virtual void synchronizeTime(const QElapsedTimer &otherTimer) = 0;
+
+protected:
+ friend class QQmlDebugConnector;
+
+ QDebugMessageService(float version, QObject *parent = 0) :
+ QQmlDebugService(s_key, version, parent) {}
+};
+class Q_QML_PRIVATE_EXPORT QQmlEngineControlService : protected QQmlDebugService
+{
+ Q_OBJECT
+public:
static const QString s_key;
+
+protected:
+ friend class QQmlDebugConnector;
+
+ QQmlEngineControlService(float version, QObject *parent = 0) :
+ QQmlDebugService(s_key, version, parent) {}
+
};
class Q_QML_PRIVATE_EXPORT QQmlNativeDebugService : protected QQmlDebugService
diff --git a/src/qml/debugger/qqmlprofilerdefinitions_p.h b/src/qml/debugger/qqmlprofilerdefinitions_p.h
index 1213b67b3c..ce708132f8 100644
--- a/src/qml/debugger/qqmlprofilerdefinitions_p.h
+++ b/src/qml/debugger/qqmlprofilerdefinitions_p.h
@@ -89,9 +89,6 @@ struct QQmlProfilerDefinitions {
enum BindingType {
QmlBinding,
- V8Binding,
- V4Binding,
-
MaximumBindingType
};
@@ -126,8 +123,8 @@ struct QQmlProfilerDefinitions {
typedef QV4::Profiling::MemoryType MemoryType;
enum ProfileFeature {
- ProfileJavaScript = QV4::Profiling::FeatureFunctionCall,
- ProfileMemory = QV4::Profiling::FeatureMemoryAllocation,
+ ProfileJavaScript,
+ ProfileMemory,
ProfilePixmapCache,
ProfileSceneGraph,
ProfileAnimations,
@@ -137,9 +134,25 @@ struct QQmlProfilerDefinitions {
ProfileBinding,
ProfileHandlingSignal,
ProfileInputEvents,
+ ProfileDebugMessages,
MaximumProfileFeature
};
+
+ enum InputEventType {
+ InputKeyPress,
+ InputKeyRelease,
+ InputKeyUnknown,
+
+ InputMousePress,
+ InputMouseRelease,
+ InputMouseMove,
+ InputMouseDoubleClick,
+ InputMouseWheel,
+ InputMouseUnknown,
+
+ MaximumInputEventType
+ };
};
QT_END_NAMESPACE
diff --git a/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc b/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc
index 9eb792bd2e..71db34695c 100644
--- a/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc
+++ b/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc
@@ -291,6 +291,7 @@ default locations to be searched by the engine. By default, this list contains:
\li The directory of the current file
\li The location specified by QLibraryInfo::Qml2ImportsPath
\li Paths specified by the \c QML2_IMPORT_PATH environment variable
+\li The qrc:/qt-project.org/imports path inside the resources.
\endlist
Additional import paths can be added through QQmlEngine::addImportPath() or the
diff --git a/src/qml/jit/qv4binop.cpp b/src/qml/jit/qv4binop.cpp
index 8b051fcb3d..ee4611525c 100644
--- a/src/qml/jit/qv4binop.cpp
+++ b/src/qml/jit/qv4binop.cpp
@@ -341,8 +341,8 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *ta
case IR::OpBitXor:
case IR::OpAdd:
case IR::OpMul:
- break;
inplaceOpWithAddress = true;
+ break;
default:
break;
}
diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp
index 5ccbccebad..80dce129c7 100644
--- a/src/qml/jsapi/qjsengine.cpp
+++ b/src/qml/jsapi/qjsengine.cpp
@@ -43,6 +43,7 @@
#include "private/qv4script_p.h"
#include "private/qv4runtime_p.h"
#include <private/qqmlbuiltinfunctions_p.h>
+#include <private/qqmldebugconnector_p.h>
#include <QtCore/qdatetime.h>
#include <QtCore/qmetaobject.h>
@@ -251,6 +252,7 @@ QJSEngine::QJSEngine()
: QObject(*new QJSEnginePrivate, 0)
, d(new QV8Engine(this))
{
+ QJSEnginePrivate::addToDebugServer(this);
}
/*!
@@ -264,6 +266,7 @@ QJSEngine::QJSEngine(QObject *parent)
: QObject(*new QJSEnginePrivate, parent)
, d(new QV8Engine(this))
{
+ QJSEnginePrivate::addToDebugServer(this);
}
/*!
@@ -284,6 +287,7 @@ QJSEngine::QJSEngine(QJSEnginePrivate &dd, QObject *parent)
*/
QJSEngine::~QJSEngine()
{
+ QJSEnginePrivate::removeFromDebugServer(this);
delete d;
}
@@ -671,6 +675,26 @@ QJSEnginePrivate::~QJSEnginePrivate()
(*iter)->release();
}
+void QJSEnginePrivate::addToDebugServer(QJSEngine *q)
+{
+ if (QCoreApplication::instance()->thread() != q->thread())
+ return;
+
+ QQmlDebugConnector *server = QQmlDebugConnector::instance();
+ if (!server || server->hasEngine(q))
+ return;
+
+ server->open();
+ server->addEngine(q);
+}
+
+void QJSEnginePrivate::removeFromDebugServer(QJSEngine *q)
+{
+ QQmlDebugConnector *server = QQmlDebugConnector::instance();
+ if (server && server->hasEngine(q))
+ server->removeEngine(q);
+}
+
QQmlPropertyCache *QJSEnginePrivate::createCache(const QMetaObject *mo)
{
if (!mo->superClass()) {
diff --git a/src/qml/jsapi/qjsengine_p.h b/src/qml/jsapi/qjsengine_p.h
index 8fdec08085..1fb8dc6fb2 100644
--- a/src/qml/jsapi/qjsengine_p.h
+++ b/src/qml/jsapi/qjsengine_p.h
@@ -70,6 +70,9 @@ public:
QJSEnginePrivate() : mutex(QMutex::Recursive) {}
~QJSEnginePrivate();
+ static void addToDebugServer(QJSEngine *q);
+ static void removeFromDebugServer(QJSEngine *q);
+
// Locker locks the QQmlEnginePrivate data structures for read and write, if necessary.
// Currently, locking is only necessary if the threaded loader is running concurrently. If it is
// either idle, or is running with the main thread blocked, no locking is necessary. This way
diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp
index a49b98c921..30d79e13d5 100644
--- a/src/qml/jsapi/qjsvalue.cpp
+++ b/src/qml/jsapi/qjsvalue.cpp
@@ -1147,6 +1147,9 @@ void QJSValue::setProperty(quint32 arrayIndex, const QJSValue& value)
bool QJSValue::deleteProperty(const QString &name)
{
QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
+ if (!engine)
+ return false;
+
Scope scope(engine);
ScopedObject o(scope, QJSValuePrivate::getValue(this));
if (!o)
diff --git a/src/qml/jsapi/qjsvalueiterator_p.h b/src/qml/jsapi/qjsvalueiterator_p.h
index dfc5e18cd6..4aa41fdefa 100644
--- a/src/qml/jsapi/qjsvalueiterator_p.h
+++ b/src/qml/jsapi/qjsvalueiterator_p.h
@@ -50,8 +50,6 @@
QT_BEGIN_NAMESPACE
-class QV8Engine;
-
class QJSValueIteratorPrivate
{
public:
diff --git a/src/qml/jsruntime/jsruntime.pri b/src/qml/jsruntime/jsruntime.pri
index 5ffdebe328..57ad85485a 100644
--- a/src/qml/jsruntime/jsruntime.pri
+++ b/src/qml/jsruntime/jsruntime.pri
@@ -111,6 +111,4 @@ valgrind {
DEFINES += V4_USE_VALGRIND
}
-ios: DEFINES += ENABLE_ASSEMBLER_WX_EXCLUSIVE=1
-
-include(../../3rdparty/double-conversion/double-conversion.pri)
+ios|tvos: DEFINES += ENABLE_ASSEMBLER_WX_EXCLUSIVE=1
diff --git a/src/qml/jsruntime/qv4dataview.cpp b/src/qml/jsruntime/qv4dataview.cpp
index 8901834e76..cd28c03fa3 100644
--- a/src/qml/jsruntime/qv4dataview.cpp
+++ b/src/qml/jsruntime/qv4dataview.cpp
@@ -285,7 +285,7 @@ ReturnedValue DataViewPrototype::method_setFloat(CallContext *ctx)
return scope.engine->throwTypeError();
idx += v->d()->byteOffset;
- double val = ctx->argc() >= 2 ? ctx->args()[1].toNumber() : qSNaN();
+ double val = ctx->argc() >= 2 ? ctx->args()[1].toNumber() : qQNaN();
bool littleEndian = ctx->argc() < 3 ? false : ctx->args()[2].toBoolean();
if (sizeof(T) == 4) {
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp
index a6e1f47d91..d414ec2084 100644
--- a/src/qml/jsruntime/qv4dateobject.cpp
+++ b/src/qml/jsruntime/qv4dateobject.cpp
@@ -198,7 +198,7 @@ static inline double MonthFromTime(double t)
else if (d < 365.0 + l)
return 11;
- return qSNaN(); // ### assert?
+ return qQNaN(); // ### assert?
}
static inline double DateFromTime(double t)
@@ -222,7 +222,7 @@ static inline double DateFromTime(double t)
case 11: return d - 333.0 - l;
}
- return qSNaN(); // ### assert
+ return qQNaN(); // ### assert
}
static inline double WeekDay(double t)
@@ -254,7 +254,7 @@ static inline double DayFromMonth(double month, double leap)
case 11: return 334.0 + leap;
}
- return qSNaN(); // ### assert?
+ return qQNaN(); // ### assert?
}
static double MakeDay(double year, double month, double day)
@@ -333,7 +333,7 @@ static inline double currentTime()
static inline double TimeClip(double t)
{
if (! qIsFinite(t) || fabs(t) > 8.64e15)
- return qSNaN();
+ return qQNaN();
return Primitive::toInteger(t);
}
@@ -538,7 +538,7 @@ static inline double ParseString(const QString &s)
}
}
if (!dt.isValid())
- return qSNaN();
+ return qQNaN();
return dt.toMSecsSinceEpoch();
}
@@ -630,7 +630,7 @@ DEFINE_OBJECT_VTABLE(DateObject);
Heap::DateObject::DateObject(const QDateTime &date)
{
- this->date = date.isValid() ? date.toMSecsSinceEpoch() : qSNaN();
+ this->date = date.isValid() ? date.toMSecsSinceEpoch() : qQNaN();
}
QDateTime DateObject::toQDateTime() const
@@ -764,7 +764,7 @@ double DatePrototype::getThisDate(ExecutionContext *ctx)
ReturnedValue DatePrototype::method_parse(CallContext *ctx)
{
if (!ctx->argc())
- return Encode(qSNaN());
+ return Encode(qQNaN());
return Encode(ParseString(ctx->args()[0].toQString()));
}
@@ -994,7 +994,7 @@ ReturnedValue DatePrototype::method_setTime(CallContext *ctx)
if (!self)
return ctx->engine()->throwTypeError();
- double t = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
+ double t = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN();
self->setDate(TimeClip(t));
return Encode(self->date());
}
@@ -1007,7 +1007,7 @@ ReturnedValue DatePrototype::method_setMilliseconds(CallContext *ctx)
return ctx->engine()->throwTypeError();
double t = LocalTime(self->date());
- double ms = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
+ double ms = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN();
self->setDate(TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)))));
return Encode(self->date());
}
@@ -1019,7 +1019,7 @@ ReturnedValue DatePrototype::method_setUTCMilliseconds(CallContext *ctx)
return ctx->engine()->throwTypeError();
double t = self->date();
- double ms = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
+ double ms = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN();
self->setDate(TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms))));
return Encode(self->date());
}
@@ -1031,7 +1031,7 @@ ReturnedValue DatePrototype::method_setSeconds(CallContext *ctx)
return ctx->engine()->throwTypeError();
double t = LocalTime(self->date());
- double sec = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
+ double sec = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN();
double ms = (ctx->argc() < 2) ? msFromTime(t) : ctx->args()[1].toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms))));
self->setDate(t);
@@ -1045,7 +1045,7 @@ ReturnedValue DatePrototype::method_setUTCSeconds(CallContext *ctx)
return ctx->engine()->throwTypeError();
double t = self->date();
- double sec = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
+ double sec = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN();
double ms = (ctx->argc() < 2) ? msFromTime(t) : ctx->args()[1].toNumber();
t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms)));
self->setDate(t);
@@ -1059,7 +1059,7 @@ ReturnedValue DatePrototype::method_setMinutes(CallContext *ctx)
return ctx->engine()->throwTypeError();
double t = LocalTime(self->date());
- double min = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
+ double min = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN();
double sec = (ctx->argc() < 2) ? SecFromTime(t) : ctx->args()[1].toNumber();
double ms = (ctx->argc() < 3) ? msFromTime(t) : ctx->args()[2].toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms))));
@@ -1074,7 +1074,7 @@ ReturnedValue DatePrototype::method_setUTCMinutes(CallContext *ctx)
return ctx->engine()->throwTypeError();
double t = self->date();
- double min = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
+ double min = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN();
double sec = (ctx->argc() < 2) ? SecFromTime(t) : ctx->args()[1].toNumber();
double ms = (ctx->argc() < 3) ? msFromTime(t) : ctx->args()[2].toNumber();
t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms)));
@@ -1089,7 +1089,7 @@ ReturnedValue DatePrototype::method_setHours(CallContext *ctx)
return ctx->engine()->throwTypeError();
double t = LocalTime(self->date());
- double hour = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
+ double hour = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN();
double min = (ctx->argc() < 2) ? MinFromTime(t) : ctx->args()[1].toNumber();
double sec = (ctx->argc() < 3) ? SecFromTime(t) : ctx->args()[2].toNumber();
double ms = (ctx->argc() < 4) ? msFromTime(t) : ctx->args()[3].toNumber();
@@ -1105,7 +1105,7 @@ ReturnedValue DatePrototype::method_setUTCHours(CallContext *ctx)
return ctx->engine()->throwTypeError();
double t = self->date();
- double hour = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
+ double hour = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN();
double min = (ctx->argc() < 2) ? MinFromTime(t) : ctx->args()[1].toNumber();
double sec = (ctx->argc() < 3) ? SecFromTime(t) : ctx->args()[2].toNumber();
double ms = (ctx->argc() < 4) ? msFromTime(t) : ctx->args()[3].toNumber();
@@ -1121,7 +1121,7 @@ ReturnedValue DatePrototype::method_setDate(CallContext *ctx)
return ctx->engine()->throwTypeError();
double t = LocalTime(self->date());
- double date = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
+ double date = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN();
t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t))));
self->setDate(t);
return Encode(self->date());
@@ -1134,7 +1134,7 @@ ReturnedValue DatePrototype::method_setUTCDate(CallContext *ctx)
return ctx->engine()->throwTypeError();
double t = self->date();
- double date = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
+ double date = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN();
t = TimeClip(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t)));
self->setDate(t);
return Encode(self->date());
@@ -1147,7 +1147,7 @@ ReturnedValue DatePrototype::method_setMonth(CallContext *ctx)
return ctx->engine()->throwTypeError();
double t = LocalTime(self->date());
- double month = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
+ double month = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN();
double date = (ctx->argc() < 2) ? DateFromTime(t) : ctx->args()[1].toNumber();
t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t))));
self->setDate(t);
@@ -1161,7 +1161,7 @@ ReturnedValue DatePrototype::method_setUTCMonth(CallContext *ctx)
return ctx->engine()->throwTypeError();
double t = self->date();
- double month = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
+ double month = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN();
double date = (ctx->argc() < 2) ? DateFromTime(t) : ctx->args()[1].toNumber();
t = TimeClip(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t)));
self->setDate(t);
@@ -1179,10 +1179,10 @@ ReturnedValue DatePrototype::method_setYear(CallContext *ctx)
t = 0;
else
t = LocalTime(t);
- double year = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
+ double year = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN();
double r;
if (std::isnan(year)) {
- r = qSNaN();
+ r = qQNaN();
} else {
if ((Primitive::toInteger(year) >= 0) && (Primitive::toInteger(year) <= 99))
year += 1900;
@@ -1201,7 +1201,7 @@ ReturnedValue DatePrototype::method_setUTCFullYear(CallContext *ctx)
return ctx->engine()->throwTypeError();
double t = self->date();
- double year = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
+ double year = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN();
double month = (ctx->argc() < 2) ? MonthFromTime(t) : ctx->args()[1].toNumber();
double date = (ctx->argc() < 3) ? DateFromTime(t) : ctx->args()[2].toNumber();
t = TimeClip(MakeDate(MakeDay(year, month, date), TimeWithinDay(t)));
@@ -1218,7 +1218,7 @@ ReturnedValue DatePrototype::method_setFullYear(CallContext *ctx)
double t = LocalTime(self->date());
if (std::isnan(t))
t = 0;
- double year = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
+ double year = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN();
double month = (ctx->argc() < 2) ? MonthFromTime(t) : ctx->args()[1].toNumber();
double date = (ctx->argc() < 3) ? DateFromTime(t) : ctx->args()[2].toNumber();
t = TimeClip(UTC(MakeDate(MakeDay(year, month, date), TimeWithinDay(t))));
diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h
index 2eaa837666..eb048b1e99 100644
--- a/src/qml/jsruntime/qv4dateobject_p.h
+++ b/src/qml/jsruntime/qv4dateobject_p.h
@@ -59,7 +59,7 @@ namespace Heap {
struct DateObject : Object {
DateObject()
{
- date = qSNaN();
+ date = qQNaN();
}
DateObject(const Value &date)
diff --git a/src/qml/jsruntime/qv4debugging.cpp b/src/qml/jsruntime/qv4debugging.cpp
index 7706a40da6..b04bcd33e7 100644
--- a/src/qml/jsruntime/qv4debugging.cpp
+++ b/src/qml/jsruntime/qv4debugging.cpp
@@ -51,290 +51,4 @@
QT_BEGIN_NAMESPACE
-using namespace QV4;
-using namespace QV4::Debugging;
-
-V4Debugger::JavaScriptJob::JavaScriptJob(QV4::ExecutionEngine *engine, int frameNr,
- const QString &script)
- : engine(engine)
- , frameNr(frameNr)
- , script(script)
- , resultIsException(false)
-{}
-
-void V4Debugger::JavaScriptJob::run()
-{
- Scope scope(engine);
-
- ExecutionContextSaver saver(scope);
-
- ExecutionContext *ctx = engine->currentContext;
- if (frameNr > 0) {
- for (int i = 0; i < frameNr; ++i) {
- ctx = engine->parentContext(ctx);
- }
- engine->pushContext(ctx);
- }
-
- QV4::Script script(ctx, this->script);
- script.strictMode = ctx->d()->strictMode;
- // In order for property lookups in QML to work, we need to disable fast v4 lookups. That
- // is a side-effect of inheritContext.
- script.inheritContext = true;
- script.parse();
- QV4::ScopedValue result(scope);
- if (!scope.engine->hasException)
- result = script.run();
- if (scope.engine->hasException) {
- result = scope.engine->catchException();
- resultIsException = true;
- }
- handleResult(result);
-}
-
-bool V4Debugger::JavaScriptJob::hasExeption() const
-{
- return resultIsException;
-}
-
-class EvalJob: public V4Debugger::JavaScriptJob
-{
- bool result;
-
-public:
- EvalJob(QV4::ExecutionEngine *engine, const QString &script)
- : V4Debugger::JavaScriptJob(engine, /*frameNr*/-1, script)
- , result(false)
- {}
-
- virtual void handleResult(QV4::ScopedValue &result)
- {
- this->result = result->toBoolean();
- }
-
- bool resultAsBoolean() const
- {
- return result;
- }
-};
-
-V4Debugger::V4Debugger(QV4::ExecutionEngine *engine)
- : m_engine(engine)
- , m_state(Running)
- , m_stepping(NotStepping)
- , m_pauseRequested(false)
- , m_haveBreakPoints(false)
- , m_breakOnThrow(false)
- , m_returnedValue(engine, Primitive::undefinedValue())
- , m_gatherSources(0)
- , m_runningJob(0)
-{
- qMetaTypeId<V4Debugger*>();
- qMetaTypeId<PauseReason>();
-}
-
-void V4Debugger::pause()
-{
- QMutexLocker locker(&m_lock);
- if (m_state == Paused)
- return;
- m_pauseRequested = true;
-}
-
-void V4Debugger::resume(Speed speed)
-{
- QMutexLocker locker(&m_lock);
- if (m_state != Paused)
- return;
-
- if (!m_returnedValue.isUndefined())
- m_returnedValue.set(m_engine, Encode::undefined());
-
- m_currentContext.set(m_engine, *m_engine->currentContext);
- m_stepping = speed;
- m_runningCondition.wakeAll();
-}
-
-void V4Debugger::addBreakPoint(const QString &fileName, int lineNumber, const QString &condition)
-{
- QMutexLocker locker(&m_lock);
- m_breakPoints.insert(DebuggerBreakPoint(fileName.mid(fileName.lastIndexOf('/') + 1), lineNumber), condition);
- m_haveBreakPoints = true;
-}
-
-void V4Debugger::removeBreakPoint(const QString &fileName, int lineNumber)
-{
- QMutexLocker locker(&m_lock);
- m_breakPoints.remove(DebuggerBreakPoint(fileName.mid(fileName.lastIndexOf('/') + 1), lineNumber));
- m_haveBreakPoints = !m_breakPoints.isEmpty();
-}
-
-void V4Debugger::setBreakOnThrow(bool onoff)
-{
- QMutexLocker locker(&m_lock);
-
- m_breakOnThrow = onoff;
-}
-
-V4Debugger::ExecutionState V4Debugger::currentExecutionState() const
-{
- ExecutionState state;
- state.fileName = getFunction()->sourceFile();
- state.lineNumber = engine()->current->lineNumber;
-
- return state;
-}
-
-QVector<StackFrame> V4Debugger::stackTrace(int frameLimit) const
-{
- return m_engine->stackTrace(frameLimit);
-}
-
-void V4Debugger::maybeBreakAtInstruction()
-{
- if (m_runningJob) // do not re-enter when we're doing a job for the debugger.
- return;
-
- QMutexLocker locker(&m_lock);
-
- if (m_gatherSources) {
- m_gatherSources->run();
- delete m_gatherSources;
- m_gatherSources = 0;
- }
-
- switch (m_stepping) {
- case StepOver:
- if (m_currentContext.asManaged()->d() != m_engine->current)
- break;
- // fall through
- case StepIn:
- pauseAndWait(Step);
- return;
- case StepOut:
- case NotStepping:
- break;
- }
-
- if (m_pauseRequested) { // Serve debugging requests from the agent
- m_pauseRequested = false;
- pauseAndWait(PauseRequest);
- } else if (m_haveBreakPoints) {
- if (Function *f = getFunction()) {
- const int lineNumber = engine()->current->lineNumber;
- if (reallyHitTheBreakPoint(f->sourceFile(), lineNumber))
- pauseAndWait(BreakPoint);
- }
- }
-}
-
-void V4Debugger::enteringFunction()
-{
- if (m_runningJob)
- return;
- QMutexLocker locker(&m_lock);
-
- if (m_stepping == StepIn) {
- m_currentContext.set(m_engine, *m_engine->currentContext);
- }
-}
-
-void V4Debugger::leavingFunction(const ReturnedValue &retVal)
-{
- if (m_runningJob)
- return;
- Q_UNUSED(retVal); // TODO
-
- QMutexLocker locker(&m_lock);
-
- if (m_stepping != NotStepping && m_currentContext.asManaged()->d() == m_engine->current) {
- m_currentContext.set(m_engine, *m_engine->parentContext(m_engine->currentContext));
- m_stepping = StepOver;
- m_returnedValue.set(m_engine, retVal);
- }
-}
-
-void V4Debugger::aboutToThrow()
-{
- if (!m_breakOnThrow)
- return;
-
- if (m_runningJob) // do not re-enter when we're doing a job for the debugger.
- return;
-
- QMutexLocker locker(&m_lock);
- pauseAndWait(Throwing);
-}
-
-Function *V4Debugger::getFunction() const
-{
- Scope scope(m_engine);
- ExecutionContext *context = m_engine->currentContext;
- ScopedFunctionObject function(scope, context->getFunctionObject());
- if (function)
- return function->function();
- else
- return context->d()->engine->globalCode;
-}
-
-void V4Debugger::pauseAndWait(PauseReason reason)
-{
- if (m_runningJob)
- return;
-
- m_state = Paused;
- emit debuggerPaused(this, reason);
-
- while (true) {
- m_runningCondition.wait(&m_lock);
- if (m_runningJob) {
- m_runningJob->run();
- m_jobIsRunning.wakeAll();
- } else {
- break;
- }
- }
-
- m_state = Running;
-}
-
-bool V4Debugger::reallyHitTheBreakPoint(const QString &filename, int linenr)
-{
- BreakPoints::iterator it = m_breakPoints.find(DebuggerBreakPoint(filename.mid(filename.lastIndexOf('/') + 1), linenr));
- if (it == m_breakPoints.end())
- return false;
- QString condition = it.value();
- if (condition.isEmpty())
- return true;
-
- Q_ASSERT(m_runningJob == 0);
- EvalJob evilJob(m_engine, condition);
- m_runningJob = &evilJob;
- m_runningJob->run();
- m_runningJob = 0;
-
- return evilJob.resultAsBoolean();
-}
-
-void V4Debugger::runInEngine(V4Debugger::Job *job)
-{
- QMutexLocker locker(&m_lock);
- runInEngine_havingLock(job);
-}
-
-void V4Debugger::runInEngine_havingLock(V4Debugger::Job *job)
-{
- Q_ASSERT(job);
- Q_ASSERT(m_runningJob == 0);
-
- m_runningJob = job;
- m_runningCondition.wakeAll();
- m_jobIsRunning.wait(&m_lock);
- m_runningJob = 0;
-}
-
-V4Debugger::Job::~Job()
-{
-}
-
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4debugging_p.h b/src/qml/jsruntime/qv4debugging_p.h
index fdc9cac24f..3a3ecef918 100644
--- a/src/qml/jsruntime/qv4debugging_p.h
+++ b/src/qml/jsruntime/qv4debugging_p.h
@@ -31,8 +31,8 @@
**
****************************************************************************/
-#ifndef DEBUGGING_H
-#define DEBUGGING_H
+#ifndef QV4DEBUGGING_H
+#define QV4DEBUGGING_H
//
// W A R N I N G
@@ -46,50 +46,13 @@
//
#include "qv4global_p.h"
-#include "qv4engine_p.h"
-#include "qv4context_p.h"
-#include "qv4scopedvalue_p.h"
-
-#include <QHash>
-#include <QThread>
-#include <QMutex>
-#include <QWaitCondition>
-
-#include <QtCore/QJsonObject>
+#include <QtCore/qobject.h>
QT_BEGIN_NAMESPACE
namespace QV4 {
-
-struct Function;
-
namespace Debugging {
-enum PauseReason {
- PauseRequest,
- BreakPoint,
- Throwing,
- Step
-};
-
-struct DebuggerBreakPoint {
- DebuggerBreakPoint(const QString &fileName, int line)
- : fileName(fileName), lineNumber(line)
- {}
- QString fileName;
- int lineNumber;
-};
-inline uint qHash(const DebuggerBreakPoint &b, uint seed = 0) Q_DECL_NOTHROW
-{
- return qHash(b.fileName, seed) ^ b.lineNumber;
-}
-inline bool operator==(const DebuggerBreakPoint &a, const DebuggerBreakPoint &b)
-{
- return a.lineNumber == b.lineNumber && a.fileName == b.fileName;
-}
-
-typedef QHash<DebuggerBreakPoint, QString> BreakPoints;
-
class Q_QML_EXPORT Debugger : public QObject
{
Q_OBJECT
@@ -103,123 +66,9 @@ public:
virtual void aboutToThrow() = 0;
};
-class Q_QML_EXPORT V4Debugger : public Debugger
-{
- Q_OBJECT
-public:
- class Q_QML_EXPORT Job
- {
- public:
- virtual ~Job() = 0;
- virtual void run() = 0;
- };
-
- class Q_QML_EXPORT JavaScriptJob: public Job
- {
- QV4::ExecutionEngine *engine;
- int frameNr;
- const QString &script;
- bool resultIsException;
-
- public:
- JavaScriptJob(QV4::ExecutionEngine *engine, int frameNr, const QString &script);
- void run();
- bool hasExeption() const;
-
- protected:
- virtual void handleResult(QV4::ScopedValue &result) = 0;
- };
-
- enum State {
- Running,
- Paused
- };
-
- enum Speed {
- FullThrottle = 0,
- StepOut,
- StepOver,
- StepIn,
-
- NotStepping = FullThrottle
- };
-
- V4Debugger(ExecutionEngine *engine);
-
- ExecutionEngine *engine() const
- { return m_engine; }
-
- void pause();
- void resume(Speed speed);
-
- State state() const { return m_state; }
-
- void addBreakPoint(const QString &fileName, int lineNumber, const QString &condition = QString());
- void removeBreakPoint(const QString &fileName, int lineNumber);
-
- void setBreakOnThrow(bool onoff);
-
- // used for testing
- struct ExecutionState
- {
- QString fileName;
- int lineNumber;
- };
- ExecutionState currentExecutionState() const;
-
- bool pauseAtNextOpportunity() const {
- return m_pauseRequested || m_haveBreakPoints || m_gatherSources || m_stepping >= StepOver;
- }
-
- QVector<StackFrame> stackTrace(int frameLimit = -1) const;
- QVector<Heap::ExecutionContext::ContextType> getScopeTypes(int frame = 0) const;
-
- Function *getFunction() const;
- void runInEngine(Job *job);
-
-public: // compile-time interface
- void maybeBreakAtInstruction();
-
-public: // execution hooks
- void enteringFunction();
- void leavingFunction(const ReturnedValue &retVal);
- void aboutToThrow();
-
-signals:
- void sourcesCollected(QV4::Debugging::V4Debugger *self, const QStringList &sources, int seq);
- void debuggerPaused(QV4::Debugging::V4Debugger *self, QV4::Debugging::PauseReason reason);
-
-private:
- // requires lock to be held
- void pauseAndWait(PauseReason reason);
- bool reallyHitTheBreakPoint(const QString &filename, int linenr);
- void runInEngine_havingLock(V4Debugger::Job *job);
-
-private:
- QV4::ExecutionEngine *m_engine;
- QV4::PersistentValue m_currentContext;
- QMutex m_lock;
- QWaitCondition m_runningCondition;
- State m_state;
- Speed m_stepping;
- bool m_pauseRequested;
- bool m_haveBreakPoints;
- bool m_breakOnThrow;
-
- BreakPoints m_breakPoints;
- QV4::PersistentValue m_returnedValue;
-
- Job *m_gatherSources;
- Job *m_runningJob;
- QWaitCondition m_jobIsRunning;
-};
-
} // namespace Debugging
} // namespace QV4
QT_END_NAMESPACE
-Q_DECLARE_METATYPE(QV4::Debugging::Debugger*)
-Q_DECLARE_METATYPE(QV4::Debugging::PauseReason)
-
-#endif // DEBUGGING_H
+#endif // QV4DEBUGGING_H
diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h
index 01a21ea06d..0fc5af8380 100644
--- a/src/qml/jsruntime/qv4global_p.h
+++ b/src/qml/jsruntime/qv4global_p.h
@@ -105,7 +105,7 @@ inline double trunc(double d) { return d > 0 ? floor(d) : ceil(d); }
// Black list some platforms
#if defined(V4_ENABLE_JIT)
-#if defined(Q_OS_IOS) || defined(Q_OS_WINRT)
+#if defined(Q_OS_IOS) || defined(Q_OS_WINRT) || defined(Q_OS_TVOS)
# undef V4_ENABLE_JIT
#endif
#endif
diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp
index 110a2c9089..b4733356ac 100644
--- a/src/qml/jsruntime/qv4globalobject.cpp
+++ b/src/qml/jsruntime/qv4globalobject.cpp
@@ -302,7 +302,7 @@ static QString decode(const QString &input, DecodeMode decodeMode, bool *ok)
++r;
}
if (*r)
- output.append(input.mid(start, i - start + 1));
+ output.append(input.midRef(start, i - start + 1));
else
output.append(QChar(b));
} else {
diff --git a/src/qml/jsruntime/qv4identifier_p.h b/src/qml/jsruntime/qv4identifier_p.h
index 605b06c685..ff93b70ff9 100644
--- a/src/qml/jsruntime/qv4identifier_p.h
+++ b/src/qml/jsruntime/qv4identifier_p.h
@@ -103,8 +103,6 @@ struct IdentifierHashBase
inline IdentifierHashBase &operator=(const IdentifierHashBase &other);
bool isEmpty() const { return !d; }
- // ###
- void reserve(int) {}
inline int count() const;
bool contains(const Identifier *i) const;
diff --git a/src/qml/jsruntime/qv4include_p.h b/src/qml/jsruntime/qv4include_p.h
index 3e3cf5e770..497566e7eb 100644
--- a/src/qml/jsruntime/qv4include_p.h
+++ b/src/qml/jsruntime/qv4include_p.h
@@ -58,7 +58,6 @@ QT_BEGIN_NAMESPACE
class QQmlEngine;
class QNetworkAccessManager;
class QNetworkReply;
-class QV8Engine;
class QV4Include : public QObject
{
Q_OBJECT
diff --git a/src/qml/jsruntime/qv4math_p.h b/src/qml/jsruntime/qv4math_p.h
index cf627bcc5d..51031356bc 100644
--- a/src/qml/jsruntime/qv4math_p.h
+++ b/src/qml/jsruntime/qv4math_p.h
@@ -47,6 +47,7 @@
#include <qglobal.h>
#include <QtCore/qnumeric.h>
+#include <QtCore/private/qnumeric_p.h>
#include <cmath>
#if defined(Q_CC_GNU)
@@ -59,84 +60,30 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
-#if defined(Q_CC_GNU) && defined(Q_PROCESSOR_X86)
-
static inline QMLJS_READONLY ReturnedValue add_int32(int a, int b)
{
- quint8 overflow = 0;
- int aa = a;
-
- asm ("addl %2, %1\n"
- "seto %0"
- : "=q" (overflow), "=r" (aa)
- : "r" (b), "1" (aa)
- : "cc"
- );
- if (Q_UNLIKELY(overflow))
+ int result;
+ if (Q_UNLIKELY(add_overflow(a, b, &result)))
return Primitive::fromDouble(static_cast<double>(a) + b).asReturnedValue();
- return Primitive::fromInt32(aa).asReturnedValue();
+ return Primitive::fromInt32(result).asReturnedValue();
}
static inline QMLJS_READONLY ReturnedValue sub_int32(int a, int b)
{
- quint8 overflow = 0;
- int aa = a;
-
- asm ("subl %2, %1\n"
- "seto %0"
- : "=q" (overflow), "=r" (aa)
- : "r" (b), "1" (aa)
- : "cc"
- );
- if (Q_UNLIKELY(overflow))
+ int result;
+ if (Q_UNLIKELY(sub_overflow(a, b, &result)))
return Primitive::fromDouble(static_cast<double>(a) - b).asReturnedValue();
- return Primitive::fromInt32(aa).asReturnedValue();
+ return Primitive::fromInt32(result).asReturnedValue();
}
static inline QMLJS_READONLY ReturnedValue mul_int32(int a, int b)
{
- quint8 overflow = 0;
- int aa = a;
-
- asm ("imul %2, %1\n"
- "setc %0"
- : "=q" (overflow), "=r" (aa)
- : "r" (b), "1" (aa)
- : "cc"
- );
- if (Q_UNLIKELY(overflow))
+ int result;
+ if (Q_UNLIKELY(mul_overflow(a, b, &result)))
return Primitive::fromDouble(static_cast<double>(a) * b).asReturnedValue();
- return Primitive::fromInt32(aa).asReturnedValue();
-}
-
-#else
-
-static inline QMLJS_READONLY ReturnedValue add_int32(int a, int b)
-{
- qint64 result = static_cast<qint64>(a) + b;
- if (Q_UNLIKELY(result > INT_MAX || result < INT_MIN))
- return Primitive::fromDouble(static_cast<double>(a) + b).asReturnedValue();
- return Primitive::fromInt32(static_cast<int>(result)).asReturnedValue();
+ return Primitive::fromInt32(result).asReturnedValue();
}
-static inline QMLJS_READONLY ReturnedValue sub_int32(int a, int b)
-{
- qint64 result = static_cast<qint64>(a) - b;
- if (Q_UNLIKELY(result > INT_MAX || result < INT_MIN))
- return Primitive::fromDouble(static_cast<double>(a) - b).asReturnedValue();
- return Primitive::fromInt32(static_cast<int>(result)).asReturnedValue();
-}
-
-static inline QMLJS_READONLY ReturnedValue mul_int32(int a, int b)
-{
- qint64 result = static_cast<qint64>(a) * b;
- if (Q_UNLIKELY(result > INT_MAX || result < INT_MIN))
- return Primitive::fromDouble(static_cast<double>(a) * b).asReturnedValue();
- return Primitive::fromInt32(static_cast<int>(result)).asReturnedValue();
-}
-
-#endif
-
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4mathobject.cpp b/src/qml/jsruntime/qv4mathobject.cpp
index 3d3ac84576..ada073fbd4 100644
--- a/src/qml/jsruntime/qv4mathobject.cpp
+++ b/src/qml/jsruntime/qv4mathobject.cpp
@@ -96,7 +96,7 @@ static double copySign(double x, double y)
ReturnedValue MathObject::method_abs(CallContext *context)
{
if (!context->argc())
- return Encode(qSNaN());
+ return Encode(qQNaN());
if (context->args()[0].isInteger()) {
int i = context->args()[0].integerValue();
@@ -114,7 +114,7 @@ ReturnedValue MathObject::method_acos(CallContext *context)
{
double v = context->argc() ? context->args()[0].toNumber() : 2;
if (v > 1)
- return Encode(qSNaN());
+ return Encode(qQNaN());
return Encode(std::acos(v));
}
@@ -123,14 +123,14 @@ ReturnedValue MathObject::method_asin(CallContext *context)
{
double v = context->argc() ? context->args()[0].toNumber() : 2;
if (v > 1)
- return Encode(qSNaN());
+ return Encode(qQNaN());
else
return Encode(std::asin(v));
}
ReturnedValue MathObject::method_atan(CallContext *context)
{
- double v = context->argc() ? context->args()[0].toNumber() : qSNaN();
+ double v = context->argc() ? context->args()[0].toNumber() : qQNaN();
if (v == 0.0)
return Encode(v);
else
@@ -139,8 +139,8 @@ ReturnedValue MathObject::method_atan(CallContext *context)
ReturnedValue MathObject::method_atan2(CallContext *context)
{
- double v1 = context->argc() ? context->args()[0].toNumber() : qSNaN();
- double v2 = context->argc() > 1 ? context->args()[1].toNumber() : qSNaN();
+ double v1 = context->argc() ? context->args()[0].toNumber() : qQNaN();
+ double v2 = context->argc() > 1 ? context->args()[1].toNumber() : qQNaN();
if ((v1 < 0) && qIsFinite(v1) && qIsInf(v2) && (copySign(1.0, v2) == 1.0))
return Encode(copySign(0, -1.0));
@@ -157,7 +157,7 @@ ReturnedValue MathObject::method_atan2(CallContext *context)
ReturnedValue MathObject::method_ceil(CallContext *context)
{
- double v = context->argc() ? context->args()[0].toNumber() : qSNaN();
+ double v = context->argc() ? context->args()[0].toNumber() : qQNaN();
if (v < 0.0 && v > -1.0)
return Encode(copySign(0, -1.0));
else
@@ -166,13 +166,13 @@ ReturnedValue MathObject::method_ceil(CallContext *context)
ReturnedValue MathObject::method_cos(CallContext *context)
{
- double v = context->argc() ? context->args()[0].toNumber() : qSNaN();
+ double v = context->argc() ? context->args()[0].toNumber() : qQNaN();
return Encode(std::cos(v));
}
ReturnedValue MathObject::method_exp(CallContext *context)
{
- double v = context->argc() ? context->args()[0].toNumber() : qSNaN();
+ double v = context->argc() ? context->args()[0].toNumber() : qQNaN();
if (qIsInf(v)) {
if (copySign(1.0, v) == -1.0)
return Encode(0);
@@ -185,15 +185,15 @@ ReturnedValue MathObject::method_exp(CallContext *context)
ReturnedValue MathObject::method_floor(CallContext *context)
{
- double v = context->argc() ? context->args()[0].toNumber() : qSNaN();
+ double v = context->argc() ? context->args()[0].toNumber() : qQNaN();
return Encode(std::floor(v));
}
ReturnedValue MathObject::method_log(CallContext *context)
{
- double v = context->argc() ? context->args()[0].toNumber() : qSNaN();
+ double v = context->argc() ? context->args()[0].toNumber() : qQNaN();
if (v < 0)
- return Encode(qSNaN());
+ return Encode(qQNaN());
else
return Encode(std::log(v));
}
@@ -224,16 +224,16 @@ ReturnedValue MathObject::method_min(CallContext *context)
ReturnedValue MathObject::method_pow(CallContext *context)
{
- double x = context->argc() > 0 ? context->args()[0].toNumber() : qSNaN();
- double y = context->argc() > 1 ? context->args()[1].toNumber() : qSNaN();
+ double x = context->argc() > 0 ? context->args()[0].toNumber() : qQNaN();
+ double y = context->argc() > 1 ? context->args()[1].toNumber() : qQNaN();
if (std::isnan(y))
- return Encode(qSNaN());
+ return Encode(qQNaN());
if (y == 0) {
return Encode(1);
} else if (((x == 1) || (x == -1)) && std::isinf(y)) {
- return Encode(qSNaN());
+ return Encode(qQNaN());
} else if (((x == 0) && copySign(1.0, x) == 1.0) && (y < 0)) {
return Encode(qInf());
} else if ((x == 0) && copySign(1.0, x) == -1.0) {
@@ -269,7 +269,7 @@ ReturnedValue MathObject::method_pow(CallContext *context)
return Encode(std::pow(x, y));
}
// ###
- return Encode(qSNaN());
+ return Encode(qQNaN());
}
Q_GLOBAL_STATIC(QThreadStorage<bool *>, seedCreatedStorage);
@@ -290,26 +290,26 @@ ReturnedValue MathObject::method_random(CallContext *context)
ReturnedValue MathObject::method_round(CallContext *context)
{
- double v = context->argc() ? context->args()[0].toNumber() : qSNaN();
+ double v = context->argc() ? context->args()[0].toNumber() : qQNaN();
v = copySign(std::floor(v + 0.5), v);
return Encode(v);
}
ReturnedValue MathObject::method_sin(CallContext *context)
{
- double v = context->argc() ? context->args()[0].toNumber() : qSNaN();
+ double v = context->argc() ? context->args()[0].toNumber() : qQNaN();
return Encode(std::sin(v));
}
ReturnedValue MathObject::method_sqrt(CallContext *context)
{
- double v = context->argc() ? context->args()[0].toNumber() : qSNaN();
+ double v = context->argc() ? context->args()[0].toNumber() : qQNaN();
return Encode(std::sqrt(v));
}
ReturnedValue MathObject::method_tan(CallContext *context)
{
- double v = context->argc() ? context->args()[0].toNumber() : qSNaN();
+ double v = context->argc() ? context->args()[0].toNumber() : qQNaN();
if (v == 0.0)
return Encode(v);
else
diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp
index 4ae30a7f35..5006c8c2cd 100644
--- a/src/qml/jsruntime/qv4numberobject.cpp
+++ b/src/qml/jsruntime/qv4numberobject.cpp
@@ -39,13 +39,31 @@
#include <QtCore/qmath.h>
#include <QtCore/QDebug>
#include <cassert>
-#include <double-conversion.h>
using namespace QV4;
DEFINE_OBJECT_VTABLE(NumberCtor);
DEFINE_OBJECT_VTABLE(NumberObject);
+struct NumberLocaleHolder : public NumberLocale
+{
+ NumberLocaleHolder() {}
+};
+
+Q_GLOBAL_STATIC(NumberLocaleHolder, numberLocaleHolder)
+
+NumberLocale::NumberLocale() : QLocale(QLocale::C),
+ // -128 means shortest string that can accurately represent the number.
+ defaultDoublePrecision(0xffffff80)
+{
+ setNumberOptions(QLocale::OmitGroupSeparator | QLocale::OmitLeadingZeroInExponent);
+}
+
+const NumberLocale *NumberLocale::instance()
+{
+ return numberLocaleHolder();
+}
+
Heap::NumberCtor::NumberCtor(QV4::ExecutionContext *scope)
: Heap::FunctionObject(scope, QStringLiteral("Number"))
{
@@ -71,7 +89,7 @@ void NumberPrototype::init(ExecutionEngine *engine, Object *ctor)
ctor->defineReadonlyProperty(engine->id_prototype(), (o = this));
ctor->defineReadonlyProperty(engine->id_length(), Primitive::fromInt32(1));
- ctor->defineReadonlyProperty(QStringLiteral("NaN"), Primitive::fromDouble(qSNaN()));
+ ctor->defineReadonlyProperty(QStringLiteral("NaN"), Primitive::fromDouble(qQNaN()));
ctor->defineReadonlyProperty(QStringLiteral("NEGATIVE_INFINITY"), Primitive::fromDouble(-qInf()));
ctor->defineReadonlyProperty(QStringLiteral("POSITIVE_INFINITY"), Primitive::fromDouble(qInf()));
ctor->defineReadonlyProperty(QStringLiteral("MAX_VALUE"), Primitive::fromDouble(1.7976931348623158e+308));
@@ -201,15 +219,9 @@ ReturnedValue NumberPrototype::method_toFixed(CallContext *ctx)
str = QStringLiteral("NaN");
else if (qIsInf(v))
str = QString::fromLatin1(v < 0 ? "-Infinity" : "Infinity");
- else if (v < 1.e21) {
- char buf[100];
- double_conversion::StringBuilder builder(buf, sizeof(buf));
- double_conversion::DoubleToStringConverter::EcmaScriptConverter().ToFixed(v, fdigits, &builder);
- str = QString::fromLatin1(builder.Finalize());
- // At some point, the 3rd party double-conversion code should be moved to qtcore.
- // When that's done, we can use:
-// str = QString::number(v, 'f', int (fdigits));
- } else
+ else if (v < 1.e21)
+ str = NumberLocale::instance()->toString(v, 'f', int(fdigits));
+ else
return RuntimeHelpers::stringFromNumber(ctx->engine(), v)->asReturnedValue();
return scope.engine->newString(str)->asReturnedValue();
}
@@ -221,7 +233,7 @@ ReturnedValue NumberPrototype::method_toExponential(CallContext *ctx)
if (scope.engine->hasException)
return Encode::undefined();
- int fdigits = -1;
+ int fdigits = NumberLocale::instance()->defaultDoublePrecision;
if (ctx->argc() && !ctx->args()[0].isUndefined()) {
fdigits = ctx->args()[0].toInt32();
@@ -231,11 +243,7 @@ ReturnedValue NumberPrototype::method_toExponential(CallContext *ctx)
}
}
- char str[100];
- double_conversion::StringBuilder builder(str, sizeof(str));
- double_conversion::DoubleToStringConverter::EcmaScriptConverter().ToExponential(d, fdigits, &builder);
- QString result = QString::fromLatin1(builder.Finalize());
-
+ QString result = NumberLocale::instance()->toString(d, 'e', fdigits);
return scope.engine->newString(result)->asReturnedValue();
}
@@ -255,10 +263,6 @@ ReturnedValue NumberPrototype::method_toPrecision(CallContext *ctx)
return ctx->engine()->throwRangeError(error);
}
- char str[100];
- double_conversion::StringBuilder builder(str, sizeof(str));
- double_conversion::DoubleToStringConverter::EcmaScriptConverter().ToPrecision(v->asDouble(), precision, &builder);
- QString result = QString::fromLatin1(builder.Finalize());
-
+ QString result = NumberLocale::instance()->toString(v->asDouble(), 'g', precision);
return scope.engine->newString(result)->asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4numberobject_p.h b/src/qml/jsruntime/qv4numberobject_p.h
index cc5033531e..bd6fe3febb 100644
--- a/src/qml/jsruntime/qv4numberobject_p.h
+++ b/src/qml/jsruntime/qv4numberobject_p.h
@@ -60,6 +60,15 @@ struct NumberCtor : FunctionObject {
}
+class NumberLocale : public QLocale
+{
+public:
+ static const NumberLocale *instance();
+ const int defaultDoublePrecision;
+protected:
+ NumberLocale();
+};
+
struct NumberCtor: FunctionObject
{
V4_OBJECT2(NumberCtor, FunctionObject)
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 8f471132b7..ee294b3678 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -1447,7 +1447,8 @@ static QV4::ReturnedValue CallOverloaded(const QQmlObjectOrGadget &object, const
const QQmlPropertyData *candidate = &data;
while (candidate) {
error += QLatin1String("\n ") +
- QString::fromUtf8(object.metaObject()->method(candidate->coreIndex).methodSignature().constData());
+ QString::fromUtf8(object.metaObject()->method(candidate->coreIndex)
+ .methodSignature());
candidate = RelatedMethod(object, candidate, dummy, propertyCache);
}
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index a988313f5f..a1bcec4987 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -43,6 +43,7 @@
#include "qv4dateobject_p.h"
#include "qv4lookup_p.h"
#include "qv4function_p.h"
+#include "qv4numberobject_p.h"
#include "private/qlocale_tools_p.h"
#include "qv4scopedvalue_p.h"
#include <private/qqmlcontextwrapper_p.h>
@@ -60,8 +61,6 @@
#include <wtf/MathExtras.h>
-#include "../../3rdparty/double-conversion/double-conversion.h"
-
#ifdef QV4_COUNT_RUNTIME_FUNCTIONS
# include <QtCore/QBuffer>
# include <QtCore/QDebug>
@@ -226,10 +225,36 @@ void RuntimeHelpers::numberToString(QString *result, double num, int radix)
}
if (radix == 10) {
- char str[100];
- double_conversion::StringBuilder builder(str, sizeof(str));
- double_conversion::DoubleToStringConverter::EcmaScriptConverter().ToShortest(num, &builder);
- *result = QString::fromLatin1(builder.Finalize());
+ // We cannot use our usual locale->toString(...) here, because EcmaScript has special rules
+ // about the longest permissible number, depending on if it's <0 or >0.
+ const int ecma_shortest_low = -6;
+ const int ecma_shortest_high = 21;
+
+ const QLatin1Char zero('0');
+ const QLatin1Char dot('.');
+
+ int decpt = 0;
+ int sign = 0;
+ *result = qdtoa(num, &decpt, &sign);
+
+ if (decpt <= ecma_shortest_low || decpt > ecma_shortest_high) {
+ if (result->length() > 1)
+ result->insert(1, dot);
+ result->append(QLatin1Char('e'));
+ if (decpt > 0)
+ result->append(QLatin1Char('+'));
+ result->append(QString::number(decpt - 1));
+ } else if (decpt <= 0) {
+ result->prepend(QString::fromLatin1("0.%1").arg(QString().fill(zero, -decpt)));
+ } else if (decpt < result->length()) {
+ result->insert(decpt, dot);
+ } else {
+ result->append(QString().fill(zero, decpt - result->length()));
+ }
+
+ if (sign)
+ result->prepend(QLatin1Char('-'));
+
return;
}
diff --git a/src/qml/jsruntime/qv4serialize_p.h b/src/qml/jsruntime/qv4serialize_p.h
index d5d48edee7..e364477a19 100644
--- a/src/qml/jsruntime/qv4serialize_p.h
+++ b/src/qml/jsruntime/qv4serialize_p.h
@@ -50,8 +50,6 @@
QT_BEGIN_NAMESPACE
-class QV8Engine;
-
namespace QV4 {
class Serialize {
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index 757ec6c6bf..8433582215 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -264,7 +264,7 @@ ReturnedValue StringPrototype::method_charCodeAt(CallContext *context)
if (pos >= 0 && pos < str.length())
return Encode(str.at(pos).unicode());
- return Encode(qSNaN());
+ return Encode(qQNaN());
}
ReturnedValue StringPrototype::method_concat(CallContext *context)
diff --git a/src/qml/parser/qqmljsengine_p.cpp b/src/qml/parser/qqmljsengine_p.cpp
index 1c0a70a372..7cc9096e59 100644
--- a/src/qml/parser/qqmljsengine_p.cpp
+++ b/src/qml/parser/qqmljsengine_p.cpp
@@ -56,7 +56,7 @@ static inline int toDigit(char c)
double integerFromString(const char *buf, int size, int radix)
{
if (size == 0)
- return qSNaN();
+ return qQNaN();
double sign = 1.0;
int i = 0;
@@ -95,7 +95,7 @@ double integerFromString(const char *buf, int size, int radix)
if (!qstrcmp(buf, "Infinity"))
result = qInf();
else
- result = qSNaN();
+ result = qQNaN();
} else {
result = 0;
double multiplier = 1;
diff --git a/src/qml/parser/qqmljskeywords_p.h b/src/qml/parser/qqmljskeywords_p.h
index f7368b94d6..c52657d1d8 100644
--- a/src/qml/parser/qqmljskeywords_p.h
+++ b/src/qml/parser/qqmljskeywords_p.h
@@ -684,7 +684,7 @@ static inline int classify8(const QChar *s, bool qmlMode) {
if (s[5].unicode() == 'r') {
if (s[6].unicode() == 't') {
if (s[7].unicode() == 'y') {
- return qmlMode ? Lexer::T_PROPERTY : Lexer::T_IDENTIFIER;
+ return Lexer::T_PROPERTY;
}
}
}
diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp
index b2bf1939b0..4ab35e69e3 100644
--- a/src/qml/qml/qqmlapplicationengine.cpp
+++ b/src/qml/qml/qqmlapplicationengine.cpp
@@ -197,6 +197,7 @@ QQmlApplicationEngine::QQmlApplicationEngine(QObject *parent)
{
Q_D(QQmlApplicationEngine);
d->init();
+ QJSEnginePrivate::addToDebugServer(this);
}
/*!
@@ -208,6 +209,7 @@ QQmlApplicationEngine::QQmlApplicationEngine(const QUrl &url, QObject *parent)
{
Q_D(QQmlApplicationEngine);
d->init();
+ QJSEnginePrivate::addToDebugServer(this);
load(url);
}
@@ -224,6 +226,7 @@ QQmlApplicationEngine::QQmlApplicationEngine(const QString &filePath, QObject *p
{
Q_D(QQmlApplicationEngine);
d->init();
+ QJSEnginePrivate::addToDebugServer(this);
load(QUrl::fromLocalFile(filePath));
}
@@ -233,6 +236,7 @@ QQmlApplicationEngine::QQmlApplicationEngine(const QString &filePath, QObject *p
QQmlApplicationEngine::~QQmlApplicationEngine()
{
Q_D(QQmlApplicationEngine);
+ QJSEnginePrivate::removeFromDebugServer(this);
d->cleanUp();//Instantiated root objects must be deleted before the engine
}
diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp
index 477a517e32..decffaf2fa 100644
--- a/src/qml/qml/qqmlboundsignal.cpp
+++ b/src/qml/qml/qqmlboundsignal.cpp
@@ -250,7 +250,7 @@ QQmlBoundSignal::QQmlBoundSignal(QObject *target, int signal, QObject *owner,
QQmlEngine *engine)
: QQmlNotifierEndpoint(QQmlNotifierEndpoint::QQmlBoundSignal),
m_prevSignal(0), m_nextSignal(0),
- m_expression(0)
+ m_enabled(true), m_expression(0)
{
addToObject(owner);
@@ -313,18 +313,33 @@ void QQmlBoundSignal::takeExpression(QQmlBoundSignalExpression *e)
m_expression->setNotifyOnValueChanged(false);
}
+/*!
+ This property holds whether the item will emit signals.
+
+ The QQmlBoundSignal callback will only emit a signal if this property is set to true.
+
+ By default, this property is true.
+ */
+void QQmlBoundSignal::setEnabled(bool enabled)
+{
+ if (m_enabled == enabled)
+ return;
+
+ m_enabled = enabled;
+}
+
void QQmlBoundSignal_callback(QQmlNotifierEndpoint *e, void **a)
{
QQmlBoundSignal *s = static_cast<QQmlBoundSignal*>(e);
- if (!s->m_expression)
+ if (!s->m_expression || !s->m_enabled)
return;
QV4DebugService *service = QQmlDebugConnector::service<QV4DebugService>();
if (service)
- service->signalEmitted(QString::fromLatin1(QMetaObjectPrivate::signal(
- s->m_expression->target()->metaObject(),
- s->signalIndex()).methodSignature()));
+ service->signalEmitted(QString::fromUtf8(QMetaObjectPrivate::signal(
+ s->m_expression->target()->metaObject(),
+ s->signalIndex()).methodSignature()));
QQmlEngine *engine;
if (s->m_expression && (engine = s->m_expression->engine())) {
diff --git a/src/qml/qml/qqmlboundsignal_p.h b/src/qml/qml/qqmlboundsignal_p.h
index 3742317484..ef8fdd4a1a 100644
--- a/src/qml/qml/qqmlboundsignal_p.h
+++ b/src/qml/qml/qqmlboundsignal_p.h
@@ -108,6 +108,8 @@ public:
QQmlBoundSignalExpression *expression() const;
void takeExpression(QQmlBoundSignalExpression *);
+ void setEnabled(bool enabled);
+
private:
friend void QQmlBoundSignal_callback(QQmlNotifierEndpoint *, void **);
friend class QQmlPropertyPrivate;
@@ -119,6 +121,8 @@ private:
QQmlBoundSignal **m_prevSignal;
QQmlBoundSignal *m_nextSignal;
+ bool m_enabled;
+
QQmlBoundSignalExpressionPointer m_expression;
};
diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h
index 15ec88dd52..0ed09d9f49 100644
--- a/src/qml/qml/qqmlcomponent_p.h
+++ b/src/qml/qml/qqmlcomponent_p.h
@@ -63,8 +63,6 @@
QT_BEGIN_NAMESPACE
-class QV8Engine;
-
class QQmlComponent;
class QQmlEngine;
class QQmlCompiledData;
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index e8422474d3..e02bc1350c 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -176,6 +176,7 @@ void QQmlEnginePrivate::registerBaseTypes(const char *uri, int versionMajor, int
qmlRegisterType<QQmlComponent>(uri,versionMajor,versionMinor,"Component");
qmlRegisterType<QObject>(uri,versionMajor,versionMinor,"QtObject");
qmlRegisterType<QQmlBind>(uri, versionMajor, versionMinor,"Binding");
+ qmlRegisterType<QQmlConnections,1>(uri, versionMajor, (versionMinor < 3 ? 3 : versionMinor), "Connections"); //Only available in >=2.3
qmlRegisterType<QQmlConnections>(uri, versionMajor, versionMinor,"Connections");
qmlRegisterType<QQmlTimer>(uri, versionMajor, versionMinor,"Timer");
qmlRegisterType<QQmlInstantiator>(uri, versionMajor, (versionMinor < 1 ? 1 : versionMinor), "Instantiator"); //Only available in >=2.1
@@ -397,6 +398,7 @@ The following functions are also on the Qt object.
\li \c "android" - Android
\li \c "blackberry" - BlackBerry OS
\li \c "ios" - iOS
+ \li \c "tvos" - tvOS
\li \c "linux" - Linux
\li \c "osx" - OS X
\li \c "unix" - Other Unix-based OS
@@ -867,11 +869,6 @@ void QQmlEnginePrivate::init()
v8engine()->setEngine(q);
rootContext = new QQmlContext(q,true);
-
- if (QCoreApplication::instance()->thread() == q->thread() && QQmlDebugConnector::instance()) {
- QQmlDebugConnector::instance()->open();
- QQmlDebugConnector::instance()->addEngine(q);
- }
}
QQuickWorkerScriptEngine *QQmlEnginePrivate::getWorkerScriptEngine()
@@ -923,6 +920,7 @@ QQmlEngine::QQmlEngine(QObject *parent)
{
Q_D(QQmlEngine);
d->init();
+ QJSEnginePrivate::addToDebugServer(this);
}
/*!
@@ -947,9 +945,7 @@ QQmlEngine::QQmlEngine(QQmlEnginePrivate &dd, QObject *parent)
QQmlEngine::~QQmlEngine()
{
Q_D(QQmlEngine);
- QQmlDebugConnector *server = QQmlDebugConnector::instance();
- if (server)
- server->removeEngine(this);
+ QJSEnginePrivate::removeFromDebugServer(this);
d->typeLoader.invalidate();
diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h
index 23cfc24e7a..3b17bd94de 100644
--- a/src/qml/qml/qqmlglobal_p.h
+++ b/src/qml/qml/qqmlglobal_p.h
@@ -227,8 +227,6 @@ inline void QQml_setParent_noEvent(QObject *object, QObject *parent)
static_cast<QQmlGraphics_DerivedObject *>(object)->setParent_noEvent(parent);
}
-
-class QV8Engine;
class Q_QML_PRIVATE_EXPORT QQmlValueTypeProvider
{
public:
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index d538199520..fcd05bfb1b 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -1007,13 +1007,21 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath,
}
#else
- Q_UNUSED(qmldirFilePath);
- Q_UNUSED(uri);
Q_UNUSED(vmaj);
Q_UNUSED(vmin);
Q_UNUSED(database);
Q_UNUSED(qmldir);
- Q_UNUSED(errors);
+
+ if (errors) {
+ QQmlError error;
+ error.setDescription(
+ QQmlImportDatabase::tr(
+ "plugin cannot be loaded for module \"%1\": library loading is disabled")
+ .arg(uri));
+ error.setUrl(QUrl::fromLocalFile(qmldirFilePath));
+ errors->prepend(error);
+ }
+
return false;
#endif // QT_NO_LIBRARY
return true;
@@ -1562,8 +1570,7 @@ QQmlImportDatabase::QQmlImportDatabase(QQmlEngine *e)
: engine(e)
{
filePluginPath << QLatin1String(".");
-
- // Search order is applicationDirPath(), $QML2_IMPORT_PATH, QLibraryInfo::Qml2ImportsPath
+ // Search order is applicationDirPath(), qrc:/qt-project.org/imports, $QML2_IMPORT_PATH, QLibraryInfo::Qml2ImportsPath
QString installImportsPath = QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath);
addImportPath(installImportsPath);
@@ -1581,6 +1588,7 @@ QQmlImportDatabase::QQmlImportDatabase(QQmlEngine *e)
addImportPath(paths.at(ii));
}
+ addImportPath(QStringLiteral("qrc:/qt-project.org/imports"));
addImportPath(QCoreApplication::applicationDirPath());
}
diff --git a/src/qml/qml/qqmllistwrapper_p.h b/src/qml/qml/qqmllistwrapper_p.h
index 6df3d83b2e..ae81a1fe0f 100644
--- a/src/qml/qml/qqmllistwrapper_p.h
+++ b/src/qml/qml/qqmllistwrapper_p.h
@@ -55,8 +55,6 @@
QT_BEGIN_NAMESPACE
-class QV8Engine;
-
namespace QV4 {
namespace Heap {
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 21e6d5f6de..cb4bbbab77 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -897,9 +897,10 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
QMetaMethod signalMethod = _qobject->metaObject()->method(property->coreIndex);
if (!QMetaObject::checkConnectArgs(signalMethod, method)) {
- recordError(binding->valueLocation, tr("Cannot connect mismatched signal/slot %1 %vs. %2")
- .arg(QString::fromLatin1(method.methodSignature().constData()))
- .arg(QString::fromLatin1(signalMethod.methodSignature().constData())));
+ recordError(binding->valueLocation,
+ tr("Cannot connect mismatched signal/slot %1 %vs. %2")
+ .arg(QString::fromUtf8(method.methodSignature()))
+ .arg(QString::fromUtf8(signalMethod.methodSignature())));
return false;
}
diff --git a/src/qml/qml/qqmlplatform.cpp b/src/qml/qml/qqmlplatform.cpp
index a453746da3..92e9096077 100644
--- a/src/qml/qml/qqmlplatform.cpp
+++ b/src/qml/qml/qqmlplatform.cpp
@@ -57,6 +57,8 @@ QString QQmlPlatform::os()
return QStringLiteral("blackberry");
#elif defined(Q_OS_IOS)
return QStringLiteral("ios");
+#elif defined(Q_OS_TVOS)
+ return QStringLiteral("tvos");
#elif defined(Q_OS_MAC)
return QStringLiteral("osx");
#elif defined(Q_OS_WINCE)
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index 1b78ada698..bcfcf391f6 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -50,7 +50,6 @@
#include "qqmlvaluetypeproxybinding_p.h"
#include <private/qjsvalue_p.h>
#include <private/qv4functionobject_p.h>
-#include <private/qv4runtime_p.h>
#include <QStringList>
#include <private/qmetaobject_p.h>
@@ -1353,12 +1352,7 @@ bool QQmlPropertyPrivate::write(QObject *object,
if (!ok) {
v = value;
- if (variantType == QVariant::Double && propertyType == QVariant::String) {
- QString number;
- QV4::RuntimeHelpers::numberToString(&number, v.toDouble());
- v = number;
- ok = true;
- } else if (v.convert(propertyType)) {
+ if (v.convert(propertyType)) {
ok = true;
} else if (v.isValid() && value.isNull()) {
// For historical reasons converting a null QVariant to another type will do the trick
diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h
index 610709ef7f..6f9b1dca56 100644
--- a/src/qml/qml/qqmlpropertycache_p.h
+++ b/src/qml/qml/qqmlpropertycache_p.h
@@ -58,7 +58,6 @@
QT_BEGIN_NAMESPACE
-class QV8Engine;
class QMetaProperty;
class QQmlEngine;
class QJSEngine;
diff --git a/src/qml/qml/qqmlstringconverters.cpp b/src/qml/qml/qqmlstringconverters.cpp
index eb0afda927..6a5c0736cf 100644
--- a/src/qml/qml/qqmlstringconverters.cpp
+++ b/src/qml/qml/qqmlstringconverters.cpp
@@ -137,8 +137,8 @@ QPointF QQmlStringConverters::pointFFromString(const QString &s, bool *ok)
bool xGood, yGood;
int index = s.indexOf(QLatin1Char(','));
- qreal xCoord = s.left(index).toDouble(&xGood);
- qreal yCoord = s.mid(index+1).toDouble(&yGood);
+ qreal xCoord = s.leftRef(index).toDouble(&xGood);
+ qreal yCoord = s.midRef(index+1).toDouble(&yGood);
if (!xGood || !yGood) {
if (ok)
*ok = false;
@@ -161,8 +161,8 @@ QSizeF QQmlStringConverters::sizeFFromString(const QString &s, bool *ok)
bool wGood, hGood;
int index = s.indexOf(QLatin1Char('x'));
- qreal width = s.left(index).toDouble(&wGood);
- qreal height = s.mid(index+1).toDouble(&hGood);
+ qreal width = s.leftRef(index).toDouble(&wGood);
+ qreal height = s.midRef(index+1).toDouble(&hGood);
if (!wGood || !hGood) {
if (ok)
*ok = false;
@@ -185,12 +185,12 @@ QRectF QQmlStringConverters::rectFFromString(const QString &s, bool *ok)
bool xGood, yGood, wGood, hGood;
int index = s.indexOf(QLatin1Char(','));
- qreal x = s.left(index).toDouble(&xGood);
+ qreal x = s.leftRef(index).toDouble(&xGood);
int index2 = s.indexOf(QLatin1Char(','), index+1);
- qreal y = s.mid(index+1, index2-index-1).toDouble(&yGood);
+ qreal y = s.midRef(index+1, index2-index-1).toDouble(&yGood);
index = s.indexOf(QLatin1Char('x'), index2+1);
- qreal width = s.mid(index2+1, index-index2-1).toDouble(&wGood);
- qreal height = s.mid(index+1).toDouble(&hGood);
+ qreal width = s.midRef(index2+1, index-index2-1).toDouble(&wGood);
+ qreal height = s.midRef(index+1).toDouble(&hGood);
if (!xGood || !yGood || !wGood || !hGood) {
if (ok)
*ok = false;
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 1e671542be..98c4341e06 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -2553,6 +2553,7 @@ QV4::ReturnedValue QQmlScriptData::scriptValueForContext(QQmlContextData *parent
if (!m_program) {
if (shared)
m_loaded = true;
+ ctxt->destroy();
return QV4::Encode::undefined();
}
diff --git a/src/qml/qml/qqmltypewrapper_p.h b/src/qml/qml/qqmltypewrapper_p.h
index e67b457c59..6f2077b64c 100644
--- a/src/qml/qml/qqmltypewrapper_p.h
+++ b/src/qml/qml/qqmltypewrapper_p.h
@@ -53,7 +53,6 @@
QT_BEGIN_NAMESPACE
-class QV8Engine;
class QQmlTypeNameCache;
namespace QV4 {
diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h
index 156b4c85d8..b08b6e344a 100644
--- a/src/qml/qml/qqmlvaluetypewrapper_p.h
+++ b/src/qml/qml/qqmlvaluetypewrapper_p.h
@@ -53,7 +53,6 @@
QT_BEGIN_NAMESPACE
-class QV8Engine;
class QQmlValueType;
namespace QV4 {
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index e85b3dc82c..cd73fa028e 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -837,8 +837,10 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
// are not rewritten correctly but this bug is deemed out-of-scope to fix for
// performance reasons; see QTBUG-24064) and thus compilation will have failed.
QQmlError e;
- e.setDescription(QString(QLatin1String("Exception occurred during compilation of function: %1")).
- arg(QLatin1String(QMetaObject::method(_id).methodSignature().constData())));
+ e.setDescription(QString::fromLatin1("Exception occurred during compilation of "
+ "function: %1")
+ .arg(QString::fromUtf8(QMetaObject::method(_id)
+ .methodSignature())));
ep->warning(e);
return -1; // The dynamic method with that id is not available.
}
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index 3521384d77..e86956d3b2 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -1984,8 +1984,6 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_get_response(CallContext *ctx)
} else {
return QV4::Encode(scope.engine->newString(QString()));
}
-
- return Encode::undefined();
}
diff --git a/src/qml/qml/qqmlxmlhttprequest_p.h b/src/qml/qml/qqmlxmlhttprequest_p.h
index 69847f14c1..e72374ed54 100644
--- a/src/qml/qml/qqmlxmlhttprequest_p.h
+++ b/src/qml/qml/qqmlxmlhttprequest_p.h
@@ -53,8 +53,6 @@
QT_BEGIN_NAMESPACE
-class QV8Engine;
-
void *qt_add_qmlxmlhttprequest(QV4::ExecutionEngine *engine);
void qt_rem_qmlxmlhttprequest(QV4::ExecutionEngine *engine, void *);
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index f4e980eefb..e859224aea 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -904,7 +904,7 @@ ReturnedValue QtObject::method_btoa(CallContext *ctx)
/*!
\qmlmethod string Qt::atob(data)
-ASCII to binary - this function returns a base64 decoding of \c data.
+ASCII to binary - this function decodes the base64 encoded \a data string and returns it.
*/
ReturnedValue QtObject::method_atob(CallContext *ctx)
{
@@ -1468,9 +1468,6 @@ QV4::ReturnedValue ConsoleObject::method_profile(CallContext *ctx)
{
QV4::ExecutionEngine *v4 = ctx->d()->engine;
- if (!v4->qmlEngine())
- return QV4::Encode::undefined(); // Not yet implemented for JavaScript.
-
QV4::StackFrame frame = v4->currentStackFrame();
const QByteArray baSource = frame.source.toUtf8();
const QByteArray baFunction = frame.function.toUtf8();
@@ -1479,7 +1476,7 @@ QV4::ReturnedValue ConsoleObject::method_profile(CallContext *ctx)
if (!service) {
logger.warning("Cannot start profiling because debug service is disabled. Start with -qmljsdebugger=port:XXXXX.");
} else {
- service->startProfiling(v4->qmlEngine());
+ service->startProfiling(v4->jsEngine());
logger.debug("Profiling started.");
}
@@ -1490,9 +1487,6 @@ QV4::ReturnedValue ConsoleObject::method_profileEnd(CallContext *ctx)
{
QV4::ExecutionEngine *v4 = ctx->d()->engine;
- if (!v4->qmlEngine())
- return QV4::Encode::undefined(); // Not yet implemented for JavaScript.
-
QV4::StackFrame frame = v4->currentStackFrame();
const QByteArray baSource = frame.source.toUtf8();
const QByteArray baFunction = frame.function.toUtf8();
@@ -1502,7 +1496,7 @@ QV4::ReturnedValue ConsoleObject::method_profileEnd(CallContext *ctx)
if (!service) {
logger.warning("Ignoring console.profileEnd(): the debug service is disabled.");
} else {
- service->stopProfiling(v4->qmlEngine());
+ service->stopProfiling(v4->jsEngine());
logger.debug("Profiling ended.");
}
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
index d373fb6ee6..3eb3b5037f 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
@@ -52,7 +52,6 @@
QT_BEGIN_NAMESPACE
class QQmlEngine;
-class QV8Engine;
namespace QV4 {
diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h
index 552470c88c..a2ccc5f3b0 100644
--- a/src/qml/qml/v8/qv8engine_p.h
+++ b/src/qml/qml/v8/qv8engine_p.h
@@ -113,7 +113,6 @@ namespace QV4 {
// The QQmlV8Function - and consequently the arguments and return value - only remains
// valid during the call. If the return value isn't set within myMethod(), the will return
// undefined.
-class QV8Engine;
class QQmlV4Function
{
diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp
index 6a93410ecb..5f69bf5f94 100644
--- a/src/qml/types/qqmlconnections.cpp
+++ b/src/qml/types/qqmlconnections.cpp
@@ -51,11 +51,12 @@ QT_BEGIN_NAMESPACE
class QQmlConnectionsPrivate : public QObjectPrivate
{
public:
- QQmlConnectionsPrivate() : target(0), targetSet(false), ignoreUnknownSignals(false), componentcomplete(true) {}
+ QQmlConnectionsPrivate() : target(0), enabled(true), targetSet(false), ignoreUnknownSignals(false), componentcomplete(true) {}
QList<QQmlBoundSignal*> boundsignals;
QObject *target;
+ bool enabled;
bool targetSet;
bool ignoreUnknownSignals;
bool componentcomplete;
@@ -177,6 +178,34 @@ void QQmlConnections::setTarget(QObject *obj)
}
/*!
+ \qmlproperty bool QtQml::Connections::enabled
+ \since 5.7
+
+ This property holds whether the item accepts change events.
+
+ By default, this property is \c true.
+*/
+bool QQmlConnections::isEnabled() const
+{
+ Q_D(const QQmlConnections);
+ return d->enabled;
+}
+
+void QQmlConnections::setEnabled(bool enabled)
+{
+ Q_D(QQmlConnections);
+ if (d->enabled == enabled)
+ return;
+
+ d->enabled = enabled;
+
+ foreach (QQmlBoundSignal *s, d->boundsignals)
+ s->setEnabled(d->enabled);
+
+ emit enabledChanged();
+}
+
+/*!
\qmlproperty bool QtQml::Connections::ignoreUnknownSignals
Normally, a connection to a non-existent signal produces runtime errors.
diff --git a/src/qml/types/qqmlconnections_p.h b/src/qml/types/qqmlconnections_p.h
index 234c5061a7..d330b772cc 100644
--- a/src/qml/types/qqmlconnections_p.h
+++ b/src/qml/types/qqmlconnections_p.h
@@ -63,6 +63,7 @@ class Q_AUTOTEST_EXPORT QQmlConnections : public QObject, public QQmlParserStatu
Q_INTERFACES(QQmlParserStatus)
Q_PROPERTY(QObject *target READ target WRITE setTarget NOTIFY targetChanged)
+ Q_REVISION(1) Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
Q_PROPERTY(bool ignoreUnknownSignals READ ignoreUnknownSignals WRITE setIgnoreUnknownSignals)
public:
@@ -72,11 +73,15 @@ public:
QObject *target() const;
void setTarget(QObject *);
+ bool isEnabled() const;
+ void setEnabled(bool enabled);
+
bool ignoreUnknownSignals() const;
void setIgnoreUnknownSignals(bool ignore);
Q_SIGNALS:
void targetChanged();
+ Q_REVISION(1) void enabledChanged();
private:
void connectSignals();
diff --git a/src/qml/types/qqmllistmodelworkeragent.cpp b/src/qml/types/qqmllistmodelworkeragent.cpp
index 76aab248bc..bcf9cd94f7 100644
--- a/src/qml/types/qqmllistmodelworkeragent.cpp
+++ b/src/qml/types/qqmllistmodelworkeragent.cpp
@@ -161,9 +161,7 @@ void QQmlListModelWorkerAgent::move(int from, int to, int count)
void QQmlListModelWorkerAgent::sync()
{
- Sync *s = new Sync;
- s->data = data;
- s->list = m_copy;
+ Sync *s = new Sync(data, m_copy);
data.changes.clear();
mutex.lock();
diff --git a/src/qml/types/qqmllistmodelworkeragent_p.h b/src/qml/types/qqmllistmodelworkeragent_p.h
index be5217eaa4..76603e4a8e 100644
--- a/src/qml/types/qqmllistmodelworkeragent_p.h
+++ b/src/qml/types/qqmllistmodelworkeragent_p.h
@@ -129,7 +129,11 @@ private:
Data data;
struct Sync : public QEvent {
- Sync() : QEvent(QEvent::User) {}
+ Sync(const Data &d, QQmlListModel *l)
+ : QEvent(QEvent::User)
+ , data(d)
+ , list(l)
+ {}
Data data;
QQmlListModel *list;
};
diff --git a/src/qmldebug/qmldebug.pro b/src/qmldebug/qmldebug.pro
new file mode 100644
index 0000000000..e5f6de3314
--- /dev/null
+++ b/src/qmldebug/qmldebug.pro
@@ -0,0 +1,21 @@
+TARGET = QtQmlDebug
+QT = core-private network packetprotocol-private qml-private
+CONFIG += static internal_module
+
+load(qt_module)
+
+SOURCES += \
+ qqmldebugclient.cpp \
+ qqmldebugconnection.cpp \
+ qqmlenginecontrolclient.cpp \
+ qqmlprofilerclient.cpp
+
+HEADERS += \
+ qqmldebugclient_p.h \
+ qqmldebugclient_p_p.h \
+ qqmldebugconnection_p.h \
+ qqmlenginecontrolclient_p.h \
+ qqmlenginecontrolclient_p_p.h \
+ qqmleventlocation_p.h \
+ qqmlprofilerclient_p.h \
+ qqmlprofilerclient_p_p.h
diff --git a/src/qmldebug/qqmldebugclient.cpp b/src/qmldebug/qqmldebugclient.cpp
new file mode 100644
index 0000000000..dfa14d6667
--- /dev/null
+++ b/src/qmldebug/qqmldebugclient.cpp
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmldebugclient_p_p.h"
+#include "qqmldebugconnection_p.h"
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qpointer.h>
+
+QT_BEGIN_NAMESPACE
+
+QQmlDebugClient::QQmlDebugClient(const QString &name, QQmlDebugConnection *parent) :
+ QObject(*(new QQmlDebugClientPrivate(name, parent)), parent)
+{
+ Q_D(QQmlDebugClient);
+ d->addToConnection();
+}
+
+QQmlDebugClient::QQmlDebugClient(QQmlDebugClientPrivate &dd) :
+ QObject(dd, dd.connection.data())
+{
+ Q_D(QQmlDebugClient);
+ d->addToConnection();
+}
+
+QQmlDebugClient::~QQmlDebugClient()
+{
+ Q_D(QQmlDebugClient);
+ if (d->connection && !d->connection->removeClient(d->name))
+ qWarning() << "QQmlDebugClient: Plugin not registered" << d->name;
+}
+
+QQmlDebugClientPrivate::QQmlDebugClientPrivate(const QString &name,
+ QQmlDebugConnection *connection) :
+ name(name), connection(connection)
+{
+}
+
+void QQmlDebugClientPrivate::addToConnection()
+{
+ Q_Q(QQmlDebugClient);
+ if (connection && !connection->addClient(name, q)) {
+ qWarning() << "QQmlDebugClient: Conflicting plugin name" << name;
+ connection = 0;
+ }
+}
+
+QString QQmlDebugClient::name() const
+{
+ Q_D(const QQmlDebugClient);
+ return d->name;
+}
+
+float QQmlDebugClient::serviceVersion() const
+{
+ Q_D(const QQmlDebugClient);
+ return d->connection->serviceVersion(d->name);
+}
+
+QQmlDebugClient::State QQmlDebugClient::state() const
+{
+ Q_D(const QQmlDebugClient);
+ if (!d->connection || !d->connection->isConnected())
+ return NotConnected;
+
+ if (d->connection->serviceVersion(d->name) != -1)
+ return Enabled;
+
+ return Unavailable;
+}
+
+void QQmlDebugClient::sendMessage(const QByteArray &message)
+{
+ Q_D(QQmlDebugClient);
+ d->connection->sendMessage(d->name, message);
+}
+
+QQmlDebugConnection *QQmlDebugClient::connection() const
+{
+ Q_D(const QQmlDebugClient);
+ return d->connection;
+}
+
+void QQmlDebugClient::stateChanged(QQmlDebugClient::State state)
+{
+ Q_UNUSED(state);
+}
+
+void QQmlDebugClient::messageReceived(const QByteArray &message)
+{
+ Q_UNUSED(message);
+}
+
+QT_END_NAMESPACE
diff --git a/tools/qmlprofiler/qqmldebugclient.h b/src/qmldebug/qqmldebugclient_p.h
index 522f6bca2f..6d391617a9 100644
--- a/tools/qmlprofiler/qqmldebugclient.h
+++ b/src/qmldebug/qqmldebugclient_p.h
@@ -31,71 +31,55 @@
**
****************************************************************************/
-#ifndef QQMLDEBUGCLIENT_H
-#define QQMLDEBUGCLIENT_H
+#ifndef QQMLDEBUGCLIENT_P_H
+#define QQMLDEBUGCLIENT_P_H
-#include <QtNetwork/qtcpsocket.h>
+#include <QtCore/qobject.h>
-class QQmlDebugConnectionPrivate;
-class QQmlDebugConnection : public QIODevice
-{
- Q_OBJECT
- Q_DISABLE_COPY(QQmlDebugConnection)
-public:
- QQmlDebugConnection(QObject * = 0);
- ~QQmlDebugConnection();
-
- void connectToHost(const QString &hostName, quint16 port);
-
- qint64 bytesAvailable() const;
- bool isConnected() const;
- QAbstractSocket::SocketState state() const;
- void flush();
- bool isSequential() const;
- void close();
- bool waitForConnected(int msecs = 30000);
-
-signals:
- void connected();
- void stateChanged(QAbstractSocket::SocketState socketState);
- void error(QAbstractSocket::SocketError socketError);
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
-protected:
- qint64 readData(char *data, qint64 maxSize);
- qint64 writeData(const char *data, qint64 maxSize);
-
-private:
- QQmlDebugConnectionPrivate *d;
- friend class QQmlDebugClient;
- friend class QQmlDebugClientPrivate;
-};
+QT_BEGIN_NAMESPACE
+class QQmlDebugConnection;
class QQmlDebugClientPrivate;
class QQmlDebugClient : public QObject
{
Q_OBJECT
Q_DISABLE_COPY(QQmlDebugClient)
+ Q_DECLARE_PRIVATE(QQmlDebugClient)
public:
enum State { NotConnected, Unavailable, Enabled };
- QQmlDebugClient(const QString &, QQmlDebugConnection *parent);
+ QQmlDebugClient(const QString &name, QQmlDebugConnection *parent);
~QQmlDebugClient();
QString name() const;
float serviceVersion() const;
State state() const;
+ void sendMessage(const QByteArray &message);
- virtual void sendMessage(const QByteArray &);
+ QQmlDebugConnection *connection() const;
protected:
- virtual void stateChanged(State);
- virtual void messageReceived(const QByteArray &);
+ QQmlDebugClient(QQmlDebugClientPrivate &dd);
private:
- QQmlDebugClientPrivate *d;
friend class QQmlDebugConnection;
- friend class QQmlDebugConnectionPrivate;
+
+ virtual void stateChanged(State state);
+ virtual void messageReceived(const QByteArray &message);
};
-#endif // QQMLDEBUGCLIENT_H
+QT_END_NAMESPACE
+
+#endif // QQMLDEBUGCLIENT_P_H
diff --git a/src/qmldebug/qqmldebugclient_p_p.h b/src/qmldebug/qqmldebugclient_p_p.h
new file mode 100644
index 0000000000..66a4f4e0c3
--- /dev/null
+++ b/src/qmldebug/qqmldebugclient_p_p.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLDEBUGCLIENT_P_P_H
+#define QQMLDEBUGCLIENT_P_P_H
+
+#include "qqmldebugclient_p.h"
+#include <private/qobject_p.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+class QQmlDebugClientPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QQmlDebugClient)
+public:
+ QQmlDebugClientPrivate(const QString &name, QQmlDebugConnection *connection);
+ void addToConnection();
+
+ QString name;
+ QPointer<QQmlDebugConnection> connection;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLDEBUGCLIENT_P_P_H
diff --git a/src/qmldebug/qqmldebugconnection.cpp b/src/qmldebug/qqmldebugconnection.cpp
new file mode 100644
index 0000000000..3c207b7cc8
--- /dev/null
+++ b/src/qmldebug/qqmldebugconnection.cpp
@@ -0,0 +1,458 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmldebugconnection_p.h"
+#include "qqmldebugclient_p.h"
+
+#include <private/qpacketprotocol_p.h>
+#include <private/qpacket_p.h>
+#include <private/qobject_p.h>
+
+#include <QtCore/qeventloop.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qdatastream.h>
+#include <QtNetwork/qlocalserver.h>
+#include <QtNetwork/qlocalsocket.h>
+#include <QtNetwork/qtcpsocket.h>
+
+QT_BEGIN_NAMESPACE
+
+static const int protocolVersion = 1;
+static const QString serverId = QLatin1String("QDeclarativeDebugServer");
+static const QString clientId = QLatin1String("QDeclarativeDebugClient");
+
+class QQmlDebugConnectionPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QQmlDebugConnection)
+
+public:
+ QQmlDebugConnectionPrivate();
+ QPacketProtocol *protocol;
+ QIODevice *device;
+ QLocalServer *server;
+ QEventLoop handshakeEventLoop;
+ QTimer handshakeTimer;
+
+ bool gotHello;
+ int currentDataStreamVersion;
+ int maximumDataStreamVersion;
+ QHash <QString, float> serverPlugins;
+ QHash<QString, QQmlDebugClient *> plugins;
+ QStringList removedPlugins;
+
+ void advertisePlugins();
+ void connectDeviceSignals();
+ void flush();
+};
+
+QQmlDebugConnectionPrivate::QQmlDebugConnectionPrivate() :
+ protocol(0), device(0), server(0), gotHello(false),
+ currentDataStreamVersion(QDataStream::Qt_4_7),
+ maximumDataStreamVersion(QDataStream::Qt_DefaultCompiledVersion)
+{
+ handshakeTimer.setSingleShot(true);
+ handshakeTimer.setInterval(3000);
+}
+
+void QQmlDebugConnectionPrivate::advertisePlugins()
+{
+ Q_Q(QQmlDebugConnection);
+ if (!q->isConnected())
+ return;
+
+ QPacket pack(currentDataStreamVersion);
+ pack << serverId << 1 << plugins.keys();
+ protocol->send(pack.data());
+ flush();
+}
+
+void QQmlDebugConnection::socketConnected()
+{
+ Q_D(QQmlDebugConnection);
+ QPacket pack(d->currentDataStreamVersion);
+ pack << serverId << 0 << protocolVersion << d->plugins.keys() << d->maximumDataStreamVersion;
+ d->protocol->send(pack.data());
+ d->flush();
+}
+
+void QQmlDebugConnection::socketDisconnected()
+{
+ Q_D(QQmlDebugConnection);
+ d->gotHello = false;
+ emit disconnected();
+}
+
+void QQmlDebugConnection::protocolReadyRead()
+{
+ Q_D(QQmlDebugConnection);
+ if (!d->gotHello) {
+ QPacket pack(d->currentDataStreamVersion, d->protocol->read());
+ QString name;
+
+ pack >> name;
+
+ bool validHello = false;
+ if (name == clientId) {
+ int op = -1;
+ pack >> op;
+ if (op == 0) {
+ int version = -1;
+ pack >> version;
+ if (version == protocolVersion) {
+ QStringList pluginNames;
+ QList<float> pluginVersions;
+ pack >> pluginNames;
+ if (!pack.atEnd())
+ pack >> pluginVersions;
+
+ const int pluginNamesSize = pluginNames.size();
+ const int pluginVersionsSize = pluginVersions.size();
+ for (int i = 0; i < pluginNamesSize; ++i) {
+ float pluginVersion = 1.0;
+ if (i < pluginVersionsSize)
+ pluginVersion = pluginVersions.at(i);
+ d->serverPlugins.insert(pluginNames.at(i), pluginVersion);
+ }
+
+ pack >> d->currentDataStreamVersion;
+ validHello = true;
+ }
+ }
+ }
+
+ if (!validHello) {
+ qWarning("QQmlDebugConnection: Invalid hello message");
+ QObject::disconnect(d->protocol, SIGNAL(protocolReadyRead()), this, SLOT(protocolReadyRead()));
+ return;
+ }
+ d->gotHello = true;
+ emit connected();
+
+ QHash<QString, QQmlDebugClient *>::Iterator iter = d->plugins.begin();
+ for (; iter != d->plugins.end(); ++iter) {
+ QQmlDebugClient::State newState = QQmlDebugClient::Unavailable;
+ if (d->serverPlugins.contains(iter.key()))
+ newState = QQmlDebugClient::Enabled;
+ iter.value()->stateChanged(newState);
+ }
+
+ d->handshakeTimer.stop();
+ d->handshakeEventLoop.quit();
+ }
+
+ while (d->protocol->packetsAvailable()) {
+ QPacket pack(d->currentDataStreamVersion, d->protocol->read());
+ QString name;
+ pack >> name;
+
+ if (name == clientId) {
+ int op = -1;
+ pack >> op;
+
+ if (op == 1) {
+ // Service Discovery
+ QHash<QString, float> oldServerPlugins = d->serverPlugins;
+ d->serverPlugins.clear();
+
+ QStringList pluginNames;
+ QList<float> pluginVersions;
+ pack >> pluginNames;
+ if (!pack.atEnd())
+ pack >> pluginVersions;
+
+ const int pluginNamesSize = pluginNames.size();
+ const int pluginVersionsSize = pluginVersions.size();
+ for (int i = 0; i < pluginNamesSize; ++i) {
+ float pluginVersion = 1.0;
+ if (i < pluginVersionsSize)
+ pluginVersion = pluginVersions.at(i);
+ d->serverPlugins.insert(pluginNames.at(i), pluginVersion);
+ }
+
+ QHash<QString, QQmlDebugClient *>::Iterator iter = d->plugins.begin();
+ for (; iter != d->plugins.end(); ++iter) {
+ const QString pluginName = iter.key();
+ QQmlDebugClient::State newSate = QQmlDebugClient::Unavailable;
+ if (d->serverPlugins.contains(pluginName))
+ newSate = QQmlDebugClient::Enabled;
+
+ if (oldServerPlugins.contains(pluginName)
+ != d->serverPlugins.contains(pluginName)) {
+ iter.value()->stateChanged(newSate);
+ }
+ }
+ } else {
+ qWarning() << "QQmlDebugConnection: Unknown control message id" << op;
+ }
+ } else {
+ QByteArray message;
+ pack >> message;
+
+ QHash<QString, QQmlDebugClient *>::Iterator iter = d->plugins.find(name);
+ if (iter == d->plugins.end()) {
+ // We can get more messages for plugins we have removed because it takes time to
+ // send the advertisement message but the removal is instant locally.
+ if (!d->removedPlugins.contains(name))
+ qWarning() << "QQmlDebugConnection: Message received for missing plugin"
+ << name;
+ } else {
+ (*iter)->messageReceived(message);
+ }
+ }
+ }
+}
+
+void QQmlDebugConnection::handshakeTimeout()
+{
+ Q_D(QQmlDebugConnection);
+ if (!d->gotHello) {
+ qWarning() << "QQmlDebugConnection: Did not get handshake answer in time";
+ d->handshakeEventLoop.quit();
+ }
+}
+
+QQmlDebugConnection::QQmlDebugConnection(QObject *parent) :
+ QObject(*(new QQmlDebugConnectionPrivate), parent)
+{
+ Q_D(QQmlDebugConnection);
+ connect(&d->handshakeTimer, SIGNAL(timeout()), this, SLOT(handshakeTimeout()));
+}
+
+QQmlDebugConnection::~QQmlDebugConnection()
+{
+ Q_D(QQmlDebugConnection);
+ QHash<QString, QQmlDebugClient*>::iterator iter = d->plugins.begin();
+ for (; iter != d->plugins.end(); ++iter)
+ iter.value()->stateChanged(QQmlDebugClient::NotConnected);
+}
+
+int QQmlDebugConnection::currentDataStreamVersion() const
+{
+ Q_D(const QQmlDebugConnection);
+ return d->currentDataStreamVersion;
+}
+
+void QQmlDebugConnection::setMaximumDataStreamVersion(int maximumVersion)
+{
+ Q_D(QQmlDebugConnection);
+ d->maximumDataStreamVersion = maximumVersion;
+}
+
+bool QQmlDebugConnection::isConnected() const
+{
+ Q_D(const QQmlDebugConnection);
+ return d->gotHello;
+}
+
+bool QQmlDebugConnection::isConnecting() const
+{
+ Q_D(const QQmlDebugConnection);
+ return !d->gotHello && d->device;
+}
+
+void QQmlDebugConnection::close()
+{
+ Q_D(QQmlDebugConnection);
+ if (d->gotHello) {
+ d->gotHello = false;
+ d->device->close();
+
+ QHash<QString, QQmlDebugClient*>::iterator iter = d->plugins.begin();
+ for (; iter != d->plugins.end(); ++iter)
+ iter.value()->stateChanged(QQmlDebugClient::NotConnected);
+ }
+
+ if (d->device) {
+ d->device->deleteLater();
+ d->device = 0;
+ }
+}
+
+bool QQmlDebugConnection::waitForConnected(int msecs)
+{
+ Q_D(QQmlDebugConnection);
+ QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(d->device);
+ if (!socket) {
+ if (!d->server || (!d->server->hasPendingConnections() &&
+ !d->server->waitForNewConnection(msecs)))
+ return false;
+ } else if (!socket->waitForConnected(msecs)) {
+ return false;
+ }
+ // wait for handshake
+ d->handshakeTimer.start();
+ d->handshakeEventLoop.exec();
+ return d->gotHello;
+}
+
+QQmlDebugClient *QQmlDebugConnection::client(const QString &name) const
+{
+ Q_D(const QQmlDebugConnection);
+ return d->plugins.value(name, 0);
+}
+
+bool QQmlDebugConnection::addClient(const QString &name, QQmlDebugClient *client)
+{
+ Q_D(QQmlDebugConnection);
+ if (d->plugins.contains(name))
+ return false;
+ d->removedPlugins.removeAll(name);
+ d->plugins.insert(name, client);
+ d->advertisePlugins();
+ return true;
+}
+
+bool QQmlDebugConnection::removeClient(const QString &name)
+{
+ Q_D(QQmlDebugConnection);
+ if (!d->plugins.contains(name))
+ return false;
+ d->plugins.remove(name);
+ d->removedPlugins.append(name);
+ d->advertisePlugins();
+ return true;
+}
+
+float QQmlDebugConnection::serviceVersion(const QString &serviceName) const
+{
+ Q_D(const QQmlDebugConnection);
+ return d->serverPlugins.value(serviceName, -1);
+}
+
+bool QQmlDebugConnection::sendMessage(const QString &name, const QByteArray &message)
+{
+ Q_D(QQmlDebugConnection);
+ if (!isConnected() || !d->serverPlugins.contains(name))
+ return false;
+
+ QPacket pack(d->currentDataStreamVersion);
+ pack << name << message;
+ d->protocol->send(pack.data());
+ d->flush();
+
+ return true;
+}
+
+void QQmlDebugConnectionPrivate::flush()
+{
+ QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(device);
+ if (socket)
+ socket->flush();
+}
+
+void QQmlDebugConnection::connectToHost(const QString &hostName, quint16 port)
+{
+ Q_D(QQmlDebugConnection);
+ if (d->gotHello)
+ close();
+ QTcpSocket *socket = new QTcpSocket(this);
+ d->device = socket;
+ d->connectDeviceSignals();
+ connect(socket, SIGNAL(connected()), this, SLOT(socketConnected()));
+ connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
+ this, SIGNAL(socketError(QAbstractSocket::SocketError)));
+ connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
+ this, SIGNAL(socketStateChanged(QAbstractSocket::SocketState)));
+ socket->connectToHost(hostName, port);
+}
+
+void QQmlDebugConnection::startLocalServer(const QString &fileName)
+{
+ Q_D(QQmlDebugConnection);
+ if (d->gotHello)
+ close();
+ if (d->server)
+ d->server->deleteLater();
+ d->server = new QLocalServer(this);
+ // QueuedConnection so that waitForNewConnection() returns true.
+ connect(d->server, SIGNAL(newConnection()), this, SLOT(newConnection()), Qt::QueuedConnection);
+ d->server->listen(fileName);
+}
+
+class LocalSocketSignalTranslator : public QObject
+{
+ Q_OBJECT
+public:
+ LocalSocketSignalTranslator(QLocalSocket *parent) : QObject(parent)
+ {
+ connect(parent, SIGNAL(stateChanged(QLocalSocket::LocalSocketState)),
+ this, SLOT(onStateChanged(QLocalSocket::LocalSocketState)));
+ connect(parent, SIGNAL(error(QLocalSocket::LocalSocketError)),
+ this, SLOT(onError(QLocalSocket::LocalSocketError)));
+ }
+
+signals:
+ void socketError(QAbstractSocket::SocketError error);
+ void socketStateChanged(QAbstractSocket::SocketState state);
+
+public slots:
+ void onError(QLocalSocket::LocalSocketError error)
+ {
+ emit socketError(static_cast<QAbstractSocket::SocketError>(error));
+ }
+
+ void onStateChanged(QLocalSocket::LocalSocketState state)
+ {
+ emit socketStateChanged(static_cast<QAbstractSocket::SocketState>(state));
+ }
+};
+
+void QQmlDebugConnection::newConnection()
+{
+ Q_D(QQmlDebugConnection);
+ delete d->device;
+ QLocalSocket *socket = d->server->nextPendingConnection();
+ d->server->close();
+ d->device = socket;
+ d->connectDeviceSignals();
+ LocalSocketSignalTranslator *translator = new LocalSocketSignalTranslator(socket);
+
+ QObject::connect(translator, SIGNAL(socketError(QAbstractSocket::SocketError)),
+ this, SIGNAL(socketError(QAbstractSocket::SocketError)));
+ QObject::connect(translator, SIGNAL(socketStateChanged(QAbstractSocket::SocketState)),
+ this, SIGNAL(socketStateChanged(QAbstractSocket::SocketState)));
+ socketConnected();
+}
+
+void QQmlDebugConnectionPrivate::connectDeviceSignals()
+{
+ Q_Q(QQmlDebugConnection);
+ delete protocol;
+ protocol = new QPacketProtocol(device, q);
+ QObject::connect(protocol, SIGNAL(readyRead()), q, SLOT(protocolReadyRead()));
+ QObject::connect(device, SIGNAL(disconnected()), q, SLOT(socketDisconnected()));
+}
+
+QT_END_NAMESPACE
+
+#include <qqmldebugconnection.moc>
diff --git a/tests/auto/qml/debugger/shared/qqmldebugclient.h b/src/qmldebug/qqmldebugconnection_p.h
index fe9da693c8..190ca25db2 100644
--- a/tests/auto/qml/debugger/shared/qqmldebugclient.h
+++ b/src/qmldebug/qqmldebugconnection_p.h
@@ -31,80 +31,69 @@
**
****************************************************************************/
-#ifndef QQMLDEBUGCLIENT_H
-#define QQMLDEBUGCLIENT_H
-
-#include <QtNetwork/qtcpsocket.h>
-
+#ifndef QQMLDEBUGCONNECTION_P_H
+#define QQMLDEBUGCONNECTION_P_H
+
+#include <QtCore/qobject.h>
+#include <QtNetwork/qabstractsocket.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+class QQmlDebugClient;
class QQmlDebugConnectionPrivate;
-class QQmlDebugConnection : public QIODevice
+class QQmlDebugConnection : public QObject
{
Q_OBJECT
Q_DISABLE_COPY(QQmlDebugConnection)
+ Q_DECLARE_PRIVATE(QQmlDebugConnection)
public:
- QQmlDebugConnection(QObject * = 0);
+ QQmlDebugConnection(QObject *parent = 0);
~QQmlDebugConnection();
void connectToHost(const QString &hostName, quint16 port);
void startLocalServer(const QString &fileName);
- void setDataStreamVersion(int dataStreamVersion);
- int dataStreamVersion();
+ int currentDataStreamVersion() const;
+ void setMaximumDataStreamVersion(int maximumVersion);
- qint64 bytesAvailable() const;
bool isConnected() const;
- QAbstractSocket::SocketState state() const;
- void flush();
- bool isSequential() const;
+ bool isConnecting() const;
+
void close();
bool waitForConnected(int msecs = 30000);
- QString stateString() const;
+ QQmlDebugClient *client(const QString &name) const;
+ bool addClient(const QString &name, QQmlDebugClient *client);
+ bool removeClient(const QString &name);
+
+ float serviceVersion(const QString &serviceName) const;
+ bool sendMessage(const QString &name, const QByteArray &message);
signals:
void connected();
- void stateChanged(QAbstractSocket::SocketState socketState);
- void error(QAbstractSocket::SocketError socketError);
-
-protected:
- qint64 readData(char *data, qint64 maxSize);
- qint64 writeData(const char *data, qint64 maxSize);
-
-private:
- QQmlDebugConnectionPrivate *d;
- int m_dataStreamVersion;
- friend class QQmlDebugClient;
- friend class QQmlDebugClientPrivate;
- friend class QQmlDebugConnectionPrivate;
+ void disconnected();
+ void socketError(QAbstractSocket::SocketError socketError);
+ void socketStateChanged(QAbstractSocket::SocketState socketState);
+
+private Q_SLOTS:
+ void newConnection();
+ void socketConnected();
+ void socketDisconnected();
+ void protocolReadyRead();
+ void handshakeTimeout();
};
-class QQmlDebugClientPrivate;
-class QQmlDebugClient : public QObject
-{
- Q_OBJECT
- Q_DISABLE_COPY(QQmlDebugClient)
-
-public:
- enum State { NotConnected, Unavailable, Enabled };
-
- QQmlDebugClient(const QString &, QQmlDebugConnection *parent);
- ~QQmlDebugClient();
-
- QString name() const;
- float serviceVersion() const;
- State state() const;
- QString stateString() const;
-
- virtual void sendMessage(const QByteArray &);
-
-protected:
- virtual void stateChanged(State);
- virtual void messageReceived(const QByteArray &);
-
-private:
- QQmlDebugClientPrivate *d;
- friend class QQmlDebugConnection;
- friend class QQmlDebugConnectionPrivate;
-};
+QT_END_NAMESPACE
-#endif // QQMLDEBUGCLIENT_H
+#endif // QQMLDEBUGCONNECTION_P_H
diff --git a/src/qmldebug/qqmlenginecontrolclient.cpp b/src/qmldebug/qqmlenginecontrolclient.cpp
new file mode 100644
index 0000000000..b45e4e1f14
--- /dev/null
+++ b/src/qmldebug/qqmlenginecontrolclient.cpp
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmlenginecontrolclient_p.h"
+#include "qqmlenginecontrolclient_p_p.h"
+#include "qqmldebugconnection_p.h"
+
+#include <private/qqmldebugserviceinterfaces_p.h>
+#include <private/qpacket_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QQmlEngineControlClient::QQmlEngineControlClient(QQmlDebugConnection *connection) :
+ QQmlDebugClient(*(new QQmlEngineControlClientPrivate(connection)))
+{
+}
+
+QQmlEngineControlClient::QQmlEngineControlClient(QQmlEngineControlClientPrivate &dd) :
+ QQmlDebugClient(dd)
+{
+}
+
+/*!
+ * Block the starting or stopping of the engine with id \a engineId for now. By calling
+ * releaseEngine later the block can be lifted again. In the debugged application the engine control
+ * server waits until a message is received before continuing. So by not sending a message here we
+ * delay the process. Blocks add up. You have to call releaseEngine() as often as you've called
+ * blockEngine before. The intention of that is to allow different debug clients to use the same
+ * engine control and communicate with their respective counterparts before the QML engine starts or
+ * shuts down.
+ */
+void QQmlEngineControlClient::blockEngine(int engineId)
+{
+ Q_D(QQmlEngineControlClient);
+ Q_ASSERT(d->blockedEngines.contains(engineId));
+ d->blockedEngines[engineId].blockers++;
+}
+
+/*!
+ * Release the engine with id \a engineId. If no other blocks are present, depending on what the
+ * engine is waiting for, the start or stop command is sent to the process being debugged.
+ */
+void QQmlEngineControlClient::releaseEngine(int engineId)
+{
+ Q_D(QQmlEngineControlClient);
+ Q_ASSERT(d->blockedEngines.contains(engineId));
+
+ QQmlEngineControlClientPrivate::EngineState &state = d->blockedEngines[engineId];
+ if (--state.blockers == 0) {
+ Q_ASSERT(state.releaseCommand != QQmlEngineControlClientPrivate::InvalidCommand);
+ d->sendCommand(state.releaseCommand, engineId);
+ d->blockedEngines.remove(engineId);
+ }
+}
+
+QList<int> QQmlEngineControlClient::blockedEngines() const
+{
+ Q_D(const QQmlEngineControlClient);
+ return d->blockedEngines.keys();
+}
+
+void QQmlEngineControlClient::messageReceived(const QByteArray &data)
+{
+ Q_D(QQmlEngineControlClient);
+ QPacket stream(d->connection->currentDataStreamVersion(), data);
+ int message;
+ int id;
+ QString name;
+
+ stream >> message >> id;
+
+ if (!stream.atEnd())
+ stream >> name;
+
+ QQmlEngineControlClientPrivate::EngineState &state = d->blockedEngines[id];
+ Q_ASSERT(state.blockers == 0);
+ Q_ASSERT(state.releaseCommand == QQmlEngineControlClientPrivate::InvalidCommand);
+
+ switch (message) {
+ case QQmlEngineControlClientPrivate::EngineAboutToBeAdded:
+ state.releaseCommand = QQmlEngineControlClientPrivate::StartWaitingEngine;
+ emit engineAboutToBeAdded(id, name);
+ break;
+ case QQmlEngineControlClientPrivate::EngineAdded:
+ emit engineAdded(id, name);
+ break;
+ case QQmlEngineControlClientPrivate::EngineAboutToBeRemoved:
+ state.releaseCommand = QQmlEngineControlClientPrivate::StopWaitingEngine;
+ emit engineAboutToBeRemoved(id, name);
+ break;
+ case QQmlEngineControlClientPrivate::EngineRemoved:
+ emit engineRemoved(id, name);
+ break;
+ }
+
+ if (state.blockers == 0 &&
+ state.releaseCommand != QQmlEngineControlClientPrivate::InvalidCommand) {
+ d->sendCommand(state.releaseCommand, id);
+ d->blockedEngines.remove(id);
+ }
+}
+
+QQmlEngineControlClientPrivate::QQmlEngineControlClientPrivate(QQmlDebugConnection *connection) :
+ QQmlDebugClientPrivate(QQmlEngineControlService::s_key, connection)
+{
+}
+
+void QQmlEngineControlClientPrivate::sendCommand(
+ QQmlEngineControlClientPrivate::CommandType command, int engineId)
+{
+ Q_Q(QQmlEngineControlClient);
+ QPacket stream(connection->currentDataStreamVersion());
+ stream << int(command) << engineId;
+ q->sendMessage(stream.data());
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/shared/qpacketprotocol.h b/src/qmldebug/qqmlenginecontrolclient_p.h
index c571e8d2b8..601f8a871d 100644
--- a/src/plugins/qmltooling/shared/qpacketprotocol.h
+++ b/src/qmldebug/qqmlenginecontrolclient_p.h
@@ -31,81 +31,50 @@
**
****************************************************************************/
-#ifndef QPACKETPROTOCOL_H
-#define QPACKETPROTOCOL_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qdatastream.h>
+#ifndef QQMLENGINECONTROLCLIENT_P_H
+#define QQMLENGINECONTROLCLIENT_P_H
+
+#include "qqmldebugclient_p.h"
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
QT_BEGIN_NAMESPACE
-class QIODevice;
-class QBuffer;
-class QPacket;
-class QPacketAutoSend;
-class QPacketProtocolPrivate;
-
-class QPacketProtocol : public QObject
+class QQmlEngineControlClientPrivate;
+class QQmlEngineControlClient : public QQmlDebugClient
{
Q_OBJECT
+ Q_DECLARE_PRIVATE(QQmlEngineControlClient)
public:
- explicit QPacketProtocol(QIODevice *dev, QObject *parent = 0);
- virtual ~QPacketProtocol();
-
- qint32 maximumPacketSize() const;
- qint32 setMaximumPacketSize(qint32);
-
- QPacketAutoSend send();
- void send(const QPacket &);
-
- qint64 packetsAvailable() const;
- QPacket read();
-
- bool waitForReadyRead(int msecs = 3000);
-
- void clear();
-
- QIODevice *device();
-
-Q_SIGNALS:
- void readyRead();
- void invalidPacket();
- void packetWritten();
-
-private:
- QPacketProtocolPrivate *d;
-};
+ QQmlEngineControlClient(QQmlDebugConnection *connection);
+ void blockEngine(int engineId);
+ void releaseEngine(int engineId);
-class QPacket : public QDataStream
-{
-public:
- QPacket();
- QPacket(const QPacket &);
- virtual ~QPacket();
+ QList<int> blockedEngines() const;
- void clear();
- bool isEmpty() const;
- QByteArray data() const;
+signals:
+ void engineAboutToBeAdded(int engineId, const QString &name);
+ void engineAdded(int engineId, const QString &name);
+ void engineAboutToBeRemoved(int engineId, const QString &name);
+ void engineRemoved(int engineId, const QString &name);
protected:
- friend class QPacketProtocol;
- QPacket(const QByteArray &ba);
- QByteArray b;
- QBuffer *buf;
-};
-
-class QPacketAutoSend : public QPacket
-{
-public:
- virtual ~QPacketAutoSend();
+ QQmlEngineControlClient(QQmlEngineControlClientPrivate &dd);
private:
- friend class QPacketProtocol;
- QPacketAutoSend(QPacketProtocol *);
- QPacketProtocol *p;
+ void messageReceived(const QByteArray &);
};
QT_END_NAMESPACE
-#endif
+#endif // QQMLENGINECONTROLCLIENT_P_H
diff --git a/src/qmldebug/qqmlenginecontrolclient_p_p.h b/src/qmldebug/qqmlenginecontrolclient_p_p.h
new file mode 100644
index 0000000000..7e99c35948
--- /dev/null
+++ b/src/qmldebug/qqmlenginecontrolclient_p_p.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLENGINECONTROLCLIENT_P_P_H
+#define QQMLENGINECONTROLCLIENT_P_P_H
+
+#include "qqmlenginecontrolclient_p.h"
+#include "qqmldebugclient_p_p.h"
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+class QQmlEngineControlClientPrivate : public QQmlDebugClientPrivate
+{
+ Q_DECLARE_PUBLIC(QQmlEngineControlClient)
+public:
+ enum MessageType {
+ EngineAboutToBeAdded,
+ EngineAdded,
+ EngineAboutToBeRemoved,
+ EngineRemoved
+ };
+
+ enum CommandType {
+ StartWaitingEngine,
+ StopWaitingEngine,
+ InvalidCommand
+ };
+
+ QQmlEngineControlClientPrivate(QQmlDebugConnection *connection);
+
+ void sendCommand(CommandType command, int engineId);
+
+ struct EngineState {
+ EngineState(CommandType command = InvalidCommand) : releaseCommand(command), blockers(0) {}
+ CommandType releaseCommand;
+ int blockers;
+ };
+
+ QHash<int, EngineState> blockedEngines;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLENGINECONTROLCLIENT_P_P_H
diff --git a/src/qmldebug/qqmleventlocation_p.h b/src/qmldebug/qqmleventlocation_p.h
new file mode 100644
index 0000000000..25d81a5989
--- /dev/null
+++ b/src/qmldebug/qqmleventlocation_p.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLEVENTLOCATION_P_H
+#define QQMLEVENTLOCATION_P_H
+
+#include <QtCore/qstring.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+struct QQmlEventLocation
+{
+ QQmlEventLocation() : line(-1), column(-1) {}
+ QQmlEventLocation(const QString &file, int lineNumber, int columnNumber) :
+ filename(file), line(lineNumber), column(columnNumber) {}
+
+ QString filename;
+ int line;
+ int column;
+};
+
+Q_DECLARE_TYPEINFO(QQmlEventLocation, Q_MOVABLE_TYPE);
+
+QT_END_NAMESPACE
+
+#endif // QQMLEVENTLOCATION_P_H
diff --git a/src/qmldebug/qqmlprofilerclient.cpp b/src/qmldebug/qqmlprofilerclient.cpp
new file mode 100644
index 0000000000..c7ad6dae53
--- /dev/null
+++ b/src/qmldebug/qqmlprofilerclient.cpp
@@ -0,0 +1,354 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmlprofilerclient_p_p.h"
+#include "qqmldebugconnection_p.h"
+#include <private/qqmldebugserviceinterfaces_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QQmlProfilerClient::QQmlProfilerClient(QQmlDebugConnection *connection) :
+ QQmlDebugClient(*(new QQmlProfilerClientPrivate(connection)))
+{
+}
+
+QQmlProfilerClient::QQmlProfilerClient(QQmlProfilerClientPrivate &dd) :
+ QQmlDebugClient(dd)
+{
+}
+
+QQmlProfilerClientPrivate::QQmlProfilerClientPrivate(QQmlDebugConnection *connection) :
+ QQmlDebugClientPrivate(QQmlProfilerService::s_key, connection),
+ features(std::numeric_limits<quint64>::max())
+{
+}
+
+void QQmlProfilerClient::setFeatures(quint64 features)
+{
+ Q_D(QQmlProfilerClient);
+ d->features = features;
+}
+
+void QQmlProfilerClient::sendRecordingStatus(bool record, int engineId, quint32 flushInterval)
+{
+ Q_D(const QQmlProfilerClient);
+
+ QPacket stream(d->connection->currentDataStreamVersion());
+ stream << record << engineId << d->features << flushInterval;
+ sendMessage(stream.data());
+}
+
+void QQmlProfilerClient::traceStarted(qint64 time, int engineId)
+{
+ Q_UNUSED(time);
+ Q_UNUSED(engineId);
+}
+
+void QQmlProfilerClient::traceFinished(qint64 time, int engineId)
+{
+ Q_UNUSED(time);
+ Q_UNUSED(engineId);
+}
+
+void QQmlProfilerClient::rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime)
+{
+ Q_UNUSED(type);
+ Q_UNUSED(startTime);
+}
+
+void QQmlProfilerClient::rangeData(QQmlProfilerDefinitions::RangeType type, qint64 time,
+ const QString &data)
+{
+ Q_UNUSED(type);
+ Q_UNUSED(time);
+ Q_UNUSED(data);
+}
+
+void QQmlProfilerClient::rangeLocation(QQmlProfilerDefinitions::RangeType type, qint64 time,
+ const QQmlEventLocation &location)
+{
+ Q_UNUSED(type);
+ Q_UNUSED(time);
+ Q_UNUSED(location);
+}
+
+void QQmlProfilerClient::rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime)
+{
+ Q_UNUSED(type);
+ Q_UNUSED(endTime);
+}
+
+void QQmlProfilerClient::animationFrame(qint64 time, int frameRate, int animationCount,
+ int threadId)
+{
+ Q_UNUSED(time);
+ Q_UNUSED(frameRate);
+ Q_UNUSED(animationCount);
+ Q_UNUSED(threadId);
+}
+
+void QQmlProfilerClient::sceneGraphEvent(QQmlProfilerDefinitions::SceneGraphFrameType type,
+ qint64 time, qint64 numericData1, qint64 numericData2,
+ qint64 numericData3, qint64 numericData4,
+ qint64 numericData5)
+{
+ Q_UNUSED(type);
+ Q_UNUSED(time);
+ Q_UNUSED(numericData1);
+ Q_UNUSED(numericData2);
+ Q_UNUSED(numericData3);
+ Q_UNUSED(numericData4);
+ Q_UNUSED(numericData5);
+}
+
+void QQmlProfilerClient::pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type,
+ qint64 time, const QString &url, int numericData1,
+ int numericData2)
+{
+ Q_UNUSED(type);
+ Q_UNUSED(time);
+ Q_UNUSED(url);
+ Q_UNUSED(numericData1);
+ Q_UNUSED(numericData2);
+}
+
+void QQmlProfilerClient::memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time,
+ qint64 amount)
+{
+ Q_UNUSED(type);
+ Q_UNUSED(time);
+ Q_UNUSED(amount);
+}
+
+void QQmlProfilerClient::inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time,
+ int a, int b)
+{
+ Q_UNUSED(type);
+ Q_UNUSED(time);
+ Q_UNUSED(a);
+ Q_UNUSED(b);
+}
+
+void QQmlProfilerClient::complete()
+{
+}
+
+void QQmlProfilerClient::unknownEvent(QQmlProfilerDefinitions::Message messageType, qint64 time,
+ int detailType)
+{
+ Q_UNUSED(messageType);
+ Q_UNUSED(time);
+ Q_UNUSED(detailType);
+}
+
+void QQmlProfilerClient::unknownData(QPacket &stream)
+{
+ Q_UNUSED(stream);
+}
+
+inline QQmlProfilerDefinitions::ProfileFeature featureFromRangeType(
+ QQmlProfilerDefinitions::RangeType range)
+{
+ switch (range) {
+ case QQmlProfilerDefinitions::Painting:
+ return QQmlProfilerDefinitions::ProfilePainting;
+ case QQmlProfilerDefinitions::Compiling:
+ return QQmlProfilerDefinitions::ProfileCompiling;
+ case QQmlProfilerDefinitions::Creating:
+ return QQmlProfilerDefinitions::ProfileCreating;
+ case QQmlProfilerDefinitions::Binding:
+ return QQmlProfilerDefinitions::ProfileBinding;
+ case QQmlProfilerDefinitions::HandlingSignal:
+ return QQmlProfilerDefinitions::ProfileHandlingSignal;
+ case QQmlProfilerDefinitions::Javascript:
+ return QQmlProfilerDefinitions::ProfileJavaScript;
+ default:
+ return QQmlProfilerDefinitions::MaximumProfileFeature;
+ }
+}
+
+void QQmlProfilerClient::messageReceived(const QByteArray &data)
+{
+ Q_D(const QQmlProfilerClient);
+
+ QPacket stream(d->connection->currentDataStreamVersion(), data);
+
+ // Force all the 1 << <FLAG> expressions to be done in 64 bit, to silence some warnings
+ const quint64 one = static_cast<quint64>(1);
+
+ qint64 time;
+ int messageType;
+
+ stream >> time >> messageType;
+
+ if (messageType >= QQmlProfilerDefinitions::MaximumMessage) {
+ unknownEvent(static_cast<QQmlProfilerDefinitions::Message>(messageType), time, -1);
+ return;
+ }
+
+ if (messageType == QQmlProfilerDefinitions::Event) {
+ int type;
+ stream >> type;
+
+ QQmlProfilerDefinitions::EventType eventType =
+ static_cast<QQmlProfilerDefinitions::EventType>(type);
+
+ if (eventType == QQmlProfilerDefinitions::EndTrace) {
+ int engineId = -1;
+ if (!stream.atEnd())
+ stream >> engineId;
+ traceFinished(time, engineId);
+ } else if (eventType == QQmlProfilerDefinitions::AnimationFrame) {
+ if (!(d->features & one << QQmlProfilerDefinitions::ProfileAnimations))
+ return;
+
+ int frameRate, animationCount;
+ int threadId = 0;
+ stream >> frameRate >> animationCount;
+ if (!stream.atEnd())
+ stream >> threadId;
+
+ animationFrame(time, frameRate, animationCount, threadId);
+ } else if (type == QQmlProfilerDefinitions::StartTrace) {
+ int engineId = -1;
+ if (!stream.atEnd())
+ stream >> engineId;
+ traceStarted(time, engineId);
+ } else if (eventType == QQmlProfilerDefinitions::Key ||
+ eventType == QQmlProfilerDefinitions::Mouse) {
+
+ if (!(d->features & one << QQmlProfilerDefinitions::ProfileInputEvents))
+ return;
+
+ int type;
+ if (!stream.atEnd()) {
+ stream >> type;
+ } else {
+ type = (eventType == QQmlProfilerDefinitions::Key) ?
+ QQmlProfilerDefinitions::InputKeyUnknown :
+ QQmlProfilerDefinitions::InputMouseUnknown;
+ }
+
+ int a = 0;
+ if (!stream.atEnd())
+ stream >> a;
+
+ int b = 0;
+ if (!stream.atEnd())
+ stream >> b;
+
+ inputEvent(static_cast<QQmlProfilerDefinitions::InputEventType>(type), time, a, b);
+ } else {
+ unknownEvent(QQmlProfilerDefinitions::Event, time, type);
+ }
+ } else if (messageType == QQmlProfilerDefinitions::Complete) {
+ complete();
+ } else if (messageType == QQmlProfilerDefinitions::SceneGraphFrame) {
+ if (!(d->features & one << QQmlProfilerDefinitions::ProfileSceneGraph))
+ return;
+
+ int type;
+ int count = 0;
+ qint64 params[5];
+
+ stream >> type;
+ while (!stream.atEnd())
+ stream >> params[count++];
+
+ while (count < 5)
+ params[count++] = 0;
+
+ sceneGraphEvent(static_cast<QQmlProfilerDefinitions::SceneGraphFrameType>(type), time,
+ params[0], params[1], params[2], params[3], params[4]);
+ } else if (messageType == QQmlProfilerDefinitions::PixmapCacheEvent) {
+ if (!(d->features & one << QQmlProfilerDefinitions::ProfilePixmapCache))
+ return;
+
+ int type, param1 = 0, param2 = 0;
+ QString pixUrl;
+ stream >> type >> pixUrl;
+
+ QQmlProfilerDefinitions::PixmapEventType pixmapEventType =
+ static_cast<QQmlProfilerDefinitions::PixmapEventType>(type);
+
+ if (pixmapEventType == QQmlProfilerDefinitions::PixmapReferenceCountChanged ||
+ pixmapEventType == QQmlProfilerDefinitions::PixmapCacheCountChanged) {
+ stream >> param1;
+ } else if (pixmapEventType == QQmlProfilerDefinitions::PixmapSizeKnown) {
+ stream >> param1 >> param2;
+ }
+
+ pixmapCacheEvent(pixmapEventType, time, pixUrl, param1, param2);
+ } else if (messageType == QQmlProfilerDefinitions::MemoryAllocation) {
+ if (!(d->features & one << QQmlProfilerDefinitions::ProfileMemory))
+ return;
+ int type;
+ qint64 delta;
+ stream >> type >> delta;
+ memoryAllocation((QQmlProfilerDefinitions::MemoryType)type, time, delta);
+ } else {
+ int range;
+ stream >> range;
+
+ QQmlProfilerDefinitions::RangeType rangeType =
+ static_cast<QQmlProfilerDefinitions::RangeType>(range);
+
+ if (range >= QQmlProfilerDefinitions::MaximumRangeType ||
+ !(d->features & one << featureFromRangeType(rangeType)))
+ return;
+
+ if (messageType == QQmlProfilerDefinitions::RangeStart) {
+ rangeStart(rangeType, time);
+ } else if (messageType == QQmlProfilerDefinitions::RangeData) {
+ QString data;
+ stream >> data;
+ rangeData(rangeType, time, data);
+ } else if (messageType == QQmlProfilerDefinitions::RangeLocation) {
+ QQmlEventLocation location;
+ stream >> location.filename >> location.line;
+
+ if (!stream.atEnd())
+ stream >> location.column;
+
+ rangeLocation(rangeType, time, location);
+ } else if (messageType == QQmlProfilerDefinitions::RangeEnd) {
+ rangeEnd(rangeType, time);
+ } else {
+ unknownEvent(static_cast<QQmlProfilerDefinitions::Message>(messageType), time, range);
+ }
+ }
+
+ if (!stream.atEnd())
+ unknownData(stream);
+}
+QT_END_NAMESPACE
diff --git a/src/qmldebug/qqmlprofilerclient_p.h b/src/qmldebug/qqmlprofilerclient_p.h
new file mode 100644
index 0000000000..0513bef608
--- /dev/null
+++ b/src/qmldebug/qqmlprofilerclient_p.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLPROFILERCLIENT_P_H
+#define QQMLPROFILERCLIENT_P_H
+
+#include "qqmldebugclient_p.h"
+#include "qqmleventlocation_p.h"
+#include <private/qqmlprofilerdefinitions_p.h>
+#include <private/qpacket_p.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+class QQmlProfilerClientPrivate;
+class QQmlProfilerClient : public QQmlDebugClient
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QQmlProfilerClient)
+
+public:
+ QQmlProfilerClient(QQmlDebugConnection *connection);
+ void setFeatures(quint64 features);
+
+public slots:
+ void sendRecordingStatus(bool record, int engineId = -1, quint32 flushInterval = 0);
+
+protected:
+ QQmlProfilerClient(QQmlProfilerClientPrivate &dd);
+
+private:
+ virtual void messageReceived(const QByteArray &message);
+
+ virtual void traceStarted(qint64 time, int engineId);
+ virtual void traceFinished(qint64 time, int engineId);
+
+ virtual void rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime);
+ virtual void rangeData(QQmlProfilerDefinitions::RangeType type, qint64 time,
+ const QString &data);
+ virtual void rangeLocation(QQmlProfilerDefinitions::RangeType type, qint64 time,
+ const QQmlEventLocation &location);
+ virtual void rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime);
+
+ virtual void animationFrame(qint64 time, int frameRate, int animationCount, int threadId);
+
+ virtual void sceneGraphEvent(QQmlProfilerDefinitions::SceneGraphFrameType type, qint64 time,
+ qint64 numericData1, qint64 numericData2, qint64 numericData3,
+ qint64 numericData4, qint64 numericData5);
+
+ virtual void pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type, qint64 time,
+ const QString &url, int numericData1, int numericData2);
+
+ virtual void memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time,
+ qint64 amount);
+
+ virtual void inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time, int a,
+ int b);
+
+ virtual void complete();
+
+ virtual void unknownEvent(QQmlProfilerDefinitions::Message messageType, qint64 time,
+ int detailType);
+ virtual void unknownData(QPacket &stream);
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLPROFILERCLIENT_P_H
diff --git a/src/qmldebug/qqmlprofilerclient_p_p.h b/src/qmldebug/qqmlprofilerclient_p_p.h
new file mode 100644
index 0000000000..c522eb7f52
--- /dev/null
+++ b/src/qmldebug/qqmlprofilerclient_p_p.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLPROFILERCLIENT_P_P_H
+#define QQMLPROFILERCLIENT_P_P_H
+
+#include "qqmlprofilerclient_p.h"
+#include "qqmldebugclient_p_p.h"
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+class QQmlProfilerClientPrivate : public QQmlDebugClientPrivate
+{
+ Q_DECLARE_PUBLIC(QQmlProfilerClient)
+public:
+ QQmlProfilerClientPrivate(QQmlDebugConnection *connection);
+ quint64 features;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLPROFILERCLIENT_P_P_H
+
diff --git a/src/qmldevtools/qmldevtools.pro b/src/qmldevtools/qmldevtools.pro
index 85f21ce6f6..0e32dc51e2 100644
--- a/src/qmldevtools/qmldevtools.pro
+++ b/src/qmldevtools/qmldevtools.pro
@@ -1,6 +1,6 @@
option(host_build)
TARGET = QtQmlDevTools
-QT = core
+QT = core-private
CONFIG += static internal_module qmldevtools_build
# Don't use pch because the auto-generated header refers to QtBootstrap,
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index 1c021e7dc6..ee880f129d 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -1250,7 +1250,7 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_globalAlpha(QV4::CallContext *c
QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
CHECK_CONTEXT_SETTER(r)
- double globalAlpha = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
+ double globalAlpha = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN();
if (!qIsFinite(globalAlpha))
return QV4::Encode::undefined();
@@ -2000,7 +2000,7 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_shadowOffsetX(QV4::CallContext
QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
CHECK_CONTEXT_SETTER(r)
- qreal offsetX = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
+ qreal offsetX = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN();
if (qIsFinite(offsetX) && offsetX != r->d()->context->state.shadowOffsetX) {
r->d()->context->state.shadowOffsetX = offsetX;
r->d()->context->buffer()->setShadowOffsetX(offsetX);
@@ -2028,7 +2028,7 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_shadowOffsetY(QV4::CallContext
QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
CHECK_CONTEXT_SETTER(r)
- qreal offsetY = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
+ qreal offsetY = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN();
if (qIsFinite(offsetY) && offsetY != r->d()->context->state.shadowOffsetY) {
r->d()->context->state.shadowOffsetY = offsetY;
r->d()->context->buffer()->setShadowOffsetY(offsetY);
diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp
index 65d7362e84..150fa6a415 100644
--- a/src/quick/items/qquickgridview.cpp
+++ b/src/quick/items/qquickgridview.cpp
@@ -1502,6 +1502,25 @@ void QQuickGridView::setHighlightFollowsCurrentItem(bool autoHighlight)
By default, key navigation is not wrapped.
*/
+
+/*!
+ \qmlproperty bool QtQuick::GridView::keyNavigationEnabled
+ \since 5.7
+
+ This property holds whether the key navigation of the grid is enabled.
+
+ If this is \c true, the user can navigate the view with a keyboard.
+ It is useful for applications that need to selectively enable or
+ disable mouse and keyboard interaction.
+
+ By default, the value of this property is bound to
+ \l {Flickable::}{interactive} to ensure behavior compatibility for
+ existing applications. When explicitly set, it will cease to be bound to
+ the interactive property.
+
+ \sa \l {Flickable::}{interactive}
+*/
+
/*!
\qmlproperty int QtQuick::GridView::cacheBuffer
This property determines whether delegates are retained outside the
@@ -2076,7 +2095,8 @@ void QQuickGridView::viewportMoved(Qt::Orientations orient)
void QQuickGridView::keyPressEvent(QKeyEvent *event)
{
Q_D(QQuickGridView);
- if (d->model && d->model->count() && d->interactive) {
+ if (d->model && d->model->count() && ((d->interactive && !d->explicitKeyNavigationEnabled)
+ || (d->explicitKeyNavigationEnabled && d->keyNavigationEnabled))) {
d->moveReason = QQuickGridViewPrivate::SetIndex;
int oldCurrent = currentIndex();
switch (event->key()) {
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 224decefec..bea0e7bd57 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -2323,7 +2323,7 @@ QQuickItem::~QQuickItem()
// XXX todo - optimize
while (!d->childItems.isEmpty())
- d->childItems.first()->setParentItem(0);
+ d->childItems.constFirst()->setParentItem(0);
for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
@@ -2485,7 +2485,7 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
from = item->parentItem();
} else {
if (!item->childItems().isEmpty())
- from = item->childItems().first();
+ from = item->d_func()->childItems.constFirst();
else
from = item->parentItem();
}
@@ -3045,6 +3045,28 @@ void QQuickItemPrivate::itemToParentTransform(QTransform &t) const
}
/*!
+ Returns a transform that maps points from window space into global space.
+*/
+QTransform QQuickItemPrivate::windowToGlobalTransform() const
+{
+ QPoint quickWidgetOffset;
+ QWindow *renderWindow = QQuickRenderControl::renderWindowFor(window, &quickWidgetOffset);
+ QPointF pos = (renderWindow ? renderWindow : window)->mapToGlobal(quickWidgetOffset);
+ return QTransform::fromTranslate(pos.x(), pos.y());
+}
+
+/*!
+ Returns a transform that maps points from global space into window space.
+*/
+QTransform QQuickItemPrivate::globalToWindowTransform() const
+{
+ QPoint quickWidgetOffset;
+ QWindow *renderWindow = QQuickRenderControl::renderWindowFor(window, &quickWidgetOffset);
+ QPointF pos = (renderWindow ? renderWindow : window)->mapToGlobal(quickWidgetOffset);
+ return QTransform::fromTranslate(-pos.x(), -pos.y());
+}
+
+/*!
Returns true if construction of the QML component is complete; otherwise
returns false.
@@ -6825,6 +6847,26 @@ QQuickItem *QQuickItem::scopedFocusItem() const
}
/*!
+ Returns \c true if this item is an ancestor of \a child (i.e., if this item
+ is \a child's parent, or one of \a child's parent's ancestors).
+
+ \since 5.7
+
+ \sa parentItem()
+ */
+bool QQuickItem::isAncestorOf(const QQuickItem *child) const
+{
+ if (!child || child == this)
+ return false;
+ const QQuickItem *ancestor = child;
+ while ((ancestor = ancestor->parentItem())) {
+ if (ancestor == this)
+ return true;
+ }
+ return false;
+}
+
+/*!
Returns the mouse buttons accepted by this item.
The default value is Qt::NoButton; that is, no mouse buttons are accepted.
@@ -7261,6 +7303,27 @@ QPointF QQuickItem::mapToScene(const QPointF &point) const
}
/*!
+ Maps the given \a point in this item's coordinate system to the equivalent
+ point within global screen coordinate system, and returns the mapped
+ coordinate.
+
+ For example, this may be helpful to add a popup to a Qt Quick component.
+
+ \note Window positioning is done by the window manager and this value is
+ treated only as a hint. So, the resulting window position may differ from
+ what is expected.
+
+ \since 5.7
+
+ \sa {Concepts - Visual Coordinates in Qt Quick}
+*/
+QPointF QQuickItem::mapToGlobal(const QPointF &point) const
+{
+ Q_D(const QQuickItem);
+ return d->windowToGlobalTransform().map(mapToScene(point));
+}
+
+/*!
Maps the given \a rect in this item's coordinate system to the equivalent
rectangular area within \a item's coordinate system, and returns the mapped
rectangle value.
@@ -7322,6 +7385,27 @@ QPointF QQuickItem::mapFromScene(const QPointF &point) const
}
/*!
+ Maps the given \a point in the global screen coordinate system to the
+ equivalent point within this item's coordinate system, and returns the
+ mapped coordinate.
+
+ For example, this may be helpful to add a popup to a Qt Quick component.
+
+ \note Window positioning is done by the window manager and this value is
+ treated only as a hint. So, the resulting window position may differ from
+ what is expected.
+
+ \since 5.7
+
+ \sa {Concepts - Visual Coordinates in Qt Quick}
+*/
+QPointF QQuickItem::mapFromGlobal(const QPointF &point) const
+{
+ Q_D(const QQuickItem);
+ return mapFromScene(d->globalToWindowTransform().map(point));
+}
+
+/*!
Maps the given \a rect in \a item's coordinate system to the equivalent
rectangular area within this item's coordinate system, and returns the mapped
rectangle value.
diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h
index d92910ce9c..013128e95f 100644
--- a/src/quick/items/qquickitem.h
+++ b/src/quick/items/qquickitem.h
@@ -278,6 +278,8 @@ public:
bool isFocusScope() const;
QQuickItem *scopedFocusItem() const;
+ bool isAncestorOf(const QQuickItem *child) const;
+
Qt::MouseButtons acceptedMouseButtons() const;
void setAcceptedMouseButtons(Qt::MouseButtons buttons);
bool acceptHoverEvents() const;
@@ -311,10 +313,12 @@ public:
QTransform itemTransform(QQuickItem *, bool *) const;
QPointF mapToItem(const QQuickItem *item, const QPointF &point) const;
QPointF mapToScene(const QPointF &point) const;
+ Q_REVISION(7) Q_INVOKABLE QPointF mapToGlobal(const QPointF &point) const;
QRectF mapRectToItem(const QQuickItem *item, const QRectF &rect) const;
QRectF mapRectToScene(const QRectF &rect) const;
QPointF mapFromItem(const QQuickItem *item, const QPointF &point) const;
QPointF mapFromScene(const QPointF &point) const;
+ Q_REVISION(7) Q_INVOKABLE QPointF mapFromGlobal(const QPointF &point) const;
QRectF mapRectFromItem(const QQuickItem *item, const QRectF &rect) const;
QRectF mapRectFromScene(const QRectF &rect) const;
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index 634aa2b658..127352aaa7 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -503,6 +503,8 @@ public:
QTransform windowToItemTransform() const;
QTransform itemToWindowTransform() const;
void itemToParentTransform(QTransform &) const;
+ QTransform globalToWindowTransform() const;
+ QTransform windowToGlobalTransform() const;
static bool focusNextPrev(QQuickItem *item, bool forward);
static QQuickItem *nextTabChildItem(const QQuickItem *item, int start);
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index 62e0adcb0a..70915584fd 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -274,6 +274,9 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterUncreatableType<QQuickEnterKeyAttached, 6>(uri, 2, 6, "EnterKey",
QQuickEnterKeyAttached::tr("EnterKey is only available via attached properties"));
qmlRegisterType<QQuickShaderEffectSource, 1>(uri, 2, 6, "ShaderEffectSource");
+
+ qmlRegisterType<QQuickListView, 7>(uri, 2, 7, "ListView");
+ qmlRegisterType<QQuickGridView, 7>(uri, 2, 7, "GridView");
}
static void initResources()
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index b618daf64b..1cc3046b60 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -448,6 +448,29 @@ void QQuickItemView::setWrapEnabled(bool wrap)
emit keyNavigationWrapsChanged();
}
+bool QQuickItemView::isKeyNavigationEnabled() const
+{
+ Q_D(const QQuickItemView);
+ return d->explicitKeyNavigationEnabled ? d->keyNavigationEnabled : d->interactive;
+}
+
+void QQuickItemView::setKeyNavigationEnabled(bool keyNavigationEnabled)
+{
+ // TODO: default binding to "interactive" can be removed in Qt 6; it only exists for compatibility reasons.
+ Q_D(QQuickItemView);
+ const bool wasImplicit = !d->explicitKeyNavigationEnabled;
+ if (wasImplicit)
+ QObject::disconnect(this, &QQuickFlickable::interactiveChanged, this, &QQuickItemView::keyNavigationEnabledChanged);
+
+ d->explicitKeyNavigationEnabled = true;
+
+ // Ensure that we emit the change signal in case there is no different in value.
+ if (d->keyNavigationEnabled != keyNavigationEnabled || wasImplicit) {
+ d->keyNavigationEnabled = keyNavigationEnabled;
+ emit keyNavigationEnabledChanged();
+ }
+}
+
int QQuickItemView::cacheBuffer() const
{
Q_D(const QQuickItemView);
@@ -1526,6 +1549,8 @@ QQuickItemViewPrivate::QQuickItemViewPrivate()
, transitioner(0)
, minExtent(0), maxExtent(0)
, ownModel(false), wrap(false)
+ , keyNavigationEnabled(true)
+ , explicitKeyNavigationEnabled(false)
, inLayout(false), inViewportMoved(false), forceLayout(false), currentIndexCleared(false)
, haveHighlightRange(false), autoHighlight(true), highlightRangeStartValid(false), highlightRangeEndValid(false)
, fillCacheBuffer(false), inRequest(false)
@@ -1654,6 +1679,7 @@ void QQuickItemViewPrivate::init()
Q_Q(QQuickItemView);
q->setFlag(QQuickItem::ItemIsFocusScope);
QObject::connect(q, SIGNAL(movementEnded()), q, SLOT(animStopped()));
+ QObject::connect(q, &QQuickFlickable::interactiveChanged, q, &QQuickItemView::keyNavigationEnabledChanged);
q->setFlickableDirection(QQuickFlickable::VerticalFlick);
}
diff --git a/src/quick/items/qquickitemview_p.h b/src/quick/items/qquickitemview_p.h
index d5c4f59ed2..0541ec44b2 100644
--- a/src/quick/items/qquickitemview_p.h
+++ b/src/quick/items/qquickitemview_p.h
@@ -69,6 +69,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickItemView : public QQuickFlickable
Q_PROPERTY(QQuickItem *currentItem READ currentItem NOTIFY currentItemChanged)
Q_PROPERTY(bool keyNavigationWraps READ isWrapEnabled WRITE setWrapEnabled NOTIFY keyNavigationWrapsChanged)
+ Q_PROPERTY(bool keyNavigationEnabled READ isKeyNavigationEnabled WRITE setKeyNavigationEnabled NOTIFY keyNavigationEnabledChanged REVISION 7)
Q_PROPERTY(int cacheBuffer READ cacheBuffer WRITE setCacheBuffer NOTIFY cacheBufferChanged)
Q_PROPERTY(int displayMarginBeginning READ displayMarginBeginning WRITE setDisplayMarginBeginning NOTIFY displayMarginBeginningChanged REVISION 2)
Q_PROPERTY(int displayMarginEnd READ displayMarginEnd WRITE setDisplayMarginEnd NOTIFY displayMarginEndChanged REVISION 2)
@@ -136,6 +137,9 @@ public:
bool isWrapEnabled() const;
void setWrapEnabled(bool);
+ bool isKeyNavigationEnabled() const;
+ void setKeyNavigationEnabled(bool);
+
int cacheBuffer() const;
void setCacheBuffer(int);
@@ -231,6 +235,7 @@ Q_SIGNALS:
void currentItemChanged();
void keyNavigationWrapsChanged();
+ Q_REVISION(7) void keyNavigationEnabledChanged();
void cacheBufferChanged();
void displayMarginBeginningChanged();
void displayMarginEndChanged();
diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h
index ea1c7c494a..2b3da20b34 100644
--- a/src/quick/items/qquickitemview_p_p.h
+++ b/src/quick/items/qquickitemview_p_p.h
@@ -308,6 +308,8 @@ public:
bool ownModel : 1;
bool wrap : 1;
+ bool keyNavigationEnabled : 1;
+ bool explicitKeyNavigationEnabled : 1;
bool inLayout : 1;
bool inViewportMoved : 1;
bool forceLayout : 1;
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index 9f53586893..80e4a431a1 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -1321,10 +1321,10 @@ void QQuickListViewPrivate::updateFooter()
}
FxListItemSG *listItem = static_cast<FxListItemSG*>(footer);
- if (visibleItems.count()) {
- if (footerPositioning == QQuickListView::OverlayFooter) {
- listItem->setPosition(isContentFlowReversed() ? -position() - footerSize() : position() + size() - footerSize());
- } else if (footerPositioning == QQuickListView::PullBackFooter) {
+ if (footerPositioning == QQuickListView::OverlayFooter) {
+ listItem->setPosition(isContentFlowReversed() ? -position() - footerSize() : position() + size() - footerSize());
+ } else if (visibleItems.count()) {
+ if (footerPositioning == QQuickListView::PullBackFooter) {
qreal viewPos = isContentFlowReversed() ? -position() : position() + size();
qreal clampedPos = qBound(originPosition() - footerSize() + size(), listItem->position(), lastPosition());
listItem->setPosition(qBound(viewPos - footerSize(), clampedPos, viewPos));
@@ -1360,26 +1360,24 @@ void QQuickListViewPrivate::updateHeader()
}
FxListItemSG *listItem = static_cast<FxListItemSG*>(header);
- if (listItem) {
- if (visibleItems.count()) {
- if (headerPositioning == QQuickListView::OverlayHeader) {
- listItem->setPosition(isContentFlowReversed() ? -position() - size() : position());
- } else if (headerPositioning == QQuickListView::PullBackHeader) {
- qreal viewPos = isContentFlowReversed() ? -position() - size() : position();
- qreal clampedPos = qBound(originPosition() - headerSize(), listItem->position(), lastPosition() - headerSize() - size());
- listItem->setPosition(qBound(viewPos - headerSize(), clampedPos, viewPos));
+ if (headerPositioning == QQuickListView::OverlayHeader) {
+ listItem->setPosition(isContentFlowReversed() ? -position() - size() : position());
+ } else if (visibleItems.count()) {
+ if (headerPositioning == QQuickListView::PullBackHeader) {
+ qreal viewPos = isContentFlowReversed() ? -position() - size() : position();
+ qreal clampedPos = qBound(originPosition() - headerSize(), listItem->position(), lastPosition() - headerSize() - size());
+ listItem->setPosition(qBound(viewPos - headerSize(), clampedPos, viewPos));
+ } else {
+ qreal startPos = originPosition();
+ if (visibleIndex == 0) {
+ listItem->setPosition(startPos - headerSize());
} else {
- qreal startPos = originPosition();
- if (visibleIndex == 0) {
+ if (position() <= startPos || listItem->position() > startPos - headerSize())
listItem->setPosition(startPos - headerSize());
- } else {
- if (position() <= startPos || listItem->position() > startPos - headerSize())
- listItem->setPosition(startPos - headerSize());
- }
}
- } else {
- listItem->setPosition(-headerSize());
}
+ } else {
+ listItem->setPosition(-headerSize());
}
if (created)
@@ -2176,6 +2174,24 @@ void QQuickListView::setOrientation(QQuickListView::Orientation orientation)
By default, key navigation is not wrapped.
*/
+/*!
+ \qmlproperty bool QtQuick::ListView::keyNavigationEnabled
+ \since 5.7
+
+ This property holds whether the key navigation of the list is enabled.
+
+ If this is \c true, the user can navigate the view with a keyboard.
+ It is useful for applications that need to selectively enable or
+ disable mouse and keyboard interaction.
+
+ By default, the value of this property is bound to
+ \l {Flickable::}{interactive} to ensure behavior compatibility for
+ existing applications. When explicitly set, it will cease to be bound to
+ the interactive property.
+
+ \sa \l {Flickable::}{interactive}
+*/
+
/*!
\qmlproperty int QtQuick::ListView::cacheBuffer
@@ -2842,8 +2858,15 @@ void QQuickListView::viewportMoved(Qt::Orientations orient)
{
Q_D(QQuickListView);
QQuickItemView::viewportMoved(orient);
- if (!d->itemCount)
+
+ if (!d->itemCount) {
+ if (d->hasStickyHeader())
+ d->updateHeader();
+ if (d->hasStickyFooter())
+ d->updateFooter();
return;
+ }
+
// Recursion can occur due to refill changing the content size.
if (d->inViewportMoved)
return;
@@ -2947,7 +2970,8 @@ void QQuickListView::viewportMoved(Qt::Orientations orient)
void QQuickListView::keyPressEvent(QKeyEvent *event)
{
Q_D(QQuickListView);
- if (d->model && d->model->count() && d->interactive) {
+ if (d->model && d->model->count() && ((d->interactive && !d->explicitKeyNavigationEnabled)
+ || (d->explicitKeyNavigationEnabled && d->keyNavigationEnabled))) {
if ((d->orient == QQuickListView::Horizontal && !d->isRightToLeft() && event->key() == Qt::Key_Left)
|| (d->orient == QQuickListView::Horizontal && d->isRightToLeft() && event->key() == Qt::Key_Right)
|| (d->orient == QQuickListView::Vertical && !d->isBottomToTop() && event->key() == Qt::Key_Up)
diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp
index 456eedd0be..0040843929 100644
--- a/src/quick/items/qquickloader.cpp
+++ b/src/quick/items/qquickloader.cpp
@@ -852,6 +852,11 @@ likelihood of glitches in animation. When loading asynchronously the status
will change to Loader.Loading. Once the entire component has been created, the
\l item will be available and the status will change to Loader.Ready.
+Changing the value of this property to \c false while an asynchronous load is in
+progress will force immediate, synchronous completion. This allows beginning an
+asynchronous load and then forcing completion if the Loader content must be
+accessed before the asynchronous load has completed.
+
To avoid seeing the items loading progressively set \c visible appropriately, e.g.
\code
@@ -878,6 +883,19 @@ void QQuickLoader::setAsynchronous(bool a)
return;
d->asynchronous = a;
+
+ if (!d->asynchronous && isComponentComplete() && d->active) {
+ if (d->loadingFromSource && d->component && d->component->isLoading()) {
+ // Force a synchronous component load
+ QUrl currentSource = d->source;
+ d->clear();
+ d->source = currentSource;
+ loadFromSource();
+ } else if (d->incubator && d->incubator->isLoading()) {
+ d->incubator->forceCompletion();
+ }
+ }
+
emit asynchronousChanged();
}
diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp
index 349207f145..3e062df5d4 100644
--- a/src/quick/items/qquickshadereffect.cpp
+++ b/src/quick/items/qquickshadereffect.cpp
@@ -710,8 +710,9 @@ QQuickShaderEffect::~QQuickShaderEffect()
\qmlproperty string QtQuick::ShaderEffect::fragmentShader
This property holds the fragment shader's GLSL source code.
- The default shader passes the texture coordinate along to the fragment
- shader as "varying highp vec2 qt_TexCoord0".
+ The default shader expects the texture coordinate to be passed from the
+ vertex shader as "varying highp vec2 qt_TexCoord0", and it samples from a
+ sampler2D named "source".
*/
void QQuickShaderEffect::setFragmentShader(const QByteArray &code)
@@ -737,9 +738,8 @@ void QQuickShaderEffect::setFragmentShader(const QByteArray &code)
\qmlproperty string QtQuick::ShaderEffect::vertexShader
This property holds the vertex shader's GLSL source code.
- The default shader expects the texture coordinate to be passed from the
- vertex shader as "varying highp vec2 qt_TexCoord0", and it samples from a
- sampler2D named "source".
+ The default shader passes the texture coordinate along to the fragment
+ shader as "varying highp vec2 qt_TexCoord0".
*/
void QQuickShaderEffect::setVertexShader(const QByteArray &code)
diff --git a/src/quick/items/qquickspriteengine.cpp b/src/quick/items/qquickspriteengine.cpp
index 243feef683..d12a96ecb1 100644
--- a/src/quick/items/qquickspriteengine.cpp
+++ b/src/quick/items/qquickspriteengine.cpp
@@ -626,11 +626,11 @@ int QQuickStochasticEngine::nextState(int curState, int curThing)
qreal r =(qreal) qrand() / (qreal) RAND_MAX;
qreal total = 0.0;
for (QVariantMap::const_iterator iter=m_states[curState]->m_to.constBegin();
- iter!=m_states[curState]->m_to.constEnd(); iter++)
+ iter!=m_states[curState]->m_to.constEnd(); ++iter)
total += (*iter).toReal();
r*=total;
for (QVariantMap::const_iterator iter= m_states[curState]->m_to.constBegin();
- iter!=m_states[curState]->m_to.constEnd(); iter++){
+ iter!=m_states[curState]->m_to.constEnd(); ++iter){
if (r < (*iter).toReal()){
bool superBreak = false;
for (int i=0; i<m_states.count(); i++){
@@ -689,7 +689,7 @@ int QQuickStochasticEngine::goalSeek(int curIdx, int spriteIdx, int dist)
dist = m_states.count();
QQuickStochasticState* curState = m_states[curIdx];
for (QVariantMap::const_iterator iter = curState->m_to.constBegin();
- iter!=curState->m_to.constEnd(); iter++){
+ iter!=curState->m_to.constEnd(); ++iter){
if (iter.key() == goalName)
for (int i=0; i<m_states.count(); i++)
if (m_states[i]->name() == goalName)
@@ -698,7 +698,7 @@ int QQuickStochasticEngine::goalSeek(int curIdx, int spriteIdx, int dist)
QSet<int> options;
for (int i=1; i<dist; i++){
for (QVariantMap::const_iterator iter = curState->m_to.constBegin();
- iter!=curState->m_to.constEnd(); iter++){
+ iter!=curState->m_to.constEnd(); ++iter){
int option = -1;
for (int j=0; j<m_states.count(); j++)//One place that could be a lot more efficient...
if (m_states[j]->name() == iter.key())
@@ -714,11 +714,11 @@ int QQuickStochasticEngine::goalSeek(int curIdx, int spriteIdx, int dist)
qreal r =(qreal) qrand() / (qreal) RAND_MAX;
qreal total = 0;
for (QSet<int>::const_iterator iter=options.constBegin();
- iter!=options.constEnd(); iter++)
+ iter!=options.constEnd(); ++iter)
total += curState->m_to.value(m_states[(*iter)]->name()).toReal();
r *= total;
for (QVariantMap::const_iterator iter = curState->m_to.constBegin();
- iter!=curState->m_to.constEnd(); iter++){
+ iter!=curState->m_to.constEnd(); ++iter){
bool superContinue = true;
for (int j=0; j<m_states.count(); j++)
if (m_states[j]->name() == iter.key())
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index 223219a3f9..d32b194803 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -73,7 +73,11 @@ QQuickTextPrivate::QQuickTextPrivate()
, elideMode(QQuickText::ElideNone), hAlign(QQuickText::AlignLeft), vAlign(QQuickText::AlignTop)
, format(QQuickText::AutoText), wrapMode(QQuickText::NoWrap)
, style(QQuickText::Normal)
+#if defined(QT_QUICK_DEFAULT_TEXT_RENDER_TYPE)
+ , renderType(QQuickText::QT_QUICK_DEFAULT_TEXT_RENDER_TYPE)
+#else
, renderType(QQuickText::QtRendering)
+#endif
, updateType(UpdatePaintNode)
, maximumLineCountValid(false), updateOnComponentComplete(true), richText(false)
, styledText(false), widthExceeded(false), heightExceeded(false), internalWidthUpdate(false)
diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp
index 04e43c017e..d0678b4278 100644
--- a/src/quick/items/qquicktextcontrol.cpp
+++ b/src/quick/items/qquicktextcontrol.cpp
@@ -1419,7 +1419,7 @@ QVariant QQuickTextControl::inputMethodQuery(Qt::InputMethodQuery property, QVar
tmpCursor.movePosition(QTextCursor::NextBlock);
--numBlocks;
}
- result += block.text().mid(0,localPos);
+ result += block.text().midRef(0,localPos);
return QVariant(result);
}
default:
diff --git a/src/quick/items/qquicktextedit_p_p.h b/src/quick/items/qquicktextedit_p_p.h
index fed0688fd7..a2b4c1ab99 100644
--- a/src/quick/items/qquicktextedit_p_p.h
+++ b/src/quick/items/qquicktextedit_p_p.h
@@ -106,7 +106,11 @@ public:
, quickDocument(0), lastSelectionStart(0), lastSelectionEnd(0), lineCount(0)
, hAlign(QQuickTextEdit::AlignLeft), vAlign(QQuickTextEdit::AlignTop)
, format(QQuickTextEdit::PlainText), wrapMode(QQuickTextEdit::NoWrap)
+#if defined(QT_QUICK_DEFAULT_TEXT_RENDER_TYPE)
+ , renderType(QQuickTextEdit::QT_QUICK_DEFAULT_TEXT_RENDER_TYPE)
+#else
, renderType(QQuickTextEdit::QtRendering)
+#endif
, contentDirection(Qt::LayoutDirectionAuto)
, mouseSelectionMode(QQuickTextEdit::SelectCharacters)
#ifndef QT_NO_IM
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index ba7142856b..37b8b12fdd 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -3534,7 +3534,7 @@ void QQuickTextInputPrivate::internalInsert(const QString &s)
int remaining = m_maxLength - m_text.length();
if (remaining != 0) {
m_text.insert(m_cursor, s.left(remaining));
- for (int i = 0; i < (int) s.left(remaining).length(); ++i)
+ for (int i = 0; i < (int) s.leftRef(remaining).length(); ++i)
addCommand(Command(Insert, m_cursor++, s.at(i), -1, -1));
m_textDirty = true;
}
@@ -3887,14 +3887,14 @@ QString QQuickTextInputPrivate::maskString(uint pos, const QString &str, bool cl
int n = findInMask(i, true, true, str[(int)strIndex]);
if (n != -1) {
if (str.length() != 1 || i == 0 || (i > 0 && (!m_maskData[i-1].separator || m_maskData[i-1].maskChar != str[(int)strIndex]))) {
- s += fill.mid(i, n-i+1);
+ s += fill.midRef(i, n-i+1);
i = n + 1; // update i to find + 1
}
} else {
// search for valid m_blank if not
n = findInMask(i, true, false, str[(int)strIndex]);
if (n != -1) {
- s += fill.mid(i, n-i);
+ s += fill.midRef(i, n-i);
switch (m_maskData[n].caseMode) {
case MaskInputData::Upper:
s += str[(int)strIndex].toUpper();
diff --git a/src/quick/items/qquicktextinput_p_p.h b/src/quick/items/qquicktextinput_p_p.h
index 00d9b2b0fa..6aaa630839 100644
--- a/src/quick/items/qquicktextinput_p_p.h
+++ b/src/quick/items/qquicktextinput_p_p.h
@@ -115,7 +115,11 @@ public:
, vAlign(QQuickTextInput::AlignTop)
, wrapMode(QQuickTextInput::NoWrap)
, m_echoMode(QQuickTextInput::Normal)
+#if defined(QT_QUICK_DEFAULT_TEXT_RENDER_TYPE)
+ , renderType(QQuickTextInput::QT_QUICK_DEFAULT_TEXT_RENDER_TYPE)
+#else
, renderType(QQuickTextInput::QtRendering)
+#endif
, updateType(UpdatePaintNode)
, mouseSelectionMode(QQuickTextInput::SelectCharacters)
, m_layoutDirection(Qt::LayoutDirectionAuto)
diff --git a/src/quick/items/qquicktextnode_p.h b/src/quick/items/qquicktextnode_p.h
index c6a1059e8a..01de0dbf2f 100644
--- a/src/quick/items/qquicktextnode_p.h
+++ b/src/quick/items/qquicktextnode_p.h
@@ -68,7 +68,7 @@ class QSGTexture;
class QQuickTextNodeEngine;
-class QQuickTextNode : public QSGTransformNode
+class Q_QUICK_PRIVATE_EXPORT QQuickTextNode : public QSGTransformNode
{
public:
enum Decoration {
diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp
index 867f7d9d15..96f6b7ddd1 100644
--- a/src/quick/items/qquickview.cpp
+++ b/src/quick/items/qquickview.cpp
@@ -601,40 +601,30 @@ void QQuickView::resizeEvent(QResizeEvent *e)
/*! \reimp */
void QQuickView::keyPressEvent(QKeyEvent *e)
{
- Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Key>());
-
QQuickWindow::keyPressEvent(e);
}
/*! \reimp */
void QQuickView::keyReleaseEvent(QKeyEvent *e)
{
- Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Key>());
-
QQuickWindow::keyReleaseEvent(e);
}
/*! \reimp */
void QQuickView::mouseMoveEvent(QMouseEvent *e)
{
- Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Mouse>());
-
QQuickWindow::mouseMoveEvent(e);
}
/*! \reimp */
void QQuickView::mousePressEvent(QMouseEvent *e)
{
- Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Mouse>());
-
QQuickWindow::mousePressEvent(e);
}
/*! \reimp */
void QQuickView::mouseReleaseEvent(QMouseEvent *e)
{
- Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Mouse>());
-
QQuickWindow::mouseReleaseEvent(e);
}
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index e12b22bb00..8d86dfc96e 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -46,6 +46,7 @@
#include <private/qsgrenderloop_p.h>
#include <private/qquickrendercontrol_p.h>
#include <private/qquickanimatorcontroller_p.h>
+#include <private/qquickprofiler_p.h>
#include <private/qguiapplication_p.h>
#include <QtGui/QInputMethod>
@@ -1433,6 +1434,8 @@ bool QQuickWindow::event(QEvent *e)
void QQuickWindow::keyPressEvent(QKeyEvent *e)
{
Q_D(QQuickWindow);
+ Q_QUICK_INPUT_PROFILE(QQuickProfiler::Key, QQuickProfiler::InputKeyPress, e->key(),
+ e->modifiers());
d->deliverKeyEvent(e);
}
@@ -1440,6 +1443,8 @@ void QQuickWindow::keyPressEvent(QKeyEvent *e)
void QQuickWindow::keyReleaseEvent(QKeyEvent *e)
{
Q_D(QQuickWindow);
+ Q_QUICK_INPUT_PROFILE(QQuickProfiler::Key, QQuickProfiler::InputKeyRelease, e->key(),
+ e->modifiers());
d->deliverKeyEvent(e);
}
@@ -1537,6 +1542,8 @@ bool QQuickWindowPrivate::deliverMouseEvent(QMouseEvent *event)
void QQuickWindow::mousePressEvent(QMouseEvent *event)
{
Q_D(QQuickWindow);
+ Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMousePress, event->button(),
+ event->buttons());
if (event->source() == Qt::MouseEventSynthesizedBySystem) {
event->accept();
@@ -1551,6 +1558,8 @@ void QQuickWindow::mousePressEvent(QMouseEvent *event)
void QQuickWindow::mouseReleaseEvent(QMouseEvent *event)
{
Q_D(QQuickWindow);
+ Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseRelease, event->button(),
+ event->buttons());
if (event->source() == Qt::MouseEventSynthesizedBySystem) {
event->accept();
@@ -1573,6 +1582,8 @@ void QQuickWindow::mouseReleaseEvent(QMouseEvent *event)
void QQuickWindow::mouseDoubleClickEvent(QMouseEvent *event)
{
Q_D(QQuickWindow);
+ Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseDoubleClick,
+ event->button(), event->buttons());
if (event->source() == Qt::MouseEventSynthesizedBySystem) {
event->accept();
@@ -1617,6 +1628,8 @@ bool QQuickWindowPrivate::sendHoverEvent(QEvent::Type type, QQuickItem *item,
void QQuickWindow::mouseMoveEvent(QMouseEvent *event)
{
Q_D(QQuickWindow);
+ Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseMove,
+ event->localPos().x(), event->localPos().y());
if (event->source() == Qt::MouseEventSynthesizedBySystem) {
event->accept();
@@ -1762,6 +1775,9 @@ bool QQuickWindowPrivate::deliverWheelEvent(QQuickItem *item, QWheelEvent *event
void QQuickWindow::wheelEvent(QWheelEvent *event)
{
Q_D(QQuickWindow);
+ Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseWheel,
+ event->angleDelta().x(), event->angleDelta().y());
+
qCDebug(DBG_MOUSE) << "QQuickWindow::wheelEvent()" << event->pixelDelta() << event->angleDelta() << event->phase();
//if the actual wheel event was accepted, accept the compatibility wheel event and return early
diff --git a/src/quick/qtquick2.cpp b/src/quick/qtquick2.cpp
index ecf6865895..cabf0589e2 100644
--- a/src/quick/qtquick2.cpp
+++ b/src/quick/qtquick2.cpp
@@ -190,10 +190,6 @@ void QQmlQtQuick2Module::defineModule()
QQmlEngineDebugService *debugService = QQmlDebugConnector::service<QQmlEngineDebugService>();
if (debugService)
debugService->setStatesDelegate(new QQmlQtQuick2DebugStatesDelegate);
-
- QQmlProfilerService *profilerService = QQmlDebugConnector::service<QQmlProfilerService>();
- if (profilerService)
- QQuickProfiler::initialize(profilerService);
}
void QQmlQtQuick2Module::undefineModule()
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index b1792d27a7..9ed5411576 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -2,6 +2,7 @@
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2014 Jolla Ltd, author: <gunnar.sletta@jollamobile.com>
+** Copyright (C) 2015 Robin Burchell <robin.burchell@viroteck.net>
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -83,7 +84,7 @@ DECLARE_DEBUG_VAR(noclip)
static QElapsedTimer qsg_renderer_timer;
#define QSGNODE_TRAVERSE(NODE) for (QSGNode *child = NODE->firstChild(); child; child = child->nextSibling())
-#define SHADOWNODE_TRAVERSE(NODE) for (QList<Node *>::const_iterator child = NODE->children.constBegin(); child != NODE->children.constEnd(); ++child)
+#define SHADOWNODE_TRAVERSE(NODE) for (Node *child = NODE->firstChild; child; child = child->nextSibling)
static inline int size_of_type(GLenum type)
{
@@ -248,7 +249,7 @@ void qsg_dumpShadowRoots(Node *n)
}
SHADOWNODE_TRAVERSE(n)
- qsg_dumpShadowRoots(*child);
+ qsg_dumpShadowRoots(child);
--indent;
#else
@@ -331,7 +332,7 @@ void Updater::visitNode(Node *n)
n->renderNodeElement()->root = m_roots.last();
// Fall through to visit children.
default:
- SHADOWNODE_TRAVERSE(n) visitNode(*child);
+ SHADOWNODE_TRAVERSE(n) visitNode(child);
break;
}
@@ -357,7 +358,7 @@ void Updater::visitClipNode(Node *n)
cn->m_matrix = &extra->matrix;
m_combined_matrix_stack << &m_identityMatrix;
- SHADOWNODE_TRAVERSE(n) visitNode(*child);
+ SHADOWNODE_TRAVERSE(n) visitNode(child);
m_current_clip = cn->m_clip_list;
m_rootMatrices.pop_back();
@@ -381,12 +382,12 @@ void Updater::visitOpacityNode(Node *n)
n->isOpaque = is;
}
++m_opacityChange;
- SHADOWNODE_TRAVERSE(n) visitNode(*child);
+ SHADOWNODE_TRAVERSE(n) visitNode(child);
--m_opacityChange;
} else {
if (m_added > 0)
n->isOpaque = on->opacity() > OPAQUE_LIMIT;
- SHADOWNODE_TRAVERSE(n) visitNode(*child);
+ SHADOWNODE_TRAVERSE(n) visitNode(child);
}
m_opacity_stack.pop_back();
@@ -436,7 +437,7 @@ void Updater::visitTransformNode(Node *n)
if (dirty)
++m_transformChange;
- SHADOWNODE_TRAVERSE(n) visitNode(*child);
+ SHADOWNODE_TRAVERSE(n) visitNode(child);
if (dirty)
--m_transformChange;
@@ -496,7 +497,7 @@ void Updater::visitGeometryNode(Node *n)
}
}
- SHADOWNODE_TRAVERSE(n) visitNode(*child);
+ SHADOWNODE_TRAVERSE(n) visitNode(child);
}
void Updater::updateRootTransforms(Node *node, Node *root, const QMatrix4x4 &combined)
@@ -976,7 +977,7 @@ void Renderer::nodeChangedBatchRoot(Node *node, Node *root)
}
SHADOWNODE_TRAVERSE(node)
- nodeChangedBatchRoot(*child, root);
+ nodeChangedBatchRoot(child, root);
}
void Renderer::nodeWasTransformed(Node *node, int *vertexCount)
@@ -998,7 +999,7 @@ void Renderer::nodeWasTransformed(Node *node, int *vertexCount)
}
SHADOWNODE_TRAVERSE(node)
- nodeWasTransformed(*child, vertexCount);
+ nodeWasTransformed(child, vertexCount);
}
void Renderer::nodeWasAdded(QSGNode *node, Node *shadowParent)
@@ -1012,7 +1013,13 @@ void Renderer::nodeWasAdded(QSGNode *node, Node *shadowParent)
m_nodes.insert(node, snode);
if (shadowParent) {
snode->parent = shadowParent;
- shadowParent->children.append(snode);
+ if (shadowParent->lastChild) {
+ shadowParent->lastChild->nextSibling = snode;
+ shadowParent->lastChild = snode;
+ } else {
+ shadowParent->firstChild = snode;
+ shadowParent->lastChild = snode;
+ }
}
if (node->type() == QSGNode::GeometryNodeType) {
@@ -1038,10 +1045,24 @@ void Renderer::nodeWasAdded(QSGNode *node, Node *shadowParent)
void Renderer::nodeWasRemoved(Node *node)
{
- // Prefix traversal as removeBatchFromParent below removes nodes
- // in a bottom-up manner
- SHADOWNODE_TRAVERSE(node)
- nodeWasRemoved(*child);
+ // Prefix traversal as removeBatchRootFromParent below removes nodes
+ // in a bottom-up manner. Note that we *cannot* use SHADOWNODE_TRAVERSE
+ // here, because we delete 'child' (when recursed, down below), so we'd
+ // have a use-after-free.
+ {
+ Node *child = node->firstChild;
+ Node *nextChild = 0;
+
+ while (child) {
+ // Get the next child now before we proceed
+ nextChild = child ? child->nextSibling : 0;
+
+ // Remove (and delete) child
+ nodeWasRemoved(child);
+
+ child = nextChild;
+ }
+ }
if (node->type() == QSGNode::GeometryNodeType) {
Element *e = node->element();
@@ -1105,7 +1126,7 @@ void Renderer::turnNodeIntoBatchRoot(Node *node)
}
SHADOWNODE_TRAVERSE(node)
- nodeChangedBatchRoot(*child, node);
+ nodeChangedBatchRoot(child, node);
}
@@ -1237,8 +1258,23 @@ void Renderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state)
// Delete happens at the very end because it deletes the shadownode.
if (state & QSGNode::DirtyNodeRemoved) {
Node *parent = shadowNode->parent;
- if (parent)
- parent->children.removeOne(shadowNode);
+ if (parent) {
+ Q_ASSERT(parent->firstChild);
+ Q_ASSERT(parent->lastChild);
+ shadowNode->parent = 0;
+ Node *child = parent->firstChild;
+ if (child == shadowNode) {
+ parent->firstChild = shadowNode->nextSibling;
+ if (parent->lastChild == shadowNode)
+ parent->lastChild = 0;
+ } else {
+ while (child->nextSibling != shadowNode)
+ child = child->nextSibling;
+ child->nextSibling = shadowNode->nextSibling;
+ if (shadowNode == parent->lastChild)
+ parent->lastChild = child;
+ }
+ }
nodeWasRemoved(shadowNode);
Q_ASSERT(m_nodes.value(node) == 0);
}
@@ -1950,25 +1986,27 @@ void Renderer::uploadBatch(Batch *b)
vd += g->sizeOfVertex();
}
- const quint16 *id =
+ if (!b->drawSets.isEmpty()) {
+ const quint16 *id =
# ifdef QSG_SEPARATE_INDEX_BUFFER
(const quint16 *) (b->ibo.data);
# else
(const quint16 *) (b->vbo.data + b->drawSets.at(0).indices);
# endif
- {
- QDebug iDump = qDebug();
- iDump << " -- Index Data, count:" << b->indexCount;
- for (int i=0; i<b->indexCount; ++i) {
- if ((i % 24) == 0)
- iDump << endl << " --- ";
- iDump << id[i];
+ {
+ QDebug iDump = qDebug();
+ iDump << " -- Index Data, count:" << b->indexCount;
+ for (int i=0; i<b->indexCount; ++i) {
+ if ((i % 24) == 0)
+ iDump << endl << " --- ";
+ iDump << id[i];
+ }
}
- }
- for (int i=0; i<b->drawSets.size(); ++i) {
- const DrawSet &s = b->drawSets.at(i);
- qDebug() << " -- DrawSet: indexCount:" << s.indexCount << " vertices:" << s.vertices << " z:" << s.zorders << " indices:" << s.indices;
+ for (int i=0; i<b->drawSets.size(); ++i) {
+ const DrawSet &s = b->drawSets.at(i);
+ qDebug() << " -- DrawSet: indexCount:" << s.indexCount << " vertices:" << s.vertices << " z:" << s.zorders << " indices:" << s.indices;
+ }
}
}
#endif // QT_NO_DEBUG_OUTPUT
@@ -2924,7 +2962,7 @@ void Renderer::visualizeChangesPrepare(Node *n, uint parentChanges)
if (n->type() == QSGNode::GeometryNodeType && selfDirty != 0)
m_visualizeChanceSet.insert(n, selfDirty);
SHADOWNODE_TRAVERSE(n) {
- visualizeChangesPrepare(*child, childDirty);
+ visualizeChangesPrepare(child, childDirty);
}
}
@@ -2960,7 +2998,7 @@ void Renderer::visualizeChanges(Node *n)
}
SHADOWNODE_TRAVERSE(n) {
- visualizeChanges(*child);
+ visualizeChanges(child);
}
}
@@ -2987,7 +3025,7 @@ void Renderer::visualizeOverdraw_helper(Node *node)
}
SHADOWNODE_TRAVERSE(node) {
- visualizeOverdraw_helper(*child);
+ visualizeOverdraw_helper(child);
}
}
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
index 8cd9e7e3ff..4a819a5fa5 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
@@ -1,6 +1,8 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2014 Jolla Ltd, author: <gunnar.sletta@jollamobile.com>
+** Copyright (C) 2015 Robin Burchell <robin.burchell@viroteck.net>
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -438,6 +440,9 @@ struct Node
: sgNode(0)
, parent(0)
, data(0)
+ , firstChild(0)
+ , nextSibling(0)
+ , lastChild(0)
, dirtyState(0)
, isOpaque(false)
, isBatchRoot(false)
@@ -447,7 +452,9 @@ struct Node
QSGNode *sgNode;
Node *parent;
void *data;
- QList<Node *> children;
+ Node *firstChild;
+ Node *nextSibling;
+ Node *lastChild;
QSGNode::DirtyState dirtyState;
diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp
index 68947d3a3c..faa162f541 100644
--- a/src/quick/scenegraph/qsgrenderloop.cpp
+++ b/src/quick/scenegraph/qsgrenderloop.cpp
@@ -136,6 +136,7 @@ public:
void maybeUpdate(QQuickWindow *window);
void update(QQuickWindow *window) { maybeUpdate(window); } // identical for this implementation.
+ void handleUpdateRequest(QQuickWindow *);
void releaseResources(QQuickWindow *) { }
@@ -144,8 +145,6 @@ public:
QSGContext *sceneGraphContext() const;
QSGRenderContext *createRenderContext(QSGContext *) const { return rc; }
- bool event(QEvent *);
-
struct WindowData {
bool updatePending : 1;
bool grabOnly : 1;
@@ -158,9 +157,6 @@ public:
QSGRenderContext *rc;
QImage grabContent;
- int m_update_timer;
-
- bool eventPending;
};
QSGRenderLoop *QSGRenderLoop::instance()
@@ -264,7 +260,6 @@ void QSGRenderLoop::handleContextCreationFailure(QQuickWindow *window,
QSGGuiThreadRenderLoop::QSGGuiThreadRenderLoop()
: gl(0)
- , eventPending(false)
{
sg = QSGContext::createDefaultContext();
rc = sg->createRenderContext();
@@ -456,45 +451,23 @@ QImage QSGGuiThreadRenderLoop::grab(QQuickWindow *window)
return grabbed;
}
-
-
void QSGGuiThreadRenderLoop::maybeUpdate(QQuickWindow *window)
{
if (!m_windows.contains(window))
return;
m_windows[window].updatePending = true;
-
- if (!eventPending) {
- const int exhaust_delay = 5;
- m_update_timer = startTimer(exhaust_delay, Qt::PreciseTimer);
- eventPending = true;
- }
+ window->requestUpdate();
}
-
-
QSGContext *QSGGuiThreadRenderLoop::sceneGraphContext() const
{
return sg;
}
-
-bool QSGGuiThreadRenderLoop::event(QEvent *e)
+void QSGGuiThreadRenderLoop::handleUpdateRequest(QQuickWindow *window)
{
- if (e->type() == QEvent::Timer) {
- eventPending = false;
- killTimer(m_update_timer);
- m_update_timer = 0;
- for (QHash<QQuickWindow *, WindowData>::const_iterator it = m_windows.constBegin();
- it != m_windows.constEnd(); ++it) {
- const WindowData &data = it.value();
- if (data.updatePending)
- renderWindow(it.key());
- }
- return true;
- }
- return QObject::event(e);
+ renderWindow(window);
}
#include "qsgrenderloop.moc"
diff --git a/src/quick/scenegraph/util/qsgatlastexture.cpp b/src/quick/scenegraph/util/qsgatlastexture.cpp
index 8e8e870505..548d57ce00 100644
--- a/src/quick/scenegraph/util/qsgatlastexture.cpp
+++ b/src/quick/scenegraph/util/qsgatlastexture.cpp
@@ -155,11 +155,11 @@ Atlas::Atlas(const QSize &size)
|| strstr(ext, "GL_EXT_texture_format_BGRA8888")
|| strstr(ext, "GL_IMG_texture_format_BGRA8888"))) {
m_internalFormat = m_externalFormat = GL_BGRA;
-#ifdef Q_OS_IOS
+#if defined(Q_OS_DARWIN) && !defined(Q_OS_OSX)
} else if (strstr(ext, "GL_APPLE_texture_format_BGRA8888")) {
m_internalFormat = GL_RGBA;
m_externalFormat = GL_BGRA;
-#endif // IOS
+#endif // IOS || TVOS
} else {
m_internalFormat = m_externalFormat = GL_RGBA;
}
diff --git a/src/quick/scenegraph/util/qsgtexture.cpp b/src/quick/scenegraph/util/qsgtexture.cpp
index df9e569ca3..e20a8f1d87 100644
--- a/src/quick/scenegraph/util/qsgtexture.cpp
+++ b/src/quick/scenegraph/util/qsgtexture.cpp
@@ -734,7 +734,7 @@ void QSGPlainTexture::bind()
|| context->hasExtension(QByteArrayLiteral("GL_IMG_texture_format_BGRA8888")))) {
externalFormat = GL_BGRA;
internalFormat = GL_BGRA;
-#ifdef Q_OS_IOS
+#if defined(Q_OS_DARWIN) && !defined(Q_OS_OSX)
} else if (context->hasExtension(QByteArrayLiteral("GL_APPLE_texture_format_BGRA8888"))) {
externalFormat = GL_BGRA;
internalFormat = GL_RGBA;
diff --git a/src/quick/util/qquickanimatorjob.cpp b/src/quick/util/qquickanimatorjob.cpp
index eb627609bf..a57d7ba6a1 100644
--- a/src/quick/util/qquickanimatorjob.cpp
+++ b/src/quick/util/qquickanimatorjob.cpp
@@ -79,7 +79,8 @@ QQuickAnimatorProxyJob::QQuickAnimatorProxyJob(QAbstractAnimationJob *job, QObje
QQuickItem *item = qobject_cast<QQuickItem *>(ctx);
if (item->window())
setWindow(item->window());
- connect(item, SIGNAL(windowChanged(QQuickWindow*)), this, SLOT(windowChanged(QQuickWindow*)));
+
+ qmlobject_connect(item, QQuickItem, SIGNAL(windowChanged(QQuickWindow*)), this, QQuickAnimatorProxyJob, SLOT(windowChanged(QQuickWindow*)));
}
}
diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp
index 2ea1a062d8..d1ca02d79f 100644
--- a/src/quick/util/qquickglobal.cpp
+++ b/src/quick/util/qquickglobal.cpp
@@ -231,10 +231,10 @@ public:
int index3 = s.indexOf(QLatin1Char(','), index2+1);
bool sGood, xGood, yGood, zGood;
- qreal sCoord = s.left(index).toDouble(&sGood);
- qreal xCoord = s.mid(index+1, index2-index-1).toDouble(&xGood);
- qreal yCoord = s.mid(index2+1, index3-index2-1).toDouble(&yGood);
- qreal zCoord = s.mid(index3+1).toDouble(&zGood);
+ qreal sCoord = s.leftRef(index).toDouble(&sGood);
+ qreal xCoord = s.midRef(index+1, index2-index-1).toDouble(&xGood);
+ qreal yCoord = s.midRef(index2+1, index3-index2-1).toDouble(&yGood);
+ qreal zCoord = s.midRef(index3+1).toDouble(&zGood);
if (sGood && xGood && yGood && zGood) {
if (ok) *ok = true;
@@ -254,7 +254,7 @@ public:
QString mutableStr = s;
for (int i = 0; vOK && i < 16; ++i) {
int cidx = mutableStr.indexOf(QLatin1Char(','));
- matValues[i] = mutableStr.left(cidx).toDouble(&vOK);
+ matValues[i] = mutableStr.leftRef(cidx).toDouble(&vOK);
mutableStr = mutableStr.mid(cidx + 1);
}
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp
index ed6da8ac91..bbb15cb872 100644
--- a/src/quick/util/qquickpixmapcache.cpp
+++ b/src/quick/util/qquickpixmapcache.cpp
@@ -1140,6 +1140,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
*ok = true;
return new QQuickPixmapData(declarativePixmap, url, texture, readSize, requestSize, autoTransform, UsePluginDefault);
}
+ break;
}
case QQuickImageProvider::Image:
@@ -1149,6 +1150,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
*ok = true;
return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, autoTransform, UsePluginDefault);
}
+ break;
}
case QQuickImageProvider::Pixmap:
{
@@ -1157,6 +1159,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
*ok = true;
return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(pixmap.toImage()), readSize, requestSize, autoTransform, UsePluginDefault);
}
+ break;
}
case QQuickImageProvider::ImageResponse:
{
diff --git a/src/quick/util/qquickprofiler.cpp b/src/quick/util/qquickprofiler.cpp
index 77ffda474a..cb6212196e 100644
--- a/src/quick/util/qquickprofiler.cpp
+++ b/src/quick/util/qquickprofiler.cpp
@@ -32,8 +32,11 @@
****************************************************************************/
#include "qquickprofiler_p.h"
-#include <QCoreApplication>
-#include <private/qqmldebugserviceinterfaces_p.h>
+
+#include <QtQml/private/qqmlabstractprofileradapter_p.h>
+
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qthread.h>
QT_BEGIN_NAMESPACE
@@ -41,93 +44,10 @@ QT_BEGIN_NAMESPACE
QQuickProfiler *QQuickProfiler::s_instance = 0;
quint64 QQuickProfiler::featuresEnabled = 0;
-// convert to QByteArrays that can be sent to the debug client
-// use of QDataStream can skew results
-// (see tst_qqmldebugtrace::trace() benchmark)
-void QQuickProfilerData::toByteArrays(QList<QByteArray> &messages) const
-{
- QByteArray data;
- Q_ASSERT_X(((messageType | detailType) & (1 << 31)) == 0, Q_FUNC_INFO, "You can use at most 31 message types and 31 detail types.");
- for (uint decodedMessageType = 0; (messageType >> decodedMessageType) != 0; ++decodedMessageType) {
- if ((messageType & (1 << decodedMessageType)) == 0)
- continue;
-
- for (uint decodedDetailType = 0; (detailType >> decodedDetailType) != 0; ++decodedDetailType) {
- if ((detailType & (1 << decodedDetailType)) == 0)
- continue;
-
- //### using QDataStream is relatively expensive
- QQmlDebugStream ds(&data, QIODevice::WriteOnly);
- ds << time << decodedMessageType << decodedDetailType;
-
- switch (decodedMessageType) {
- case QQuickProfiler::Event:
- if (decodedDetailType == (int)QQuickProfiler::AnimationFrame)
- ds << framerate << count << threadId;
- break;
- case QQuickProfiler::PixmapCacheEvent:
- ds << detailUrl.toString();
- switch (decodedDetailType) {
- case QQuickProfiler::PixmapSizeKnown: ds << x << y; break;
- case QQuickProfiler::PixmapReferenceCountChanged: ds << count; break;
- case QQuickProfiler::PixmapCacheCountChanged: ds << count; break;
- default: break;
- }
- break;
- case QQuickProfiler::SceneGraphFrame:
- switch (decodedDetailType) {
- // RendererFrame: preprocessTime, updateTime, bindingTime, renderTime
- case QQuickProfiler::SceneGraphRendererFrame: ds << subtime_1 << subtime_2 << subtime_3 << subtime_4; break;
- // AdaptationLayerFrame: glyphCount (which is an integer), glyphRenderTime, glyphStoreTime
- case QQuickProfiler::SceneGraphAdaptationLayerFrame: ds << subtime_3 << subtime_1 << subtime_2; break;
- // ContextFrame: compiling material time
- case QQuickProfiler::SceneGraphContextFrame: ds << subtime_1; break;
- // RenderLoop: syncTime, renderTime, swapTime
- case QQuickProfiler::SceneGraphRenderLoopFrame: ds << subtime_1 << subtime_2 << subtime_3; break;
- // TexturePrepare: bind, convert, swizzle, upload, mipmap
- case QQuickProfiler::SceneGraphTexturePrepare: ds << subtime_1 << subtime_2 << subtime_3 << subtime_4 << subtime_5; break;
- // TextureDeletion: deletionTime
- case QQuickProfiler::SceneGraphTextureDeletion: ds << subtime_1; break;
- // PolishAndSync: polishTime, waitTime, syncTime, animationsTime,
- case QQuickProfiler::SceneGraphPolishAndSync: ds << subtime_1 << subtime_2 << subtime_3 << subtime_4; break;
- // WindowsRenderLoop: GL time, make current time, SceneGraph time
- case QQuickProfiler::SceneGraphWindowsRenderShow: ds << subtime_1 << subtime_2 << subtime_3; break;
- // WindowsAnimations: update time
- case QQuickProfiler::SceneGraphWindowsAnimations: ds << subtime_1; break;
- // non-threaded rendering: polish time
- case QQuickProfiler::SceneGraphPolishFrame: ds << subtime_1; break;
- default:break;
- }
- break;
- default:
- Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid message type.");
- break;
- }
- messages << data;
- data.clear();
- }
- }
-}
-
-qint64 QQuickProfiler::sendMessages(qint64 until, QList<QByteArray> &messages)
-{
- QMutexLocker lock(&m_dataMutex);
- while (next < m_data.size()) {
- if (m_data[next].time <= until)
- m_data[next++].toByteArrays(messages);
- else
- return m_data[next].time;
- }
- m_data.clear();
- next = 0;
- return -1;
-}
-
-void QQuickProfiler::initialize(QQmlProfilerService *service)
+void QQuickProfiler::initialize(QObject *parent)
{
Q_ASSERT(s_instance == 0);
- s_instance = new QQuickProfiler(service);
- service->addGlobalProfiler(s_instance);
+ s_instance = new QQuickProfiler(parent);
}
void animationTimerCallback(qint64 delta)
@@ -154,26 +74,10 @@ public slots:
#include "qquickprofiler.moc"
-QQuickProfiler::QQuickProfiler(QQmlProfilerService *service) :
- QQmlAbstractProfilerAdapter(service), next(0)
+QQuickProfiler::QQuickProfiler(QObject *parent) : QObject(parent)
{
// This is safe because at this point the m_instance isn't initialized, yet.
m_timer.start();
-
- // We can always do DirectConnection here as all methods are protected by mutexes
- connect(this, SIGNAL(profilingEnabled(quint64)), this, SLOT(startProfilingImpl(quint64)),
- Qt::DirectConnection);
- connect(this, SIGNAL(profilingEnabledWhileWaiting(quint64)),
- this, SLOT(startProfilingImpl(quint64)), Qt::DirectConnection);
- connect(this, SIGNAL(referenceTimeKnown(QElapsedTimer)), this, SLOT(setTimer(QElapsedTimer)),
- Qt::DirectConnection);
- connect(this, SIGNAL(profilingDisabled()), this, SLOT(stopProfilingImpl()),
- Qt::DirectConnection);
- connect(this, SIGNAL(profilingDisabledWhileWaiting()), this, SLOT(stopProfilingImpl()),
- Qt::DirectConnection);
- connect(this, SIGNAL(dataRequested()), this, SLOT(reportDataImpl()),
- Qt::DirectConnection);
-
CallbackRegistrationHelper *helper = new CallbackRegistrationHelper; // will delete itself
helper->moveToThread(QCoreApplication::instance()->thread());
QMetaObject::invokeMethod(helper, "registerAnimationTimerCallback", Qt::QueuedConnection);
@@ -189,7 +93,6 @@ QQuickProfiler::~QQuickProfiler()
void QQuickProfiler::startProfilingImpl(quint64 features)
{
QMutexLocker lock(&m_dataMutex);
- next = 0;
m_data.clear();
featuresEnabled = features;
}
@@ -200,12 +103,12 @@ void QQuickProfiler::stopProfilingImpl()
QMutexLocker lock(&m_dataMutex);
featuresEnabled = 0;
}
- service->dataReady(this);
+ emit dataReady(m_data);
}
void QQuickProfiler::reportDataImpl()
{
- service->dataReady(this);
+ emit dataReady(m_data);
}
void QQuickProfiler::setTimer(const QElapsedTimer &t)
diff --git a/src/quick/util/qquickprofiler_p.h b/src/quick/util/qquickprofiler_p.h
index 6b6e7fa062..4983adf63b 100644
--- a/src/quick/util/qquickprofiler_p.h
+++ b/src/quick/util/qquickprofiler_p.h
@@ -45,13 +45,14 @@
// We mean it.
//
-#include <private/qtquickglobal_p.h>
#include <QtCore/private/qabstractanimation_p.h>
-#include <QtQml/private/qqmlabstractprofileradapter_p.h>
-#include <QUrl>
-#include <QSize>
-#include <QMutex>
-#include <QThreadStorage>
+#include <QtQml/private/qqmlprofilerdefinitions_p.h>
+#include <QtQuick/private/qtquickglobal_p.h>
+
+#include <QtCore/qurl.h>
+#include <QtCore/qsize.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qthreadstorage.h>
QT_BEGIN_NAMESPACE
@@ -97,8 +98,9 @@ QT_BEGIN_NAMESPACE
(QQuickProfiler::reportSceneGraphFrame<Type, true>(Payload)))
-#define Q_QUICK_INPUT_PROFILE(Method)\
- Q_QUICK_PROFILE(QQuickProfiler::ProfileInputEvents, Method)
+#define Q_QUICK_INPUT_PROFILE(Type, DetailType, A, B)\
+ Q_QUICK_PROFILE_IF_ENABLED(QQuickProfiler::ProfileInputEvents,\
+ (QQuickProfiler::inputEvent<Type, DetailType>(A, B)))
// This struct is somewhat dangerous to use:
// You can save values either with 32 or 64 bit precision. toByteArrays will
@@ -117,10 +119,10 @@ struct Q_AUTOTEST_EXPORT QQuickProfilerData
time(time), messageType(messageType), detailType(detailType), detailUrl(url), x(x), y(y),
framerate(framerate), count(count) {}
- QQuickProfilerData(qint64 time, int messageType, int detailType, int framerate = 0,
- int count = 0, int threadId = 0) :
- time(time), messageType(messageType), detailType(detailType), framerate(framerate),
- count(count), threadId(threadId) {}
+ QQuickProfilerData(qint64 time, int messageType, int detailType, int framerateOrInputType = 0,
+ int countOrInputA = 0, int threadIdOrInputB = 0) :
+ time(time), messageType(messageType), detailType(detailType),
+ framerate(framerateOrInputType), count(countOrInputA), threadId(threadIdOrInputB) {}
// Special ctor for scenegraph frames. Note that it's missing the QString/QUrl params.
// This is slightly ugly, but makes it easier to disambiguate between int and qint64 params.
@@ -149,19 +151,20 @@ struct Q_AUTOTEST_EXPORT QQuickProfilerData
union {
qint64 subtime_3;
int framerate; //used by animation events
+ int inputType;
};
union {
qint64 subtime_4;
int count; //used by animation events and for pixmaps
+ int inputA; //used by input events
};
union {
qint64 subtime_5;
int threadId;
+ int inputB; //used by input events
};
-
- void toByteArrays(QList<QByteArray> &messages) const;
};
Q_DECLARE_TYPEINFO(QQuickProfilerData, Q_MOVABLE_TYPE);
@@ -199,7 +202,7 @@ public:
}
};
-class Q_QUICK_PRIVATE_EXPORT QQuickProfiler : public QQmlAbstractProfilerAdapter {
+class Q_QUICK_PRIVATE_EXPORT QQuickProfiler : public QObject, public QQmlProfilerDefinitions {
Q_OBJECT
public:
@@ -208,11 +211,11 @@ public:
RenderThread
};
- template<EventType DetailType>
- static void addEvent()
+ template<EventType DetailType, InputEventType InputType>
+ static void inputEvent(int x, int y = 0)
{
s_instance->processMessage(QQuickProfilerData(s_instance->timestamp(), 1 << Event,
- 1 << DetailType));
+ 1 << DetailType, InputType, x, y));
}
static void animationFrame(qint64 delta, AnimationThread threadId)
@@ -310,7 +313,6 @@ public:
qint64 timestamp() { return m_timer.nsecsElapsed(); }
- qint64 sendMessages(qint64 until, QList<QByteArray> &messages);
static quint64 featuresEnabled;
static bool profilingSceneGraph()
@@ -318,19 +320,20 @@ public:
return featuresEnabled & (1 << QQuickProfiler::ProfileSceneGraph);
}
- static void initialize(QQmlProfilerService *service);
+ static void initialize(QObject *parent);
virtual ~QQuickProfiler();
protected:
- int next;
+ friend class QQuickProfilerAdapter;
+
static QQuickProfiler *s_instance;
QMutex m_dataMutex;
QElapsedTimer m_timer;
- QVarLengthArray<QQuickProfilerData> m_data;
+ QVector<QQuickProfilerData> m_data;
QQuickProfilerSceneGraphData m_sceneGraphData;
- QQuickProfiler(QQmlProfilerService *service);
+ QQuickProfiler(QObject *parent);
void processMessage(const QQuickProfilerData &message)
{
@@ -338,6 +341,9 @@ protected:
m_data.append(message);
}
+signals:
+ void dataReady(const QVector<QQuickProfilerData> &data);
+
protected slots:
void startProfilingImpl(quint64 features);
void stopProfilingImpl();
diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp
index 2120be768c..11e7953e93 100644
--- a/src/quickwidgets/qquickwidget.cpp
+++ b/src/quickwidgets/qquickwidget.cpp
@@ -1049,7 +1049,8 @@ void QQuickWidget::resizeEvent(QResizeEvent *e)
void QQuickWidget::keyPressEvent(QKeyEvent *e)
{
Q_D(QQuickWidget);
- Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Key>());
+ Q_QUICK_INPUT_PROFILE(QQuickProfiler::Key, QQuickProfiler::InputKeyPress, e->key(),
+ e->modifiers());
QCoreApplication::sendEvent(d->offscreenWindow, e);
}
@@ -1058,7 +1059,8 @@ void QQuickWidget::keyPressEvent(QKeyEvent *e)
void QQuickWidget::keyReleaseEvent(QKeyEvent *e)
{
Q_D(QQuickWidget);
- Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Key>());
+ Q_QUICK_INPUT_PROFILE(QQuickProfiler::Key, QQuickProfiler::InputKeyRelease, e->key(),
+ e->modifiers());
QCoreApplication::sendEvent(d->offscreenWindow, e);
}
@@ -1067,7 +1069,8 @@ void QQuickWidget::keyReleaseEvent(QKeyEvent *e)
void QQuickWidget::mouseMoveEvent(QMouseEvent *e)
{
Q_D(QQuickWidget);
- Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Mouse>());
+ Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseMove, e->localPos().x(),
+ e->localPos().y());
// Use the constructor taking localPos and screenPos. That puts localPos into the
// event's localPos and windowPos, and screenPos into the event's screenPos. This way
@@ -1082,7 +1085,8 @@ void QQuickWidget::mouseMoveEvent(QMouseEvent *e)
void QQuickWidget::mouseDoubleClickEvent(QMouseEvent *e)
{
Q_D(QQuickWidget);
- Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Mouse>());
+ Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseDoubleClick,
+ e->button(), e->buttons());
// As the second mouse press is suppressed in widget windows we emulate it here for QML.
// See QTBUG-25831
@@ -1130,7 +1134,8 @@ void QQuickWidget::hideEvent(QHideEvent *)
void QQuickWidget::mousePressEvent(QMouseEvent *e)
{
Q_D(QQuickWidget);
- Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Mouse>());
+ Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMousePress, e->button(),
+ e->buttons());
QMouseEvent mappedEvent(e->type(), e->localPos(), e->screenPos(), e->button(), e->buttons(), e->modifiers());
QCoreApplication::sendEvent(d->offscreenWindow, &mappedEvent);
@@ -1141,7 +1146,8 @@ void QQuickWidget::mousePressEvent(QMouseEvent *e)
void QQuickWidget::mouseReleaseEvent(QMouseEvent *e)
{
Q_D(QQuickWidget);
- Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Mouse>());
+ Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseRelease, e->button(),
+ e->buttons());
QMouseEvent mappedEvent(e->type(), e->localPos(), e->screenPos(), e->button(), e->buttons(), e->modifiers());
QCoreApplication::sendEvent(d->offscreenWindow, &mappedEvent);
@@ -1153,7 +1159,8 @@ void QQuickWidget::mouseReleaseEvent(QMouseEvent *e)
void QQuickWidget::wheelEvent(QWheelEvent *e)
{
Q_D(QQuickWidget);
- Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Mouse>());
+ Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseWheel,
+ e->angleDelta().x(), e->angleDelta().y());
// Wheel events only have local and global positions, no need to map.
QCoreApplication::sendEvent(d->offscreenWindow, e);
@@ -1282,6 +1289,14 @@ void QQuickWidget::triggerUpdate()
Q_D(QQuickWidget);
d->updatePending = true;
if (!d->eventPending) {
+ // There's no sense in immediately kicking a render off now, as
+ // there may be a number of triggerUpdate calls to come from a multitude
+ // of different sources (network, touch/mouse/keyboard, timers,
+ // animations, ...), and we want to batch them all into single frames as
+ // much as possible for the sake of interactivity and responsiveness.
+ //
+ // To achieve this, we set a timer and only perform the rendering when
+ // this is complete.
const int exhaustDelay = 5;
d->updateTimer.start(exhaustDelay, Qt::PreciseTimer, this);
d->eventPending = true;
diff --git a/src/src.pro b/src/src.pro
index ac48f017e6..18e9ba6704 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -14,6 +14,7 @@ qtHaveModule(gui):contains(QT_CONFIG, opengl(es1|es2)?) {
SUBDIRS += \
plugins \
+ qmldebug \
imports \
qmldevtools
diff --git a/sync.profile b/sync.profile
index 28d0698da9..46280ade96 100644
--- a/sync.profile
+++ b/sync.profile
@@ -5,6 +5,8 @@
"QtQuickParticles" => "$basedir/src/particles",
"QtQuickTest" => "$basedir/src/qmltest",
"QtQmlDevTools" => "$basedir/src/qmldevtools",
+ "QtPacketProtocol" => "$basedir/src/plugins/qmltooling/packetprotocol",
+ "QtQmlDebug" => "$basedir/src/qmldebug",
);
%moduleheaders = ( # restrict the module headers to those found in relative path
"QtQmlDevTools" => "../qml/parser;../qml/jsruntime;../qml/qml/ftw;../qml/compiler;../qml/memory;.",
diff --git a/tests/auto/particles/qquickage/qquickage.pro b/tests/auto/particles/qquickage/qquickage.pro
index 3fffb28f31..557daac86f 100644
--- a/tests/auto/particles/qquickage/qquickage.pro
+++ b/tests/auto/particles/qquickage/qquickage.pro
@@ -8,4 +8,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private quickparticles-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/particles/qquickangleddirection/qquickangleddirection.pro b/tests/auto/particles/qquickangleddirection/qquickangleddirection.pro
index 4533f94388..b813b64a3c 100644
--- a/tests/auto/particles/qquickangleddirection/qquickangleddirection.pro
+++ b/tests/auto/particles/qquickangleddirection/qquickangleddirection.pro
@@ -8,4 +8,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private quickparticles-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/particles/qquickcumulativedirection/qquickcumulativedirection.pro b/tests/auto/particles/qquickcumulativedirection/qquickcumulativedirection.pro
index ba4a6ba9d9..145bffd3b3 100644
--- a/tests/auto/particles/qquickcumulativedirection/qquickcumulativedirection.pro
+++ b/tests/auto/particles/qquickcumulativedirection/qquickcumulativedirection.pro
@@ -8,4 +8,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private quickparticles-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/particles/qquickcustomaffector/qquickcustomaffector.pro b/tests/auto/particles/qquickcustomaffector/qquickcustomaffector.pro
index 9442a29fb9..01a831ca9c 100644
--- a/tests/auto/particles/qquickcustomaffector/qquickcustomaffector.pro
+++ b/tests/auto/particles/qquickcustomaffector/qquickcustomaffector.pro
@@ -8,4 +8,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private quickparticles-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/particles/qquickcustomparticle/qquickcustomparticle.pro b/tests/auto/particles/qquickcustomparticle/qquickcustomparticle.pro
index 48e7303f86..d02b45457a 100644
--- a/tests/auto/particles/qquickcustomparticle/qquickcustomparticle.pro
+++ b/tests/auto/particles/qquickcustomparticle/qquickcustomparticle.pro
@@ -1,5 +1,4 @@
CONFIG += testcase
-CONFIG += parallel_test
TARGET = tst_qquickcustomparticle
SOURCES += tst_qquickcustomparticle.cpp
macx:CONFIG -= app_bundle
@@ -9,4 +8,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private quickparticles-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/particles/qquickellipseextruder/qquickellipseextruder.pro b/tests/auto/particles/qquickellipseextruder/qquickellipseextruder.pro
index 324b980e78..a1d79daca7 100644
--- a/tests/auto/particles/qquickellipseextruder/qquickellipseextruder.pro
+++ b/tests/auto/particles/qquickellipseextruder/qquickellipseextruder.pro
@@ -8,4 +8,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private quickparticles-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/particles/qquickfriction/qquickfriction.pro b/tests/auto/particles/qquickfriction/qquickfriction.pro
index b90b31ece2..8a15dee4c4 100644
--- a/tests/auto/particles/qquickfriction/qquickfriction.pro
+++ b/tests/auto/particles/qquickfriction/qquickfriction.pro
@@ -8,4 +8,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private quickparticles-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/particles/qquickgravity/qquickgravity.pro b/tests/auto/particles/qquickgravity/qquickgravity.pro
index 07c9eba314..899d58ed38 100644
--- a/tests/auto/particles/qquickgravity/qquickgravity.pro
+++ b/tests/auto/particles/qquickgravity/qquickgravity.pro
@@ -8,4 +8,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private quickparticles-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/particles/qquickgroupgoal/qquickgroupgoal.pro b/tests/auto/particles/qquickgroupgoal/qquickgroupgoal.pro
index 31b6fa5457..3236231f14 100644
--- a/tests/auto/particles/qquickgroupgoal/qquickgroupgoal.pro
+++ b/tests/auto/particles/qquickgroupgoal/qquickgroupgoal.pro
@@ -8,4 +8,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private testlib quick-private quickparticles-private
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/particles/qquickimageparticle/qquickimageparticle.pro b/tests/auto/particles/qquickimageparticle/qquickimageparticle.pro
index 271b2ec57c..cf0f81f0ff 100644
--- a/tests/auto/particles/qquickimageparticle/qquickimageparticle.pro
+++ b/tests/auto/particles/qquickimageparticle/qquickimageparticle.pro
@@ -7,4 +7,3 @@ include (../../shared/util.pri)
TESTDATA = data/*
QT += core-private gui-private qml-private quick-private quickparticles-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/particles/qquickitemparticle/qquickitemparticle.pro b/tests/auto/particles/qquickitemparticle/qquickitemparticle.pro
index 7db55d29e9..8c39fc9736 100644
--- a/tests/auto/particles/qquickitemparticle/qquickitemparticle.pro
+++ b/tests/auto/particles/qquickitemparticle/qquickitemparticle.pro
@@ -1,5 +1,4 @@
CONFIG += testcase
-CONFIG += parallel_test
TARGET = tst_qquickitemparticle
SOURCES += tst_qquickitemparticle.cpp
macx:CONFIG -= app_bundle
@@ -9,4 +8,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private quickparticles-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/particles/qquicklineextruder/qquicklineextruder.pro b/tests/auto/particles/qquicklineextruder/qquicklineextruder.pro
index 85e98f3cd4..2ccc5b3765 100644
--- a/tests/auto/particles/qquicklineextruder/qquicklineextruder.pro
+++ b/tests/auto/particles/qquicklineextruder/qquicklineextruder.pro
@@ -8,4 +8,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private quickparticles-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/particles/qquickmaskextruder/qquickmaskextruder.pro b/tests/auto/particles/qquickmaskextruder/qquickmaskextruder.pro
index d83006e523..cf63196539 100644
--- a/tests/auto/particles/qquickmaskextruder/qquickmaskextruder.pro
+++ b/tests/auto/particles/qquickmaskextruder/qquickmaskextruder.pro
@@ -8,4 +8,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private quickparticles-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/particles/qquickparticlegroup/qquickparticlegroup.pro b/tests/auto/particles/qquickparticlegroup/qquickparticlegroup.pro
index 3d98e5f3bd..06febb3825 100644
--- a/tests/auto/particles/qquickparticlegroup/qquickparticlegroup.pro
+++ b/tests/auto/particles/qquickparticlegroup/qquickparticlegroup.pro
@@ -8,4 +8,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private quickparticles-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/particles/qquickparticlesystem/qquickparticlesystem.pro b/tests/auto/particles/qquickparticlesystem/qquickparticlesystem.pro
index d3aeaecdca..f076d6f0c0 100644
--- a/tests/auto/particles/qquickparticlesystem/qquickparticlesystem.pro
+++ b/tests/auto/particles/qquickparticlesystem/qquickparticlesystem.pro
@@ -8,4 +8,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private quickparticles-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/particles/qquickpointattractor/qquickpointattractor.pro b/tests/auto/particles/qquickpointattractor/qquickpointattractor.pro
index 60b1c1fc7f..2d2c4f375d 100644
--- a/tests/auto/particles/qquickpointattractor/qquickpointattractor.pro
+++ b/tests/auto/particles/qquickpointattractor/qquickpointattractor.pro
@@ -8,4 +8,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private quickparticles-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/particles/qquickpointdirection/qquickpointdirection.pro b/tests/auto/particles/qquickpointdirection/qquickpointdirection.pro
index e61527a11d..8174e52964 100644
--- a/tests/auto/particles/qquickpointdirection/qquickpointdirection.pro
+++ b/tests/auto/particles/qquickpointdirection/qquickpointdirection.pro
@@ -8,4 +8,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private quickparticles-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/particles/qquickrectangleextruder/qquickrectangleextruder.pro b/tests/auto/particles/qquickrectangleextruder/qquickrectangleextruder.pro
index a8b2c1ca95..add9981d0b 100644
--- a/tests/auto/particles/qquickrectangleextruder/qquickrectangleextruder.pro
+++ b/tests/auto/particles/qquickrectangleextruder/qquickrectangleextruder.pro
@@ -8,4 +8,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private quickparticles-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/particles/qquickspritegoal/qquickspritegoal.pro b/tests/auto/particles/qquickspritegoal/qquickspritegoal.pro
index eb127c5fc2..f5a5f745bd 100644
--- a/tests/auto/particles/qquickspritegoal/qquickspritegoal.pro
+++ b/tests/auto/particles/qquickspritegoal/qquickspritegoal.pro
@@ -8,4 +8,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private testlib quick-private quickparticles-private
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/particles/qquicktargetdirection/qquicktargetdirection.pro b/tests/auto/particles/qquicktargetdirection/qquicktargetdirection.pro
index 9fe6747378..e8c5c2d33d 100644
--- a/tests/auto/particles/qquicktargetdirection/qquicktargetdirection.pro
+++ b/tests/auto/particles/qquicktargetdirection/qquicktargetdirection.pro
@@ -8,4 +8,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private quickparticles-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro b/tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro
index 1cb792eff2..2f54e13000 100644
--- a/tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro
+++ b/tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro
@@ -8,4 +8,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private quickparticles-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/particles/qquickturbulence/qquickturbulence.pro b/tests/auto/particles/qquickturbulence/qquickturbulence.pro
index 2db3d54e4c..8758a5203b 100644
--- a/tests/auto/particles/qquickturbulence/qquickturbulence.pro
+++ b/tests/auto/particles/qquickturbulence/qquickturbulence.pro
@@ -8,4 +8,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private quickparticles-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/particles/qquickwander/qquickwander.pro b/tests/auto/particles/qquickwander/qquickwander.pro
index 41171645a2..58da3f39d8 100644
--- a/tests/auto/particles/qquickwander/qquickwander.pro
+++ b/tests/auto/particles/qquickwander/qquickwander.pro
@@ -8,4 +8,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private quickparticles-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/animation/qabstractanimationjob/qabstractanimationjob.pro b/tests/auto/qml/animation/qabstractanimationjob/qabstractanimationjob.pro
index f63a437c54..f7ba4c275c 100644
--- a/tests/auto/qml/animation/qabstractanimationjob/qabstractanimationjob.pro
+++ b/tests/auto/qml/animation/qabstractanimationjob/qabstractanimationjob.pro
@@ -1,6 +1,5 @@
-CONFIG += testcase parallel_test
+CONFIG += testcase
macx:CONFIG -= app_bundle
TARGET = tst_qabstractanimationjob
QT = core-private qml-private testlib
SOURCES = tst_qabstractanimationjob.cpp
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/animation/qanimationgroupjob/qanimationgroupjob.pro b/tests/auto/qml/animation/qanimationgroupjob/qanimationgroupjob.pro
index 136999ce13..0c52094bfd 100644
--- a/tests/auto/qml/animation/qanimationgroupjob/qanimationgroupjob.pro
+++ b/tests/auto/qml/animation/qanimationgroupjob/qanimationgroupjob.pro
@@ -1,6 +1,5 @@
-CONFIG += testcase parallel_test
+CONFIG += testcase
macx:CONFIG -= app_bundle
TARGET = tst_qanimationgroupjob
QT = core-private qml-private testlib
SOURCES = tst_qanimationgroupjob.cpp
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/animation/qparallelanimationgroupjob/qparallelanimationgroupjob.pro b/tests/auto/qml/animation/qparallelanimationgroupjob/qparallelanimationgroupjob.pro
index 2cc057cb90..982aafbfe7 100644
--- a/tests/auto/qml/animation/qparallelanimationgroupjob/qparallelanimationgroupjob.pro
+++ b/tests/auto/qml/animation/qparallelanimationgroupjob/qparallelanimationgroupjob.pro
@@ -1,7 +1,5 @@
CONFIG += testcase
-CONFIG += parallel_test
macx:CONFIG -= app_bundle
TARGET = tst_qparallelanimationgroupjob
QT = core-private gui qml-private testlib gui-private
SOURCES = tst_qparallelanimationgroupjob.cpp
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/animation/qpauseanimationjob/qpauseanimationjob.pro b/tests/auto/qml/animation/qpauseanimationjob/qpauseanimationjob.pro
index 7102096384..b80bb0c55c 100644
--- a/tests/auto/qml/animation/qpauseanimationjob/qpauseanimationjob.pro
+++ b/tests/auto/qml/animation/qpauseanimationjob/qpauseanimationjob.pro
@@ -1,7 +1,5 @@
CONFIG += testcase
-CONFIG += parallel_test
macx:CONFIG -= app_bundle
TARGET = tst_qpauseanimationjob
QT = core-private gui-private qml-private testlib
SOURCES = tst_qpauseanimationjob.cpp
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/animation/qsequentialanimationgroupjob/qsequentialanimationgroupjob.pro b/tests/auto/qml/animation/qsequentialanimationgroupjob/qsequentialanimationgroupjob.pro
index eda764cedd..370d33607b 100644
--- a/tests/auto/qml/animation/qsequentialanimationgroupjob/qsequentialanimationgroupjob.pro
+++ b/tests/auto/qml/animation/qsequentialanimationgroupjob/qsequentialanimationgroupjob.pro
@@ -1,6 +1,5 @@
-CONFIG += testcase parallel_test
+CONFIG += testcase
macx:CONFIG -= app_bundle
TARGET = tst_qsequentialanimationgroupjob
QT = core-private qml-private testlib
SOURCES = tst_qsequentialanimationgroupjob.cpp
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/debugger/debugger.pro b/tests/auto/qml/debugger/debugger.pro
index 6b47801720..ccb2d71c53 100644
--- a/tests/auto/qml/debugger/debugger.pro
+++ b/tests/auto/qml/debugger/debugger.pro
@@ -1,6 +1,7 @@
TEMPLATE = subdirs
PUBLICTESTS += \
+ qdebugmessageservice \
qqmlenginedebugservice \
qqmldebugjs \
qqmlinspector \
@@ -14,7 +15,8 @@ PUBLICTESTS += \
PRIVATETESTS += \
qqmldebugclient \
qqmldebuglocal \
- qqmldebugservice
+ qqmldebugservice \
+ qv4debugger
SUBDIRS += $$PUBLICTESTS
diff --git a/tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro b/tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro
index 0d6484f8e6..6c729ab235 100644
--- a/tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro
+++ b/tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro
@@ -1,7 +1,7 @@
CONFIG += testcase
TARGET = tst_qdebugmessageservice
QT += qml network testlib gui-private core-private
-macx:CONFIG -= app_bundle
+osx:CONFIG -= app_bundle
SOURCES += tst_qdebugmessageservice.cpp
@@ -12,4 +12,3 @@ include(../shared/debugutil.pri)
TESTDATA = data/*
OTHER_FILES += data/test.qml
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp
index d0801dd4ee..75c301f958 100644
--- a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp
+++ b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp
@@ -31,14 +31,17 @@
**
****************************************************************************/
-#include "qqmldebugclient.h"
-
//QQmlDebugTest
#include "debugutil_p.h"
#include "../../../shared/util.h"
-#include <QtCore/QString>
-#include <QtTest/QtTest>
+#include <private/qqmldebugclient_p.h>
+#include <private/qqmldebugconnection_p.h>
+#include <private/qpacket_p.h>
+
+#include <QtCore/qstring.h>
+#include <QtCore/qlibraryinfo.h>
+#include <QtTest/qtest.h>
const char *NORMALMODE = "-qmljsdebugger=port:3777,3787,block";
const char *QMLFILE = "test.qml";
@@ -76,15 +79,19 @@ struct LogEntry {
int line;
QString file;
QString function;
+ QString category;
- QString toString() const { return QString::number(type) + ": " + message; }
+ QString toString() const
+ {
+ return QString::number(type) + ": " + message + " (" + category + ")";
+ }
};
bool operator==(const LogEntry &t1, const LogEntry &t2)
{
return t1.type == t2.type && t1.message == t2.message
&& t1.line == t2.line && t1.file == t2.file
- && t1.function == t2.function;
+ && t1.function == t2.function && t1.category == t2.category;
}
class QQmlDebugMsgClient : public QQmlDebugClient
@@ -117,7 +124,7 @@ void QQmlDebugMsgClient::stateChanged(State state)
void QQmlDebugMsgClient::messageReceived(const QByteArray &data)
{
- QDataStream ds(data);
+ QPacket ds(connection()->currentDataStreamVersion(), data);
QByteArray command;
ds >> command;
@@ -126,17 +133,21 @@ void QQmlDebugMsgClient::messageReceived(const QByteArray &data)
QByteArray message;
QByteArray file;
QByteArray function;
+ QByteArray category;
+ qint64 timestamp;
int line;
- ds >> type >> message >> file >> line >> function;
+ ds >> type >> message >> file >> line >> function >> category >> timestamp;
QVERIFY(ds.atEnd());
QVERIFY(type >= QtDebugMsg);
QVERIFY(type <= QtFatalMsg);
+ QVERIFY(timestamp > 0);
LogEntry entry((QtMsgType)type, QString::fromUtf8(message));
entry.line = line;
entry.file = QString::fromUtf8(file);
entry.function = QString::fromUtf8(function);
+ entry.category = QString::fromUtf8(category);
logBuffer << entry;
emit debugOutput();
} else {
@@ -212,23 +223,20 @@ void tst_QDebugMessageService::retrieveDebugOutput()
{
init();
- int maxTries = 2;
- while ((m_client->logBuffer.size() < 2)
- || (maxTries-- > 0))
- QQmlDebugTest::waitForSignal(m_client, SIGNAL(debugOutput()), 1000);
-
- QVERIFY(m_client->logBuffer.size() >= 2);
+ QTRY_VERIFY(m_client->logBuffer.size() >= 2);
const QString path =
QUrl::fromLocalFile(QQmlDataTest::instance()->testFile(QMLFILE)).toString();
LogEntry entry1(QtDebugMsg, QLatin1String("console.log"));
- entry1.line = 48;
+ entry1.line = 40;
entry1.file = path;
entry1.function = QLatin1String("onCompleted");
+ entry1.category = QLatin1String("qml");
LogEntry entry2(QtDebugMsg, QLatin1String("console.count: 1"));
- entry2.line = 49;
+ entry2.line = 41;
entry2.file = path;
entry2.function = QLatin1String("onCompleted");
+ entry2.category = QLatin1String("default");
QVERIFY(m_client->logBuffer.contains(entry1));
QVERIFY(m_client->logBuffer.contains(entry2));
diff --git a/tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro b/tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro
index 716d8f0be9..a7c0fa7f8e 100644
--- a/tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro
+++ b/tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro
@@ -1,12 +1,10 @@
CONFIG += testcase
TARGET = tst_qpacketprotocol
-macx:CONFIG -= app_bundle
+osx:CONFIG -= app_bundle
SOURCES += tst_qpacketprotocol.cpp
INCLUDEPATH += ../shared
include(../shared/debugutil.pri)
-CONFIG += parallel_test
QT += qml network testlib gui-private core-private
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp b/tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp
index db9e621d54..b68cc5d6c9 100644
--- a/tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp
+++ b/tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp
@@ -38,7 +38,8 @@
#include <QDebug>
#include <QBuffer>
-#include "../../../../../src/plugins/qmltooling/shared/qpacketprotocol.h"
+#include <private/qpacketprotocol_p.h>
+#include <private/qpacket_p.h>
#include "debugutil_p.h"
@@ -55,18 +56,10 @@ private slots:
void init();
void cleanup();
- void maximumPacketSize();
- void setMaximumPacketSize();
- void setMaximumPacketSize_data();
void send();
- void send_data();
void packetsAvailable();
void packetsAvailable_data();
- void clear();
void read();
- void device();
-
- void tst_QPacket_clear();
};
void tst_QPacketProtocol::init()
@@ -95,65 +88,26 @@ void tst_QPacketProtocol::cleanup()
delete m_server;
}
-void tst_QPacketProtocol::maximumPacketSize()
-{
- QPacketProtocol p(m_client);
- QCOMPARE(p.maximumPacketSize(), 0x7FFFFFFF);
-}
-
-void tst_QPacketProtocol::setMaximumPacketSize()
-{
- QFETCH(qint32, size);
- QFETCH(qint32, expected);
-
- QPacketProtocol out(m_serverConn);
- QCOMPARE(out.setMaximumPacketSize(size), expected);
-}
-
-void tst_QPacketProtocol::setMaximumPacketSize_data()
-{
- QTest::addColumn<int>("size");
- QTest::addColumn<int>("expected");
-
- QTest::newRow("invalid") << qint32(sizeof(qint32) - 1) << qint32(0x7FFFFFFF);
- QTest::newRow("still invalid") << qint32(sizeof(qint32)) << qint32(0x7FFFFFFF);
- QTest::newRow("valid") << qint32(sizeof(qint32) + 1) << qint32(sizeof(qint32) + 1);
-}
-
void tst_QPacketProtocol::send()
{
- QFETCH(bool, useAutoSend);
-
QPacketProtocol in(m_client);
QPacketProtocol out(m_serverConn);
QByteArray ba;
int num;
- if (useAutoSend) {
- out.send() << "Hello world" << 123;
- } else {
- QPacket packet;
- packet << "Hello world" << 123;
- out.send(packet);
- }
+ QPacket packet(QDataStream::Qt_DefaultCompiledVersion);
+ packet << "Hello world" << 123;
+ out.send(packet.data());
QVERIFY(QQmlDebugTest::waitForSignal(&in, SIGNAL(readyRead())));
- QPacket p = in.read();
+ QPacket p(QDataStream::Qt_DefaultCompiledVersion, in.read());
p >> ba >> num;
QCOMPARE(ba, QByteArray("Hello world") + '\0');
QCOMPARE(num, 123);
}
-void tst_QPacketProtocol::send_data()
-{
- QTest::addColumn<bool>("useAutoSend");
-
- QTest::newRow("auto send") << true;
- QTest::newRow("no auto send") << false;
-}
-
void tst_QPacketProtocol::packetsAvailable()
{
QFETCH(int, packetCount);
@@ -164,8 +118,11 @@ void tst_QPacketProtocol::packetsAvailable()
QCOMPARE(out.packetsAvailable(), qint64(0));
QCOMPARE(in.packetsAvailable(), qint64(0));
- for (int i=0; i<packetCount; i++)
- out.send() << "Hello";
+ for (int i=0; i<packetCount; i++) {
+ QPacket packet(QDataStream::Qt_DefaultCompiledVersion);
+ packet << "Hello";
+ out.send(packet.data());
+ }
QVERIFY(QQmlDebugTest::waitForSignal(&in, SIGNAL(readyRead())));
QCOMPARE(in.packetsAvailable(), qint64(packetCount));
@@ -180,19 +137,6 @@ void tst_QPacketProtocol::packetsAvailable_data()
QTest::newRow("10") << 10;
}
-void tst_QPacketProtocol::clear()
-{
- QPacketProtocol in(m_client);
- QPacketProtocol out(m_serverConn);
-
- out.send() << 123;
- out.send() << 456;
- QVERIFY(QQmlDebugTest::waitForSignal(&in, SIGNAL(readyRead())));
-
- in.clear();
- QVERIFY(in.read().isEmpty());
-}
-
void tst_QPacketProtocol::read()
{
QPacketProtocol in(m_client);
@@ -200,61 +144,30 @@ void tst_QPacketProtocol::read()
QVERIFY(in.read().isEmpty());
- out.send() << 123;
- out.send() << 456;
+ QPacket packet(QDataStream::Qt_DefaultCompiledVersion);
+ packet << 123;
+ out.send(packet.data());
+
+ QPacket packet2(QDataStream::Qt_DefaultCompiledVersion);
+ packet2 << 456;
+ out.send(packet2.data());
QVERIFY(QQmlDebugTest::waitForSignal(&in, SIGNAL(readyRead())));
int num;
- QPacket p1 = in.read();
- QVERIFY(!p1.isEmpty());
+ QPacket p1(QDataStream::Qt_DefaultCompiledVersion, in.read());
+ QVERIFY(!p1.atEnd());
p1 >> num;
QCOMPARE(num, 123);
- QPacket p2 = in.read();
- QVERIFY(!p2.isEmpty());
+ QPacket p2(QDataStream::Qt_DefaultCompiledVersion, in.read());
+ QVERIFY(!p2.atEnd());
p2 >> num;
QCOMPARE(num, 456);
QVERIFY(in.read().isEmpty());
}
-void tst_QPacketProtocol::device()
-{
- QPacketProtocol p(m_client);
- QCOMPARE(p.device(), m_client);
-}
-
-void tst_QPacketProtocol::tst_QPacket_clear()
-{
- QPacketProtocol protocol(m_client);
-
- QPacket packet;
-
- packet << "Hello world!" << 123;
- protocol.send(packet);
-
- packet.clear();
- QVERIFY(packet.isEmpty());
- packet << "Goodbyte world!" << 789;
- protocol.send(packet);
-
- QByteArray ba;
- int num;
- QPacketProtocol in(m_serverConn);
- QVERIFY(QQmlDebugTest::waitForSignal(&in, SIGNAL(readyRead())));
-
- QPacket p1 = in.read();
- p1 >> ba >> num;
- QCOMPARE(ba, QByteArray("Hello world!") + '\0');
- QCOMPARE(num, 123);
-
- QPacket p2 = in.read();
- p2 >> ba >> num;
- QCOMPARE(ba, QByteArray("Goodbyte world!") + '\0');
- QCOMPARE(num, 789);
-}
-
QTEST_MAIN(tst_QPacketProtocol)
#include "tst_qpacketprotocol.moc"
diff --git a/tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro b/tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro
index ad431d4871..622b373692 100644
--- a/tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro
+++ b/tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro
@@ -1,6 +1,6 @@
CONFIG += testcase
TARGET = tst_qqmldebugclient
-macx:CONFIG -= app_bundle
+osx:CONFIG -= app_bundle
HEADERS += ../shared/qqmldebugtestservice.h
@@ -15,4 +15,3 @@ DEFINES += QT_QML_DEBUG_NO_WARNING
CONFIG += qml_debug
QT += qml-private testlib gui-private core-private
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp b/tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp
index 6fc6c6a914..1bf03dbdee 100644
--- a/tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp
+++ b/tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp
@@ -30,19 +30,20 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#include <qtest.h>
-#include <QSignalSpy>
-#include <QTimer>
-#include <QHostAddress>
-#include <QDebug>
-#include <QThread>
-
-#include <QtQml/qqmlengine.h>
#include "debugutil_p.h"
#include "qqmldebugtestservice.h"
#include <private/qqmldebugconnector_p.h>
+#include <private/qqmldebugconnection_p.h>
+
+#include <QtTest/qtest.h>
+#include <QtTest/qsignalspy.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qthread.h>
+#include <QtNetwork/qhostaddress.h>
+#include <QtQml/qqmlengine.h>
#define PORT 13770
#define STR_PORT "13770"
@@ -68,10 +69,20 @@ private slots:
void tst_QQmlDebugClient::initTestCase()
{
QQmlDebugConnector::setPluginKey(QLatin1String("QQmlDebugServer"));
+ QQmlDebugConnector::setServices(QStringList()
+ << QStringLiteral("tst_QQmlDebugClient::handshake()"));
QTest::ignoreMessage(QtWarningMsg,
"QML debugger: Cannot set plugin key after loading the plugin.");
m_service = new QQmlDebugTestService("tst_QQmlDebugClient::handshake()");
+
+ foreach (const QString &service, QQmlDebuggingEnabler::debuggerServices())
+ QCOMPARE(QQmlDebugConnector::instance()->service(service), (QQmlDebugService *)0);
+ foreach (const QString &service, QQmlDebuggingEnabler::inspectorServices())
+ QCOMPARE(QQmlDebugConnector::instance()->service(service), (QQmlDebugService *)0);
+ foreach (const QString &service, QQmlDebuggingEnabler::profilerServices())
+ QCOMPARE(QQmlDebugConnector::instance()->service(service), (QQmlDebugService *)0);
+
const QString waitingMsg = QString("QML Debugger: Waiting for connection on port %1...").arg(PORT);
QTest::ignoreMessage(QtDebugMsg, waitingMsg.toLatin1().constData());
QQmlDebuggingEnabler::startTcpDebugServer(PORT);
@@ -144,7 +155,9 @@ void tst_QQmlDebugClient::parallelConnect()
QTest::ignoreMessage(QtWarningMsg, "QML Debugger: Another client is already connected.");
// will connect & immediately disconnect
connection2.connectToHost("127.0.0.1", PORT);
- QTRY_COMPARE(connection2.state(), QAbstractSocket::UnconnectedState);
+ QTest::ignoreMessage(QtWarningMsg, "QQmlDebugConnection: Did not get handshake answer in time");
+ QVERIFY(!connection2.waitForConnected(1000));
+ QVERIFY(!connection2.isConnected());
QVERIFY(m_conn->isConnected());
}
@@ -155,7 +168,6 @@ void tst_QQmlDebugClient::sequentialConnect()
m_conn->close();
QVERIFY(!m_conn->isConnected());
- QCOMPARE(m_conn->state(), QAbstractSocket::UnconnectedState);
// Make sure that the disconnect is actually delivered to the server
QTest::qWait(100);
diff --git a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp
index 98ef590317..27a64842e9 100644
--- a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp
+++ b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp
@@ -31,18 +31,20 @@
**
****************************************************************************/
-#include <qtest.h>
-#include <QtCore/QProcess>
-#include <QtCore/QTimer>
-#include <QtCore/QFileInfo>
-#include <QtCore/QDir>
-#include <QtCore/QMutex>
-#include <QtCore/QLibraryInfo>
-
#include "debugutil_p.h"
-#include "qqmldebugclient.h"
#include "../../../shared/util.h"
+#include <private/qqmldebugclient_p.h>
+#include <private/qqmldebugconnection_p.h>
+
+#include <QtTest/qtest.h>
+#include <QtCore/qprocess.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qfileinfo.h>
+#include <QtCore/qdir.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qlibraryinfo.h>
+
class tst_QQmlDebuggingEnabler : public QQmlDataTest
{
Q_OBJECT
@@ -53,13 +55,14 @@ private slots:
void initTestCase();
void cleanupTestCase();
void cleanup();
- void qmlscene();
- void qmlsceneBlock();
+ void qmlscene_data();
+ void qmlscene();
+ void custom_data();
void custom();
- void customBlock();
private:
+ void data();
QQmlDebugProcess *process;
QQmlDebugConnection *connection;
QTime t;
@@ -142,24 +145,92 @@ void tst_QQmlDebuggingEnabler::cleanup()
connection = 0;
}
-void tst_QQmlDebuggingEnabler::qmlscene()
+void tst_QQmlDebuggingEnabler::data()
{
- QVERIFY(init(false, true, 5555, 5565));
+ QTest::addColumn<bool>("blockMode");
+ QTest::addColumn<QStringList>("services");
+
+ QTest::newRow("noblock,all") << false << QStringList();
+ QTest::newRow("block,all") << true << QStringList();
+ QTest::newRow("noblock,debugger") << false << QQmlDebuggingEnabler::debuggerServices();
+ QTest::newRow("block,debugger") << true << QQmlDebuggingEnabler::debuggerServices();
+ QTest::newRow("noblock,inspector") << false << QQmlDebuggingEnabler::inspectorServices();
+ QTest::newRow("block,inspector") << true << QQmlDebuggingEnabler::inspectorServices();
+ QTest::newRow("noblock,profiler") << false << QQmlDebuggingEnabler::profilerServices();
+ QTest::newRow("block,profiler") << true << QQmlDebuggingEnabler::profilerServices();
+ QTest::newRow("noblock,debugger+inspector")
+ << false << QQmlDebuggingEnabler::debuggerServices() +
+ QQmlDebuggingEnabler::inspectorServices();
+ QTest::newRow("block,debugger+inspector")
+ << true << QQmlDebuggingEnabler::debuggerServices() +
+ QQmlDebuggingEnabler::inspectorServices();
+
}
-void tst_QQmlDebuggingEnabler::qmlsceneBlock()
+void tst_QQmlDebuggingEnabler::qmlscene_data()
{
- QVERIFY(init(true, true, 5555, 5565));
+ data();
}
-void tst_QQmlDebuggingEnabler::custom()
+void tst_QQmlDebuggingEnabler::qmlscene()
{
- QVERIFY(init(false, false, 5555, 5565));
+ QFETCH(bool, blockMode);
+ QFETCH(QStringList, services);
+
+ connection = new QQmlDebugConnection();
+ QList<QQmlDebugClient *> clients = QQmlDebugTest::createOtherClients(connection);
+ process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene",
+ this);
+ process->setMaximumBindErrors(1);
+ process->start(QStringList()
+ << QString::fromLatin1("-qmljsdebugger=port:5555,5565%1%2%3")
+ .arg(blockMode ? QLatin1String(",block") : QString())
+ .arg(services.isEmpty() ? QString() : QString::fromLatin1(",services:"))
+ .arg(services.isEmpty() ? QString() : services.join(","))
+ << testFile(QLatin1String("test.qml")));
+
+ QVERIFY(process->waitForSessionStart());
+ connection->connectToHost("127.0.0.1", process->debugPort());
+ QVERIFY(connection->waitForConnected());
+ foreach (QQmlDebugClient *client, clients)
+ QCOMPARE(client->state(), (services.isEmpty() || services.contains(client->name())) ?
+ QQmlDebugClient::Enabled : QQmlDebugClient::Unavailable);
+}
+
+void tst_QQmlDebuggingEnabler::custom_data()
+{
+ data();
}
-void tst_QQmlDebuggingEnabler::customBlock()
+void tst_QQmlDebuggingEnabler::custom()
{
- QVERIFY(init(true, false, 5555, 5565));
+ QFETCH(bool, blockMode);
+ QFETCH(QStringList, services);
+ const int portFrom = 5555;
+ const int portTo = 5565;
+
+ connection = new QQmlDebugConnection();
+ QList<QQmlDebugClient *> clients = QQmlDebugTest::createOtherClients(connection);
+ process = new QQmlDebugProcess(QCoreApplication::applicationDirPath() +
+ QLatin1String("/qqmldebuggingenablerserver"), this);
+ process->setMaximumBindErrors(portTo - portFrom);
+
+ QStringList args;
+ if (blockMode)
+ args << QLatin1String("-block");
+
+ args << QString::number(portFrom) << QString::number(portTo);
+ if (!services.isEmpty())
+ args << QLatin1String("-services") << services;
+
+ process->start(args);
+
+ QVERIFY(process->waitForSessionStart());
+ connection->connectToHost("127.0.0.1", process->debugPort());
+ QVERIFY(connection->waitForConnected());
+ foreach (QQmlDebugClient *client, clients)
+ QCOMPARE(client->state(), (services.isEmpty() || services.contains(client->name())) ?
+ QQmlDebugClient::Enabled : QQmlDebugClient::Unavailable);
}
QTEST_MAIN(tst_QQmlDebuggingEnabler)
diff --git a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenablerserver/qqmldebuggingenablerserver.cpp b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenablerserver/qqmldebuggingenablerserver.cpp
index bddece6452..f4fef7ff16 100644
--- a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenablerserver/qqmldebuggingenablerserver.cpp
+++ b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenablerserver/qqmldebuggingenablerserver.cpp
@@ -31,8 +31,10 @@
**
****************************************************************************/
-#include "debugutil_p.h"
-#include <QtCore/QCoreApplication>
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qlibraryinfo.h>
+#include <QtQml/qqmldebug.h>
+#include <QtQml/qqmlengine.h>
int main(int argc, char *argv[])
{
@@ -54,6 +56,9 @@ int main(int argc, char *argv[])
portTo = arguments.takeFirst().toInt();
}
+ if (arguments.size() && arguments.takeFirst() == QLatin1String("-services"))
+ QQmlDebuggingEnabler::setServices(arguments);
+
if (!portFrom || !portTo)
qFatal("Port range has to be specified.");
diff --git a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenablerserver/qqmldebuggingenablerserver.pro b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenablerserver/qqmldebuggingenablerserver.pro
index fdd9ce8f11..a40ff6978b 100644
--- a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenablerserver/qqmldebuggingenablerserver.pro
+++ b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenablerserver/qqmldebuggingenablerserver.pro
@@ -3,7 +3,7 @@ osx:CONFIG -= app_bundle
CONFIG -= debug_and_release_target
INCLUDEPATH += ../../shared
SOURCES += qqmldebuggingenablerserver.cpp
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 QT_QML_DEBUG_NO_WARNING
+DEFINES += QT_QML_DEBUG_NO_WARNING
DESTDIR = ../qqmldebuggingenabler
diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro
index fb06df9c99..bd6debcea1 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro
+++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro
@@ -1,24 +1,4 @@
-CONFIG += testcase
-TARGET = tst_qqmldebugjs
-QT += qml testlib gui-private core-private
-macx:CONFIG -= app_bundle
+TEMPLATE = subdirs
+SUBDIRS = qqmldebugjs qqmldebugjsserver
-SOURCES += tst_qqmldebugjs.cpp
-
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
-include(../shared/debugutil.pri)
-
-TESTDATA = data/*
-
-OTHER_FILES += data/test.qml data/test.js \
- data/timer.qml \
- data/exception.qml \
- data/oncompleted.qml \
- data/loadjsfile.qml \
- data/condition.qml \
- data/changeBreakpoint.qml \
- data/stepAction.qml \
- data/breakpointRelocation.qml \
- data/createComponent.qml
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
+qqmldebugjs.depends = qqmldebugjsserver
diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/breakpointRelocation.qml b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/breakpointRelocation.qml
index 55663b7983..55663b7983 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/data/breakpointRelocation.qml
+++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/breakpointRelocation.qml
diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/changeBreakpoint.qml b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/changeBreakpoint.qml
index 1bd9191334..1bd9191334 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/data/changeBreakpoint.qml
+++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/changeBreakpoint.qml
diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/condition.qml b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/condition.qml
index 2f9b3aceb2..2f9b3aceb2 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/data/condition.qml
+++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/condition.qml
diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/createComponent.qml b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/createComponent.qml
index 53b1f52745..53b1f52745 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/data/createComponent.qml
+++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/createComponent.qml
diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/exception.qml b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/exception.qml
index d0fa4e715c..d0fa4e715c 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/data/exception.qml
+++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/exception.qml
diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/loadjsfile.qml b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/loadjsfile.qml
index 9fc75d251f..9fc75d251f 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/data/loadjsfile.qml
+++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/loadjsfile.qml
diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/oncompleted.qml b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/oncompleted.qml
index 6f32af39ad..6f32af39ad 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/data/oncompleted.qml
+++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/oncompleted.qml
diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/quit.qml b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/quit.qml
index b858fdf942..b858fdf942 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/data/quit.qml
+++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/quit.qml
diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/stepAction.qml b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/stepAction.qml
index b9ee1380aa..b9ee1380aa 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/data/stepAction.qml
+++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/stepAction.qml
diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/test.js b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/test.js
index ca25e9baf7..ca25e9baf7 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/data/test.js
+++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/test.js
diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/test.qml b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/test.qml
index 5a7fa718f2..5a7fa718f2 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/data/test.qml
+++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/test.qml
diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/timer.qml b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/timer.qml
index 1fee24a1fa..1fee24a1fa 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/data/timer.qml
+++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/timer.qml
diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro
new file mode 100644
index 0000000000..79e772c1ee
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro
@@ -0,0 +1,24 @@
+CONFIG += testcase
+TARGET = tst_qqmldebugjs
+QT += qml testlib gui-private core-private
+CONFIG -= debug_and_release_target
+osx:CONFIG -= app_bundle
+
+SOURCES += tst_qqmldebugjs.cpp
+
+INCLUDEPATH += ../../shared
+include(../../../../shared/util.pri)
+include(../../shared/debugutil.pri)
+
+TESTDATA = data/*
+
+OTHER_FILES += data/test.qml data/test.js \
+ data/timer.qml \
+ data/exception.qml \
+ data/oncompleted.qml \
+ data/loadjsfile.qml \
+ data/condition.qml \
+ data/changeBreakpoint.qml \
+ data/stepAction.qml \
+ data/breakpointRelocation.qml \
+ data/createComponent.qml
diff --git a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp
index 7dbe35807d..e0451466ef 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp
+++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp
@@ -31,19 +31,22 @@
**
****************************************************************************/
-#include <qtest.h>
-#include <QtCore/QProcess>
-#include <QtCore/QTimer>
-#include <QtCore/QFileInfo>
-#include <QtCore/QDir>
-#include <QtCore/QMutex>
-#include <QtCore/QLibraryInfo>
-#include <QtQml/QJSEngine>
-
//QQmlDebugTest
#include "debugutil_p.h"
-#include "qqmldebugclient.h"
-#include "../../../shared/util.h"
+#include "../../../../shared/util.h"
+
+#include <private/qqmldebugclient_p.h>
+#include <private/qqmldebugconnection_p.h>
+#include <private/qpacket_p.h>
+
+#include <QtTest/qtest.h>
+#include <QtCore/qprocess.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qfileinfo.h>
+#include <QtCore/qdir.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qlibraryinfo.h>
+#include <QtQml/qjsengine.h>
#if defined (Q_OS_WINCE)
#undef IN
@@ -159,7 +162,7 @@ class tst_QQmlDebugJS : public QQmlDataTest
{
Q_OBJECT
- void init(const QString &qmlFile = QString(TEST_QMLFILE), bool blockMode = true,
+ void init(bool qmlscene, const QString &qmlFile = QString(TEST_QMLFILE), bool blockMode = true,
bool restrictServices = false);
private slots:
@@ -170,43 +173,65 @@ private slots:
void connect_data();
void connect();
+ void interrupt_data() { targetData(); }
void interrupt();
+ void getVersion_data() { targetData(); }
void getVersion();
// void getVersionWhenAttaching();
+ void disconnect_data() { targetData(); }
void disconnect();
+ void setBreakpointInScriptOnCompleted_data() { targetData(); }
void setBreakpointInScriptOnCompleted();
+ void setBreakpointInScriptOnComponentCreated_data() { targetData(); }
void setBreakpointInScriptOnComponentCreated();
+ void setBreakpointInScriptOnTimerCallback_data() { targetData(); }
void setBreakpointInScriptOnTimerCallback();
+ void setBreakpointInScriptInDifferentFile_data() { targetData(); }
void setBreakpointInScriptInDifferentFile();
+ void setBreakpointInScriptOnComment_data() { targetData(); }
void setBreakpointInScriptOnComment();
+ void setBreakpointInScriptOnEmptyLine_data() { targetData(); }
void setBreakpointInScriptOnEmptyLine();
+ void setBreakpointInScriptOnOptimizedBinding_data() { targetData(); }
void setBreakpointInScriptOnOptimizedBinding();
+ void setBreakpointInScriptWithCondition_data() { targetData(); }
void setBreakpointInScriptWithCondition();
+ void setBreakpointInScriptThatQuits_data() { targetData(); }
void setBreakpointInScriptThatQuits();
//void setBreakpointInFunction(); //NOT SUPPORTED
// void setBreakpointOnEvent();
// void setBreakpointWhenAttaching();
+ void clearBreakpoint_data() { targetData(); }
void clearBreakpoint();
+ void setExceptionBreak_data() { targetData(); }
void setExceptionBreak();
+ void stepNext_data() { targetData(); }
void stepNext();
+ void stepIn_data() { targetData(); }
void stepIn();
+ void stepOut_data() { targetData(); }
void stepOut();
+ void continueDebugging_data() { targetData(); }
void continueDebugging();
+ void backtrace_data() { targetData(); }
void backtrace();
+ void getFrameDetails_data() { targetData(); }
void getFrameDetails();
+ void getScopeDetails_data() { targetData(); }
void getScopeDetails();
// void evaluateInGlobalScope(); // Not supported yet.
// void evaluateInLocalScope(); // Not supported yet.
+ void getScripts_data() { targetData(); }
void getScripts();
// void profile(); //NOT SUPPORTED
@@ -214,6 +239,8 @@ private slots:
// void verifyQMLOptimizerDisabled();
private:
+ void targetData();
+
QQmlDebugProcess *process;
QJSDebugClient *client;
QQmlDebugConnection *connection;
@@ -557,11 +584,9 @@ void QJSDebugClient::setBreakpoint(QString type, QString target, int line, int c
// }
if (type == QLatin1String(EVENT)) {
- QByteArray reply;
- QDataStream rs(&reply, QIODevice::WriteOnly);
+ QPacket rs(connection()->currentDataStreamVersion());
rs << target.toUtf8() << enabled;
- sendMessage(packMessage(QByteArray("breakonsignal"), reply));
-
+ sendMessage(packMessage(QByteArray("breakonsignal"), rs.data()));
} else {
VARIANTMAPINIT;
jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SETBREAKPOINT)));
@@ -709,7 +734,7 @@ void QJSDebugClient::stateChanged(State state)
void QJSDebugClient::messageReceived(const QByteArray &data)
{
- QDataStream ds(data);
+ QPacket ds(connection()->currentDataStreamVersion(), data);
QByteArray command;
ds >> command;
@@ -794,11 +819,10 @@ void QJSDebugClient::flushSendBuffer()
QByteArray QJSDebugClient::packMessage(const QByteArray &type, const QByteArray &message)
{
- QByteArray reply;
- QDataStream rs(&reply, QIODevice::WriteOnly);
+ QPacket rs(connection()->currentDataStreamVersion());
QByteArray cmd = "V8DEBUG";
rs << cmd << type << message;
- return reply;
+ return rs.data();
}
void tst_QQmlDebugJS::initTestCase()
@@ -826,11 +850,18 @@ void tst_QQmlDebugJS::cleanupTestCase()
// qDebug() << "Time Elapsed:" << t.elapsed();
}
-void tst_QQmlDebugJS::init(const QString &qmlFile, bool blockMode, bool restrictServices)
+void tst_QQmlDebugJS::init(bool qmlscene, const QString &qmlFile, bool blockMode,
+ bool restrictServices)
{
connection = new QQmlDebugConnection();
- process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this);
+ if (qmlscene)
+ process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) +
+ "/qmlscene", this);
+ else
+ process = new QQmlDebugProcess(QCoreApplication::applicationDirPath() +
+ QLatin1String("/qqmldebugjsserver"), this);
client = new QJSDebugClient(connection);
+ QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(connection);
const char *args = 0;
if (blockMode)
@@ -849,6 +880,11 @@ void tst_QQmlDebugJS::init(const QString &qmlFile, bool blockMode, bool restrict
if (client->state() != QQmlDebugClient::Enabled)
QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(enabled())));
+
+ foreach (QQmlDebugClient *otherClient, others)
+ QCOMPARE(otherClient->state(), restrictServices ? QQmlDebugClient::Unavailable :
+ QQmlDebugClient::Enabled);
+ qDeleteAll(others);
}
void tst_QQmlDebugJS::cleanup()
@@ -878,17 +914,23 @@ void tst_QQmlDebugJS::connect_data()
{
QTest::addColumn<bool>("blockMode");
QTest::addColumn<bool>("restrictMode");
- QTest::newRow("normal/unrestricted") << false << false;
- QTest::newRow("block/unrestricted") << true << false;
- QTest::newRow("normal/restricted") << false << true;
- QTest::newRow("block/restricted") << true << true;
+ QTest::addColumn<bool>("qmlscene");
+ QTest::newRow("normal / unrestricted / custom") << false << false << false;
+ QTest::newRow("block / unrestricted / custom") << true << false << false;
+ QTest::newRow("normal / restricted / custom") << false << true << false;
+ QTest::newRow("block / restricted / custom") << true << true << false;
+ QTest::newRow("normal / unrestricted / qmlscene") << false << false << true;
+ QTest::newRow("block / unrestricted / qmlscene") << true << false << true;
+ QTest::newRow("normal / restricted / qmlscene") << false << true << true;
+ QTest::newRow("block / restricted / qmlscene") << true << true << true;
}
void tst_QQmlDebugJS::connect()
{
QFETCH(bool, blockMode);
QFETCH(bool, restrictMode);
- init(QString(TEST_QMLFILE), blockMode, restrictMode);
+ QFETCH(bool, qmlscene);
+ init(qmlscene, QString(TEST_QMLFILE), blockMode, restrictMode);
client->connect();
QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(connected())));
}
@@ -897,7 +939,8 @@ void tst_QQmlDebugJS::interrupt()
{
//void connect()
- init();
+ QFETCH(bool, qmlscene);
+ init(qmlscene);
client->connect();
client->interrupt();
@@ -908,7 +951,8 @@ void tst_QQmlDebugJS::getVersion()
{
//void version()
- init();
+ QFETCH(bool, qmlscene);
+ init(qmlscene);
client->connect();
QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(connected())));
@@ -933,7 +977,8 @@ void tst_QQmlDebugJS::disconnect()
{
//void disconnect()
- init();
+ QFETCH(bool, qmlscene);
+ init(qmlscene);
client->connect();
client->disconnect();
@@ -943,9 +988,10 @@ void tst_QQmlDebugJS::disconnect()
void tst_QQmlDebugJS::setBreakpointInScriptOnCompleted()
{
//void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
+ QFETCH(bool, qmlscene);
int sourceLine = 39;
- init(ONCOMPLETED_QMLFILE);
+ init(qmlscene, ONCOMPLETED_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
client->connect();
@@ -963,9 +1009,10 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnCompleted()
void tst_QQmlDebugJS::setBreakpointInScriptOnComponentCreated()
{
//void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
+ QFETCH(bool, qmlscene);
int sourceLine = 39;
- init(CREATECOMPONENT_QMLFILE);
+ init(qmlscene, CREATECOMPONENT_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
client->connect();
@@ -982,8 +1029,9 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnComponentCreated()
void tst_QQmlDebugJS::setBreakpointInScriptOnTimerCallback()
{
+ QFETCH(bool, qmlscene);
int sourceLine = 40;
- init(TIMER_QMLFILE);
+ init(qmlscene, TIMER_QMLFILE);
client->connect();
//We can set the breakpoint after connect() here because the timer is repeating and if we miss
@@ -1003,9 +1051,10 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnTimerCallback()
void tst_QQmlDebugJS::setBreakpointInScriptInDifferentFile()
{
//void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
+ QFETCH(bool, qmlscene);
int sourceLine = 35;
- init(LOADJSFILE_QMLFILE);
+ init(qmlscene, LOADJSFILE_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TEST_JSFILE), sourceLine, -1, true);
client->connect();
@@ -1023,10 +1072,11 @@ void tst_QQmlDebugJS::setBreakpointInScriptInDifferentFile()
void tst_QQmlDebugJS::setBreakpointInScriptOnComment()
{
//void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
+ QFETCH(bool, qmlscene);
int sourceLine = 39;
int actualLine = 41;
- init(BREAKPOINTRELOCATION_QMLFILE);
+ init(qmlscene, BREAKPOINTRELOCATION_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
client->connect();
@@ -1045,10 +1095,11 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnComment()
void tst_QQmlDebugJS::setBreakpointInScriptOnEmptyLine()
{
//void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
+ QFETCH(bool, qmlscene);
int sourceLine = 40;
int actualLine = 41;
- init(BREAKPOINTRELOCATION_QMLFILE);
+ init(qmlscene, BREAKPOINTRELOCATION_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
client->connect();
@@ -1067,9 +1118,10 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnEmptyLine()
void tst_QQmlDebugJS::setBreakpointInScriptOnOptimizedBinding()
{
//void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
+ QFETCH(bool, qmlscene);
int sourceLine = 44;
- init(BREAKPOINTRELOCATION_QMLFILE);
+ init(qmlscene, BREAKPOINTRELOCATION_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
client->connect();
@@ -1086,9 +1138,10 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnOptimizedBinding()
void tst_QQmlDebugJS::setBreakpointInScriptWithCondition()
{
+ QFETCH(bool, qmlscene);
int out = 10;
int sourceLine = 42;
- init(CONDITION_QMLFILE);
+ init(qmlscene, CONDITION_QMLFILE);
client->connect();
//The breakpoint is in a timer loop so we can set it after connect().
@@ -1122,7 +1175,8 @@ void tst_QQmlDebugJS::setBreakpointInScriptWithCondition()
void tst_QQmlDebugJS::setBreakpointInScriptThatQuits()
{
- init(QUIT_QMLFILE);
+ QFETCH(bool, qmlscene);
+ init(qmlscene, QUIT_QMLFILE);
int sourceLine = 41;
@@ -1181,10 +1235,11 @@ void tst_QQmlDebugJS::setBreakpointOnEvent()
void tst_QQmlDebugJS::clearBreakpoint()
{
//void clearBreakpoint(int breakpoint);
+ QFETCH(bool, qmlscene);
int sourceLine1 = 42;
int sourceLine2 = 43;
- init(CHANGEBREAKPOINT_QMLFILE);
+ init(qmlscene, CHANGEBREAKPOINT_QMLFILE);
client->connect();
//The breakpoints are in a timer loop so we can set them after connect().
@@ -1228,8 +1283,9 @@ void tst_QQmlDebugJS::clearBreakpoint()
void tst_QQmlDebugJS::setExceptionBreak()
{
//void setExceptionBreak(QString type, bool enabled = false);
+ QFETCH(bool, qmlscene);
- init(EXCEPTION_QMLFILE);
+ init(qmlscene, EXCEPTION_QMLFILE);
client->setExceptionBreak(QJSDebugClient::All,true);
client->connect();
QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
@@ -1238,9 +1294,10 @@ void tst_QQmlDebugJS::setExceptionBreak()
void tst_QQmlDebugJS::stepNext()
{
//void continueDebugging(StepAction stepAction, int stepCount = 1);
+ QFETCH(bool, qmlscene);
int sourceLine = 42;
- init(STEPACTION_QMLFILE);
+ init(qmlscene, STEPACTION_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
client->connect();
@@ -1261,10 +1318,11 @@ void tst_QQmlDebugJS::stepNext()
void tst_QQmlDebugJS::stepIn()
{
//void continueDebugging(StepAction stepAction, int stepCount = 1);
+ QFETCH(bool, qmlscene);
int sourceLine = 46;
int actualLine = 42;
- init(STEPACTION_QMLFILE);
+ init(qmlscene, STEPACTION_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, 1, true);
client->connect();
@@ -1285,10 +1343,11 @@ void tst_QQmlDebugJS::stepIn()
void tst_QQmlDebugJS::stepOut()
{
//void continueDebugging(StepAction stepAction, int stepCount = 1);
+ QFETCH(bool, qmlscene);
int sourceLine = 42;
int actualLine = 46;
- init(STEPACTION_QMLFILE);
+ init(qmlscene, STEPACTION_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
client->connect();
@@ -1309,10 +1368,11 @@ void tst_QQmlDebugJS::stepOut()
void tst_QQmlDebugJS::continueDebugging()
{
//void continueDebugging(StepAction stepAction, int stepCount = 1);
+ QFETCH(bool, qmlscene);
int sourceLine1 = 46;
int sourceLine2 = 43;
- init(STEPACTION_QMLFILE);
+ init(qmlscene, STEPACTION_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine1, -1, true);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine2, -1, true);
@@ -1334,9 +1394,10 @@ void tst_QQmlDebugJS::continueDebugging()
void tst_QQmlDebugJS::backtrace()
{
//void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false);
+ QFETCH(bool, qmlscene);
int sourceLine = 39;
- init(ONCOMPLETED_QMLFILE);
+ init(qmlscene, ONCOMPLETED_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
client->connect();
@@ -1349,9 +1410,10 @@ void tst_QQmlDebugJS::backtrace()
void tst_QQmlDebugJS::getFrameDetails()
{
//void frame(int number = -1);
+ QFETCH(bool, qmlscene);
int sourceLine = 39;
- init(ONCOMPLETED_QMLFILE);
+ init(qmlscene, ONCOMPLETED_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
client->connect();
@@ -1364,9 +1426,10 @@ void tst_QQmlDebugJS::getFrameDetails()
void tst_QQmlDebugJS::getScopeDetails()
{
//void scope(int number = -1, int frameNumber = -1);
+ QFETCH(bool, qmlscene);
int sourceLine = 39;
- init(ONCOMPLETED_QMLFILE);
+ init(qmlscene, ONCOMPLETED_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
client->connect();
@@ -1437,7 +1500,8 @@ void tst_QQmlDebugJS::getScripts()
{
//void scripts(int types = -1, QList<int> ids = QList<int>(), bool includeSource = false, QVariant filter = QVariant());
- init();
+ QFETCH(bool, qmlscene);
+ init(qmlscene);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QString(TEST_QMLFILE), 40, -1, true);
client->connect();
@@ -1455,6 +1519,13 @@ void tst_QQmlDebugJS::getScripts()
QVERIFY(scripts.first().toMap()[QStringLiteral("name")].toString().endsWith(QStringLiteral("data/test.qml")));
}
+void tst_QQmlDebugJS::targetData()
+{
+ QTest::addColumn<bool>("qmlscene");
+ QTest::newRow("custom") << false;
+ QTest::newRow("qmlscene") << true;
+}
+
QTEST_MAIN(tst_QQmlDebugJS)
#include "tst_qqmldebugjs.moc"
diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjsserver/qqmldebugjsserver.cpp b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjsserver/qqmldebugjsserver.cpp
new file mode 100644
index 0000000000..dd3416a78f
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjsserver/qqmldebugjsserver.cpp
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qguiapplication.h>
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlapplicationengine.h>
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+ QQmlEngine someWeirdEngine; // add another engine to cause some trouble
+
+ QQmlApplicationEngine engine;
+ engine.load(QUrl::fromLocalFile(QLatin1String(argv[argc - 1])));
+
+ return app.exec();
+}
+
diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjsserver/qqmldebugjsserver.pro b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjsserver/qqmldebugjsserver.pro
new file mode 100644
index 0000000000..837eaed9f1
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjsserver/qqmldebugjsserver.pro
@@ -0,0 +1,12 @@
+QT += qml testlib
+osx:CONFIG -= app_bundle
+CONFIG -= debug_and_release_target
+INCLUDEPATH += ../../shared
+SOURCES += qqmldebugjsserver.cpp
+DEFINES += QT_QML_DEBUG_NO_WARNING
+
+DESTDIR = ../qqmldebugjs
+
+target.path = $$[QT_INSTALL_TESTS]/tst_qqmldebugjs
+INSTALLS += target
+
diff --git a/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro b/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro
index b612da11de..860d39cca4 100644
--- a/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro
+++ b/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro
@@ -10,7 +10,6 @@ SOURCES += tst_qqmldebuglocal.cpp \
INCLUDEPATH += ../shared
include(../shared/debugutil.pri)
-CONFIG += parallel_test
QT += qml-private testlib gui-private core-private
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 QT_QML_DEBUG_NO_WARNING
+DEFINES += QT_QML_DEBUG_NO_WARNING
diff --git a/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp b/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp
index 0343ea77ee..083e6de09e 100644
--- a/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp
+++ b/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp
@@ -31,18 +31,20 @@
**
****************************************************************************/
-#include <qtest.h>
-#include <QSignalSpy>
-#include <QTimer>
-#include <QHostAddress>
-#include <QDebug>
-#include <QThread>
-#include <ctime>
-
-#include "debugutil_p.h"
#include "qqmldebugtestservice.h"
+#include "debugutil_p.h"
#include <private/qqmldebugconnector_p.h>
+#include <private/qqmldebugconnection_p.h>
+
+#include <QtTest/qtest.h>
+#include <QtTest/qsignalspy.h>
+#include <QtNetwork/qhostaddress.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qthread.h>
+
+#include <ctime>
QString fileName;
diff --git a/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro b/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro
index 573e58d3a6..79cbe52331 100644
--- a/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro
+++ b/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro
@@ -1,6 +1,6 @@
CONFIG += testcase
TARGET = tst_qqmldebugservice
-macx:CONFIG -= app_bundle
+osx:CONFIG -= app_bundle
HEADERS += ../shared/qqmldebugtestservice.h
@@ -19,4 +19,3 @@ OTHER_FILES += \
DEFINES += QT_QML_DEBUG_NO_WARNING
QT += qml-private testlib gui-private core-private
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp b/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp
index b63c5c0a6d..e2cdc89a56 100644
--- a/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp
+++ b/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp
@@ -30,22 +30,25 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#include <qtest.h>
-#include <QSignalSpy>
-#include <QTimer>
-#include <QHostAddress>
-#include <QDebug>
-#include <QThread>
-#include <QLibraryInfo>
-#include <QtQml/qqmlengine.h>
-#include "../../../shared/util.h"
-#include "debugutil_p.h"
-#include "qqmldebugclient.h"
#include "qqmldebugtestservice.h"
+#include "debugutil_p.h"
+#include "../../../shared/util.h"
+
+#include <private/qqmldebugclient_p.h>
+#include <private/qqmldebugconnection_p.h>
#include <private/qqmldebugconnector_p.h>
+#include <QtTest/qtest.h>
+#include <QtTest/qsignalspy.h>
+#include <QtNetwork/qhostaddress.h>
+#include <QtQml/qqmlengine.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qthread.h>
+#include <QtCore/qlibraryinfo.h>
+
#define PORT 3769
#define STR_PORT "3769"
@@ -74,10 +77,19 @@ void tst_QQmlDebugService::initTestCase()
{
QQmlDataTest::initTestCase();
QQmlDebugConnector::setPluginKey(QLatin1String("QQmlDebugServer"));
+ QQmlDebugConnector::setServices(QStringList()
+ << QStringLiteral("tst_QQmlDebugService"));
QTest::ignoreMessage(QtWarningMsg,
"QML debugger: Cannot set plugin key after loading the plugin.");
m_service = new QQmlDebugTestService("tst_QQmlDebugService", 2);
+ foreach (const QString &service, QQmlDebuggingEnabler::debuggerServices())
+ QCOMPARE(QQmlDebugConnector::instance()->service(service), (QQmlDebugService *)0);
+ foreach (const QString &service, QQmlDebuggingEnabler::inspectorServices())
+ QCOMPARE(QQmlDebugConnector::instance()->service(service), (QQmlDebugService *)0);
+ foreach (const QString &service, QQmlDebuggingEnabler::profilerServices())
+ QCOMPARE(QQmlDebugConnector::instance()->service(service), (QQmlDebugService *)0);
+
const QString waitingMsg = QString("QML Debugger: Waiting for connection on port %1...").arg(PORT);
QTest::ignoreMessage(QtDebugMsg, waitingMsg.toLatin1().constData());
QQmlDebuggingEnabler::startTcpDebugServer(PORT);
@@ -195,7 +207,7 @@ void tst_QQmlDebugService::checkSupportForDataStreamVersion()
client.sendMessage(msg);
QByteArray resp = client.waitForResponse();
QCOMPARE(resp, msg);
- QCOMPARE(m_conn->dataStreamVersion(), int(QDataStream::Qt_5_0));
+ QCOMPARE(m_conn->currentDataStreamVersion(), int(QDataStream::Qt_DefaultCompiledVersion));
}
void tst_QQmlDebugService::idForObject()
@@ -238,7 +250,7 @@ void tst_QQmlDebugService::checkSupportForOldDataStreamVersion()
//create a new connection;
delete m_conn;
m_conn = new QQmlDebugConnection(this);
- m_conn->setDataStreamVersion(QDataStream::Qt_4_7);
+ m_conn->setMaximumDataStreamVersion(QDataStream::Qt_5_0);
for (int i = 0; i < 50; ++i) {
// try for 5 seconds ...
m_conn->connectToHost("127.0.0.1", PORT);
@@ -258,7 +270,7 @@ void tst_QQmlDebugService::checkSupportForOldDataStreamVersion()
client.sendMessage(msg);
QByteArray resp = client.waitForResponse();
QCOMPARE(resp, msg);
- QCOMPARE(m_conn->dataStreamVersion(), int(QDataStream::Qt_4_7));
+ QCOMPARE(m_conn->currentDataStreamVersion(), int(QDataStream::Qt_5_0));
}
QTEST_MAIN(tst_QQmlDebugService)
diff --git a/tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro b/tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro
index 901dd229c0..2518650493 100644
--- a/tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro
+++ b/tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro
@@ -1,6 +1,6 @@
CONFIG += testcase
TARGET = tst_qqmlenginecontrol
-macx:CONFIG -= app_bundle
+osx:CONFIG -= app_bundle
SOURCES += tst_qqmlenginecontrol.cpp
@@ -11,7 +11,6 @@ include(../shared/debugutil.pri)
TESTDATA = data/*
QT += core qml testlib gui-private core-private
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
OTHER_FILES += \
data/test.qml \
diff --git a/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp b/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp
index 11fa56d710..fb4d46b8c8 100644
--- a/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp
+++ b/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp
@@ -31,60 +31,43 @@
**
****************************************************************************/
-#include <qtest.h>
-#include <QLibraryInfo>
-
#include "debugutil_p.h"
-#include "qqmldebugclient.h"
#include "../../../shared/util.h"
+#include <private/qqmldebugclient_p.h>
+#include <private/qqmldebugconnection_p.h>
+#include <private/qpacket_p.h>
+#include <private/qqmlenginecontrolclient_p.h>
+
+#include <QtTest/qtest.h>
+#include <QtCore/qlibraryinfo.h>
+
#define STR_PORT_FROM "13773"
#define STR_PORT_TO "13783"
-class QQmlEngineControlClient : public QQmlDebugClient
+class QQmlEngineBlocker : public QObject
{
Q_OBJECT
public:
- enum MessageType {
- EngineAboutToBeAdded,
- EngineAdded,
- EngineAboutToBeRemoved,
- EngineRemoved,
-
- MaximumMessageType
- };
-
- enum CommandType {
- StartWaitingEngine,
- StopWaitingEngine,
-
- MaximumCommandType
- };
-
- QQmlEngineControlClient(QQmlDebugConnection *connection)
- : QQmlDebugClient(QLatin1String("EngineControl"), connection)
- {}
-
-
- void command(CommandType command, int engine) {
- QByteArray message;
- QDataStream stream(&message, QIODevice::WriteOnly);
- stream << (int)command << engine;
- sendMessage(message);
- }
+ QQmlEngineBlocker(QQmlEngineControlClient *parent);
- QList<int> startingEngines;
- QList<int> stoppingEngines;
+public slots:
+ void blockEngine(int engineId, const QString &name);
+};
-signals:
- void engineAboutToBeAdded();
- void engineAdded();
- void engineAboutToBeRemoved();
- void engineRemoved();
+QQmlEngineBlocker::QQmlEngineBlocker(QQmlEngineControlClient *parent): QObject(parent)
+{
+ connect(parent, &QQmlEngineControlClient::engineAboutToBeAdded,
+ this, &QQmlEngineBlocker::blockEngine);
+ connect(parent, &QQmlEngineControlClient::engineAboutToBeRemoved,
+ this, &QQmlEngineBlocker::blockEngine);
+}
-protected:
- void messageReceived(const QByteArray &message);
-};
+void QQmlEngineBlocker::blockEngine(int engineId, const QString &name)
+{
+ Q_UNUSED(name);
+ static_cast<QQmlEngineControlClient *>(parent())->blockEngine(engineId);
+}
class tst_QQmlEngineControl : public QQmlDataTest
{
@@ -97,7 +80,6 @@ public:
, m_client(0)
{}
-
private:
QQmlDebugProcess *m_process;
QQmlDebugConnection *m_connection;
@@ -115,42 +97,6 @@ private slots:
void stopEngine();
};
-void QQmlEngineControlClient::messageReceived(const QByteArray &message)
-{
- QByteArray msg = message;
- QDataStream stream(&msg, QIODevice::ReadOnly);
-
- int messageType;
- int engineId;
- stream >> messageType >> engineId;
-
- switch (messageType) {
- case EngineAboutToBeAdded:
- startingEngines.append(engineId);
- emit engineAboutToBeAdded();
- break;
- case EngineAdded:
- QVERIFY(startingEngines.contains(engineId));
- startingEngines.removeOne(engineId);
- emit engineAdded();
- break;
- case EngineAboutToBeRemoved:
- stoppingEngines.append(engineId);
- emit engineAboutToBeRemoved();
- break;
- case EngineRemoved:
- QVERIFY(stoppingEngines.contains(engineId));
- stoppingEngines.removeOne(engineId);
- emit engineRemoved();
- break;
- default:
- QString failMsg = QString("Unknown message type:") + messageType;
- QFAIL(qPrintable(failMsg));
- break;
- }
- QVERIFY(stream.atEnd());
-}
-
void tst_QQmlEngineControl::connect(const QString &testFile, bool restrictServices)
{
const QString executable = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene";
@@ -167,11 +113,17 @@ void tst_QQmlEngineControl::connect(const QString &testFile, bool restrictServic
m_connection = new QQmlDebugConnection();
m_client = new QQmlEngineControlClient(m_connection);
+ new QQmlEngineBlocker(m_client);
+ QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_connection);
const int port = m_process->debugPort();
m_connection->connectToHost(QLatin1String("127.0.0.1"), port);
QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
+ foreach (QQmlDebugClient *other, others)
+ QCOMPARE(other->state(), restrictServices ? QQmlDebugClient::Unavailable :
+ QQmlDebugClient::Enabled);
+ qDeleteAll(others);
}
void tst_QQmlEngineControl::cleanup()
@@ -179,8 +131,8 @@ void tst_QQmlEngineControl::cleanup()
if (QTest::currentTestFailed()) {
qDebug() << "Process State:" << (m_process ? m_process->state() : QLatin1String("null"));
qDebug() << "Application Output:" << (m_process ? m_process->output() : QLatin1String("null"));
- qDebug() << "Connection State:" << (m_connection ? m_connection->stateString() : QLatin1String("null"));
- qDebug() << "Client State:" << (m_client ? m_client->stateString() : QLatin1String("null"));
+ qDebug() << "Connection State:" << QQmlDebugTest::connectionStateString(m_connection);
+ qDebug() << "Client State:" << QQmlDebugTest::clientStateString(m_client);
}
delete m_process;
m_process = 0;
@@ -208,10 +160,10 @@ void tst_QQmlEngineControl::startEngine()
connect("test.qml", restrictMode);
- QTRY_VERIFY(!m_client->startingEngines.empty());
- m_client->command(QQmlEngineControlClient::StartWaitingEngine, m_client->startingEngines.last());
+ QTRY_VERIFY(!m_client->blockedEngines().empty());
+ m_client->releaseEngine(m_client->blockedEngines().last());
- QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineAdded())),
+ QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineAdded(int,QString))),
"No engine start message received in time.");
}
@@ -226,16 +178,16 @@ void tst_QQmlEngineControl::stopEngine()
connect("exit.qml", restrictMode);
- QTRY_VERIFY(!m_client->startingEngines.empty());
- m_client->command(QQmlEngineControlClient::StartWaitingEngine, m_client->startingEngines.last());
+ QTRY_VERIFY(!m_client->blockedEngines().empty());
+ m_client->releaseEngine(m_client->blockedEngines().last());
- QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineAdded())),
+ QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineAdded(int,QString))),
"No engine start message received in time.");
- QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineAboutToBeRemoved())),
+ QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineAboutToBeRemoved(int,QString))),
"No engine about to stop message received in time.");
- m_client->command(QQmlEngineControlClient::StopWaitingEngine, m_client->stoppingEngines.last());
- QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineRemoved())),
+ m_client->releaseEngine(m_client->blockedEngines().last());
+ QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineRemoved(int,QString))),
"No engine stop message received in time.");
}
diff --git a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro
index 028eb3644d..e11ccdc6ca 100644
--- a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro
+++ b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro
@@ -2,7 +2,7 @@ CONFIG += testcase
TARGET = tst_qqmlenginedebuginspectorintegration
QT += qml testlib gui-private core-private
-macx:CONFIG -= app_bundle
+osx:CONFIG -= app_bundle
SOURCES += tst_qqmlenginedebuginspectorintegration.cpp
@@ -13,4 +13,3 @@ include(../shared/qqmlenginedebugclient.pri)
include(../shared/debugutil.pri)
TESTDATA = data/*
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp
index 0285bae189..04b068161b 100644
--- a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp
+++ b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp
@@ -31,18 +31,20 @@
**
****************************************************************************/
-#include <qtest.h>
-#include <QSignalSpy>
-#include <QTimer>
-#include <QHostAddress>
-#include <QDebug>
-#include <QThread>
-#include <QtCore/QLibraryInfo>
-
-#include "../shared/debugutil_p.h"
-#include "../../../shared/util.h"
#include "qqmlinspectorclient.h"
#include "qqmlenginedebugclient.h"
+#include "../shared/debugutil_p.h"
+#include "../../../shared/util.h"
+
+#include <private/qqmldebugconnection_p.h>
+
+#include <QtTest/qtest.h>
+#include <QtTest/qsignalspy.h>
+#include <QtNetwork/qhostaddress.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qthread.h>
+#include <QtCore/qlibraryinfo.h>
#define STR_PORT_FROM "3776"
#define STR_PORT_TO "3786"
@@ -111,9 +113,14 @@ void tst_QQmlEngineDebugInspectorIntegration::init(bool restrictServices)
QQmlDebugConnection *m_connection = new QQmlDebugConnection(this);
m_inspectorClient = new QQmlInspectorClient(m_connection);
m_engineDebugClient = new QQmlEngineDebugClient(m_connection);
+ QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_connection);
m_connection->connectToHost(QLatin1String("127.0.0.1"), m_process->debugPort());
QVERIFY(m_connection->waitForConnected());
+ foreach (QQmlDebugClient *other, others)
+ QCOMPARE(other->state(), restrictServices ? QQmlDebugClient::Unavailable :
+ QQmlDebugClient::Enabled);
+ qDeleteAll(others);
}
void tst_QQmlEngineDebugInspectorIntegration::cleanup()
diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro b/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro
index 5dadef62e4..06250d9940 100644
--- a/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro
+++ b/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro
@@ -1,6 +1,6 @@
CONFIG += testcase
TARGET = tst_qqmlenginedebugservice
-macx:CONFIG -= app_bundle
+osx:CONFIG -= app_bundle
SOURCES += \
tst_qqmlenginedebugservice.cpp
@@ -13,4 +13,3 @@ include(../shared/debugutil.pri)
DEFINES += QT_QML_DEBUG_NO_WARNING
QT += core-private qml-private quick-private testlib gui-private
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
index bc3220ad8c..fe4000bbb4 100644
--- a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
+++ b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
@@ -30,31 +30,33 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#include <qtest.h>
-#include <QSignalSpy>
-#include <QTimer>
-#include <QHostAddress>
-#include <QDebug>
-#include <QThread>
-#include <QModelIndex>
-#include <QtQml/qqmlengine.h>
-#include <QtQml/qqmlcontext.h>
-#include <QtQml/qqmlcomponent.h>
-#include <QtQml/qqmlexpression.h>
-#include <QtQml/qqmlproperty.h>
-#include <QtQuick/qquickitem.h>
+#include "qqmlenginedebugclient.h"
+#include "debugutil_p.h"
+#include "../../../shared/util.h"
#include <private/qqmlbinding_p.h>
#include <private/qqmlboundsignal_p.h>
#include <private/qqmldebugservice_p.h>
#include <private/qqmlmetatype_p.h>
#include <private/qqmlproperty_p.h>
+#include <private/qqmldebugconnection_p.h>
-#include "debugutil_p.h"
-#include "qqmlenginedebugclient.h"
+#include <QtTest/qtest.h>
+#include <QtTest/qsignalspy.h>
-#include "../../../shared/util.h"
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlcontext.h>
+#include <QtQml/qqmlcomponent.h>
+#include <QtQml/qqmlexpression.h>
+#include <QtQml/qqmlproperty.h>
+#include <QtQuick/qquickitem.h>
+
+#include <QtNetwork/qhostaddress.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qthread.h>
+#include <QtCore/qabstractitemmodel.h>
#define QVERIFYOBJECT(statement) \
do {\
@@ -352,7 +354,11 @@ void tst_QQmlEngineDebugService::initTestCase()
bool ok = m_conn->waitForConnected();
QVERIFY(ok);
m_dbg = new QQmlEngineDebugClient(m_conn);
+ QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_conn);
QTRY_COMPARE(m_dbg->state(), QQmlEngineDebugClient::Enabled);
+ foreach (QQmlDebugClient *other, others)
+ QCOMPARE(other->state(), QQmlDebugClient::Unavailable);
+ qDeleteAll(others);
}
void tst_QQmlEngineDebugService::cleanupTestCase()
diff --git a/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro b/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro
index 3a1d59f3fa..ee5f3c708a 100644
--- a/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro
+++ b/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro
@@ -2,7 +2,7 @@ CONFIG += testcase
TARGET = tst_qqmlinspector
QT += qml testlib gui-private core-private
-macx:CONFIG -= app_bundle
+osx:CONFIG -= app_bundle
SOURCES += tst_qqmlinspector.cpp
@@ -12,4 +12,3 @@ include(../shared/qqmlinspectorclient.pri)
include(../shared/debugutil.pri)
TESTDATA = data/*
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
index 70833f5e2c..d5aa1f41ad 100644
--- a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
+++ b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
@@ -30,17 +30,20 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#include <qtest.h>
-#include <QSignalSpy>
-#include <QTimer>
-#include <QHostAddress>
-#include <QDebug>
-#include <QThread>
-#include <QtCore/QLibraryInfo>
+#include "qqmlinspectorclient.h"
#include "../shared/debugutil_p.h"
#include "../../../shared/util.h"
-#include "qqmlinspectorclient.h"
+
+#include <private/qqmldebugconnection_p.h>
+
+#include <QtTest/qtest.h>
+#include <QtTest/qsignalspy.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qthread.h>
+#include <QtCore/qlibraryinfo.h>
+#include <QtNetwork/qhostaddress.h>
#define STR_PORT_FROM "3772"
#define STR_PORT_TO "3782"
@@ -91,11 +94,16 @@ void tst_QQmlInspector::startQmlsceneProcess(const char * /* qmlFile */, bool re
m_connection = new QQmlDebugConnection();
m_client = new QQmlInspectorClient(m_connection);
+ QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_connection);
m_connection->connectToHost(QLatin1String("127.0.0.1"), m_process->debugPort());
QVERIFY(m_client);
QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
+ foreach (QQmlDebugClient *other, others)
+ QCOMPARE(other->state(), restrictServices ? QQmlDebugClient::Unavailable :
+ QQmlDebugClient::Enabled);
+ qDeleteAll(others);
}
void tst_QQmlInspector::cleanup()
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro b/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro
index e422d3ef99..71a58d6f34 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro
@@ -1,6 +1,6 @@
CONFIG += testcase
TARGET = tst_qqmlprofilerservice
-macx:CONFIG -= app_bundle
+osx:CONFIG -= app_bundle
SOURCES += tst_qqmlprofilerservice.cpp
@@ -11,7 +11,6 @@ include(../shared/debugutil.pri)
TESTDATA = data/*
QT += core qml testlib gui-private core-private
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
OTHER_FILES += \
data/pixmapCacheTest.qml \
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
index 0e63e18952..3a9666b8fe 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
@@ -31,20 +31,25 @@
**
****************************************************************************/
-#include <qtest.h>
-#include <QLibraryInfo>
-
#include "debugutil_p.h"
-#include "qqmldebugclient.h"
#include "../../../shared/util.h"
+#include <private/qqmlprofilerclient_p.h>
+#include <private/qqmldebugconnection_p.h>
+
+#include <QtTest/qtest.h>
+#include <QtCore/qlibraryinfo.h>
+
#define STR_PORT_FROM "13773"
#define STR_PORT_TO "13783"
struct QQmlProfilerData
{
- QQmlProfilerData(int messageType = 0, int detailType = 0, const QString &detailData = QString())
- : messageType(messageType), detailType(detailType), detailData(detailData) {}
+ QQmlProfilerData(qint64 time = -2, int messageType = -1, int detailType = -1,
+ const QString &detailData = QString()) :
+ time(time), messageType(messageType), detailType(detailType), detailData(detailData),
+ line(-1), column(-1), framerate(-1), animationcount(-1), amount(-1)
+ {}
qint64 time;
int messageType;
@@ -57,109 +62,184 @@ struct QQmlProfilerData
int framerate; //used by animation events
int animationcount; //used by animation events
qint64 amount; //used by heap events
-
- QByteArray toByteArray() const;
};
-class QQmlProfilerClient : public QQmlDebugClient
+class QQmlProfilerTestClient : public QQmlProfilerClient
{
Q_OBJECT
public:
- enum Message {
- Event,
- RangeStart,
- RangeData,
- RangeLocation,
- RangeEnd,
- Complete, // end of transmission
- PixmapCacheEvent,
- SceneGraphFrame,
- MemoryAllocation,
-
- MaximumMessage
- };
+ QQmlProfilerTestClient(QQmlDebugConnection *connection) : QQmlProfilerClient(connection) {}
- enum EventType {
- FramePaint,
- Mouse,
- Key,
- AnimationFrame,
- EndTrace,
- StartTrace,
+ QVector<QQmlProfilerData> qmlMessages;
+ QVector<QQmlProfilerData> javascriptMessages;
+ QVector<QQmlProfilerData> jsHeapMessages;
+ QVector<QQmlProfilerData> asynchronousMessages;
+ QVector<QQmlProfilerData> pixmapMessages;
- MaximumEventType
- };
+signals:
+ void recordingFinished();
- enum RangeType {
- Painting,
- Compiling,
- Creating,
- Binding, //running a binding
- HandlingSignal, //running a signal handler
- Javascript,
+private:
+ void traceStarted(qint64 time, int engineId);
+ void traceFinished(qint64 time, int engineId);
+ void rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime);
+ void rangeData(QQmlProfilerDefinitions::RangeType type, qint64 time, const QString &data);
+ void rangeLocation(QQmlProfilerDefinitions::RangeType type, qint64 time,
+ const QQmlEventLocation &location);
+ void rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime);
+ void animationFrame(qint64 time, int frameRate, int animationCount, int threadId);
+ void sceneGraphEvent(QQmlProfilerDefinitions::SceneGraphFrameType type, qint64 time,
+ qint64 numericData1, qint64 numericData2, qint64 numericData3,
+ qint64 numericData4, qint64 numericData5);
+ void pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type, qint64 time,
+ const QString &url, int numericData1, int numericData2);
+ void memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time, qint64 amount);
+ void inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time, int a, int b);
+ void complete();
- MaximumRangeType
- };
+ void unknownEvent(QQmlProfilerDefinitions::Message messageType, qint64 time, int detailType);
+ void unknownData(QPacket &stream);
+};
- enum PixmapEventType {
- PixmapSizeKnown,
- PixmapReferenceCountChanged,
- PixmapCacheCountChanged,
- PixmapLoadingStarted,
- PixmapLoadingFinished,
- PixmapLoadingError,
+void QQmlProfilerTestClient::traceStarted(qint64 time, int engineId)
+{
+ asynchronousMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::Event,
+ QQmlProfilerDefinitions::StartTrace,
+ QString::number(engineId)));
+}
- MaximumPixmapEventType
- };
+void QQmlProfilerTestClient::traceFinished(qint64 time, int engineId)
+{
+ asynchronousMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::Event,
+ QQmlProfilerDefinitions::EndTrace,
+ QString::number(engineId)));
+}
- enum SceneGraphFrameType {
- SceneGraphRendererFrame,
- SceneGraphAdaptationLayerFrame,
- SceneGraphContextFrame,
- SceneGraphRenderLoopFrame,
- SceneGraphTexturePrepare,
- SceneGraphTextureDeletion,
- SceneGraphPolishAndSync,
- SceneGraphWindowsRenderShow,
- SceneGraphWindowsAnimations,
- SceneGraphWindowsPolishFrame,
-
- MaximumSceneGraphFrameType
- };
+void QQmlProfilerTestClient::rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime)
+{
+ QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType);
+ QQmlProfilerData data(startTime, QQmlProfilerDefinitions::RangeStart, type);
+ if (type == QQmlProfilerDefinitions::Javascript)
+ javascriptMessages.append(data);
+ else
+ qmlMessages.append(data);
+}
- enum MemoryType {
- HeapPage,
- LargeItem,
- SmallItem
- };
+void QQmlProfilerTestClient::rangeData(QQmlProfilerDefinitions::RangeType type, qint64 time,
+ const QString &string)
+{
+ QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType);
+ QQmlProfilerData data(time, QQmlProfilerDefinitions::RangeData, type, string);
+ if (type == QQmlProfilerDefinitions::Javascript)
+ javascriptMessages.append(data);
+ else
+ qmlMessages.append(data);
+}
- QQmlProfilerClient(QQmlDebugConnection *connection)
- : QQmlDebugClient(QLatin1String("CanvasFrameRate"), connection)
- {
- }
+void QQmlProfilerTestClient::rangeLocation(QQmlProfilerDefinitions::RangeType type, qint64 time,
+ const QQmlEventLocation &location)
+{
+ QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType);
+ QVERIFY(location.line >= -2);
+ QQmlProfilerData data(time, QQmlProfilerDefinitions::RangeLocation, type, location.filename);
+ data.line = location.line;
+ data.column = location.column;
+ if (type == QQmlProfilerDefinitions::Javascript)
+ javascriptMessages.append(data);
+ else
+ qmlMessages.append(data);
+}
- QVector<QQmlProfilerData> qmlMessages;
- QVector<QQmlProfilerData> javascriptMessages;
- QVector<QQmlProfilerData> jsHeapMessages;
- QVector<QQmlProfilerData> asynchronousMessages;
- QVector<QQmlProfilerData> pixmapMessages;
+void QQmlProfilerTestClient::rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime)
+{
+ QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType);
+ QQmlProfilerData data(endTime, QQmlProfilerDefinitions::RangeEnd, type);
+ if (type == QQmlProfilerDefinitions::Javascript)
+ javascriptMessages.append(data);
+ else
+ qmlMessages.append(data);
+}
+
+void QQmlProfilerTestClient::animationFrame(qint64 time, int frameRate, int animationCount, int threadId)
+{
+ QVERIFY(threadId >= 0);
+ QVERIFY(frameRate != -1);
+ QVERIFY(animationCount != -1);
+ QQmlProfilerData data(time, QQmlProfilerDefinitions::Event,
+ QQmlProfilerDefinitions::AnimationFrame);
+ data.framerate = frameRate;
+ data.animationcount = animationCount;
+ asynchronousMessages.append(data);
+}
- void setTraceState(bool enabled, quint32 flushInterval = 0) {
- QByteArray message;
- QDataStream stream(&message, QIODevice::WriteOnly);
- stream << enabled;
- if (enabled && flushInterval)
- stream << -1 << std::numeric_limits<quint64>::max() << flushInterval;
- sendMessage(message);
+void QQmlProfilerTestClient::sceneGraphEvent(QQmlProfilerDefinitions::SceneGraphFrameType type,
+ qint64 time, qint64 numericData1, qint64 numericData2,
+ qint64 numericData3, qint64 numericData4,
+ qint64 numericData5)
+{
+ Q_UNUSED(numericData1);
+ Q_UNUSED(numericData2);
+ Q_UNUSED(numericData3);
+ Q_UNUSED(numericData4);
+ Q_UNUSED(numericData5);
+ asynchronousMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::SceneGraphFrame,
+ type));
+}
+
+void QQmlProfilerTestClient::pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type,
+ qint64 time, const QString &url, int numericData1,
+ int numericData2)
+{
+ QQmlProfilerData data(time, QQmlProfilerDefinitions::PixmapCacheEvent, type, url);
+ switch (type) {
+ case QQmlProfilerDefinitions::PixmapSizeKnown:
+ data.line = numericData1;
+ data.column = numericData2;
+ break;
+ case QQmlProfilerDefinitions::PixmapReferenceCountChanged:
+ case QQmlProfilerDefinitions::PixmapCacheCountChanged:
+ data.animationcount = numericData1;
+ break;
+ default:
+ break;
}
+ pixmapMessages.append(data);
+}
-signals:
- void complete();
+void QQmlProfilerTestClient::memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time,
+ qint64 amount)
+{
+ QQmlProfilerData data(time, QQmlProfilerDefinitions::MemoryAllocation, type);
+ data.amount = amount;
+ jsHeapMessages.append(data);
+}
-protected:
- void messageReceived(const QByteArray &message);
-};
+void QQmlProfilerTestClient::inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time,
+ int a, int b)
+{
+ qmlMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::Event, type,
+ QString::number(a) + QLatin1Char('x') +
+ QString::number(b)));
+}
+
+void QQmlProfilerTestClient::unknownEvent(QQmlProfilerDefinitions::Message messageType, qint64 time,
+ int detailType)
+{
+ QFAIL(qPrintable(QString::fromLatin1("Unknown event %1 with detail type %2 received at %3.")
+ .arg(messageType).arg(detailType).arg(time)));
+}
+
+void QQmlProfilerTestClient::unknownData(QPacket &stream)
+{
+ QFAIL(qPrintable(QString::fromLatin1("%1 bytes of extra data after receiving message.")
+ .arg(stream.device()->bytesAvailable())));
+}
+
+void QQmlProfilerTestClient::complete()
+{
+ emit recordingFinished();
+}
class tst_QQmlProfilerService : public QQmlDataTest
{
@@ -177,7 +257,7 @@ public:
private:
QQmlDebugProcess *m_process;
QQmlDebugConnection *m_connection;
- QQmlProfilerClient *m_client;
+ QQmlProfilerTestClient *m_client;
enum MessageListType {
MessageListQML,
@@ -219,143 +299,6 @@ private slots:
#define VERIFY(type, position, expected, checks) QVERIFY(verify(type, position, expected, checks))
-void QQmlProfilerClient::messageReceived(const QByteArray &message)
-{
- QByteArray msg = message;
- QDataStream stream(&msg, QIODevice::ReadOnly);
-
-
- QQmlProfilerData data;
- data.time = -2;
- data.messageType = -1;
- data.detailType = -1;
- data.line = -1;
- data.framerate = -1;
- data.animationcount = -1;
-
- stream >> data.time >> data.messageType;
-
- switch (data.messageType) {
- case (QQmlProfilerClient::Event): {
- stream >> data.detailType;
-
- switch (data.detailType) {
- case QQmlProfilerClient::AnimationFrame: {
- int threadId;
- stream >> data.framerate >> data.animationcount >> threadId;
- QVERIFY(threadId >= 0);
- QVERIFY(data.framerate != -1);
- QVERIFY(data.animationcount != -1);
- break;
- }
- case QQmlProfilerClient::FramePaint:
- case QQmlProfilerClient::Mouse:
- case QQmlProfilerClient::Key:
- break;
- case QQmlProfilerClient::EndTrace:
- case QQmlProfilerClient::StartTrace: {
- int engineId = -1;
- if (!stream.atEnd()) {
- stream >> engineId;
- QVERIFY(engineId >= 0);
- }
- break;
- }
- default: {
- QString failMsg = QString("Unknown event type:") + data.detailType;
- QFAIL(qPrintable(failMsg));
- break;
- }
- }
- break;
- }
- case QQmlProfilerClient::Complete: {
- emit complete();
- return;
- }
- case QQmlProfilerClient::RangeStart: {
- stream >> data.detailType;
- QVERIFY(data.detailType >= 0 && data.detailType < QQmlProfilerClient::MaximumRangeType);
- break;
- }
- case QQmlProfilerClient::RangeEnd: {
- stream >> data.detailType;
- QVERIFY(data.detailType >= 0 && data.detailType < QQmlProfilerClient::MaximumRangeType);
- break;
- }
- case QQmlProfilerClient::RangeData: {
- stream >> data.detailType >> data.detailData;
- QVERIFY(data.detailType >= 0 && data.detailType < QQmlProfilerClient::MaximumRangeType);
- break;
- }
- case QQmlProfilerClient::RangeLocation: {
- stream >> data.detailType >> data.detailData >> data.line >> data.column;
- QVERIFY(data.detailType >= 0 && data.detailType < QQmlProfilerClient::MaximumRangeType);
- QVERIFY(data.line >= -2);
- break;
- }
- case QQmlProfilerClient::PixmapCacheEvent: {
- stream >> data.detailType >> data.detailData;
- if (data.detailType == QQmlProfilerClient::PixmapSizeKnown)
- stream >> data.line >> data.column;
- if (data.detailType == QQmlProfilerClient::PixmapReferenceCountChanged)
- stream >> data.animationcount;
- if (data.detailType == QQmlProfilerClient::PixmapCacheCountChanged)
- stream >> data.animationcount;
- break;
- }
- case QQmlProfilerClient::SceneGraphFrame: {
- stream >> data.detailType;
- qint64 subtime_1, subtime_2, subtime_3, subtime_4, subtime_5;
- int glyphCount;
- switch (data.detailType) {
- // RendererFrame: preprocessTime, updateTime, bindingTime, renderTime
- case QQmlProfilerClient::SceneGraphRendererFrame: stream >> subtime_1 >> subtime_2 >> subtime_3 >> subtime_4; break;
- // AdaptationLayerFrame: glyphCount, glyphRenderTime, glyphStoreTime
- case QQmlProfilerClient::SceneGraphAdaptationLayerFrame: stream >> glyphCount >> subtime_2 >> subtime_3; break;
- // ContextFrame: compiling material time
- case QQmlProfilerClient::SceneGraphContextFrame: stream >> subtime_1; break;
- // RenderLoop: syncTime, renderTime, swapTime
- case QQmlProfilerClient::SceneGraphRenderLoopFrame: stream >> subtime_1 >> subtime_2 >> subtime_3; break;
- // TexturePrepare: bind, convert, swizzle, upload, mipmap
- case QQmlProfilerClient::SceneGraphTexturePrepare: stream >> subtime_1 >> subtime_2 >> subtime_3 >> subtime_4 >> subtime_5; break;
- // TextureDeletion: deletionTime
- case QQmlProfilerClient::SceneGraphTextureDeletion: stream >> subtime_1; break;
- // PolishAndSync: polishTime, waitTime, syncTime, animationsTime,
- case QQmlProfilerClient::SceneGraphPolishAndSync: stream >> subtime_1 >> subtime_2 >> subtime_3 >> subtime_4; break;
- // WindowsRenderLoop: GL time, make current time, SceneGraph time
- case QQmlProfilerClient::SceneGraphWindowsRenderShow: stream >> subtime_1 >> subtime_2 >> subtime_3; break;
- // WindowsAnimations: update time
- case QQmlProfilerClient::SceneGraphWindowsAnimations: stream >> subtime_1; break;
- // WindowsRenderWindow: polish time
- case QQmlProfilerClient::SceneGraphWindowsPolishFrame: stream >> subtime_1; break;
- }
- break;
- }
- case QQmlProfilerClient::MemoryAllocation: {
- stream >> data.detailType;
- stream >> data.amount;
- break;
- }
- default:
- QString failMsg = QString("Unknown message type:") + data.messageType;
- QFAIL(qPrintable(failMsg));
- break;
- }
- QVERIFY(stream.atEnd());
- if (data.messageType == QQmlProfilerClient::PixmapCacheEvent)
- pixmapMessages.append(data);
- else if (data.messageType == QQmlProfilerClient::SceneGraphFrame ||
- data.messageType == QQmlProfilerClient::Event)
- asynchronousMessages.append(data);
- else if (data.messageType == QQmlProfilerClient::MemoryAllocation)
- jsHeapMessages.append(data);
- else if (data.detailType == QQmlProfilerClient::Javascript)
- javascriptMessages.append(data);
- else
- qmlMessages.append(data);
-}
-
void tst_QQmlProfilerService::connect(bool block, const QString &testFile, bool restrictServices)
{
// ### Still using qmlscene due to QTBUG-33377
@@ -372,24 +315,32 @@ void tst_QQmlProfilerService::connect(bool block, const QString &testFile, bool
QVERIFY2(m_process->waitForSessionStart(), "Could not launch application, or did not get 'Waiting for connection'.");
m_connection = new QQmlDebugConnection();
- m_client = new QQmlProfilerClient(m_connection);
+ m_client = new QQmlProfilerTestClient(m_connection);
+ QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_connection);
const int port = m_process->debugPort();
m_connection->connectToHost(QLatin1String("127.0.0.1"), port);
QVERIFY(m_client);
QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
+
+ foreach (QQmlDebugClient *other, others)
+ QCOMPARE(other->state(), restrictServices ? QQmlDebugClient::Unavailable :
+ QQmlDebugClient::Enabled);
+ qDeleteAll(others);
}
void tst_QQmlProfilerService::checkTraceReceived()
{
- QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(complete())), "No trace received in time.");
+ QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(recordingFinished())),
+ "No trace received in time.");
// must start with "StartTrace"
- QQmlProfilerData expected(QQmlProfilerClient::Event, QQmlProfilerClient::StartTrace);
+ QQmlProfilerData expected(0, QQmlProfilerDefinitions::Event,
+ QQmlProfilerDefinitions::StartTrace);
VERIFY(MessageListAsynchronous, 0, expected, CheckMessageType | CheckDetailType);
// must end with "EndTrace"
- expected.detailType = QQmlProfilerClient::EndTrace;
+ expected.detailType = QQmlProfilerDefinitions::EndTrace;
VERIFY(MessageListAsynchronous, m_client->asynchronousMessages.length() - 1, expected,
CheckMessageType | CheckDetailType);
}
@@ -406,15 +357,15 @@ void tst_QQmlProfilerService::checkJsHeap()
qint64 lastTimestamp = -1;
foreach (const QQmlProfilerData &message, m_client->jsHeapMessages) {
switch (message.detailType) {
- case QQmlProfilerClient::HeapPage:
+ case QV4::Profiling::HeapPage:
allocated += message.amount;
seen_alloc = true;
break;
- case QQmlProfilerClient::SmallItem:
+ case QV4::Profiling::SmallItem:
used += message.amount;
seen_small = true;
break;
- case QQmlProfilerClient::LargeItem:
+ case QV4::Profiling::LargeItem:
allocated += message.amount;
used += message.amount;
seen_large = true;
@@ -549,8 +500,8 @@ void tst_QQmlProfilerService::cleanup()
qDebug() << " ";
qDebug() << "Process State:" << (m_process ? m_process->state() : QLatin1String("null"));
qDebug() << "Application Output:" << (m_process ? m_process->output() : QLatin1String("null"));
- qDebug() << "Connection State:" << (m_connection ? m_connection->stateString() : QLatin1String("null"));
- qDebug() << "Client State:" << m_client->stateString();
+ qDebug() << "Connection State:" << QQmlDebugTest::connectionStateString(m_connection);
+ qDebug() << "Client State:" << QQmlDebugTest::clientStateString(m_client);
}
delete m_process;
m_process = 0;
@@ -585,9 +536,9 @@ void tst_QQmlProfilerService::connect()
// if the engine is waiting, then the first message determines if it starts with trace enabled
if (!traceEnabled)
- m_client->setTraceState(false);
- m_client->setTraceState(true);
- m_client->setTraceState(false);
+ m_client->sendRecordingStatus(false);
+ m_client->sendRecordingStatus(true);
+ m_client->sendRecordingStatus(false);
checkTraceReceived();
checkJsHeap();
}
@@ -596,36 +547,36 @@ void tst_QQmlProfilerService::pixmapCacheData()
{
connect(true, "pixmapCacheTest.qml");
- m_client->setTraceState(true);
+ m_client->sendRecordingStatus(true);
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
while (m_process->output().indexOf(QLatin1String("image loaded")) == -1 &&
m_process->output().indexOf(QLatin1String("image error")) == -1)
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
- m_client->setTraceState(false);
+ m_client->sendRecordingStatus(false);
checkTraceReceived();
checkJsHeap();
- QQmlProfilerData expected(QQmlProfilerClient::PixmapCacheEvent);
+ QQmlProfilerData expected(0, QQmlProfilerDefinitions::PixmapCacheEvent);
// image starting to load
- expected.detailType = QQmlProfilerClient::PixmapLoadingStarted;
+ expected.detailType = QQmlProfilerDefinitions::PixmapLoadingStarted;
VERIFY(MessageListPixmap, 0, expected, CheckMessageType | CheckDetailType);
// image size
- expected.detailType = QQmlProfilerClient::PixmapSizeKnown;
+ expected.detailType = QQmlProfilerDefinitions::PixmapSizeKnown;
expected.line = expected.column = 2; // width and height, in fact
VERIFY(MessageListPixmap, 1, expected,
CheckMessageType | CheckDetailType | CheckLine | CheckColumn);
// image loaded
- expected.detailType = QQmlProfilerClient::PixmapLoadingFinished;
+ expected.detailType = QQmlProfilerDefinitions::PixmapLoadingFinished;
VERIFY(MessageListPixmap, 2, expected, CheckMessageType | CheckDetailType);
// cache size
- expected.detailType = QQmlProfilerClient::PixmapCacheCountChanged;
+ expected.detailType = QQmlProfilerDefinitions::PixmapCacheCountChanged;
VERIFY(MessageListPixmap, 3, expected, CheckMessageType | CheckDetailType);
}
@@ -633,11 +584,11 @@ void tst_QQmlProfilerService::scenegraphData()
{
connect(true, "scenegraphTest.qml");
- m_client->setTraceState(true);
+ m_client->sendRecordingStatus(true);
while (!m_process->output().contains(QLatin1String("tick")))
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
- m_client->setTraceState(false);
+ m_client->sendRecordingStatus(false);
checkTraceReceived();
checkJsHeap();
@@ -653,8 +604,8 @@ void tst_QQmlProfilerService::scenegraphData()
qint64 renderFrameTime = -1;
foreach (const QQmlProfilerData &msg, m_client->asynchronousMessages) {
- if (msg.messageType == QQmlProfilerClient::SceneGraphFrame) {
- if (msg.detailType == QQmlProfilerClient::SceneGraphContextFrame) {
+ if (msg.messageType == QQmlProfilerDefinitions::SceneGraphFrame) {
+ if (msg.detailType == QQmlProfilerDefinitions::SceneGraphContextFrame) {
contextFrameTime = msg.time;
break;
}
@@ -664,7 +615,7 @@ void tst_QQmlProfilerService::scenegraphData()
QVERIFY(contextFrameTime != -1);
foreach (const QQmlProfilerData &msg, m_client->asynchronousMessages) {
- if (msg.detailType == QQmlProfilerClient::SceneGraphRendererFrame) {
+ if (msg.detailType == QQmlProfilerDefinitions::SceneGraphRendererFrame) {
QVERIFY(msg.time >= contextFrameTime);
renderFrameTime = msg.time;
break;
@@ -674,7 +625,7 @@ void tst_QQmlProfilerService::scenegraphData()
QVERIFY(renderFrameTime != -1);
foreach (const QQmlProfilerData &msg, m_client->asynchronousMessages) {
- if (msg.detailType == QQmlProfilerClient::SceneGraphRenderLoopFrame) {
+ if (msg.detailType == QQmlProfilerDefinitions::SceneGraphRenderLoopFrame) {
QVERIFY(msg.time >= renderFrameTime);
break;
}
@@ -685,7 +636,7 @@ void tst_QQmlProfilerService::profileOnExit()
{
connect(true, "exit.qml");
- m_client->setTraceState(true);
+ m_client->sendRecordingStatus(true);
checkTraceReceived();
checkJsHeap();
@@ -695,7 +646,7 @@ void tst_QQmlProfilerService::controlFromJS()
{
connect(true, "controlFromJS.qml");
- m_client->setTraceState(false);
+ m_client->sendRecordingStatus(false);
checkTraceReceived();
checkJsHeap();
}
@@ -704,15 +655,15 @@ void tst_QQmlProfilerService::signalSourceLocation()
{
connect(true, "signalSourceLocation.qml");
- m_client->setTraceState(true);
+ m_client->sendRecordingStatus(true);
while (!(m_process->output().contains(QLatin1String("500"))))
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
- m_client->setTraceState(false);
+ m_client->sendRecordingStatus(false);
checkTraceReceived();
checkJsHeap();
- QQmlProfilerData expected(QQmlProfilerClient::RangeLocation,
- QQmlProfilerClient::HandlingSignal,
+ QQmlProfilerData expected(0, QQmlProfilerDefinitions::RangeLocation,
+ QQmlProfilerDefinitions::HandlingSignal,
QLatin1String("signalSourceLocation.qml"));
expected.line = 8;
expected.column = 28;
@@ -727,28 +678,29 @@ void tst_QQmlProfilerService::javascript()
{
connect(true, "javascript.qml");
- m_client->setTraceState(true);
+ m_client->sendRecordingStatus(true);
while (!(m_process->output().contains(QLatin1String("done"))))
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
- m_client->setTraceState(false);
+ m_client->sendRecordingStatus(false);
checkTraceReceived();
checkJsHeap();
- QQmlProfilerData expected(QQmlProfilerClient::RangeStart, QQmlProfilerClient::Javascript);
+ QQmlProfilerData expected(0, QQmlProfilerDefinitions::RangeStart,
+ QQmlProfilerDefinitions::Javascript);
VERIFY(MessageListJavaScript, 6, expected, CheckMessageType | CheckDetailType);
- expected.messageType = QQmlProfilerClient::RangeLocation;
+ expected.messageType = QQmlProfilerDefinitions::RangeLocation;
expected.detailData = QLatin1String("javascript.qml");
expected.line = 4;
expected.column = 5;
VERIFY(MessageListJavaScript, 7, expected, CheckAll);
- expected.messageType = QQmlProfilerClient::RangeData;
+ expected.messageType = QQmlProfilerDefinitions::RangeData;
expected.detailData = QLatin1String("something");
VERIFY(MessageListJavaScript, 8, expected,
CheckMessageType | CheckDetailType | CheckDataEndsWith);
- expected.messageType = QQmlProfilerClient::RangeEnd;
+ expected.messageType = QQmlProfilerDefinitions::RangeEnd;
VERIFY(MessageListJavaScript, 21, expected, CheckMessageType | CheckDetailType);
}
@@ -756,14 +708,14 @@ void tst_QQmlProfilerService::flushInterval()
{
connect(true, "timer.qml");
- m_client->setTraceState(true, 1);
+ m_client->sendRecordingStatus(true, -1, 1);
// Make sure we get multiple messages
QTRY_VERIFY(m_client->qmlMessages.length() > 0);
QVERIFY(m_client->qmlMessages.length() < 100);
QTRY_VERIFY(m_client->qmlMessages.length() > 100);
- m_client->setTraceState(false);
+ m_client->sendRecordingStatus(false);
checkTraceReceived();
checkJsHeap();
}
diff --git a/tests/auto/qml/debugger/qv4debugger/qv4debugger.pro b/tests/auto/qml/debugger/qv4debugger/qv4debugger.pro
new file mode 100644
index 0000000000..d11de56e43
--- /dev/null
+++ b/tests/auto/qml/debugger/qv4debugger/qv4debugger.pro
@@ -0,0 +1,17 @@
+CONFIG += testcase
+TARGET = tst_qv4debugger
+osx:CONFIG -= app_bundle
+
+SOURCES += \
+ $$PWD/tst_qv4debugger.cpp \
+ $$PWD/../../../../../src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp \
+ $$PWD/../../../../../src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp
+
+HEADERS += \
+ $$PWD/../../../../../src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h \
+ $$PWD/../../../../../src/plugins/qmltooling/qmldbg_debugger/qv4debugger.h
+
+INCLUDEPATH += \
+ $$PWD/../../../../../src/plugins/qmltooling/qmldbg_debugger
+
+QT += core-private gui-private qml-private network testlib
diff --git a/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
index 39a1fbc173..70883047c8 100644
--- a/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp
+++ b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
@@ -33,6 +33,7 @@
#include <QtTest/QtTest>
#include "qv4datacollector.h"
+#include "qv4debugger.h"
#include <QJSEngine>
#include <QQmlEngine>
@@ -103,11 +104,8 @@ public:
typedef QV4DataCollector::Refs Refs;
typedef QV4DataCollector::Ref Ref;
struct NamedRefs {
- NamedRefs(QV4DataCollector *collector = 0): collector(collector) {}
-
QStringList names;
- Refs refs;
- QV4DataCollector *collector;
+ QJsonArray refs;
int size() const {
Q_ASSERT(names.size() == refs.size());
@@ -125,7 +123,7 @@ public:
QJsonObject rawValue(const QString &name) const {
Q_ASSERT(contains(name));
- return collector->lookupRef(refs.at(names.indexOf(name)));
+ return refs.at(names.indexOf(name)).toObject();
}
QJsonValue value(const QString &name) const {
@@ -142,7 +140,7 @@ public:
return;
}
- QJsonObject o = collector->lookupRef(refs.at(names.indexOf(name)));
+ QJsonObject o = refs.at(names.indexOf(name)).toObject();
QJsonDocument d;
d.setObject(o);
qDebug() << name << "=" << d.toJson(QJsonDocument::Indented);
@@ -159,7 +157,7 @@ public:
}
public slots:
- void debuggerPaused(V4Debugger *debugger, QV4::Debugging::PauseReason reason)
+ void debuggerPaused(QV4Debugger *debugger, QV4Debugger::PauseReason reason)
{
Q_ASSERT(debugger == m_debugger);
Q_ASSERT(debugger->engine() == collector.engine());
@@ -167,14 +165,10 @@ public slots:
m_pauseReason = reason;
m_statesWhenPaused << debugger->currentExecutionState();
- if (debugger->state() == V4Debugger::Paused &&
- debugger->engine()->hasException) {
- Refs refs;
- RefHolder holder(&collector, &refs);
+ if (debugger->state() == QV4Debugger::Paused && debugger->engine()->hasException) {
ExceptionCollectJob job(debugger->engine(), &collector);
debugger->runInEngine(&job);
- Q_ASSERT(refs.size() > 0);
- m_thrownValue = refs.first();
+ m_thrownValue = job.exceptionValue();
}
foreach (const TestBreakPoint &bp, m_breakPointsToAddWhenPaused)
@@ -184,19 +178,19 @@ public slots:
m_stackTrace = debugger->stackTrace();
while (!m_expressionRequests.isEmpty()) {
- Q_ASSERT(debugger->state() == V4Debugger::Paused);
+ Q_ASSERT(debugger->state() == QV4Debugger::Paused);
ExpressionRequest request = m_expressionRequests.takeFirst();
- m_expressionResults << Refs();
- RefHolder holder(&collector, &m_expressionResults.last());
ExpressionEvalJob job(debugger->engine(), request.frameNr, request.expression,
&collector);
debugger->runInEngine(&job);
+ m_expressionResults << job.returnValue();
+ m_expressionRefs << job.refs();
}
if (m_captureContextInfo)
captureContextInfo(debugger);
- debugger->resume(V4Debugger::FullThrottle);
+ debugger->resume(QV4Debugger::FullThrottle);
}
public:
@@ -209,35 +203,34 @@ public:
int lineNumber;
};
- void captureContextInfo(V4Debugger *debugger)
+ void captureContextInfo(QV4Debugger *debugger)
{
for (int i = 0, ei = m_stackTrace.size(); i != ei; ++i) {
- m_capturedArguments.append(NamedRefs(&collector));
- RefHolder argHolder(&collector, &m_capturedArguments.last().refs);
+ m_capturedArguments.append(NamedRefs());
ArgumentCollectJob argumentsJob(debugger->engine(), &collector,
&m_capturedArguments.last().names, i, 0);
debugger->runInEngine(&argumentsJob);
+ m_capturedArguments.last().refs = collector.flushCollectedRefs();
- m_capturedLocals.append(NamedRefs(&collector));
- RefHolder localHolder(&collector, &m_capturedLocals.last().refs);
+ m_capturedLocals.append(NamedRefs());
LocalCollectJob localsJob(debugger->engine(), &collector,
&m_capturedLocals.last().names, i, 0);
debugger->runInEngine(&localsJob);
+ m_capturedLocals.last().refs = collector.flushCollectedRefs();
}
}
- void addDebugger(V4Debugger *debugger)
+ void addDebugger(QV4Debugger *debugger)
{
Q_ASSERT(!m_debugger);
m_debugger = debugger;
- connect(m_debugger, &V4Debugger::debuggerPaused,
- this, &TestAgent::debuggerPaused);
+ connect(m_debugger, &QV4Debugger::debuggerPaused, this, &TestAgent::debuggerPaused);
}
bool m_wasPaused;
- PauseReason m_pauseReason;
+ QV4Debugger::PauseReason m_pauseReason;
bool m_captureContextInfo;
- QList<V4Debugger::ExecutionState> m_statesWhenPaused;
+ QList<QV4Debugger::ExecutionState> m_statesWhenPaused;
QList<TestBreakPoint> m_breakPointsToAddWhenPaused;
QVector<QV4::StackFrame> m_stackTrace;
QVector<NamedRefs> m_capturedArguments;
@@ -250,8 +243,9 @@ public:
int frameNr;
};
QVector<ExpressionRequest> m_expressionRequests;
- QVector<Refs> m_expressionResults;
- V4Debugger *m_debugger;
+ QList<QJsonObject> m_expressionResults;
+ QList<QJsonArray> m_expressionRefs;
+ QV4Debugger *m_debugger;
// Utility methods:
void dumpStackTrace() const
@@ -295,9 +289,9 @@ private slots:
void evaluateExpression();
private:
- V4Debugger *debugger() const
+ QV4Debugger *debugger() const
{
- return static_cast<V4Debugger *>(m_v4->debugger);
+ return static_cast<QV4Debugger *>(m_v4->debugger);
}
void evaluateJavaScript(const QString &script, const QString &fileName, int lineNumber = 1)
{
@@ -319,7 +313,7 @@ void tst_qv4debugger::init()
m_engine = new TestEngine;
m_v4 = m_engine->v4Engine();
m_v4->iselFactory.reset(new QV4::Moth::ISelFactory);
- m_v4->setDebugger(new V4Debugger(m_v4));
+ m_v4->setDebugger(new QV4Debugger(m_v4));
m_engine->moveToThread(m_javaScriptThread);
m_javaScriptThread->start();
m_debuggerAgent = new TestAgent(m_v4);
@@ -359,7 +353,7 @@ void tst_qv4debugger::pendingBreakpoint()
evaluateJavaScript(script, "testfile");
QVERIFY(m_debuggerAgent->m_wasPaused);
QCOMPARE(m_debuggerAgent->m_statesWhenPaused.count(), 1);
- V4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first();
+ QV4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first();
QCOMPARE(state.fileName, QString("testfile"));
QCOMPARE(state.lineNumber, 2);
}
@@ -375,7 +369,7 @@ void tst_qv4debugger::liveBreakPoint()
evaluateJavaScript(script, "liveBreakPoint");
QVERIFY(m_debuggerAgent->m_wasPaused);
QCOMPARE(m_debuggerAgent->m_statesWhenPaused.count(), 2);
- V4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.at(1);
+ QV4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.at(1);
QCOMPARE(state.fileName, QString("liveBreakPoint"));
QCOMPARE(state.lineNumber, 3);
}
@@ -404,7 +398,7 @@ void tst_qv4debugger::addBreakPointWhilePaused()
QVERIFY(m_debuggerAgent->m_wasPaused);
QCOMPARE(m_debuggerAgent->m_statesWhenPaused.count(), 2);
- V4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.at(0);
+ QV4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.at(0);
QCOMPARE(state.fileName, QString("addBreakPointWhilePaused"));
QCOMPARE(state.lineNumber, 1);
@@ -415,7 +409,7 @@ void tst_qv4debugger::addBreakPointWhilePaused()
static QV4::ReturnedValue someCall(QV4::CallContext *ctx)
{
- static_cast<V4Debugger *>(ctx->d()->engine->debugger)
+ static_cast<QV4Debugger *>(ctx->d()->engine->debugger)
->removeBreakPoint("removeBreakPointForNextInstruction", 2);
return QV4::Encode::undefined();
}
@@ -450,7 +444,7 @@ void tst_qv4debugger::conditionalBreakPoint()
evaluateJavaScript(script, "conditionalBreakPoint");
QVERIFY(m_debuggerAgent->m_wasPaused);
QCOMPARE(m_debuggerAgent->m_statesWhenPaused.count(), 4);
- V4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first();
+ QV4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first();
QCOMPARE(state.fileName, QString("conditionalBreakPoint"));
QCOMPARE(state.lineNumber, 3);
@@ -465,7 +459,7 @@ void tst_qv4debugger::conditionalBreakPointInQml()
{
QQmlEngine engine;
QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine);
- V4Debugger *v4Debugger = new V4Debugger(v4);
+ QV4Debugger *v4Debugger = new QV4Debugger(v4);
v4->iselFactory.reset(new QV4::Moth::ISelFactory);
v4->setDebugger(v4Debugger);
@@ -578,7 +572,7 @@ void tst_qv4debugger::readObject()
QCOMPARE(b_tail.value("name").toString(), QStringLiteral("tail"));
QVERIFY(b_tail.contains("ref"));
- QJsonObject b_tail_value = frame0.collector->lookupRef(b_tail.value("ref").toInt());
+ QJsonObject b_tail_value = m_debuggerAgent->collector.lookupRef(b_tail.value("ref").toInt());
QCOMPARE(b_tail_value.value("type").toString(), QStringLiteral("object"));
QVERIFY(b_tail_value.contains("properties"));
QJsonArray b_tail_props = b_tail_value.value("properties").toArray();
@@ -644,7 +638,7 @@ void tst_qv4debugger::pauseOnThrow()
debugger()->setBreakOnThrow(true);
evaluateJavaScript(script, "pauseOnThrow");
QVERIFY(m_debuggerAgent->m_wasPaused);
- QCOMPARE(m_debuggerAgent->m_pauseReason, Throwing);
+ QCOMPARE(m_debuggerAgent->m_pauseReason, QV4Debugger::Throwing);
QCOMPARE(m_debuggerAgent->m_stackTrace.size(), 2);
QVERIFY(m_debuggerAgent->m_thrownValue >= qint64(0));
QJsonObject exception = m_debuggerAgent->collector.lookupRef(m_debuggerAgent->m_thrownValue);
@@ -665,9 +659,9 @@ void tst_qv4debugger::breakInCatch()
debugger()->addBreakPoint("breakInCatch", 4);
evaluateJavaScript(script, "breakInCatch");
QVERIFY(m_debuggerAgent->m_wasPaused);
- QCOMPARE(m_debuggerAgent->m_pauseReason, BreakPoint);
+ QCOMPARE(m_debuggerAgent->m_pauseReason, QV4Debugger::BreakPointHit);
QCOMPARE(m_debuggerAgent->m_statesWhenPaused.count(), 1);
- V4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first();
+ QV4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first();
QCOMPARE(state.fileName, QString("breakInCatch"));
QCOMPARE(state.lineNumber, 4);
}
@@ -682,9 +676,9 @@ void tst_qv4debugger::breakInWith()
debugger()->addBreakPoint("breakInWith", 2);
evaluateJavaScript(script, "breakInWith");
QVERIFY(m_debuggerAgent->m_wasPaused);
- QCOMPARE(m_debuggerAgent->m_pauseReason, BreakPoint);
+ QCOMPARE(m_debuggerAgent->m_pauseReason, QV4Debugger::BreakPointHit);
QCOMPARE(m_debuggerAgent->m_statesWhenPaused.count(), 1);
- V4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first();
+ QV4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first();
QCOMPARE(state.fileName, QString("breakInWith"));
QCOMPARE(state.lineNumber, 2);
}
@@ -711,15 +705,13 @@ void tst_qv4debugger::evaluateExpression()
evaluateJavaScript(script, "evaluateExpression");
- QCOMPARE(m_debuggerAgent->m_expressionResults.count(), 2);
- QCOMPARE(m_debuggerAgent->m_expressionResults[0].size(), 1);
- QJsonObject result0 =
- m_debuggerAgent->collector.lookupRef(m_debuggerAgent->m_expressionResults[0].first());
+ QCOMPARE(m_debuggerAgent->m_expressionRefs.count(), 2);
+ QCOMPARE(m_debuggerAgent->m_expressionRefs[0].size(), 1);
+ QJsonObject result0 = m_debuggerAgent->m_expressionRefs[0].first().toObject();
QCOMPARE(result0.value("type").toString(), QStringLiteral("number"));
QCOMPARE(result0.value("value").toInt(), 10);
- QCOMPARE(m_debuggerAgent->m_expressionResults[1].size(), 1);
- QJsonObject result1 =
- m_debuggerAgent->collector.lookupRef(m_debuggerAgent->m_expressionResults[1].first());
+ QCOMPARE(m_debuggerAgent->m_expressionRefs[1].size(), 1);
+ QJsonObject result1 = m_debuggerAgent->m_expressionRefs[1].first().toObject();
QCOMPARE(result1.value("type").toString(), QStringLiteral("number"));
QCOMPARE(result1.value("value").toInt(), 20);
}
diff --git a/tests/auto/qml/debugger/shared/debugutil.cpp b/tests/auto/qml/debugger/shared/debugutil.cpp
index 51d706b818..54720fc848 100644
--- a/tests/auto/qml/debugger/shared/debugutil.cpp
+++ b/tests/auto/qml/debugger/shared/debugutil.cpp
@@ -33,10 +33,12 @@
#include "debugutil_p.h"
-#include <QEventLoop>
-#include <QTimer>
-#include <QFileInfo>
-#include <QDir>
+#include <private/qqmldebugconnection_p.h>
+
+#include <QtCore/qeventloop.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qfileinfo.h>
+#include <QtCore/qdir.h>
bool QQmlDebugTest::waitForSignal(QObject *receiver, const char *member, int timeout) {
QEventLoop loop;
@@ -51,6 +53,46 @@ bool QQmlDebugTest::waitForSignal(QObject *receiver, const char *member, int tim
return timer.isActive();
}
+QList<QQmlDebugClient *> QQmlDebugTest::createOtherClients(QQmlDebugConnection *connection)
+{
+ QList<QQmlDebugClient *> ret;
+ foreach (const QString &service, QQmlDebuggingEnabler::debuggerServices()) {
+ if (!connection->client(service))
+ ret << new QQmlDebugClient(service, connection);
+ }
+ foreach (const QString &service, QQmlDebuggingEnabler::inspectorServices()) {
+ if (!connection->client(service))
+ ret << new QQmlDebugClient(service, connection);
+ }
+ foreach (const QString &service, QQmlDebuggingEnabler::profilerServices()) {
+ if (!connection->client(service))
+ ret << new QQmlDebugClient(service, connection);
+ }
+ return ret;
+}
+
+QString QQmlDebugTest::clientStateString(const QQmlDebugClient *client)
+{
+ if (!client)
+ return QLatin1String("null");
+
+ switch (client->state()) {
+ case QQmlDebugClient::NotConnected: return QLatin1String("Not connected");
+ case QQmlDebugClient::Unavailable: return QLatin1String("Unavailable");
+ case QQmlDebugClient::Enabled: return QLatin1String("Enabled");
+ default: return QLatin1String("Invalid");
+ }
+
+}
+
+QString QQmlDebugTest::connectionStateString(const QQmlDebugConnection *connection)
+{
+ if (!connection)
+ return QLatin1String("null");
+
+ return connection->isConnected() ? QLatin1String("connected") : QLatin1String("not connected");
+}
+
QQmlDebugTestClient::QQmlDebugTestClient(const QString &s, QQmlDebugConnection *c)
: QQmlDebugClient(s, c)
{
diff --git a/tests/auto/qml/debugger/shared/debugutil.pri b/tests/auto/qml/debugger/shared/debugutil.pri
index cb9c761395..1983f3583e 100644
--- a/tests/auto/qml/debugger/shared/debugutil.pri
+++ b/tests/auto/qml/debugger/shared/debugutil.pri
@@ -1,8 +1,4 @@
-HEADERS += $$PWD/debugutil_p.h \
- $$PWD/qqmldebugclient.h \
- $$PWD/../../../../../src/plugins/qmltooling/shared/qpacketprotocol.h
-
-SOURCES += $$PWD/debugutil.cpp \
- $$PWD/qqmldebugclient.cpp \
- $$PWD/../../../../../src/plugins/qmltooling/shared/qpacketprotocol.cpp
+QT += qmldebug-private
+HEADERS += $$PWD/debugutil_p.h
+SOURCES += $$PWD/debugutil.cpp
diff --git a/tests/auto/qml/debugger/shared/debugutil_p.h b/tests/auto/qml/debugger/shared/debugutil_p.h
index d544a89ff2..7ab817a509 100644
--- a/tests/auto/qml/debugger/shared/debugutil_p.h
+++ b/tests/auto/qml/debugger/shared/debugutil_p.h
@@ -32,8 +32,8 @@
**
****************************************************************************/
-#ifndef DEBUGUTIL_H
-#define DEBUGUTIL_H
+#ifndef DEBUGUTIL_P_H
+#define DEBUGUTIL_P_H
//
// W A R N I N G
@@ -46,21 +46,23 @@
// We mean it.
//
-#include <QEventLoop>
-#include <QTimer>
-#include <QThread>
-#include <QTest>
-#include <QProcess>
-#include <QMutex>
+#include <private/qqmldebugclient_p.h>
+#include <QtCore/qeventloop.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qthread.h>
+#include <QtCore/qprocess.h>
+#include <QtCore/qmutex.h>
+#include <QtTest/qtest.h>
#include <QtQml/qqmlengine.h>
-#include "qqmldebugclient.h"
-
class QQmlDebugTest
{
public:
static bool waitForSignal(QObject *receiver, const char *member, int timeout = 5000);
+ static QList<QQmlDebugClient *> createOtherClients(QQmlDebugConnection *connection);
+ static QString clientStateString(const QQmlDebugClient *client);
+ static QString connectionStateString(const QQmlDebugConnection *connection);
};
class QQmlDebugTestClient : public QQmlDebugClient
@@ -128,4 +130,4 @@ private:
int m_receivedBindErrors;
};
-#endif // DEBUGUTIL_H
+#endif // DEBUGUTIL_P_H
diff --git a/tests/auto/qml/debugger/shared/qqmldebugclient.cpp b/tests/auto/qml/debugger/shared/qqmldebugclient.cpp
deleted file mode 100644
index 0f7e572e02..0000000000
--- a/tests/auto/qml/debugger/shared/qqmldebugclient.cpp
+++ /dev/null
@@ -1,511 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqmldebugclient.h"
-#include "../../../../../src/plugins/qmltooling/shared/qpacketprotocol.h"
-
-#include <QtCore/qdebug.h>
-#include <QtCore/qeventloop.h>
-#include <QtCore/qstringlist.h>
-#include <QtCore/qtimer.h>
-#include <QtNetwork/qnetworkproxy.h>
-#include <QtNetwork/qlocalserver.h>
-#include <QtNetwork/qlocalsocket.h>
-
-const int protocolVersion = 1;
-const QString serverId = QLatin1String("QDeclarativeDebugServer");
-const QString clientId = QLatin1String("QDeclarativeDebugClient");
-
-class QQmlDebugClientPrivate
-{
-public:
- QQmlDebugClientPrivate();
-
- QString name;
- QQmlDebugConnection *connection;
-};
-
-class QQmlDebugConnectionPrivate : public QObject
-{
- Q_OBJECT
-public:
- QQmlDebugConnectionPrivate(QQmlDebugConnection *c);
- QQmlDebugConnection *q;
- QPacketProtocol *protocol;
- QIODevice *device;
- QLocalServer *server;
- QEventLoop handshakeEventLoop;
- QTimer handshakeTimer;
-
- bool gotHello;
- QHash <QString, float> serverPlugins;
- QHash<QString, QQmlDebugClient *> plugins;
-
- void advertisePlugins();
- void connectDeviceSignals();
-
-public Q_SLOTS:
- void forwardStateChange(QLocalSocket::LocalSocketState state);
- void forwardError(QLocalSocket::LocalSocketError error);
-
- void newConnection();
- void connected();
- void readyRead();
- void deviceAboutToClose();
- void handshakeTimeout();
-};
-
-QQmlDebugConnectionPrivate::QQmlDebugConnectionPrivate(QQmlDebugConnection *c)
- : QObject(c), q(c), protocol(0), device(0), server(0), gotHello(false)
-{
- protocol = new QPacketProtocol(q, this);
- QObject::connect(c, SIGNAL(connected()), this, SLOT(connected()));
- QObject::connect(protocol, SIGNAL(readyRead()), this, SLOT(readyRead()));
-
- handshakeTimer.setSingleShot(true);
- handshakeTimer.setInterval(3000);
- connect(&handshakeTimer, SIGNAL(timeout()), SLOT(handshakeTimeout()));
-}
-
-void QQmlDebugConnectionPrivate::advertisePlugins()
-{
- if (!q->isConnected())
- return;
-
- QPacket pack;
- pack << serverId << 1 << plugins.keys();
- protocol->send(pack);
- q->flush();
-}
-
-void QQmlDebugConnectionPrivate::connected()
-{
- QPacket pack;
- pack << serverId << 0 << protocolVersion << plugins.keys()
- << q->m_dataStreamVersion;
- protocol->send(pack);
- q->flush();
-}
-
-void QQmlDebugConnectionPrivate::readyRead()
-{
- if (!gotHello) {
- QPacket pack = protocol->read();
- QString name;
-
- pack >> name;
-
- bool validHello = false;
- if (name == clientId) {
- int op = -1;
- pack >> op;
- if (op == 0) {
- int version = -1;
- pack >> version;
- if (version == protocolVersion) {
- QStringList pluginNames;
- QList<float> pluginVersions;
- pack >> pluginNames;
- if (!pack.isEmpty())
- pack >> pluginVersions;
-
- const int pluginNamesSize = pluginNames.size();
- const int pluginVersionsSize = pluginVersions.size();
- for (int i = 0; i < pluginNamesSize; ++i) {
- float pluginVersion = 1.0;
- if (i < pluginVersionsSize)
- pluginVersion = pluginVersions.at(i);
- serverPlugins.insert(pluginNames.at(i), pluginVersion);
- }
-
- pack >> q->m_dataStreamVersion;
- validHello = true;
- }
- }
- }
-
- if (!validHello) {
- qWarning("QQmlDebugConnection: Invalid hello message");
- QObject::disconnect(protocol, SIGNAL(readyRead()), this, SLOT(readyRead()));
- return;
- }
- gotHello = true;
-
- QHash<QString, QQmlDebugClient *>::Iterator iter = plugins.begin();
- for (; iter != plugins.end(); ++iter) {
- QQmlDebugClient::State newState = QQmlDebugClient::Unavailable;
- if (serverPlugins.contains(iter.key()))
- newState = QQmlDebugClient::Enabled;
- iter.value()->stateChanged(newState);
- }
-
- handshakeTimer.stop();
- handshakeEventLoop.quit();
- }
-
- while (protocol->packetsAvailable()) {
- QPacket pack = protocol->read();
- QString name;
- pack >> name;
-
- if (name == clientId) {
- int op = -1;
- pack >> op;
-
- if (op == 1) {
- // Service Discovery
- QHash<QString, float> oldServerPlugins = serverPlugins;
- serverPlugins.clear();
-
- QStringList pluginNames;
- QList<float> pluginVersions;
- pack >> pluginNames;
- if (!pack.isEmpty())
- pack >> pluginVersions;
-
- const int pluginNamesSize = pluginNames.size();
- const int pluginVersionsSize = pluginVersions.size();
- for (int i = 0; i < pluginNamesSize; ++i) {
- float pluginVersion = 1.0;
- if (i < pluginVersionsSize)
- pluginVersion = pluginVersions.at(i);
- serverPlugins.insert(pluginNames.at(i), pluginVersion);
- }
-
- QHash<QString, QQmlDebugClient *>::Iterator iter = plugins.begin();
- for (; iter != plugins.end(); ++iter) {
- const QString pluginName = iter.key();
- QQmlDebugClient::State newSate = QQmlDebugClient::Unavailable;
- if (serverPlugins.contains(pluginName))
- newSate = QQmlDebugClient::Enabled;
-
- if (oldServerPlugins.contains(pluginName)
- != serverPlugins.contains(pluginName)) {
- iter.value()->stateChanged(newSate);
- }
- }
- } else {
- qWarning() << "QQmlDebugConnection: Unknown control message id" << op;
- }
- } else {
- QByteArray message;
- pack >> message;
-
- QHash<QString, QQmlDebugClient *>::Iterator iter =
- plugins.find(name);
- if (iter == plugins.end()) {
- qWarning() << "QQmlDebugConnection: Message received for missing plugin" << name;
- } else {
- (*iter)->messageReceived(message);
- }
- }
- }
-}
-
-void QQmlDebugConnectionPrivate::deviceAboutToClose()
-{
- // This is nasty syntax but we want to emit our own aboutToClose signal (by calling QIODevice::close())
- // without calling the underlying device close fn as that would cause an infinite loop
- q->QIODevice::close();
-}
-
-void QQmlDebugConnectionPrivate::handshakeTimeout()
-{
- if (!gotHello) {
- qWarning() << "Qml Debug Client: Did not get handshake answer in time";
- handshakeEventLoop.quit();
- }
-}
-
-QQmlDebugConnection::QQmlDebugConnection(QObject *parent)
- : QIODevice(parent), d(new QQmlDebugConnectionPrivate(this)),
- m_dataStreamVersion(QDataStream::Qt_5_0)
-{
-}
-
-QQmlDebugConnection::~QQmlDebugConnection()
-{
- QHash<QString, QQmlDebugClient*>::iterator iter = d->plugins.begin();
- for (; iter != d->plugins.end(); ++iter) {
- iter.value()->d->connection = 0;
- iter.value()->stateChanged(QQmlDebugClient::NotConnected);
- }
-}
-
-void QQmlDebugConnection::setDataStreamVersion(int dataStreamVersion)
-{
- m_dataStreamVersion = dataStreamVersion;
-}
-
-int QQmlDebugConnection::dataStreamVersion()
-{
- return m_dataStreamVersion;
-}
-
-bool QQmlDebugConnection::isConnected() const
-{
- return state() == QAbstractSocket::ConnectedState;
-}
-
-qint64 QQmlDebugConnection::readData(char *data, qint64 maxSize)
-{
- return d->device->read(data, maxSize);
-}
-
-qint64 QQmlDebugConnection::writeData(const char *data, qint64 maxSize)
-{
- return d->device->write(data, maxSize);
-}
-
-qint64 QQmlDebugConnection::bytesAvailable() const
-{
- return d->device->bytesAvailable();
-}
-
-bool QQmlDebugConnection::isSequential() const
-{
- return true;
-}
-
-void QQmlDebugConnection::close()
-{
- if (isOpen()) {
- QIODevice::close();
- d->device->close();
- emit stateChanged(QAbstractSocket::UnconnectedState);
-
- QHash<QString, QQmlDebugClient*>::iterator iter = d->plugins.begin();
- for (; iter != d->plugins.end(); ++iter) {
- iter.value()->stateChanged(QQmlDebugClient::NotConnected);
- }
- }
-}
-
-bool QQmlDebugConnection::waitForConnected(int msecs)
-{
- QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(d->device);
- if (!socket) {
- if (!d->server || (!d->server->hasPendingConnections() &&
- !d->server->waitForNewConnection(msecs)))
- return false;
- } else if (!socket->waitForConnected(msecs)) {
- return false;
- }
- // wait for handshake
- d->handshakeTimer.start();
- d->handshakeEventLoop.exec();
- return d->gotHello;
-}
-
-QString QQmlDebugConnection::stateString() const
-{
- QString state;
-
- if (isConnected())
- state = "Connected";
- else
- state = "Not connected";
-
- if (d->gotHello)
- state += ", got hello";
- else
- state += ", did not get hello!";
-
- return state;
-}
-
-QAbstractSocket::SocketState QQmlDebugConnection::state() const
-{
- QAbstractSocket *abstractSocket = qobject_cast<QAbstractSocket*>(d->device);
- if (abstractSocket)
- return abstractSocket->state();
-
- QLocalSocket *localSocket = qobject_cast<QLocalSocket*>(d->device);
- if (localSocket)
- return static_cast<QAbstractSocket::SocketState>(localSocket->state());
-
- return QAbstractSocket::UnconnectedState;
-}
-
-void QQmlDebugConnection::flush()
-{
- QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(d->device);
- if (socket) {
- socket->flush();
- return;
- }
-}
-
-void QQmlDebugConnection::connectToHost(const QString &hostName, quint16 port)
-{
- QTcpSocket *socket = new QTcpSocket(d);
- socket->setProxy(QNetworkProxy::NoProxy);
- d->device = socket;
- d->connectDeviceSignals();
- d->gotHello = false;
- connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SIGNAL(stateChanged(QAbstractSocket::SocketState)));
- connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SIGNAL(error(QAbstractSocket::SocketError)));
- connect(socket, SIGNAL(connected()), this, SIGNAL(connected()));
- socket->connectToHost(hostName, port);
- QIODevice::open(ReadWrite | Unbuffered);
-}
-
-void QQmlDebugConnection::startLocalServer(const QString &fileName)
-{
- d->gotHello = false;
- d->server = new QLocalServer(d);
- // QueuedConnection so that waitForNewConnection() returns true.
- connect(d->server, SIGNAL(newConnection()), d, SLOT(newConnection()), Qt::QueuedConnection);
- d->server->listen(fileName);
- QIODevice::open(ReadWrite | Unbuffered);
-}
-
-void QQmlDebugConnectionPrivate::newConnection()
-{
- QLocalSocket *socket = server->nextPendingConnection();
- server->close();
- device = socket;
- connectDeviceSignals();
- connect(socket, SIGNAL(stateChanged(QLocalSocket::LocalSocketState)),
- this, SLOT(forwardStateChange(QLocalSocket::LocalSocketState)));
- connect(socket, SIGNAL(error(QLocalSocket::LocalSocketError)),
- this, SLOT(forwardError(QLocalSocket::LocalSocketError)));
- emit q->connected();
-}
-
-void QQmlDebugConnectionPrivate::connectDeviceSignals()
-{
- connect(device, SIGNAL(bytesWritten(qint64)), q, SIGNAL(bytesWritten(qint64)));
- connect(device, SIGNAL(readyRead()), q, SIGNAL(readyRead()));
- connect(device, SIGNAL(aboutToClose()), this, SLOT(deviceAboutToClose()));
-}
-
-void QQmlDebugConnectionPrivate::forwardStateChange(QLocalSocket::LocalSocketState state)
-{
- emit q->stateChanged(static_cast<QAbstractSocket::SocketState>(state));
-}
-
-void QQmlDebugConnectionPrivate::forwardError(QLocalSocket::LocalSocketError error)
-{
- emit q->error(static_cast<QAbstractSocket::SocketError>(error));
-}
-
-QQmlDebugClientPrivate::QQmlDebugClientPrivate()
- : connection(0)
-{
-}
-
-QQmlDebugClient::QQmlDebugClient(const QString &name,
- QQmlDebugConnection *parent)
- : QObject(parent),
- d(new QQmlDebugClientPrivate)
-{
- d->name = name;
- d->connection = parent;
-
- if (!d->connection)
- return;
-
- if (d->connection->d->plugins.contains(name)) {
- qWarning() << "QQmlDebugClient: Conflicting plugin name" << name;
- d->connection = 0;
- } else {
- d->connection->d->plugins.insert(name, this);
- d->connection->d->advertisePlugins();
- }
-}
-
-QQmlDebugClient::~QQmlDebugClient()
-{
- if (d->connection && d->connection->d) {
- d->connection->d->plugins.remove(d->name);
- d->connection->d->advertisePlugins();
- }
- delete d;
-}
-
-QString QQmlDebugClient::name() const
-{
- return d->name;
-}
-
-float QQmlDebugClient::serviceVersion() const
-{
- if (d->connection->d->serverPlugins.contains(d->name))
- return d->connection->d->serverPlugins.value(d->name);
- return -1;
-}
-
-QQmlDebugClient::State QQmlDebugClient::state() const
-{
- if (!d->connection
- || !d->connection->isConnected()
- || !d->connection->d->gotHello)
- return NotConnected;
-
- if (d->connection->d->serverPlugins.contains(d->name))
- return Enabled;
-
- return Unavailable;
-}
-
-QString QQmlDebugClient::stateString() const
-{
- switch (state()) {
- case NotConnected: return QLatin1String("Not connected");
- case Unavailable: return QLatin1String("Unavailable");
- case Enabled: return QLatin1String("Enabled");
- }
- return QLatin1String("Invalid");
-}
-
-void QQmlDebugClient::sendMessage(const QByteArray &message)
-{
- if (state() != Enabled)
- return;
-
- QPacket pack;
- pack << d->name << message;
- d->connection->d->protocol->send(pack);
- d->connection->flush();
-}
-
-void QQmlDebugClient::stateChanged(State)
-{
-}
-
-void QQmlDebugClient::messageReceived(const QByteArray &)
-{
-}
-
-#include <qqmldebugclient.moc>
diff --git a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp
index 9b48b40c07..ef5c3e09ca 100644
--- a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp
+++ b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp
@@ -32,7 +32,7 @@
****************************************************************************/
#include "qqmlenginedebugclient.h"
-#include "qdatastream.h"
+#include <private/qqmldebugconnection_p.h>
struct QmlObjectData {
QUrl url;
@@ -46,7 +46,7 @@ struct QmlObjectData {
int parentId;
};
-QDataStream &operator>>(QDataStream &ds, QmlObjectData &data)
+QPacket &operator>>(QPacket &ds, QmlObjectData &data)
{
ds >> data.url >> data.lineNumber >> data.columnNumber >> data.idString
>> data.objectName >> data.objectType >> data.objectId >> data.contextId
@@ -64,7 +64,7 @@ struct QmlObjectProperty {
bool hasNotifySignal;
};
-QDataStream &operator>>(QDataStream &ds, QmlObjectProperty &data)
+QPacket &operator>>(QPacket &ds, QmlObjectProperty &data)
{
int type;
ds >> type >> data.name >> data.value >> data.valueTypeName
@@ -77,8 +77,7 @@ QQmlEngineDebugClient::QQmlEngineDebugClient(
QQmlDebugConnection *connection)
: QQmlDebugClient(QLatin1String("QmlDebugger"), connection),
m_nextId(0),
- m_valid(false),
- m_connection(connection)
+ m_valid(false)
{
}
@@ -89,11 +88,10 @@ quint32 QQmlEngineDebugClient::addWatch(
*success = false;
if (state() == QQmlDebugClient::Enabled) {
id = getId();
- QByteArray message;
- QDataStream ds(&message, QIODevice::WriteOnly);
+ QPacket ds(connection()->currentDataStreamVersion());
ds << QByteArray("WATCH_PROPERTY") << id << property.objectDebugId
<< property.name.toUtf8();
- sendMessage(message);
+ sendMessage(ds.data());
*success = true;
}
return id;
@@ -115,10 +113,9 @@ quint32 QQmlEngineDebugClient::addWatch(
*success = false;
if (state() == QQmlDebugClient::Enabled) {
id = getId();
- QByteArray message;
- QDataStream ds(&message, QIODevice::WriteOnly);
+ QPacket ds(connection()->currentDataStreamVersion());
ds << QByteArray("WATCH_EXPR_OBJECT") << id << object.debugId << expr;
- sendMessage(message);
+ sendMessage(ds.data());
*success = true;
}
return id;
@@ -131,10 +128,9 @@ quint32 QQmlEngineDebugClient::addWatch(
*success = false;
if (state() == QQmlDebugClient::Enabled) {
id = getId();
- QByteArray message;
- QDataStream ds(&message, QIODevice::WriteOnly);
+ QPacket ds(connection()->currentDataStreamVersion());
ds << QByteArray("WATCH_OBJECT") << id << object.debugId;
- sendMessage(message);
+ sendMessage(ds.data());
*success = true;
}
return id;
@@ -152,10 +148,9 @@ void QQmlEngineDebugClient::removeWatch(quint32 id, bool *success)
{
*success = false;
if (state() == QQmlDebugClient::Enabled) {
- QByteArray message;
- QDataStream ds(&message, QIODevice::WriteOnly);
+ QPacket ds(connection()->currentDataStreamVersion());
ds << QByteArray("NO_WATCH") << id;
- sendMessage(message);
+ sendMessage(ds.data());
*success = true;
}
}
@@ -167,10 +162,9 @@ quint32 QQmlEngineDebugClient::queryAvailableEngines(bool *success)
*success = false;
if (state() == QQmlDebugClient::Enabled) {
id = getId();
- QByteArray message;
- QDataStream ds(&message, QIODevice::WriteOnly);
+ QPacket ds(connection()->currentDataStreamVersion());
ds << QByteArray("LIST_ENGINES") << id;
- sendMessage(message);
+ sendMessage(ds.data());
*success = true;
}
return id;
@@ -184,10 +178,9 @@ quint32 QQmlEngineDebugClient::queryRootContexts(
*success = false;
if (state() == QQmlDebugClient::Enabled && engine.debugId != -1) {
id = getId();
- QByteArray message;
- QDataStream ds(&message, QIODevice::WriteOnly);
+ QPacket ds(connection()->currentDataStreamVersion());
ds << QByteArray("LIST_OBJECTS") << id << engine.debugId;
- sendMessage(message);
+ sendMessage(ds.data());
*success = true;
}
return id;
@@ -201,11 +194,9 @@ quint32 QQmlEngineDebugClient::queryObject(
*success = false;
if (state() == QQmlDebugClient::Enabled && object.debugId != -1) {
id = getId();
- QByteArray message;
- QDataStream ds(&message, QIODevice::WriteOnly);
- ds << QByteArray("FETCH_OBJECT") << id << object.debugId << false <<
- true;
- sendMessage(message);
+ QPacket ds(connection()->currentDataStreamVersion());
+ ds << QByteArray("FETCH_OBJECT") << id << object.debugId << false << true;
+ sendMessage(ds.data());
*success = true;
}
return id;
@@ -219,11 +210,10 @@ quint32 QQmlEngineDebugClient::queryObjectsForLocation(
*success = false;
if (state() == QQmlDebugClient::Enabled) {
id = getId();
- QByteArray message;
- QDataStream ds(&message, QIODevice::WriteOnly);
+ QPacket ds(connection()->currentDataStreamVersion());
ds << QByteArray("FETCH_OBJECTS_FOR_LOCATION") << id << file << lineNumber
<< columnNumber << false << true;
- sendMessage(message);
+ sendMessage(ds.data());
*success = true;
}
return id;
@@ -237,11 +227,9 @@ quint32 QQmlEngineDebugClient::queryObjectRecursive(
*success = false;
if (state() == QQmlDebugClient::Enabled && object.debugId != -1) {
id = getId();
- QByteArray message;
- QDataStream ds(&message, QIODevice::WriteOnly);
- ds << QByteArray("FETCH_OBJECT") << id << object.debugId << true <<
- true;
- sendMessage(message);
+ QPacket ds(connection()->currentDataStreamVersion());
+ ds << QByteArray("FETCH_OBJECT") << id << object.debugId << true << true;
+ sendMessage(ds.data());
*success = true;
}
return id;
@@ -255,11 +243,10 @@ quint32 QQmlEngineDebugClient::queryObjectsForLocationRecursive(const QString &f
*success = false;
if (state() == QQmlDebugClient::Enabled) {
id = getId();
- QByteArray message;
- QDataStream ds(&message, QIODevice::WriteOnly);
+ QPacket ds(connection()->currentDataStreamVersion());
ds << QByteArray("FETCH_OBJECTS_FOR_LOCATION") << id << file << lineNumber
<< columnNumber << true << true;
- sendMessage(message);
+ sendMessage(ds.data());
*success = true;
}
return id;
@@ -273,11 +260,10 @@ quint32 QQmlEngineDebugClient::queryExpressionResult(
*success = false;
if (state() == QQmlDebugClient::Enabled) {
id = getId();
- QByteArray message;
- QDataStream ds(&message, QIODevice::WriteOnly);
+ QPacket ds(connection()->currentDataStreamVersion());
ds << QByteArray("EVAL_EXPRESSION") << id << objectDebugId << expr
<< engines()[0].debugId;
- sendMessage(message);
+ sendMessage(ds.data());
*success = true;
}
return id;
@@ -291,10 +277,9 @@ quint32 QQmlEngineDebugClient::queryExpressionResultBC(
*success = false;
if (state() == QQmlDebugClient::Enabled) {
id = getId();
- QByteArray message;
- QDataStream ds(&message, QIODevice::WriteOnly);
+ QPacket ds(connection()->currentDataStreamVersion());
ds << QByteArray("EVAL_EXPRESSION") << id << objectDebugId << expr;
- sendMessage(message);
+ sendMessage(ds.data());
*success = true;
}
return id;
@@ -312,11 +297,10 @@ quint32 QQmlEngineDebugClient::setBindingForObject(
*success = false;
if (state() == QQmlDebugClient::Enabled && objectDebugId != -1) {
id = getId();
- QByteArray message;
- QDataStream ds(&message, QIODevice::WriteOnly);
+ QPacket ds(connection()->currentDataStreamVersion());
ds << QByteArray("SET_BINDING") << id << objectDebugId << propertyName
<< bindingExpression << isLiteralValue << source << line;
- sendMessage(message);
+ sendMessage(ds.data());
*success = true;
}
return id;
@@ -331,10 +315,9 @@ quint32 QQmlEngineDebugClient::resetBindingForObject(
*success = false;
if (state() == QQmlDebugClient::Enabled && objectDebugId != -1) {
id = getId();
- QByteArray message;
- QDataStream ds(&message, QIODevice::WriteOnly);
+ QPacket ds(connection()->currentDataStreamVersion());
ds << QByteArray("RESET_BINDING") << id << objectDebugId << propertyName;
- sendMessage(message);
+ sendMessage(ds.data());
*success = true;
}
return id;
@@ -348,17 +331,16 @@ quint32 QQmlEngineDebugClient::setMethodBody(
*success = false;
if (state() == QQmlDebugClient::Enabled && objectDebugId != -1) {
id = getId();
- QByteArray message;
- QDataStream ds(&message, QIODevice::WriteOnly);
+ QPacket ds(connection()->currentDataStreamVersion());
ds << QByteArray("SET_METHOD_BODY") << id << objectDebugId
<< methodName << methodBody;
- sendMessage(message);
+ sendMessage(ds.data());
*success = true;
}
return id;
}
-void QQmlEngineDebugClient::decode(QDataStream &ds,
+void QQmlEngineDebugClient::decode(QPacket &ds,
QmlDebugObjectReference &o,
bool simple)
{
@@ -419,7 +401,7 @@ void QQmlEngineDebugClient::decode(QDataStream &ds,
}
}
-void QQmlEngineDebugClient::decode(QDataStream &ds,
+void QQmlEngineDebugClient::decode(QPacket &ds,
QList<QmlDebugObjectReference> &o,
bool simple)
{
@@ -432,7 +414,7 @@ void QQmlEngineDebugClient::decode(QDataStream &ds,
}
}
-void QQmlEngineDebugClient::decode(QDataStream &ds,
+void QQmlEngineDebugClient::decode(QPacket &ds,
QmlDebugContextReference &c)
{
ds >> c.name >> c.debugId;
@@ -460,9 +442,7 @@ void QQmlEngineDebugClient::decode(QDataStream &ds,
void QQmlEngineDebugClient::messageReceived(const QByteArray &data)
{
m_valid = false;
- QDataStream ds(data);
- ds.setVersion(m_connection->dataStreamVersion());
-
+ QPacket ds(connection()->currentDataStreamVersion(), data);
int queryId;
QByteArray type;
diff --git a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h
index 28adb8b159..cd80a8ed46 100644
--- a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h
+++ b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h
@@ -34,13 +34,12 @@
#ifndef QQMLENGINEDEBUGCLIENT_H
#define QQMLENGINEDEBUGCLIENT_H
-#include "qqmldebugclient.h"
+#include <private/qqmldebugclient_p.h>
+#include <private/qpacket_p.h>
#include <QtCore/qurl.h>
#include <QtCore/qvariant.h>
-class QQmlDebugConnection;
-
struct QmlDebugPropertyReference
{
QmlDebugPropertyReference()
@@ -207,9 +206,9 @@ public:
quint32 getId() { return m_nextId++; }
- void decode(QDataStream &, QmlDebugContextReference &);
- void decode(QDataStream &, QmlDebugObjectReference &, bool simple);
- void decode(QDataStream &ds, QList<QmlDebugObjectReference> &o, bool simple);
+ void decode(QPacket &ds, QmlDebugContextReference &);
+ void decode(QPacket &ds, QmlDebugObjectReference &, bool simple);
+ void decode(QPacket &ds, QList<QmlDebugObjectReference> &o, bool simple);
QList<QmlDebugEngineReference> engines() { return m_engines; }
QmlDebugContextReference rootContext() { return m_rootContext; }
@@ -234,8 +233,6 @@ private:
QmlDebugObjectReference m_object;
QList<QmlDebugObjectReference> m_objects;
QVariant m_exprResult;
-
- QQmlDebugConnection *m_connection;
};
#endif // QQMLENGINEDEBUGCLIENT_H
diff --git a/tests/auto/qml/debugger/shared/qqmlinspectorclient.cpp b/tests/auto/qml/debugger/shared/qqmlinspectorclient.cpp
index a46bd9012b..5fce58c17d 100644
--- a/tests/auto/qml/debugger/shared/qqmlinspectorclient.cpp
+++ b/tests/auto/qml/debugger/shared/qqmlinspectorclient.cpp
@@ -32,33 +32,34 @@
****************************************************************************/
#include "qqmlinspectorclient.h"
-#include "qdatastream.h"
+
+#include <private/qpacket_p.h>
+#include <private/qqmldebugconnection_p.h>
+#include <QtCore/qdebug.h>
void QQmlInspectorClient::setShowAppOnTop(bool showOnTop)
{
- QByteArray message;
- QDataStream ds(&message, QIODevice::WriteOnly);
+ QPacket ds(connection()->currentDataStreamVersion());
ds << QByteArray("request") << m_requestId++
<< QByteArray("showAppOnTop") << showOnTop;
- sendMessage(message);
+ sendMessage(ds.data());
}
void QQmlInspectorClient::reloadQml(const QHash<QString, QByteArray> &changesHash)
{
- QByteArray message;
- QDataStream ds(&message, QIODevice::WriteOnly);
+ QPacket ds(connection()->currentDataStreamVersion());
m_reloadRequestId = m_requestId;
ds << QByteArray("request") << m_requestId++
<< QByteArray("reload") << changesHash;
- sendMessage(message);
+ sendMessage(ds.data());
}
void QQmlInspectorClient::messageReceived(const QByteArray &message)
{
- QDataStream ds(message);
+ QPacket ds(connection()->currentDataStreamVersion(), message);
QByteArray type;
ds >> type;
diff --git a/tests/auto/qml/debugger/shared/qqmlinspectorclient.h b/tests/auto/qml/debugger/shared/qqmlinspectorclient.h
index a8b42c8430..964dac7701 100644
--- a/tests/auto/qml/debugger/shared/qqmlinspectorclient.h
+++ b/tests/auto/qml/debugger/shared/qqmlinspectorclient.h
@@ -33,7 +33,7 @@
#ifndef QQMLINSPECTORCLIENT_H
#define QQMLINSPECTORCLIENT_H
-#include "qqmldebugclient.h"
+#include <private/qqmldebugclient_p.h>
class QQmlInspectorClient : public QQmlDebugClient
{
diff --git a/tests/auto/qml/parserstress/parserstress.pro b/tests/auto/qml/parserstress/parserstress.pro
index 8d92d69494..7c37745585 100644
--- a/tests/auto/qml/parserstress/parserstress.pro
+++ b/tests/auto/qml/parserstress/parserstress.pro
@@ -6,7 +6,5 @@ SOURCES += tst_parserstress.cpp
TESTDATA = tests/*
-CONFIG += parallel_test
QT += core-private gui-private qml-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qjsengine/qjsengine.pro b/tests/auto/qml/qjsengine/qjsengine.pro
index fc2452c2bc..c9d78e22a0 100644
--- a/tests/auto/qml/qjsengine/qjsengine.pro
+++ b/tests/auto/qml/qjsengine/qjsengine.pro
@@ -1,5 +1,4 @@
CONFIG += testcase
-CONFIG += parallel_test
TARGET = tst_qjsengine
QT += qml qml-private widgets testlib gui-private
macx:CONFIG -= app_bundle
@@ -7,4 +6,3 @@ SOURCES += tst_qjsengine.cpp
RESOURCES += qjsengine.qrc
TESTDATA = script/*
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qjsonbinding/qjsonbinding.pro b/tests/auto/qml/qjsonbinding/qjsonbinding.pro
index a54eab198b..75b48aa854 100644
--- a/tests/auto/qml/qjsonbinding/qjsonbinding.pro
+++ b/tests/auto/qml/qjsonbinding/qjsonbinding.pro
@@ -12,6 +12,4 @@ include (../../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
QT += core qml testlib gui-private
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qjsvalue/qjsvalue.pro b/tests/auto/qml/qjsvalue/qjsvalue.pro
index d914d40762..3bbbbd4787 100644
--- a/tests/auto/qml/qjsvalue/qjsvalue.pro
+++ b/tests/auto/qml/qjsvalue/qjsvalue.pro
@@ -1,8 +1,6 @@
CONFIG += testcase
-CONFIG += parallel_test
TARGET = tst_qjsvalue
macx:CONFIG -= app_bundle
QT += qml widgets testlib gui-private
SOURCES += tst_qjsvalue.cpp
HEADERS += tst_qjsvalue.h
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
index bf9bd18807..0d15268d6f 100644
--- a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
+++ b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
@@ -540,7 +540,7 @@ void tst_QJSValue::toBoolean() // deprecated
QCOMPARE(number.toBool(), false);
QCOMPARE(qjsvalue_cast<bool>(number), false);
- QJSValue number2 = eng.toScriptValue(qSNaN());
+ QJSValue number2 = eng.toScriptValue(qQNaN());
QCOMPARE(number2.toBool(), false);
QCOMPARE(qjsvalue_cast<bool>(number2), false);
@@ -583,7 +583,7 @@ void tst_QJSValue::toBoolean() // deprecated
QCOMPARE(number.toBool(), false);
QCOMPARE(qjsvalue_cast<bool>(number), false);
- QJSValue number2 = QJSValue(qSNaN());
+ QJSValue number2 = QJSValue(qQNaN());
QCOMPARE(number2.toBool(), false);
QCOMPARE(qjsvalue_cast<bool>(number2), false);
@@ -633,7 +633,7 @@ void tst_QJSValue::toBool()
QCOMPARE(number.toBool(), false);
QCOMPARE(qjsvalue_cast<bool>(number), false);
- QJSValue number2 = eng.toScriptValue(qSNaN());
+ QJSValue number2 = eng.toScriptValue(qQNaN());
QCOMPARE(number2.toBool(), false);
QCOMPARE(qjsvalue_cast<bool>(number2), false);
@@ -676,7 +676,7 @@ void tst_QJSValue::toBool()
QCOMPARE(number.toBool(), false);
QCOMPARE(qjsvalue_cast<bool>(number), false);
- QJSValue number2 = QJSValue(qSNaN());
+ QJSValue number2 = QJSValue(qQNaN());
QCOMPARE(number2.toBool(), false);
QCOMPARE(qjsvalue_cast<bool>(number2), false);
@@ -714,7 +714,7 @@ void tst_QJSValue::toInt()
QCOMPARE(number.toInt(), 123);
QCOMPARE(qjsvalue_cast<qint32>(number), 123);
- QJSValue number2 = eng.toScriptValue(qSNaN());
+ QJSValue number2 = eng.toScriptValue(qQNaN());
QCOMPARE(number2.toInt(), 0);
QCOMPARE(qjsvalue_cast<qint32>(number2), 0);
@@ -776,7 +776,7 @@ void tst_QJSValue::toInt()
QCOMPARE(number.toInt(), 123);
QCOMPARE(qjsvalue_cast<qint32>(number), 123);
- QJSValue number2 = QJSValue(qSNaN());
+ QJSValue number2 = QJSValue(qQNaN());
QCOMPARE(number2.toInt(), 0);
QCOMPARE(qjsvalue_cast<qint32>(number2), 0);
@@ -850,7 +850,7 @@ void tst_QJSValue::toUInt()
QCOMPARE(number.toUInt(), quint32(123));
QCOMPARE(qjsvalue_cast<quint32>(number), quint32(123));
- QJSValue number2 = eng.toScriptValue(qSNaN());
+ QJSValue number2 = eng.toScriptValue(qQNaN());
QCOMPARE(number2.toUInt(), quint32(0));
QCOMPARE(qjsvalue_cast<quint32>(number2), quint32(0));
@@ -910,7 +910,7 @@ void tst_QJSValue::toUInt()
QCOMPARE(number.toUInt(), quint32(123));
QCOMPARE(qjsvalue_cast<quint32>(number), quint32(123));
- QJSValue number2 = QJSValue(qSNaN());
+ QJSValue number2 = QJSValue(qQNaN());
QCOMPARE(number2.toUInt(), quint32(0));
QCOMPARE(qjsvalue_cast<quint32>(number2), quint32(0));
@@ -1015,7 +1015,7 @@ void tst_QJSValue::toVariant()
{
QVariant var = qobject.toVariant();
QCOMPARE(var.userType(), int(QMetaType::QObjectStar));
- QCOMPARE(qVariantValue<QObject*>(var), (QObject *)&temp);
+ QCOMPARE(qvariant_cast<QObject*>(var), (QObject *)&temp);
}
{
diff --git a/tests/auto/qml/qjsvalueiterator/qjsvalueiterator.pro b/tests/auto/qml/qjsvalueiterator/qjsvalueiterator.pro
index 9f4d4fb371..4ee1693ad8 100644
--- a/tests/auto/qml/qjsvalueiterator/qjsvalueiterator.pro
+++ b/tests/auto/qml/qjsvalueiterator/qjsvalueiterator.pro
@@ -1,9 +1,7 @@
CONFIG += testcase
-CONFIG += parallel_test
TARGET = tst_qjsvalueiterator
macx:CONFIG -= app_bundle
QT = core qml testlib
SOURCES += tst_qjsvalueiterator.cpp
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qml.pro b/tests/auto/qml/qml.pro
index 66c19098ef..5e798f3b48 100644
--- a/tests/auto/qml/qml.pro
+++ b/tests/auto/qml/qml.pro
@@ -57,7 +57,6 @@ PRIVATETESTS += \
qrcqml \
qqmltimer \
qqmlinstantiator \
- qv4debugger \
qqmlenginecleanup \
v4misc \
qqmltranslation \
diff --git a/tests/auto/qml/qmlmin/qmlmin.pro b/tests/auto/qml/qmlmin/qmlmin.pro
index 03b60aea19..6af6653270 100644
--- a/tests/auto/qml/qmlmin/qmlmin.pro
+++ b/tests/auto/qml/qmlmin/qmlmin.pro
@@ -6,7 +6,5 @@ macx:CONFIG -= app_bundle
SOURCES += tst_qmlmin.cpp
DEFINES += SRCDIR=\\\"$$PWD\\\"
-CONFIG += parallel_test
cross_compile: DEFINES += QTEST_CROSS_COMPILED
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qmlplugindump/qmlplugindump.pro b/tests/auto/qml/qmlplugindump/qmlplugindump.pro
index 902bcad585..c713edc541 100644
--- a/tests/auto/qml/qmlplugindump/qmlplugindump.pro
+++ b/tests/auto/qml/qmlplugindump/qmlplugindump.pro
@@ -2,7 +2,5 @@ CONFIG += testcase
TARGET = tst_qmlplugindump
QT += testlib gui-private
macx:CONFIG -= app_bundle
-CONFIG += parallel_test
SOURCES += tst_qmlplugindump.cpp
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlbinding/qqmlbinding.pro b/tests/auto/qml/qqmlbinding/qqmlbinding.pro
index 35a5f1ca74..45298f8ffc 100644
--- a/tests/auto/qml/qqmlbinding/qqmlbinding.pro
+++ b/tests/auto/qml/qqmlbinding/qqmlbinding.pro
@@ -8,7 +8,4 @@ include (../../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlchangeset/qqmlchangeset.pro b/tests/auto/qml/qqmlchangeset/qqmlchangeset.pro
index b65e58c0b3..9f854f1fa2 100644
--- a/tests/auto/qml/qqmlchangeset/qqmlchangeset.pro
+++ b/tests/auto/qml/qqmlchangeset/qqmlchangeset.pro
@@ -4,7 +4,4 @@ macx:CONFIG -= app_bundle
SOURCES += tst_qqmlchangeset.cpp
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlcomponent/qqmlcomponent.pro b/tests/auto/qml/qqmlcomponent/qqmlcomponent.pro
index 8151bacd75..9f8c8a4e24 100644
--- a/tests/auto/qml/qqmlcomponent/qqmlcomponent.pro
+++ b/tests/auto/qml/qqmlcomponent/qqmlcomponent.pro
@@ -13,4 +13,3 @@ include (../../shared/util.pri)
TESTDATA = data/*
QT += core-private gui-private qml-private quick-private network testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlconnections/data/test-connection.qml b/tests/auto/qml/qqmlconnections/data/test-connection.qml
index ce851fc3db..f44cbc047f 100644
--- a/tests/auto/qml/qqmlconnections/data/test-connection.qml
+++ b/tests/auto/qml/qqmlconnections/data/test-connection.qml
@@ -6,5 +6,5 @@ Item {
property bool tested: false
signal testMe
- Connections { target: screen; onWidthChanged: screen.tested = true }
+ Connections { objectName: "connections"; target: screen; onWidthChanged: screen.tested = true }
}
diff --git a/tests/auto/qml/qqmlconnections/qqmlconnections.pro b/tests/auto/qml/qqmlconnections/qqmlconnections.pro
index 7004ee0385..99cc4d0d0b 100644
--- a/tests/auto/qml/qqmlconnections/qqmlconnections.pro
+++ b/tests/auto/qml/qqmlconnections/qqmlconnections.pro
@@ -8,7 +8,4 @@ include (../../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp
index e529c74acc..b148baab35 100644
--- a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp
+++ b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp
@@ -56,6 +56,7 @@ private slots:
void errors();
void rewriteErrors();
void singletonTypeTarget();
+ void enableDisable_QTBUG_36350();
private:
QQmlEngine engine;
@@ -329,6 +330,33 @@ void tst_qqmlconnections::singletonTypeTarget()
delete object;
}
+void tst_qqmlconnections::enableDisable_QTBUG_36350()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("test-connection.qml"));
+ QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
+ QVERIFY(item != 0);
+
+ QQmlConnections *connections = item->findChild<QQmlConnections*>("connections");
+ QVERIFY(connections);
+
+ connections->setEnabled(false);
+ QCOMPARE(item->property("tested").toBool(), false);
+ QCOMPARE(item->width(), 50.);
+ emit item->setWidth(100.);
+ QCOMPARE(item->width(), 100.);
+ QCOMPARE(item->property("tested").toBool(), false); //Should not have received signal to change property
+
+ connections->setEnabled(true); //Re-enable the connectSignals()
+ QCOMPARE(item->property("tested").toBool(), false);
+ QCOMPARE(item->width(), 100.);
+ emit item->setWidth(50.);
+ QCOMPARE(item->width(), 50.);
+ QCOMPARE(item->property("tested").toBool(), true); //Should have received signal to change property
+
+ delete item;
+}
+
QTEST_MAIN(tst_qqmlconnections)
#include "tst_qqmlconnections.moc"
diff --git a/tests/auto/qml/qqmlconsole/qqmlconsole.pro b/tests/auto/qml/qqmlconsole/qqmlconsole.pro
index 0f3f10bd89..99192c4b16 100644
--- a/tests/auto/qml/qqmlconsole/qqmlconsole.pro
+++ b/tests/auto/qml/qqmlconsole/qqmlconsole.pro
@@ -8,7 +8,4 @@ macx:CONFIG -= app_bundle
TESTDATA = data/*
-CONFIG += parallel_test
-
QT += qml testlib gui-private
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlcontext/qqmlcontext.pro b/tests/auto/qml/qqmlcontext/qqmlcontext.pro
index 2fb299cb10..19e5c1072a 100644
--- a/tests/auto/qml/qqmlcontext/qqmlcontext.pro
+++ b/tests/auto/qml/qqmlcontext/qqmlcontext.pro
@@ -8,7 +8,4 @@ macx:CONFIG -= app_bundle
TESTDATA = data/*
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlcpputils/qqmlcpputils.pro b/tests/auto/qml/qqmlcpputils/qqmlcpputils.pro
index 75436dd8e2..bc692a6e78 100644
--- a/tests/auto/qml/qqmlcpputils/qqmlcpputils.pro
+++ b/tests/auto/qml/qqmlcpputils/qqmlcpputils.pro
@@ -4,7 +4,4 @@ macx:CONFIG -= app_bundle
SOURCES += tst_qqmlcpputils.cpp
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmldirparser/qqmldirparser.pro b/tests/auto/qml/qqmldirparser/qqmldirparser.pro
index 0be38a0a35..dda74b1ef9 100644
--- a/tests/auto/qml/qqmldirparser/qqmldirparser.pro
+++ b/tests/auto/qml/qqmldirparser/qqmldirparser.pro
@@ -6,6 +6,3 @@ macx:CONFIG -= app_bundle
SOURCES += tst_qqmldirparser.cpp
include (../../shared/util.pri)
-
-CONFIG += parallel_test
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlecmascript/qqmlecmascript.pro b/tests/auto/qml/qqmlecmascript/qqmlecmascript.pro
index 6f3f765aba..101181bba0 100644
--- a/tests/auto/qml/qqmlecmascript/qqmlecmascript.pro
+++ b/tests/auto/qml/qqmlecmascript/qqmlecmascript.pro
@@ -20,5 +20,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private network testlib
qtHaveModule(widgets): QT += widgets
-
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index b30dfcbd0b..5a7732fa9a 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -4910,7 +4910,7 @@ void tst_qqmlecmascript::propertyVarImplicitOwnership()
QCOMPARE(rootObject->property("rectCanary").toInt(), 5);
QCOMPARE(childObject->property("textCanary").toInt(), 10);
QMetaObject::invokeMethod(childObject, "constructQObject"); // creates a reference to a constructed QObject.
- QWeakPointer<QObject> qobjectGuard(childObject->property("vp").value<QObject*>()); // get the pointer prior to processing deleteLater events.
+ QPointer<QObject> qobjectGuard(childObject->property("vp").value<QObject*>()); // get the pointer prior to processing deleteLater events.
QVERIFY(!qobjectGuard.isNull());
QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); // process deleteLater() events from QV8QObjectWrapper.
QCoreApplication::processEvents();
@@ -4933,9 +4933,9 @@ void tst_qqmlecmascript::propertyVarReparent()
QObject *rect = object->property("vp").value<QObject*>();
QObject *text = rect->findChild<QObject*>("textOne");
QObject *text2 = rect->findChild<QObject*>("textTwo");
- QWeakPointer<QObject> rectGuard(rect);
- QWeakPointer<QObject> textGuard(text);
- QWeakPointer<QObject> text2Guard(text2);
+ QPointer<QObject> rectGuard(rect);
+ QPointer<QObject> textGuard(text);
+ QPointer<QObject> text2Guard(text2);
QVERIFY(!rectGuard.isNull());
QVERIFY(!textGuard.isNull());
QVERIFY(!text2Guard.isNull());
@@ -4944,7 +4944,7 @@ void tst_qqmlecmascript::propertyVarReparent()
// now construct an image which we will reparent.
QMetaObject::invokeMethod(text2, "constructQObject");
QObject *image = text2->property("vp").value<QObject*>();
- QWeakPointer<QObject> imageGuard(image);
+ QPointer<QObject> imageGuard(image);
QVERIFY(!imageGuard.isNull());
QCOMPARE(image->property("imageCanary").toInt(), 13);
// now reparent the "Image" object (currently, it has JS ownership)
@@ -4975,9 +4975,9 @@ void tst_qqmlecmascript::propertyVarReparentNullContext()
QObject *rect = object->property("vp").value<QObject*>();
QObject *text = rect->findChild<QObject*>("textOne");
QObject *text2 = rect->findChild<QObject*>("textTwo");
- QWeakPointer<QObject> rectGuard(rect);
- QWeakPointer<QObject> textGuard(text);
- QWeakPointer<QObject> text2Guard(text2);
+ QPointer<QObject> rectGuard(rect);
+ QPointer<QObject> textGuard(text);
+ QPointer<QObject> text2Guard(text2);
QVERIFY(!rectGuard.isNull());
QVERIFY(!textGuard.isNull());
QVERIFY(!text2Guard.isNull());
@@ -4986,7 +4986,7 @@ void tst_qqmlecmascript::propertyVarReparentNullContext()
// now construct an image which we will reparent.
QMetaObject::invokeMethod(text2, "constructQObject");
QObject *image = text2->property("vp").value<QObject*>();
- QWeakPointer<QObject> imageGuard(image);
+ QPointer<QObject> imageGuard(image);
QVERIFY(!imageGuard.isNull());
QCOMPARE(image->property("imageCanary").toInt(), 13);
// now reparent the "Image" object (currently, it has JS ownership)
@@ -5044,9 +5044,9 @@ void tst_qqmlecmascript::propertyVarCircular2()
QVERIFY(rootObject != 0);
QObject *childObject = rootObject->findChild<QObject*>("text");
QVERIFY(childObject != 0);
- QWeakPointer<QObject> rootObjectTracker(rootObject);
+ QPointer<QObject> rootObjectTracker(rootObject);
QVERIFY(!rootObjectTracker.isNull());
- QWeakPointer<QObject> childObjectTracker(childObject);
+ QPointer<QObject> childObjectTracker(childObject);
QVERIFY(!childObjectTracker.isNull());
gc(engine);
QCOMPARE(rootObject->property("rectCanary").toInt(), 5);
@@ -6613,8 +6613,7 @@ void tst_qqmlecmascript::urlPropertyWithEncoding()
MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
QVERIFY(object != 0);
object->setStringProperty("http://qt-project.org");
- QUrl encoded;
- encoded.setEncodedUrl("http://qt-project.org/?get%3cDATA%3e", QUrl::TolerantMode);
+ const QUrl encoded = QUrl::fromEncoded("http://qt-project.org/?get%3cDATA%3e", QUrl::TolerantMode);
QCOMPARE(object->urlProperty(), encoded);
QCOMPARE(object->value(), 0); // Interpreting URL as string yields canonicalised version
QCOMPARE(object->property("result").toBool(), true);
@@ -6632,8 +6631,7 @@ void tst_qqmlecmascript::urlListPropertyWithEncoding()
MySequenceConversionObject *msco3 = object->findChild<MySequenceConversionObject *>(QLatin1String("msco3"));
MySequenceConversionObject *msco4 = object->findChild<MySequenceConversionObject *>(QLatin1String("msco4"));
QVERIFY(msco1 != 0 && msco2 != 0 && msco3 != 0 && msco4 != 0);
- QUrl encoded;
- encoded.setEncodedUrl("http://qt-project.org/?get%3cDATA%3e", QUrl::TolerantMode);
+ const QUrl encoded = QUrl::fromEncoded("http://qt-project.org/?get%3cDATA%3e", QUrl::TolerantMode);
QCOMPARE(msco1->urlListProperty(), (QList<QUrl>() << encoded));
QCOMPARE(msco2->urlListProperty(), (QList<QUrl>() << encoded));
QCOMPARE(msco3->urlListProperty(), (QList<QUrl>() << encoded << encoded));
@@ -7332,7 +7330,7 @@ void tst_qqmlecmascript::sequenceSort_data()
QString fnName = QLatin1String("test_") + testName;
bool useComparer = c != 0;
testName += useComparer ? QLatin1String("[custom]") : QLatin1String("[default]");
- QTest::newRow(testName.toAscii().constData()) << fnName << useComparer;
+ QTest::newRow(testName.toLatin1().constData()) << fnName << useComparer;
}
}
}
@@ -7351,7 +7349,7 @@ void tst_qqmlecmascript::sequenceSort()
QVERIFY(object != 0);
QVariant q;
- QMetaObject::invokeMethod(object, function.toAscii().constData(), Q_RETURN_ARG(QVariant, q), Q_ARG(QVariant, useComparer));
+ QMetaObject::invokeMethod(object, function.toLatin1().constData(), Q_RETURN_ARG(QVariant, q), Q_ARG(QVariant, useComparer));
QVERIFY(q.toBool());
delete object;
diff --git a/tests/auto/qml/qqmlengine/qqmlengine.pro b/tests/auto/qml/qqmlengine/qqmlengine.pro
index e84512fae3..e7952d8e3a 100644
--- a/tests/auto/qml/qqmlengine/qqmlengine.pro
+++ b/tests/auto/qml/qqmlengine/qqmlengine.pro
@@ -7,4 +7,3 @@ include (../../shared/util.pri)
SOURCES += tst_qqmlengine.cpp
QT += core-private gui-private qml-private network testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlenginecleanup/qqmlenginecleanup.pro b/tests/auto/qml/qqmlenginecleanup/qqmlenginecleanup.pro
index 6428933233..5bcec9f5b4 100644
--- a/tests/auto/qml/qqmlenginecleanup/qqmlenginecleanup.pro
+++ b/tests/auto/qml/qqmlenginecleanup/qqmlenginecleanup.pro
@@ -7,4 +7,3 @@ include (../../shared/util.pri)
SOURCES += tst_qqmlenginecleanup.cpp
QT += testlib qml
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlerror/qqmlerror.pro b/tests/auto/qml/qqmlerror/qqmlerror.pro
index 5339f8740b..17a1d1dec7 100644
--- a/tests/auto/qml/qqmlerror/qqmlerror.pro
+++ b/tests/auto/qml/qqmlerror/qqmlerror.pro
@@ -6,9 +6,6 @@ include (../../shared/util.pri)
macx:CONFIG -= app_bundle
-CONFIG += parallel_test
-
TESTDATA = data/*
QT += core-private gui-private qml-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlexpression/qqmlexpression.pro b/tests/auto/qml/qqmlexpression/qqmlexpression.pro
index 45545b084e..5b1d397555 100644
--- a/tests/auto/qml/qqmlexpression/qqmlexpression.pro
+++ b/tests/auto/qml/qqmlexpression/qqmlexpression.pro
@@ -8,7 +8,4 @@ include (../../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlfileselector/qqmlfileselector.pro b/tests/auto/qml/qqmlfileselector/qqmlfileselector.pro
index 3475fa4b1d..8a55f4de9c 100644
--- a/tests/auto/qml/qqmlfileselector/qqmlfileselector.pro
+++ b/tests/auto/qml/qqmlfileselector/qqmlfileselector.pro
@@ -8,6 +8,4 @@ include (../../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
QT += core-private gui-private qml-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlglobal/qqmlglobal.pro b/tests/auto/qml/qqmlglobal/qqmlglobal.pro
index d0d9fc400e..dbc8806de7 100644
--- a/tests/auto/qml/qqmlglobal/qqmlglobal.pro
+++ b/tests/auto/qml/qqmlglobal/qqmlglobal.pro
@@ -3,6 +3,4 @@ TARGET = tst_qqmlglobal
SOURCES += tst_qqmlglobal.cpp
macx:CONFIG -= app_bundle
-CONFIG += parallel_test
QT += qml-private testlib core-private gui-private
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlimport/qqmlimport.pro b/tests/auto/qml/qqmlimport/qqmlimport.pro
index 6c99c00570..c8b0f68d9f 100644
--- a/tests/auto/qml/qqmlimport/qqmlimport.pro
+++ b/tests/auto/qml/qqmlimport/qqmlimport.pro
@@ -6,6 +6,3 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qqmlimport.cpp
include (../../shared/util.pri)
-
-CONFIG += parallel_test
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp
index c53977482b..1f495c3581 100644
--- a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp
+++ b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp
@@ -43,6 +43,7 @@ class tst_QQmlImport : public QQmlDataTest
Q_OBJECT
private slots:
+ void importPathOrder();
void testDesignerSupported();
void uiFormatLoading();
void cleanup();
@@ -81,7 +82,7 @@ void tst_QQmlImport::testDesignerSupported()
warningString.remove('\r');
#endif
warningString = warningString.arg(testFileUrl("testfile_unsupported.qml").toString());
- QTest::ignoreMessage(QtWarningMsg, warningString.toAscii());
+ QTest::ignoreMessage(QtWarningMsg, warningString.toLocal8Bit());
window->setSource(testFileUrl("testfile_unsupported.qml"));
QVERIFY(!window->errors().isEmpty());
@@ -127,6 +128,29 @@ void tst_QQmlImport::uiFormatLoading()
delete test;
}
+void tst_QQmlImport::importPathOrder()
+{
+ QStringList expectedImportPaths;
+ QString appDirPath = QCoreApplication::applicationDirPath();
+ QString qml2Imports = QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath);
+#ifdef Q_OS_WIN
+ // The drive letter has a different case as QQmlImport will
+ // cause it to be converted after passing through QUrl
+ appDirPath[0] = appDirPath[0].toUpper();
+ qml2Imports[0] = qml2Imports[0].toUpper();
+#endif
+ expectedImportPaths << appDirPath
+ << QLatin1String("qrc:/qt-project.org/imports")
+ << qml2Imports;
+ QQmlEngine engine;
+ QCOMPARE(expectedImportPaths, engine.importPathList());
+
+ // Add an import path
+ engine.addImportPath(QT_QMLTEST_DATADIR);
+ expectedImportPaths.prepend(QT_QMLTEST_DATADIR);
+ QCOMPARE(expectedImportPaths, engine.importPathList());
+}
+
QTEST_MAIN(tst_QQmlImport)
#include "tst_qqmlimport.moc"
diff --git a/tests/auto/qml/qqmlincubator/qqmlincubator.pro b/tests/auto/qml/qqmlincubator/qqmlincubator.pro
index 9249061912..e5fa45f1d3 100644
--- a/tests/auto/qml/qqmlincubator/qqmlincubator.pro
+++ b/tests/auto/qml/qqmlincubator/qqmlincubator.pro
@@ -11,7 +11,5 @@ include (../../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
QT += core-private gui-private qml-private network testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlinfo/qqmlinfo.pro b/tests/auto/qml/qqmlinfo/qqmlinfo.pro
index e813982210..89b4abd00c 100644
--- a/tests/auto/qml/qqmlinfo/qqmlinfo.pro
+++ b/tests/auto/qml/qqmlinfo/qqmlinfo.pro
@@ -8,6 +8,4 @@ include (../../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
QT += core-private gui-private qml-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlitemmodels/qqmlitemmodels.pro b/tests/auto/qml/qqmlitemmodels/qqmlitemmodels.pro
index f76c6d0d25..d50c630003 100644
--- a/tests/auto/qml/qqmlitemmodels/qqmlitemmodels.pro
+++ b/tests/auto/qml/qqmlitemmodels/qqmlitemmodels.pro
@@ -9,10 +9,7 @@ include (../../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
-
QT += core qml testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
DISTFILES += \
data/modelindex.qml \
diff --git a/tests/auto/qml/qqmllanguage/qqmllanguage.pro b/tests/auto/qml/qqmllanguage/qqmllanguage.pro
index f0c8bb6c1b..99c0c3e823 100644
--- a/tests/auto/qml/qqmllanguage/qqmllanguage.pro
+++ b/tests/auto/qml/qqmllanguage/qqmllanguage.pro
@@ -15,7 +15,6 @@ TESTDATA = data/*
QT += core-private gui-private qml-private network testlib
include (../../shared/util.pri)
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
OTHER_FILES += \
data/readonlyObjectProperty.qml
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index 1f299c0dbb..32b0d9661f 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -677,8 +677,7 @@ void tst_qqmllanguage::assignBasicTypes()
QCOMPARE(object->variantProperty(), QVariant("Hello World!"));
QCOMPARE(object->vectorProperty(), QVector3D(10, 1, 2.2f));
QCOMPARE(object->vector4Property(), QVector4D(10, 1, 2.2f, 2.3f));
- QUrl encoded;
- encoded.setEncodedUrl("main.qml?with%3cencoded%3edata", QUrl::TolerantMode);
+ const QUrl encoded = QUrl::fromEncoded("main.qml?with%3cencoded%3edata", QUrl::TolerantMode);
QCOMPARE(object->urlProperty(), component.url().resolved(encoded));
QVERIFY(object->objectProperty() != 0);
MyTypeObject *child = qobject_cast<MyTypeObject *>(object->objectProperty());
@@ -1156,8 +1155,7 @@ void tst_qqmllanguage::bindTypeToJSValue()
} {
MyQmlObject *object = root->findChild<MyQmlObject *>("urlProperty");
QJSValue value = object->qjsvalue();
- QUrl encoded;
- encoded.setEncodedUrl("main.qml?with%3cencoded%3edata", QUrl::TolerantMode);
+ const QUrl encoded = QUrl::fromEncoded("main.qml?with%3cencoded%3edata", QUrl::TolerantMode);
QCOMPARE(value.toString(), component.url().resolved(encoded).toString());
} {
MyQmlObject *object = root->findChild<MyQmlObject *>("objectProperty");
diff --git a/tests/auto/qml/qqmllistcompositor/qqmllistcompositor.pro b/tests/auto/qml/qqmllistcompositor/qqmllistcompositor.pro
index e6c9dc3a29..4ada590a2a 100644
--- a/tests/auto/qml/qqmllistcompositor/qqmllistcompositor.pro
+++ b/tests/auto/qml/qqmllistcompositor/qqmllistcompositor.pro
@@ -4,7 +4,4 @@ macx:CONFIG -= app_bundle
SOURCES += tst_qqmllistcompositor.cpp
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmllistmodel/qqmllistmodel.pro b/tests/auto/qml/qqmllistmodel/qqmllistmodel.pro
index 1555dc2b2c..8e3aed0baf 100644
--- a/tests/auto/qml/qqmllistmodel/qqmllistmodel.pro
+++ b/tests/auto/qml/qqmllistmodel/qqmllistmodel.pro
@@ -8,7 +8,4 @@ include (../../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmllistmodelworkerscript/qqmllistmodelworkerscript.pro b/tests/auto/qml/qqmllistmodelworkerscript/qqmllistmodelworkerscript.pro
index 7647c3d713..9e1cea9867 100644
--- a/tests/auto/qml/qqmllistmodelworkerscript/qqmllistmodelworkerscript.pro
+++ b/tests/auto/qml/qqmllistmodelworkerscript/qqmllistmodelworkerscript.pro
@@ -9,4 +9,3 @@ include (../../shared/util.pri)
TESTDATA = data/*
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmllistreference/qqmllistreference.pro b/tests/auto/qml/qqmllistreference/qqmllistreference.pro
index f30b245975..dceb7d1133 100644
--- a/tests/auto/qml/qqmllistreference/qqmllistreference.pro
+++ b/tests/auto/qml/qqmllistreference/qqmllistreference.pro
@@ -8,7 +8,4 @@ include (../../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmllocale/qqmllocale.pro b/tests/auto/qml/qqmllocale/qqmllocale.pro
index 6d8eccd61c..d3d022b44e 100644
--- a/tests/auto/qml/qqmllocale/qqmllocale.pro
+++ b/tests/auto/qml/qqmllocale/qqmllocale.pro
@@ -8,7 +8,5 @@ include (../../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
QT += qml testlib gui-private
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlmetaobject/qqmlmetaobject.pro b/tests/auto/qml/qqmlmetaobject/qqmlmetaobject.pro
index 87f70852fa..03aaf8ecdd 100644
--- a/tests/auto/qml/qqmlmetaobject/qqmlmetaobject.pro
+++ b/tests/auto/qml/qqmlmetaobject/qqmlmetaobject.pro
@@ -8,6 +8,4 @@ include (../../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
QT += qml testlib gui-private
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlmetatype/qqmlmetatype.pro b/tests/auto/qml/qqmlmetatype/qqmlmetatype.pro
index 54a6e0507f..0d8de91931 100644
--- a/tests/auto/qml/qqmlmetatype/qqmlmetatype.pro
+++ b/tests/auto/qml/qqmlmetatype/qqmlmetatype.pro
@@ -6,6 +6,4 @@ macx:CONFIG -= app_bundle
TESTDATA = data/*
include (../../shared/util.pri)
-CONFIG += parallel_test
QT += core-private gui-private qml-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlmoduleplugin/invalidFirstCommandModule/invalidFirstCommandModule.pro b/tests/auto/qml/qqmlmoduleplugin/invalidFirstCommandModule/invalidFirstCommandModule.pro
index 9a6ee63b88..523c6eaea1 100644
--- a/tests/auto/qml/qqmlmoduleplugin/invalidFirstCommandModule/invalidFirstCommandModule.pro
+++ b/tests/auto/qml/qqmlmoduleplugin/invalidFirstCommandModule/invalidFirstCommandModule.pro
@@ -10,4 +10,3 @@ IMPORT_FILES = \
qmldir
include (../../../shared/imports.pri)
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlmoduleplugin/invalidNamespaceModule/invalidNamespaceModule.pro b/tests/auto/qml/qqmlmoduleplugin/invalidNamespaceModule/invalidNamespaceModule.pro
index 002f177cfd..4a8ce58edc 100644
--- a/tests/auto/qml/qqmlmoduleplugin/invalidNamespaceModule/invalidNamespaceModule.pro
+++ b/tests/auto/qml/qqmlmoduleplugin/invalidNamespaceModule/invalidNamespaceModule.pro
@@ -10,4 +10,3 @@ IMPORT_FILES = \
qmldir
include (../../../shared/imports.pri)
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/invalidStrictModule.pro b/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/invalidStrictModule.pro
index 562d109179..150f2f08d3 100644
--- a/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/invalidStrictModule.pro
+++ b/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/invalidStrictModule.pro
@@ -10,4 +10,3 @@ IMPORT_FILES = \
qmldir
include (../../../shared/imports.pri)
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlmoduleplugin/nestedPlugin/nestedPlugin.pro b/tests/auto/qml/qqmlmoduleplugin/nestedPlugin/nestedPlugin.pro
index 5636941951..eca74e9bef 100644
--- a/tests/auto/qml/qqmlmoduleplugin/nestedPlugin/nestedPlugin.pro
+++ b/tests/auto/qml/qqmlmoduleplugin/nestedPlugin/nestedPlugin.pro
@@ -10,4 +10,3 @@ IMPORT_FILES = \
qmldir
include (../../../shared/imports.pri)
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlmoduleplugin/nonstrictModule/nonstrictModule.pro b/tests/auto/qml/qqmlmoduleplugin/nonstrictModule/nonstrictModule.pro
index 0d900eb707..49d290132b 100644
--- a/tests/auto/qml/qqmlmoduleplugin/nonstrictModule/nonstrictModule.pro
+++ b/tests/auto/qml/qqmlmoduleplugin/nonstrictModule/nonstrictModule.pro
@@ -10,4 +10,3 @@ IMPORT_FILES = \
qmldir
include (../../../shared/imports.pri)
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlmoduleplugin/plugin.2.1/plugin.2.1.pro b/tests/auto/qml/qqmlmoduleplugin/plugin.2.1/plugin.2.1.pro
index 445b98d647..9389679f2d 100644
--- a/tests/auto/qml/qqmlmoduleplugin/plugin.2.1/plugin.2.1.pro
+++ b/tests/auto/qml/qqmlmoduleplugin/plugin.2.1/plugin.2.1.pro
@@ -10,4 +10,3 @@ IMPORT_FILES = \
qmldir
include (../../../shared/imports.pri)
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlmoduleplugin/plugin.2/plugin.2.pro b/tests/auto/qml/qqmlmoduleplugin/plugin.2/plugin.2.pro
index 00c076d9cf..76544aa553 100644
--- a/tests/auto/qml/qqmlmoduleplugin/plugin.2/plugin.2.pro
+++ b/tests/auto/qml/qqmlmoduleplugin/plugin.2/plugin.2.pro
@@ -11,4 +11,3 @@ IMPORT_FILES = \
qmldir
include (../../../shared/imports.pri)
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlmoduleplugin/plugin/plugin.pro b/tests/auto/qml/qqmlmoduleplugin/plugin/plugin.pro
index 3a0455569e..bd1399b1aa 100644
--- a/tests/auto/qml/qqmlmoduleplugin/plugin/plugin.pro
+++ b/tests/auto/qml/qqmlmoduleplugin/plugin/plugin.pro
@@ -10,4 +10,3 @@ IMPORT_FILES = \
qmldir
include (../../../shared/imports.pri)
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlmoduleplugin/pluginMixed/pluginMixed.pro b/tests/auto/qml/qqmlmoduleplugin/pluginMixed/pluginMixed.pro
index d3b237b0f7..c7e0f6dc09 100644
--- a/tests/auto/qml/qqmlmoduleplugin/pluginMixed/pluginMixed.pro
+++ b/tests/auto/qml/qqmlmoduleplugin/pluginMixed/pluginMixed.pro
@@ -11,4 +11,3 @@ IMPORT_FILES = \
qmldir
include (../../../shared/imports.pri)
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlmoduleplugin/pluginVersion/pluginVersion.pro b/tests/auto/qml/qqmlmoduleplugin/pluginVersion/pluginVersion.pro
index 5cec9b8ebd..bc9ee5c102 100644
--- a/tests/auto/qml/qqmlmoduleplugin/pluginVersion/pluginVersion.pro
+++ b/tests/auto/qml/qqmlmoduleplugin/pluginVersion/pluginVersion.pro
@@ -10,4 +10,3 @@ IMPORT_FILES = \
qmldir
include (../../../shared/imports.pri)
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlmoduleplugin/pluginWithQmlFile/pluginWithQmlFile.pro b/tests/auto/qml/qqmlmoduleplugin/pluginWithQmlFile/pluginWithQmlFile.pro
index ba66d60f18..9decde52bf 100644
--- a/tests/auto/qml/qqmlmoduleplugin/pluginWithQmlFile/pluginWithQmlFile.pro
+++ b/tests/auto/qml/qqmlmoduleplugin/pluginWithQmlFile/pluginWithQmlFile.pro
@@ -11,4 +11,3 @@ IMPORT_FILES = \
MyQmlFile.qml
include (../../../shared/imports.pri)
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlmoduleplugin/pluginWrongCase/pluginWrongCase.pro b/tests/auto/qml/qqmlmoduleplugin/pluginWrongCase/pluginWrongCase.pro
index 99bac141de..26f553ea89 100644
--- a/tests/auto/qml/qqmlmoduleplugin/pluginWrongCase/pluginWrongCase.pro
+++ b/tests/auto/qml/qqmlmoduleplugin/pluginWrongCase/pluginWrongCase.pro
@@ -11,4 +11,3 @@ IMPORT_FILES = \
qmldir
include (../../../shared/imports.pri)
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlmoduleplugin/preemptedStrictModule/preemptedStrictModule.pro b/tests/auto/qml/qqmlmoduleplugin/preemptedStrictModule/preemptedStrictModule.pro
index 22926bf1ca..45255800f3 100644
--- a/tests/auto/qml/qqmlmoduleplugin/preemptedStrictModule/preemptedStrictModule.pro
+++ b/tests/auto/qml/qqmlmoduleplugin/preemptedStrictModule/preemptedStrictModule.pro
@@ -10,4 +10,3 @@ IMPORT_FILES = \
qmldir
include (../../../shared/imports.pri)
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlmoduleplugin/preemptiveModule/preemptiveModule.pro b/tests/auto/qml/qqmlmoduleplugin/preemptiveModule/preemptiveModule.pro
index c07f0621f7..745d1dc405 100644
--- a/tests/auto/qml/qqmlmoduleplugin/preemptiveModule/preemptiveModule.pro
+++ b/tests/auto/qml/qqmlmoduleplugin/preemptiveModule/preemptiveModule.pro
@@ -10,4 +10,3 @@ IMPORT_FILES = \
qmldir
include (../../../shared/imports.pri)
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlmoduleplugin/protectedModule/protectedModule.pro b/tests/auto/qml/qqmlmoduleplugin/protectedModule/protectedModule.pro
index 749a440ca8..fb64f4415f 100644
--- a/tests/auto/qml/qqmlmoduleplugin/protectedModule/protectedModule.pro
+++ b/tests/auto/qml/qqmlmoduleplugin/protectedModule/protectedModule.pro
@@ -10,4 +10,3 @@ IMPORT_FILES = \
qmldir
include (../../../shared/imports.pri)
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro b/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro
index b715c6b82e..5c30d8cc00 100644
--- a/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro
+++ b/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro
@@ -22,6 +22,4 @@ SUBDIRS =\
tst_qqmlmoduleplugin_pro.depends += plugin
SUBDIRS += tst_qqmlmoduleplugin.pro
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private
diff --git a/tests/auto/qml/qqmlmoduleplugin/strictModule.2/strictModule.2.pro b/tests/auto/qml/qqmlmoduleplugin/strictModule.2/strictModule.2.pro
index 14f3c59c21..b87cd19e0d 100644
--- a/tests/auto/qml/qqmlmoduleplugin/strictModule.2/strictModule.2.pro
+++ b/tests/auto/qml/qqmlmoduleplugin/strictModule.2/strictModule.2.pro
@@ -10,4 +10,3 @@ IMPORT_FILES = \
qmldir
include (../../../shared/imports.pri)
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlmoduleplugin/strictModule/strictModule.pro b/tests/auto/qml/qqmlmoduleplugin/strictModule/strictModule.pro
index bf1c5df1a7..aedca480d3 100644
--- a/tests/auto/qml/qqmlmoduleplugin/strictModule/strictModule.pro
+++ b/tests/auto/qml/qqmlmoduleplugin/strictModule/strictModule.pro
@@ -10,4 +10,3 @@ IMPORT_FILES = \
qmldir
include (../../../shared/imports.pri)
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.pro b/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.pro
index c483ef8ccd..43bd112415 100644
--- a/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.pro
+++ b/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.pro
@@ -11,4 +11,3 @@ include (../../shared/util.pri)
TESTDATA = data/* imports/* $$OUT_PWD/imports/*
QT += core-private gui-private qml-private network testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlobjectmodel/qqmlobjectmodel.pro b/tests/auto/qml/qqmlobjectmodel/qqmlobjectmodel.pro
index f8232f8854..88bb630e29 100644
--- a/tests/auto/qml/qqmlobjectmodel/qqmlobjectmodel.pro
+++ b/tests/auto/qml/qqmlobjectmodel/qqmlobjectmodel.pro
@@ -4,7 +4,5 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qqmlobjectmodel.cpp
-CONFIG += parallel_test
-
QT += qml testlib
QT += core-private qml-private
diff --git a/tests/auto/qml/qqmlopenmetaobject/qqmlopenmetaobject.pro b/tests/auto/qml/qqmlopenmetaobject/qqmlopenmetaobject.pro
index c81394e77e..f29a444395 100644
--- a/tests/auto/qml/qqmlopenmetaobject/qqmlopenmetaobject.pro
+++ b/tests/auto/qml/qqmlopenmetaobject/qqmlopenmetaobject.pro
@@ -4,6 +4,4 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qqmlopenmetaobject.cpp
-CONFIG += parallel_test
QT += core-private gui-private qml-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlparser/qqmlparser.pro b/tests/auto/qml/qqmlparser/qqmlparser.pro
index c666b71d6c..74cb620f06 100644
--- a/tests/auto/qml/qqmlparser/qqmlparser.pro
+++ b/tests/auto/qml/qqmlparser/qqmlparser.pro
@@ -6,7 +6,4 @@ macx:CONFIG -= app_bundle
SOURCES += tst_qqmlparser.cpp
DEFINES += SRCDIR=\\\"$$PWD\\\"
-CONFIG += parallel_test
-
cross_compile: DEFINES += QTEST_CROSS_COMPILED
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlproperty/data/floatToStringPrecision.qml b/tests/auto/qml/qqmlproperty/data/floatToStringPrecision.qml
index a0429e0cc8..a1ff0c527a 100644
--- a/tests/auto/qml/qqmlproperty/data/floatToStringPrecision.qml
+++ b/tests/auto/qml/qqmlproperty/data/floatToStringPrecision.qml
@@ -2,9 +2,27 @@ import QtQuick 2.0
QtObject {
property double a: 3.4
- property string b: a
+ property string a1: a
+ property string a2: a + ""
- property double c: 0.035003945
- property string d: c
+ property double b: 0.035003945
+ property string b1: b
+ property string b2: b + ""
+
+ property double c: 0.0000012345
+ property string c1: c
+ property string c2: c + ""
+
+ property double d: 0.00000012345
+ property string d1: d
+ property string d2: d + ""
+
+ property double e: 100000000000000000000
+ property string e1: e
+ property string e2: e + ""
+
+ property double f: 1000000000000000000000
+ property string f1: f
+ property string f2: f + ""
}
diff --git a/tests/auto/qml/qqmlproperty/qqmlproperty.pro b/tests/auto/qml/qqmlproperty/qqmlproperty.pro
index c2177d5fbf..b1bcf1f17d 100644
--- a/tests/auto/qml/qqmlproperty/qqmlproperty.pro
+++ b/tests/auto/qml/qqmlproperty/qqmlproperty.pro
@@ -8,7 +8,4 @@ include (../../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
index 6ada14ce79..fbbc10b0a1 100644
--- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
+++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
@@ -147,6 +147,8 @@ private slots:
void registeredCompositeTypeProperty();
void deeplyNestedObject();
void readOnlyDynamicProperties();
+
+ void floatToStringPrecision_data();
void floatToStringPrecision();
void copy();
@@ -2055,23 +2057,43 @@ void tst_qqmlproperty::readOnlyDynamicProperties()
delete obj;
}
+void tst_qqmlproperty::floatToStringPrecision_data()
+{
+ QTest::addColumn<QString>("propertyName");
+ QTest::addColumn<double>("number");
+ QTest::addColumn<QString>("qtString");
+ QTest::addColumn<QString>("jsString");
+
+ QTest::newRow("3.4") << "a" << 3.4 << "3.4" << "3.4";
+ QTest::newRow("0.035003945") << "b" << 0.035003945 << "0.035003945" << "0.035003945";
+ QTest::newRow("0.0000012345") << "c" << 0.0000012345 << "1.2345e-6" << "0.0000012345";
+ QTest::newRow("0.00000012345") << "d" << 0.00000012345 << "1.2345e-7" << "1.2345e-7";
+ QTest::newRow("1e20") << "e" << 1e20 << "1e+20" << "100000000000000000000";
+ QTest::newRow("1e21") << "f" << 1e21 << "1e+21" << "1e+21";
+}
+
void tst_qqmlproperty::floatToStringPrecision()
{
QQmlComponent comp(&engine, testFileUrl("floatToStringPrecision.qml"));
QObject *obj = comp.create();
QVERIFY(obj != 0);
- QCOMPARE(obj->property("a").toDouble(), 3.4);
- QEXPECT_FAIL("", "QVariant's double-to-string conversion is worse than V4's.", Continue);
- QCOMPARE(obj->property("a").toString(), QLatin1String("3.4"));
- QCOMPARE(obj->property("b").toDouble(), 3.4);
- QCOMPARE(obj->property("b").toString(), QLatin1String("3.4"));
-
- QCOMPARE(obj->property("c").toDouble(), 0.035003945);
- QEXPECT_FAIL("", "QVariant's double-to-string conversion is worse than V4's.", Continue);
- QCOMPARE(obj->property("c").toString(), QLatin1String("0.035003945"));
- QCOMPARE(obj->property("d").toDouble(), 0.035003945);
- QCOMPARE(obj->property("d").toString(), QLatin1String("0.035003945"));
+ QFETCH(QString, propertyName);
+ QFETCH(double, number);
+ QFETCH(QString, qtString);
+ QFETCH(QString, jsString);
+
+ const char *name = propertyName.toLatin1().constData();
+ QCOMPARE(obj->property(name).toDouble(), number);
+ QCOMPARE(obj->property(name).toString(), qtString);
+
+ const char *name1 = (propertyName + QLatin1Char('1')).toLatin1().constData();
+ QCOMPARE(obj->property(name1).toDouble(), number);
+ QCOMPARE(obj->property(name1).toString(), qtString);
+
+ const char *name2 = (propertyName + QLatin1Char('2')).toLatin1().constData();
+ QCOMPARE(obj->property(name2).toDouble(), number);
+ QCOMPARE(obj->property(name2).toString(), jsString);
delete obj;
}
diff --git a/tests/auto/qml/qqmlpropertycache/qqmlpropertycache.pro b/tests/auto/qml/qqmlpropertycache/qqmlpropertycache.pro
index 7cc83cd440..9a04c899fe 100644
--- a/tests/auto/qml/qqmlpropertycache/qqmlpropertycache.pro
+++ b/tests/auto/qml/qqmlpropertycache/qqmlpropertycache.pro
@@ -4,6 +4,4 @@ macx:CONFIG -= app_bundle
SOURCES += tst_qqmlpropertycache.cpp
-CONFIG += parallel_test
QT += core-private gui-private qml-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlpropertymap/qqmlpropertymap.pro b/tests/auto/qml/qqmlpropertymap/qqmlpropertymap.pro
index 81212bb064..8da300171d 100644
--- a/tests/auto/qml/qqmlpropertymap/qqmlpropertymap.pro
+++ b/tests/auto/qml/qqmlpropertymap/qqmlpropertymap.pro
@@ -6,7 +6,4 @@ SOURCES += tst_qqmlpropertymap.cpp
include (../../shared/util.pri)
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlqt/qqmlqt.pro b/tests/auto/qml/qqmlqt/qqmlqt.pro
index 0470156e28..74306d704f 100644
--- a/tests/auto/qml/qqmlqt/qqmlqt.pro
+++ b/tests/auto/qml/qqmlqt/qqmlqt.pro
@@ -9,4 +9,3 @@ macx:CONFIG -= app_bundle
TESTDATA = data/*
QT += core-private qml-private quick-private testlib gui gui-private
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlsettings/qqmlsettings.pro b/tests/auto/qml/qqmlsettings/qqmlsettings.pro
index efcef27f7e..392f496dc8 100644
--- a/tests/auto/qml/qqmlsettings/qqmlsettings.pro
+++ b/tests/auto/qml/qqmlsettings/qqmlsettings.pro
@@ -9,4 +9,3 @@ include (../../shared/util.pri)
TESTDATA = data/*
QT += qml testlib
-CONFIG += parallel_test
diff --git a/tests/auto/qml/qqmlsqldatabase/qqmlsqldatabase.pro b/tests/auto/qml/qqmlsqldatabase/qqmlsqldatabase.pro
index c32f3c6c34..fbb873b649 100644
--- a/tests/auto/qml/qqmlsqldatabase/qqmlsqldatabase.pro
+++ b/tests/auto/qml/qqmlsqldatabase/qqmlsqldatabase.pro
@@ -9,4 +9,3 @@ include (../../shared/util.pri)
TESTDATA = data/*
QT += core-private gui-private qml-private quick-private sql testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlstatemachine/qqmlstatemachine.pro b/tests/auto/qml/qqmlstatemachine/qqmlstatemachine.pro
index 002af1d707..635f2fa5e0 100644
--- a/tests/auto/qml/qqmlstatemachine/qqmlstatemachine.pro
+++ b/tests/auto/qml/qqmlstatemachine/qqmlstatemachine.pro
@@ -6,6 +6,4 @@ SOURCES += tst_qqmlstatemachine.cpp
include (../../shared/util.pri)
-CONFIG += parallel_test
QT += core-private gui-private qml-private quick-private gui testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmltimer/qqmltimer.pro b/tests/auto/qml/qqmltimer/qqmltimer.pro
index 28f8e6959f..da66bc87ca 100644
--- a/tests/auto/qml/qqmltimer/qqmltimer.pro
+++ b/tests/auto/qml/qqmltimer/qqmltimer.pro
@@ -4,6 +4,4 @@ macx:CONFIG -= app_bundle
SOURCES += tst_qqmltimer.cpp
-CONFIG += parallel_test
QT += core-private gui-private qml-private quick-private gui testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmltranslation/qqmltranslation.pro b/tests/auto/qml/qqmltranslation/qqmltranslation.pro
index 6ccec6fc7d..ac329a204b 100644
--- a/tests/auto/qml/qqmltranslation/qqmltranslation.pro
+++ b/tests/auto/qml/qqmltranslation/qqmltranslation.pro
@@ -9,7 +9,4 @@ include (../../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.pro b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.pro
index 9e2261df8d..3a20e94741 100644
--- a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.pro
+++ b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.pro
@@ -7,5 +7,3 @@ SOURCES += tst_qqmltypeloader.cpp
include (../../shared/util.pri)
-CONFIG += parallel_test
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlvaluetypeproviders/qqmlvaluetypeproviders.pro b/tests/auto/qml/qqmlvaluetypeproviders/qqmlvaluetypeproviders.pro
index 7ef81e0cc4..0c36088853 100644
--- a/tests/auto/qml/qqmlvaluetypeproviders/qqmlvaluetypeproviders.pro
+++ b/tests/auto/qml/qqmlvaluetypeproviders/qqmlvaluetypeproviders.pro
@@ -11,7 +11,4 @@ include (../../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private quick-private gui testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlvaluetypes/qqmlvaluetypes.pro b/tests/auto/qml/qqmlvaluetypes/qqmlvaluetypes.pro
index e36be45f41..36b36d2f0e 100644
--- a/tests/auto/qml/qqmlvaluetypes/qqmlvaluetypes.pro
+++ b/tests/auto/qml/qqmlvaluetypes/qqmlvaluetypes.pro
@@ -11,10 +11,7 @@ include (../../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private quick-private gui testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
DISTFILES += \
data/customvaluetype.qml
diff --git a/tests/auto/qml/qqmlxmlhttprequest/qqmlxmlhttprequest.pro b/tests/auto/qml/qqmlxmlhttprequest/qqmlxmlhttprequest.pro
index fcfdf23d33..44b2963918 100644
--- a/tests/auto/qml/qqmlxmlhttprequest/qqmlxmlhttprequest.pro
+++ b/tests/auto/qml/qqmlxmlhttprequest/qqmlxmlhttprequest.pro
@@ -13,4 +13,3 @@ include (../../shared/util.pri)
TESTDATA = data/*
QT += core-private gui-private qml-private network testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qquickfolderlistmodel/qquickfolderlistmodel.pro b/tests/auto/qml/qquickfolderlistmodel/qquickfolderlistmodel.pro
index c4fdcdc7dd..23b9117889 100644
--- a/tests/auto/qml/qquickfolderlistmodel/qquickfolderlistmodel.pro
+++ b/tests/auto/qml/qquickfolderlistmodel/qquickfolderlistmodel.pro
@@ -8,8 +8,6 @@ include (../../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
QT += core-private gui-private qml-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
RESOURCES += data/introspect.qrc
diff --git a/tests/auto/qml/qquickworkerscript/qquickworkerscript.pro b/tests/auto/qml/qquickworkerscript/qquickworkerscript.pro
index 268b45f4e7..be8b9089a2 100644
--- a/tests/auto/qml/qquickworkerscript/qquickworkerscript.pro
+++ b/tests/auto/qml/qquickworkerscript/qquickworkerscript.pro
@@ -8,7 +8,4 @@ include (../../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qrcqml/qrcqml.pro b/tests/auto/qml/qrcqml/qrcqml.pro
index 3bbc6d6085..60ccba27f2 100644
--- a/tests/auto/qml/qrcqml/qrcqml.pro
+++ b/tests/auto/qml/qrcqml/qrcqml.pro
@@ -5,6 +5,3 @@ macx:CONFIG -= app_bundle
SOURCES += tst_qrcqml.cpp
RESOURCES = qrcqml.qrc
-
-CONFIG += parallel_test
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qtqmlmodules/qtqmlmodules.pro b/tests/auto/qml/qtqmlmodules/qtqmlmodules.pro
index c6d442ecac..69e14aaecf 100644
--- a/tests/auto/qml/qtqmlmodules/qtqmlmodules.pro
+++ b/tests/auto/qml/qtqmlmodules/qtqmlmodules.pro
@@ -9,4 +9,3 @@ macx:CONFIG -= app_bundle
TESTDATA = data/*
QT += core-private qml-private testlib gui gui-private
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qv4debugger/qv4debugger.pro b/tests/auto/qml/qv4debugger/qv4debugger.pro
deleted file mode 100644
index 540cab70e6..0000000000
--- a/tests/auto/qml/qv4debugger/qv4debugger.pro
+++ /dev/null
@@ -1,15 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qv4debugger
-macx:CONFIG -= app_bundle
-
-SOURCES += \
- $$PWD/tst_qv4debugger.cpp \
- $$PWD/../../../../src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
-
-HEADERS += \
- $$PWD/../../../../src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
-
-INCLUDEPATH += \
- $$PWD/../../../../src/plugins/qmltooling/qmldbg_debugger
-
-QT += core-private gui-private qml-private network testlib
diff --git a/tests/auto/qml/v4misc/v4misc.pro b/tests/auto/qml/v4misc/v4misc.pro
index d68025f410..5150df5999 100644
--- a/tests/auto/qml/v4misc/v4misc.pro
+++ b/tests/auto/qml/v4misc/v4misc.pro
@@ -4,6 +4,4 @@ macx:CONFIG -= app_bundle
SOURCES += tst_v4misc.cpp
-CONFIG += parallel_test
QT += core-private qml-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qmldevtools/compile/compile.pro b/tests/auto/qmldevtools/compile/compile.pro
index 0ed113a031..186ef71e8d 100644
--- a/tests/auto/qmldevtools/compile/compile.pro
+++ b/tests/auto/qmldevtools/compile/compile.pro
@@ -12,4 +12,3 @@ macx:CONFIG -= app_bundle
SOURCES += tst_compile.cpp
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qmltest/qmltest.pro b/tests/auto/qmltest/qmltest.pro
index 7662cb1687..54db7a78ab 100644
--- a/tests/auto/qmltest/qmltest.pro
+++ b/tests/auto/qmltest/qmltest.pro
@@ -10,6 +10,5 @@ importFiles.files = borderimage buttonclick createbenchmark events qqmlbindi
importFiles.path = .
DEPLOYMENT += importFiles
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
CONFIG+=insignificant_test # QTBUG-33723
diff --git a/tests/auto/quick/examples/examples.pro b/tests/auto/quick/examples/examples.pro
index 3d821fc13d..fd8cfd83c8 100644
--- a/tests/auto/quick/examples/examples.pro
+++ b/tests/auto/quick/examples/examples.pro
@@ -6,9 +6,7 @@ macx:CONFIG -= app_bundle
SOURCES += tst_examples.cpp
DEFINES += SRCDIR=\\\"$$PWD\\\"
-CONFIG += parallel_test
#temporary
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
!qtHaveModule(xmlpatterns): DEFINES += QT_NO_XMLPATTERNS
diff --git a/tests/auto/quick/geometry/geometry.pro b/tests/auto/quick/geometry/geometry.pro
index 4a225c2546..0b7e64d038 100644
--- a/tests/auto/quick/geometry/geometry.pro
+++ b/tests/auto/quick/geometry/geometry.pro
@@ -7,4 +7,3 @@ SOURCES += tst_geometry.cpp
CONFIG+=parallel_test
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/nodes/nodes.pro b/tests/auto/quick/nodes/nodes.pro
index 256318a441..6cfcc43a98 100644
--- a/tests/auto/quick/nodes/nodes.pro
+++ b/tests/auto/quick/nodes/nodes.pro
@@ -7,4 +7,3 @@ SOURCES += tst_nodestest.cpp
CONFIG+=parallel_test
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/nokeywords/nokeywords.pro b/tests/auto/quick/nokeywords/nokeywords.pro
index 51fd490cb7..6872dac22a 100644
--- a/tests/auto/quick/nokeywords/nokeywords.pro
+++ b/tests/auto/quick/nokeywords/nokeywords.pro
@@ -7,4 +7,3 @@ SOURCES += tst_nokeywords.cpp
CONFIG+=parallel_test
QT += quick core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickaccessible/qquickaccessible.pro b/tests/auto/quick/qquickaccessible/qquickaccessible.pro
index bdbe2e3fb4..02915e8e22 100644
--- a/tests/auto/quick/qquickaccessible/qquickaccessible.pro
+++ b/tests/auto/quick/qquickaccessible/qquickaccessible.pro
@@ -16,12 +16,9 @@ OTHER_FILES += data/checkbuttons.qml \
data/statictext.qml \
data/ignored.qml \
-CONFIG += parallel_test
-
wince*: {
accessneeded.files = $$QT.widgets.plugins/accessible/*.dll
accessneeded.path = accessible
DEPLOYMENT += accessneeded
}
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickanchors/qquickanchors.pro b/tests/auto/quick/qquickanchors/qquickanchors.pro
index 184066753b..a5b47e3797 100644
--- a/tests/auto/quick/qquickanchors/qquickanchors.pro
+++ b/tests/auto/quick/qquickanchors/qquickanchors.pro
@@ -9,7 +9,4 @@ macx:CONFIG -= app_bundle
TESTDATA = data/*
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickanimatedimage/qquickanimatedimage.pro b/tests/auto/quick/qquickanimatedimage/qquickanimatedimage.pro
index 83607137e1..5792626720 100644
--- a/tests/auto/quick/qquickanimatedimage/qquickanimatedimage.pro
+++ b/tests/auto/quick/qquickanimatedimage/qquickanimatedimage.pro
@@ -11,4 +11,3 @@ macx:CONFIG -= app_bundle
TESTDATA = data/*
QT += core-private gui-private qml-private quick-private network testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickanimatedsprite/qquickanimatedsprite.pro b/tests/auto/quick/qquickanimatedsprite/qquickanimatedsprite.pro
index 3e47844feb..81c73be831 100644
--- a/tests/auto/quick/qquickanimatedsprite/qquickanimatedsprite.pro
+++ b/tests/auto/quick/qquickanimatedsprite/qquickanimatedsprite.pro
@@ -8,10 +8,7 @@ macx:CONFIG -= app_bundle
TESTDATA = data/*
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private quick-private network testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
OTHER_FILES += \
data/largeAnimation.qml
diff --git a/tests/auto/quick/qquickanimationcontroller/qquickanimationcontroller.pro b/tests/auto/quick/qquickanimationcontroller/qquickanimationcontroller.pro
index b5e03ee620..6909922cb1 100644
--- a/tests/auto/quick/qquickanimationcontroller/qquickanimationcontroller.pro
+++ b/tests/auto/quick/qquickanimationcontroller/qquickanimationcontroller.pro
@@ -3,8 +3,6 @@ TEMPLATE=app
TARGET=tst_qquickanimationcontroller
CONFIG += qmltestcase
-CONFIG += parallel_test
SOURCES += tst_qquickanimationcontroller.cpp
TESTDATA = data/*
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickanimations/qquickanimations.pro b/tests/auto/quick/qquickanimations/qquickanimations.pro
index dc8f471259..8bb1f47af5 100644
--- a/tests/auto/quick/qquickanimations/qquickanimations.pro
+++ b/tests/auto/quick/qquickanimations/qquickanimations.pro
@@ -8,7 +8,60 @@ macx:CONFIG -= app_bundle
TESTDATA = data/*
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private quick-private testlib
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
+
+OTHER_FILES += \
+ data/attached.qml \
+ data/badproperty1.qml \
+ data/badproperty2.qml \
+ data/badtype1.qml \
+ data/badtype2.qml \
+ data/badtype3.qml \
+ data/badtype4.qml \
+ data/disabledTransition.qml \
+ data/dontAutoStart.qml \
+ data/dontStart.qml \
+ data/dontStart2.qml \
+ data/dotproperty.qml \
+ data/Double.qml \
+ data/doubleRegistrationBug.qml \
+ data/looping.qml \
+ data/mixedtype1.qml \
+ data/mixedtype2.qml \
+ data/nonTransitionBug.qml \
+ data/parallelAnimationNullChildBug.qml \
+ data/pathAnimation.qml \
+ data/pathAnimation2.qml \
+ data/pathAnimationInOutBackCrash.qml \
+ data/pathAnimationNoStart.qml \
+ data/pathInterpolator.qml \
+ data/pathInterpolatorBack.qml \
+ data/pathInterpolatorBack2.qml \
+ data/pathTransition.qml \
+ data/pauseBindingBug.qml \
+ data/pauseBug.qml \
+ data/properties.qml \
+ data/properties2.qml \
+ data/properties3.qml \
+ data/properties4.qml \
+ data/properties5.qml \
+ data/propertiesTransition.qml \
+ data/propertiesTransition2.qml \
+ data/propertiesTransition3.qml \
+ data/propertiesTransition4.qml \
+ data/propertiesTransition5.qml \
+ data/propertiesTransition6.qml \
+ data/propertiesTransition7.qml \
+ data/reanchor.qml \
+ data/registrationBug.qml \
+ data/reparent.qml \
+ data/rotation.qml \
+ data/runningTrueBug.qml \
+ data/scriptActionBug.qml \
+ data/scriptActionCrash.qml \
+ data/sequentialAnimationNullChildBug.qml \
+ data/signals.qml \
+ data/transitionAssignmentBug.qml \
+ data/valuesource.qml \
+ data/valuesource2.qml
diff --git a/tests/auto/quick/qquickapplication/qquickapplication.pro b/tests/auto/quick/qquickapplication/qquickapplication.pro
index 7079478628..59445a6c16 100644
--- a/tests/auto/quick/qquickapplication/qquickapplication.pro
+++ b/tests/auto/quick/qquickapplication/qquickapplication.pro
@@ -1,9 +1,7 @@
CONFIG += testcase
-CONFIG += parallel_test
TARGET = tst_qquickapplication
macx:CONFIG -= app_bundle
SOURCES += tst_qquickapplication.cpp
QT += core-private gui-private qml quick qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickbehaviors/qquickbehaviors.pro b/tests/auto/quick/qquickbehaviors/qquickbehaviors.pro
index f005c03a82..51bc42c390 100644
--- a/tests/auto/quick/qquickbehaviors/qquickbehaviors.pro
+++ b/tests/auto/quick/qquickbehaviors/qquickbehaviors.pro
@@ -8,7 +8,4 @@ macx:CONFIG -= app_bundle
TESTDATA = data/*
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickborderimage/qquickborderimage.pro b/tests/auto/quick/qquickborderimage/qquickborderimage.pro
index ac213f0265..3e16063559 100644
--- a/tests/auto/quick/qquickborderimage/qquickborderimage.pro
+++ b/tests/auto/quick/qquickborderimage/qquickborderimage.pro
@@ -11,4 +11,3 @@ include (../../shared/util.pri)
TESTDATA = data/*
QT += core-private gui-private qml-private quick-private network testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickcanvasitem/qquickcanvasitem.pro b/tests/auto/quick/qquickcanvasitem/qquickcanvasitem.pro
index c770dbb488..3c41d498e5 100644
--- a/tests/auto/quick/qquickcanvasitem/qquickcanvasitem.pro
+++ b/tests/auto/quick/qquickcanvasitem/qquickcanvasitem.pro
@@ -8,7 +8,6 @@ SOURCES += tst_qquickcanvasitem.cpp
TESTDATA = data/*
OTHER_FILES += \
- data/testhelper.js \
data/tst_transform.qml \
data/tst_text.qml \
data/tst_strokeStyle.qml \
@@ -19,15 +18,38 @@ OTHER_FILES += \
data/tst_line.qml \
data/tst_fillStyle.qml \
data/tst_fillrect.qml \
- data/tst_drawimage.qml \
data/tst_composite.qml \
data/tst_canvas.qml \
data/tst_pixel.qml \
data/tst_gradient.qml \
data/tst_arcto.qml \
data/tst_arc.qml \
- data/tst_context.qml
+ data/tst_context.qml \
+ data/CanvasTestCase.qml \
+ data/CanvasComponent.qml \
+ data/tst_image.qml \
+ data/tst_svgpath.qml \
+ data/anim-gr.gif \
+ data/anim-gr.png \
+ data/anim-poster-gr.png \
+ data/background.png \
+ data/broken.png \
+ data/ggrr-256x256.png \
+ data/green-1x1.png \
+ data/green-2x2.png \
+ data/green-16x16.png \
+ data/green-256x256.png \
+ data/green.png \
+ data/grgr-256x256.png \
+ data/red-16x16.png \
+ data/red.png \
+ data/redtransparent.png \
+ data/rgrg-256x256.png \
+ data/rrgg-256x256.png \
+ data/transparent.png \
+ data/transparent50.png \
+ data/yellow.png \
+ data/yellow75.png
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
CONFIG += insignificant_test # QTBUG-41043
diff --git a/tests/auto/quick/qquickdesignersupport/qquickdesignersupport.pro b/tests/auto/quick/qquickdesignersupport/qquickdesignersupport.pro
index af932d834b..6e1ad6b95e 100644
--- a/tests/auto/quick/qquickdesignersupport/qquickdesignersupport.pro
+++ b/tests/auto/quick/qquickdesignersupport/qquickdesignersupport.pro
@@ -10,7 +10,6 @@ osx:CONFIG -= app_bundle
TESTDATA = data/*
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
DISTFILES += \
data/TestComponent.qml
diff --git a/tests/auto/quick/qquickdrag/qquickdrag.pro b/tests/auto/quick/qquickdrag/qquickdrag.pro
index 6e02a4d443..4bc6b2b2f6 100644
--- a/tests/auto/quick/qquickdrag/qquickdrag.pro
+++ b/tests/auto/quick/qquickdrag/qquickdrag.pro
@@ -4,7 +4,4 @@ macx:CONFIG -= app_bundle
SOURCES += tst_qquickdrag.cpp
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private quick-private network testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickdroparea/qquickdroparea.pro b/tests/auto/quick/qquickdroparea/qquickdroparea.pro
index c7ffbfd427..a34d5ad009 100644
--- a/tests/auto/quick/qquickdroparea/qquickdroparea.pro
+++ b/tests/auto/quick/qquickdroparea/qquickdroparea.pro
@@ -4,7 +4,4 @@ macx:CONFIG -= app_bundle
SOURCES += tst_qquickdroparea.cpp
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private quick-private network testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickdynamicpropertyanimation/qquickdynamicpropertyanimation.pro b/tests/auto/quick/qquickdynamicpropertyanimation/qquickdynamicpropertyanimation.pro
index a67daa91ba..33fa9aff7a 100644
--- a/tests/auto/quick/qquickdynamicpropertyanimation/qquickdynamicpropertyanimation.pro
+++ b/tests/auto/quick/qquickdynamicpropertyanimation/qquickdynamicpropertyanimation.pro
@@ -8,7 +8,4 @@ macx:CONFIG -= app_bundle
TESTDATA = data/*
-CONFIG += parallel_test
-
QT += core gui qml quick testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickflickable/qquickflickable.pro b/tests/auto/quick/qquickflickable/qquickflickable.pro
index 88dc2fbc2a..99a840218d 100644
--- a/tests/auto/quick/qquickflickable/qquickflickable.pro
+++ b/tests/auto/quick/qquickflickable/qquickflickable.pro
@@ -10,4 +10,3 @@ include (../shared/util.pri)
TESTDATA = data/*
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickflipable/qquickflipable.pro b/tests/auto/quick/qquickflipable/qquickflipable.pro
index 3e4d04a401..5a1fb6e816 100644
--- a/tests/auto/quick/qquickflipable/qquickflipable.pro
+++ b/tests/auto/quick/qquickflipable/qquickflipable.pro
@@ -8,7 +8,4 @@ include (../../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickfocusscope/qquickfocusscope.pro b/tests/auto/quick/qquickfocusscope/qquickfocusscope.pro
index 9ec643dc4d..7a4b7302d0 100644
--- a/tests/auto/quick/qquickfocusscope/qquickfocusscope.pro
+++ b/tests/auto/quick/qquickfocusscope/qquickfocusscope.pro
@@ -10,4 +10,3 @@ macx:CONFIG -= app_bundle
TESTDATA = data/*
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickfontloader/qquickfontloader.pro b/tests/auto/quick/qquickfontloader/qquickfontloader.pro
index 2e7300564e..cea5b55bdf 100644
--- a/tests/auto/quick/qquickfontloader/qquickfontloader.pro
+++ b/tests/auto/quick/qquickfontloader/qquickfontloader.pro
@@ -11,4 +11,3 @@ include (../../shared/util.pri)
TESTDATA = data/*
QT += core-private gui-private qml-private quick-private network testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickfontmetrics/qquickfontmetrics.pro b/tests/auto/quick/qquickfontmetrics/qquickfontmetrics.pro
index 452dd70bd3..15e3bb00c1 100644
--- a/tests/auto/quick/qquickfontmetrics/qquickfontmetrics.pro
+++ b/tests/auto/quick/qquickfontmetrics/qquickfontmetrics.pro
@@ -4,7 +4,4 @@ osx:CONFIG -= app_bundle
SOURCES += tst_quickfontmetrics.cpp
-CONFIG += parallel_test
-
QT += core gui qml quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickframebufferobject/qquickframebufferobject.pro b/tests/auto/quick/qquickframebufferobject/qquickframebufferobject.pro
index 612b6f7283..f4e9e1f890 100644
--- a/tests/auto/quick/qquickframebufferobject/qquickframebufferobject.pro
+++ b/tests/auto/quick/qquickframebufferobject/qquickframebufferobject.pro
@@ -7,7 +7,6 @@ include(../../shared/util.pri)
macx:CONFIG -= app_bundle
-CONFIG += parallel_test
QT += quick testlib
OTHER_FILES += \
diff --git a/tests/auto/quick/qquickgridview/qquickgridview.pro b/tests/auto/quick/qquickgridview/qquickgridview.pro
index 3b98ed4dea..3c33cc78fb 100644
--- a/tests/auto/quick/qquickgridview/qquickgridview.pro
+++ b/tests/auto/quick/qquickgridview/qquickgridview.pro
@@ -12,4 +12,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
index 3699bef56d..e8261be675 100644
--- a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
+++ b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
@@ -211,6 +211,8 @@ private slots:
void QTBUG_45640();
+ void keyNavigationEnabled();
+
private:
QList<int> toIntList(const QVariantList &list);
void matchIndexLists(const QVariantList &indexLists, const QList<int> &expectedIndexes);
@@ -6566,6 +6568,71 @@ void tst_QQuickGridView::QTBUG_45640()
delete window;
}
+void tst_QQuickGridView::keyNavigationEnabled()
+{
+ QScopedPointer<QQuickView> window(createView());
+ window->setSource(testFileUrl("gridview4.qml"));
+ window->show();
+ window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
+
+ QQuickGridView *gridView = qobject_cast<QQuickGridView *>(window->rootObject());
+ QVERIFY(gridView);
+ QCOMPARE(gridView->isKeyNavigationEnabled(), true);
+
+ gridView->setFocus(true);
+ QVERIFY(gridView->hasActiveFocus());
+
+ gridView->setHighlightMoveDuration(0);
+
+ // If keyNavigationEnabled is not explicitly set to true, respect the original behavior
+ // of disabling both mouse and keyboard interaction.
+ QSignalSpy enabledSpy(gridView, SIGNAL(keyNavigationEnabledChanged()));
+ gridView->setInteractive(false);
+ QCOMPARE(enabledSpy.count(), 1);
+ QCOMPARE(gridView->isKeyNavigationEnabled(), false);
+
+ flick(window.data(), QPoint(200, 175), QPoint(200, 50), 100);
+ QVERIFY(!gridView->isMoving());
+ QCOMPARE(gridView->contentY(), 0.0);
+ QCOMPARE(gridView->currentIndex(), 0);
+
+ QTest::keyClick(window.data(), Qt::Key_Right);
+ QCOMPARE(gridView->currentIndex(), 0);
+
+ // Check that isKeyNavigationEnabled implicitly follows the value of interactive.
+ gridView->setInteractive(true);
+ QCOMPARE(enabledSpy.count(), 2);
+ QCOMPARE(gridView->isKeyNavigationEnabled(), true);
+
+ // Change it back again for the next check.
+ gridView->setInteractive(false);
+ QCOMPARE(enabledSpy.count(), 3);
+ QCOMPARE(gridView->isKeyNavigationEnabled(), false);
+
+ // Setting keyNavigationEnabled to true shouldn't enable mouse interaction.
+ gridView->setKeyNavigationEnabled(true);
+ QCOMPARE(enabledSpy.count(), 4);
+ flick(window.data(), QPoint(200, 175), QPoint(200, 50), 100);
+ QVERIFY(!gridView->isMoving());
+ QCOMPARE(gridView->contentY(), 0.0);
+ QCOMPARE(gridView->currentIndex(), 0);
+
+ // Should now work.
+ QTest::keyClick(window.data(), Qt::Key_Right);
+ QCOMPARE(gridView->currentIndex(), 1);
+
+ // Changing interactive now shouldn't result in keyNavigationEnabled changing,
+ // since we broke the "binding".
+ gridView->setInteractive(true);
+ QCOMPARE(enabledSpy.count(), 4);
+
+ // Keyboard interaction shouldn't work now.
+ gridView->setKeyNavigationEnabled(false);
+ QTest::keyClick(window.data(), Qt::Key_Right);
+ QCOMPARE(gridView->currentIndex(), 1);
+}
+
QTEST_MAIN(tst_QQuickGridView)
#include "tst_qquickgridview.moc"
diff --git a/tests/auto/quick/qquickimage/qquickimage.pro b/tests/auto/quick/qquickimage/qquickimage.pro
index 9581ae02d1..5b1059bd24 100644
--- a/tests/auto/quick/qquickimage/qquickimage.pro
+++ b/tests/auto/quick/qquickimage/qquickimage.pro
@@ -12,4 +12,3 @@ include (../shared/util.pri)
TESTDATA = data/*
QT += core-private gui-private qml-private quick-private network testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickimageprovider/qquickimageprovider.pro b/tests/auto/quick/qquickimageprovider/qquickimageprovider.pro
index 496dc31d30..f67b697c0f 100644
--- a/tests/auto/quick/qquickimageprovider/qquickimageprovider.pro
+++ b/tests/auto/quick/qquickimageprovider/qquickimageprovider.pro
@@ -4,7 +4,4 @@ macx:CONFIG -= app_bundle
SOURCES += tst_qquickimageprovider.cpp
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private quick-private network testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickitem/qquickitem.pro b/tests/auto/quick/qquickitem/qquickitem.pro
index 1d8ae0148b..9aca5926f2 100644
--- a/tests/auto/quick/qquickitem/qquickitem.pro
+++ b/tests/auto/quick/qquickitem/qquickitem.pro
@@ -11,4 +11,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickitem2/qquickitem2.pro b/tests/auto/quick/qquickitem2/qquickitem2.pro
index ac4200a8a3..37bfb68f1c 100644
--- a/tests/auto/quick/qquickitem2/qquickitem2.pro
+++ b/tests/auto/quick/qquickitem2/qquickitem2.pro
@@ -9,4 +9,3 @@ include (../../shared/util.pri)
TESTDATA = data/*
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
index c7717b9cca..518e248207 100644
--- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
@@ -117,6 +117,7 @@ private slots:
void contains_data();
void contains();
void childAt();
+ void isAncestorOf();
void grab();
@@ -2959,6 +2960,43 @@ void tst_QQuickItem::grab()
}
+void tst_QQuickItem::isAncestorOf()
+{
+ QQuickItem parent;
+
+ QQuickItem sub1;
+ sub1.setParentItem(&parent);
+
+ QQuickItem child1;
+ child1.setParentItem(&sub1);
+ QQuickItem child2;
+ child2.setParentItem(&sub1);
+
+ QQuickItem sub2;
+ sub2.setParentItem(&parent);
+
+ QQuickItem child3;
+ child3.setParentItem(&sub2);
+ QQuickItem child4;
+ child4.setParentItem(&sub2);
+
+ QVERIFY(parent.isAncestorOf(&sub1));
+ QVERIFY(parent.isAncestorOf(&sub2));
+ QVERIFY(parent.isAncestorOf(&child1));
+ QVERIFY(parent.isAncestorOf(&child2));
+ QVERIFY(parent.isAncestorOf(&child3));
+ QVERIFY(parent.isAncestorOf(&child4));
+ QVERIFY(sub1.isAncestorOf(&child1));
+ QVERIFY(sub1.isAncestorOf(&child2));
+ QVERIFY(!sub1.isAncestorOf(&child3));
+ QVERIFY(!sub1.isAncestorOf(&child4));
+ QVERIFY(sub2.isAncestorOf(&child3));
+ QVERIFY(sub2.isAncestorOf(&child4));
+ QVERIFY(!sub2.isAncestorOf(&child1));
+ QVERIFY(!sub2.isAncestorOf(&child2));
+ QVERIFY(!sub1.isAncestorOf(&sub1));
+ QVERIFY(!sub2.isAncestorOf(&sub2));
+}
QTEST_MAIN(tst_QQuickItem)
diff --git a/tests/auto/quick/qquickitemlayer/qquickitemlayer.pro b/tests/auto/quick/qquickitemlayer/qquickitemlayer.pro
index a087948f6d..ec890b99b4 100644
--- a/tests/auto/quick/qquickitemlayer/qquickitemlayer.pro
+++ b/tests/auto/quick/qquickitemlayer/qquickitemlayer.pro
@@ -8,7 +8,6 @@ TESTDATA = data/*
include(../../shared/util.pri)
-CONFIG += parallel_test
QT += core-private gui-private qml-private quick-private testlib
OTHER_FILES += \
@@ -27,4 +26,3 @@ OTHER_FILES += \
data/ItemEffect.qml \
data/RectangleEffect.qml \
data/TextureMirroring.qml
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquicklistview/qquicklistview.pro b/tests/auto/quick/qquicklistview/qquicklistview.pro
index c9b634b9e8..a95b6fdf33 100644
--- a/tests/auto/quick/qquicklistview/qquicklistview.pro
+++ b/tests/auto/quick/qquicklistview/qquicklistview.pro
@@ -18,5 +18,4 @@ include (../shared/util.pri)
TESTDATA = data/*
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
index 1fec04d08a..c50559fcc3 100644
--- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
+++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
@@ -253,6 +253,7 @@ private slots:
void QTBUG_48870_fastModelUpdates();
void QTBUG_50105();
+ void keyNavigationEnabled();
private:
template <class T> void items(const QUrl &source);
@@ -8309,6 +8310,72 @@ void tst_QQuickListView::QTBUG_48044_currentItemNotVisibleAfterTransition()
QVERIFY(!currentPriv->culled);
}
+void tst_QQuickListView::keyNavigationEnabled()
+{
+ QScopedPointer<QQuickView> window(createView());
+ window->setSource(testFileUrl("simplelistview.qml"));
+ window->show();
+ window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
+
+ QQuickListView *listView = qobject_cast<QQuickListView *>(window->rootObject());
+ QVERIFY(listView);
+ QCOMPARE(listView->isKeyNavigationEnabled(), true);
+
+ listView->setFocus(true);
+ QVERIFY(listView->hasActiveFocus());
+
+ listView->setHighlightMoveDuration(0);
+
+ // If keyNavigationEnabled is not explicitly set to true, respect the original behavior
+ // of disabling both mouse and keyboard interaction.
+ QSignalSpy enabledSpy(listView, SIGNAL(keyNavigationEnabledChanged()));
+ listView->setInteractive(false);
+ QCOMPARE(enabledSpy.count(), 1);
+ QCOMPARE(listView->isKeyNavigationEnabled(), false);
+
+ flick(window.data(), QPoint(200, 200), QPoint(200, 50), 100);
+ QVERIFY(!listView->isMoving());
+ QCOMPARE(listView->contentY(), 0.0);
+ QCOMPARE(listView->currentIndex(), 0);
+
+ QTest::keyClick(window.data(), Qt::Key_Down);
+ QCOMPARE(listView->currentIndex(), 0);
+
+ // Check that isKeyNavigationEnabled implicitly follows the value of interactive.
+ listView->setInteractive(true);
+ QCOMPARE(enabledSpy.count(), 2);
+ QCOMPARE(listView->isKeyNavigationEnabled(), true);
+
+ // Change it back again for the next check.
+ listView->setInteractive(false);
+ QCOMPARE(enabledSpy.count(), 3);
+ QCOMPARE(listView->isKeyNavigationEnabled(), false);
+
+ // Setting keyNavigationEnabled to true shouldn't enable mouse interaction.
+ listView->setKeyNavigationEnabled(true);
+ QCOMPARE(enabledSpy.count(), 4);
+ flick(window.data(), QPoint(200, 200), QPoint(200, 50), 100);
+ QVERIFY(!listView->isMoving());
+ QCOMPARE(listView->contentY(), 0.0);
+ QCOMPARE(listView->currentIndex(), 0);
+
+ // Should now work.
+ QTest::keyClick(window.data(), Qt::Key_Down);
+ QCOMPARE(listView->currentIndex(), 1);
+ // contentY won't change for one index change in a view this high.
+
+ // Changing interactive now shouldn't result in keyNavigationEnabled changing,
+ // since we broke the "binding".
+ listView->setInteractive(true);
+ QCOMPARE(enabledSpy.count(), 4);
+
+ // Keyboard interaction shouldn't work now.
+ listView->setKeyNavigationEnabled(false);
+ QTest::keyClick(window.data(), Qt::Key_Down);
+ QCOMPARE(listView->currentIndex(), 1);
+}
+
static bool testVisibleItems(const QQuickItemViewPrivate *priv, bool *nonUnique, FxViewItem **failItem, int *expectedIdx)
{
QHash<QQuickItem*, int> uniqueItems;
diff --git a/tests/auto/quick/qquickloader/qquickloader.pro b/tests/auto/quick/qquickloader/qquickloader.pro
index 567917877c..32350388e8 100644
--- a/tests/auto/quick/qquickloader/qquickloader.pro
+++ b/tests/auto/quick/qquickloader/qquickloader.pro
@@ -13,4 +13,3 @@ include (../../shared/util.pri)
TESTDATA = data/*
QT += core-private gui-private qml-private quick-private network testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
index f4fab1d79f..b9d058ab80 100644
--- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp
+++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
@@ -111,6 +111,8 @@ private slots:
void asynchronous();
void asynchronous_clear();
void simultaneousSyncAsync();
+ void asyncToSync1();
+ void asyncToSync2();
void loadedSignal();
void parented();
@@ -1035,6 +1037,73 @@ void tst_QQuickLoader::simultaneousSyncAsync()
delete root;
}
+void tst_QQuickLoader::asyncToSync1()
+{
+ QQmlEngine engine;
+ PeriodicIncubationController *controller = new PeriodicIncubationController;
+ QQmlIncubationController *previous = engine.incubationController();
+ engine.setIncubationController(controller);
+ delete previous;
+
+ QQmlComponent component(&engine, testFileUrl("asynchronous.qml"));
+ QQuickItem *root = qobject_cast<QQuickItem*>(component.create());
+ QVERIFY(root);
+
+ QQuickLoader *loader = root->findChild<QQuickLoader*>("loader");
+ QVERIFY(loader);
+
+ QVERIFY(!loader->item());
+ root->setProperty("comp", "BigComponent.qml");
+ QMetaObject::invokeMethod(root, "loadComponent");
+ QVERIFY(!loader->item());
+
+ controller->start();
+ QCOMPARE(loader->status(), QQuickLoader::Loading);
+ QCOMPARE(engine.incubationController()->incubatingObjectCount(), 0);
+
+ // force completion before component created
+ loader->setAsynchronous(false);
+ QVERIFY(loader->item());
+ QCOMPARE(loader->progress(), 1.0);
+ QCOMPARE(loader->status(), QQuickLoader::Ready);
+ QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1);
+
+ delete root;
+}
+
+void tst_QQuickLoader::asyncToSync2()
+{
+ PeriodicIncubationController *controller = new PeriodicIncubationController;
+ QQmlIncubationController *previous = engine.incubationController();
+ engine.setIncubationController(controller);
+ delete previous;
+
+ QQmlComponent component(&engine, testFileUrl("asynchronous.qml"));
+ QQuickItem *root = qobject_cast<QQuickItem*>(component.create());
+ QVERIFY(root);
+
+ QQuickLoader *loader = root->findChild<QQuickLoader*>("loader");
+ QVERIFY(loader);
+
+ QVERIFY(!loader->item());
+ root->setProperty("comp", "BigComponent.qml");
+ QMetaObject::invokeMethod(root, "loadComponent");
+ QVERIFY(!loader->item());
+
+ controller->start();
+ QCOMPARE(loader->status(), QQuickLoader::Loading);
+ QTRY_COMPARE(engine.incubationController()->incubatingObjectCount(), 1);
+
+ // force completion after component created but before incubation complete
+ loader->setAsynchronous(false);
+ QVERIFY(loader->item());
+ QCOMPARE(loader->progress(), 1.0);
+ QCOMPARE(loader->status(), QQuickLoader::Ready);
+ QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1);
+
+ delete root;
+}
+
void tst_QQuickLoader::loadedSignal()
{
PeriodicIncubationController *controller = new PeriodicIncubationController;
diff --git a/tests/auto/quick/qquickmousearea/qquickmousearea.pro b/tests/auto/quick/qquickmousearea/qquickmousearea.pro
index dd7b434898..15a080aa3e 100644
--- a/tests/auto/quick/qquickmousearea/qquickmousearea.pro
+++ b/tests/auto/quick/qquickmousearea/qquickmousearea.pro
@@ -11,4 +11,3 @@ include (../../shared/util.pri)
TESTDATA = data/*
QT += core-private gui-private qml-private quick-private network testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickmultipointtoucharea/qquickmultipointtoucharea.pro b/tests/auto/quick/qquickmultipointtoucharea/qquickmultipointtoucharea.pro
index 5724a7179e..e5a2bae840 100644
--- a/tests/auto/quick/qquickmultipointtoucharea/qquickmultipointtoucharea.pro
+++ b/tests/auto/quick/qquickmultipointtoucharea/qquickmultipointtoucharea.pro
@@ -1,6 +1,5 @@
TARGET = tst_qquickmultipointtoucharea
CONFIG += testcase
-CONFIG += parallel_test
macx:CONFIG -= app_bundle
SOURCES += tst_qquickmultipointtoucharea.cpp
@@ -11,4 +10,3 @@ include(../../shared/util.pri)
include(../shared/util.pri)
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickopenglinfo/qquickopenglinfo.pro b/tests/auto/quick/qquickopenglinfo/qquickopenglinfo.pro
index 8489dfffd2..650ec04029 100644
--- a/tests/auto/quick/qquickopenglinfo/qquickopenglinfo.pro
+++ b/tests/auto/quick/qquickopenglinfo/qquickopenglinfo.pro
@@ -7,7 +7,6 @@ include(../../shared/util.pri)
osx:CONFIG -= app_bundle
-CONFIG += parallel_test
QT += quick testlib
OTHER_FILES += \
diff --git a/tests/auto/quick/qquickpainteditem/qquickpainteditem.pro b/tests/auto/quick/qquickpainteditem/qquickpainteditem.pro
index 381167cd09..a188001bd4 100644
--- a/tests/auto/quick/qquickpainteditem/qquickpainteditem.pro
+++ b/tests/auto/quick/qquickpainteditem/qquickpainteditem.pro
@@ -4,7 +4,4 @@ macx:CONFIG -= app_bundle
SOURCES += tst_qquickpainteditem.cpp
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private quick-private network testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickpath/qquickpath.pro b/tests/auto/quick/qquickpath/qquickpath.pro
index 4898f28c14..492f82f53d 100644
--- a/tests/auto/quick/qquickpath/qquickpath.pro
+++ b/tests/auto/quick/qquickpath/qquickpath.pro
@@ -8,7 +8,4 @@ include (../../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickpathview/qquickpathview.pro b/tests/auto/quick/qquickpathview/qquickpathview.pro
index e6cf9a488f..90c1eb0c67 100644
--- a/tests/auto/quick/qquickpathview/qquickpathview.pro
+++ b/tests/auto/quick/qquickpathview/qquickpathview.pro
@@ -11,4 +11,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private testlib
qtHaveModule(widgets): QT += widgets
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickpincharea/qquickpincharea.pro b/tests/auto/quick/qquickpincharea/qquickpincharea.pro
index fa14afa261..d37b37309d 100644
--- a/tests/auto/quick/qquickpincharea/qquickpincharea.pro
+++ b/tests/auto/quick/qquickpincharea/qquickpincharea.pro
@@ -1,5 +1,4 @@
CONFIG += testcase
-CONFIG += parallel_test
TARGET = tst_qquickpincharea
macx:CONFIG -= app_bundle
@@ -11,4 +10,3 @@ include (../shared/util.pri)
TESTDATA = data/*
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickpixmapcache/qquickpixmapcache.pro b/tests/auto/quick/qquickpixmapcache/qquickpixmapcache.pro
index 62678dc660..185eb2c213 100644
--- a/tests/auto/quick/qquickpixmapcache/qquickpixmapcache.pro
+++ b/tests/auto/quick/qquickpixmapcache/qquickpixmapcache.pro
@@ -15,4 +15,3 @@ TESTDATA = data/*
# LIBS += -lgcov
QT += core-private gui-private qml-private quick-private network testlib concurrent
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickpositioners/qquickpositioners.pro b/tests/auto/quick/qquickpositioners/qquickpositioners.pro
index f6a046e622..6e85ba9db8 100644
--- a/tests/auto/quick/qquickpositioners/qquickpositioners.pro
+++ b/tests/auto/quick/qquickpositioners/qquickpositioners.pro
@@ -10,4 +10,3 @@ macx:CONFIG -= app_bundle
TESTDATA = data/*
QT += testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickrectangle/qquickrectangle.pro b/tests/auto/quick/qquickrectangle/qquickrectangle.pro
index e881926c80..daefb5fe75 100644
--- a/tests/auto/quick/qquickrectangle/qquickrectangle.pro
+++ b/tests/auto/quick/qquickrectangle/qquickrectangle.pro
@@ -10,4 +10,3 @@ include (../shared/util.pri)
TESTDATA = data/*
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickrepeater/qquickrepeater.pro b/tests/auto/quick/qquickrepeater/qquickrepeater.pro
index a27c34c84b..5554342943 100644
--- a/tests/auto/quick/qquickrepeater/qquickrepeater.pro
+++ b/tests/auto/quick/qquickrepeater/qquickrepeater.pro
@@ -9,6 +9,4 @@ include (../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickscreen/qquickscreen.pro b/tests/auto/quick/qquickscreen/qquickscreen.pro
index fa64556a69..145ae0f04e 100644
--- a/tests/auto/quick/qquickscreen/qquickscreen.pro
+++ b/tests/auto/quick/qquickscreen/qquickscreen.pro
@@ -6,6 +6,4 @@ include (../../shared/util.pri)
macx:CONFIG -= app_bundle
-CONFIG += parallel_test
QT += core-private gui-private qml-private testlib quick-private
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickshadereffect/qquickshadereffect.pro b/tests/auto/quick/qquickshadereffect/qquickshadereffect.pro
index 0af54f83f6..437a548a90 100644
--- a/tests/auto/quick/qquickshadereffect/qquickshadereffect.pro
+++ b/tests/auto/quick/qquickshadereffect/qquickshadereffect.pro
@@ -5,6 +5,4 @@ SOURCES += tst_qquickshadereffect.cpp
include (../../shared/util.pri)
macx:CONFIG -= app_bundle
-CONFIG += parallel_test
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickshortcut/qquickshortcut.pro b/tests/auto/quick/qquickshortcut/qquickshortcut.pro
index 917a7605e6..d780d9061a 100644
--- a/tests/auto/quick/qquickshortcut/qquickshortcut.pro
+++ b/tests/auto/quick/qquickshortcut/qquickshortcut.pro
@@ -8,4 +8,3 @@ include (../../shared/util.pri)
TESTDATA = data/*
QT += core gui qml quick testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquicksmoothedanimation/qquicksmoothedanimation.pro b/tests/auto/quick/qquicksmoothedanimation/qquicksmoothedanimation.pro
index 4694172ac4..3d71ef4c62 100644
--- a/tests/auto/quick/qquicksmoothedanimation/qquicksmoothedanimation.pro
+++ b/tests/auto/quick/qquicksmoothedanimation/qquicksmoothedanimation.pro
@@ -8,7 +8,4 @@ include (../../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickspringanimation/qquickspringanimation.pro b/tests/auto/quick/qquickspringanimation/qquickspringanimation.pro
index 2f0395d3ea..bf8ddfe8ae 100644
--- a/tests/auto/quick/qquickspringanimation/qquickspringanimation.pro
+++ b/tests/auto/quick/qquickspringanimation/qquickspringanimation.pro
@@ -8,7 +8,4 @@ include (../../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickspritesequence/qquickspritesequence.pro b/tests/auto/quick/qquickspritesequence/qquickspritesequence.pro
index ee5cb5d25b..a61396bd0e 100644
--- a/tests/auto/quick/qquickspritesequence/qquickspritesequence.pro
+++ b/tests/auto/quick/qquickspritesequence/qquickspritesequence.pro
@@ -8,7 +8,4 @@ macx:CONFIG -= app_bundle
TESTDATA = data/*
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private quick-private network testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickstates/qquickstates.pro b/tests/auto/quick/qquickstates/qquickstates.pro
index 1b638dfa67..85fdebff96 100644
--- a/tests/auto/quick/qquickstates/qquickstates.pro
+++ b/tests/auto/quick/qquickstates/qquickstates.pro
@@ -8,6 +8,4 @@ include (../../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickstyledtext/qquickstyledtext.pro b/tests/auto/quick/qquickstyledtext/qquickstyledtext.pro
index e9a8ffe8ee..def2a27bf7 100644
--- a/tests/auto/quick/qquickstyledtext/qquickstyledtext.pro
+++ b/tests/auto/quick/qquickstyledtext/qquickstyledtext.pro
@@ -4,6 +4,4 @@ macx:CONFIG -= app_bundle
SOURCES += tst_qquickstyledtext.cpp
-CONFIG += parallel_test
QT += core-private gui-private qml-private quick-private network testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquicksystempalette/qquicksystempalette.pro b/tests/auto/quick/qquicksystempalette/qquicksystempalette.pro
index 48fd7e8e9a..9aa57b146b 100644
--- a/tests/auto/quick/qquicksystempalette/qquicksystempalette.pro
+++ b/tests/auto/quick/qquicksystempalette/qquicksystempalette.pro
@@ -4,7 +4,5 @@ macx:CONFIG -= app_bundle
SOURCES += tst_qquicksystempalette.cpp
-CONFIG += parallel_test
QT += core-private gui-private qml-private quick-private testlib
qtHaveModule(widgets): QT += widgets
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquicktext/qquicktext.pro b/tests/auto/quick/qquicktext/qquicktext.pro
index ee0a9be776..4f4b77ed7b 100644
--- a/tests/auto/quick/qquicktext/qquicktext.pro
+++ b/tests/auto/quick/qquicktext/qquicktext.pro
@@ -13,4 +13,3 @@ include (../../shared/util.pri)
TESTDATA = data/*
QT += core-private gui-private qml-private quick-private network testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquicktextdocument/qquicktextdocument.pro b/tests/auto/quick/qquicktextdocument/qquicktextdocument.pro
index e6bfdbd099..b5866e9e89 100644
--- a/tests/auto/quick/qquicktextdocument/qquicktextdocument.pro
+++ b/tests/auto/quick/qquicktextdocument/qquicktextdocument.pro
@@ -8,8 +8,5 @@ include (../../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquicktextedit/qquicktextedit.pro b/tests/auto/quick/qquicktextedit/qquicktextedit.pro
index c6f2bb91a8..ea6e8bc60d 100644
--- a/tests/auto/quick/qquicktextedit/qquicktextedit.pro
+++ b/tests/auto/quick/qquicktextedit/qquicktextedit.pro
@@ -14,5 +14,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private network-private testlib
osx: LIBS += -framework AppKit
-
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquicktextinput/qquicktextinput.pro b/tests/auto/quick/qquicktextinput/qquicktextinput.pro
index 4929289920..7868b60d1b 100644
--- a/tests/auto/quick/qquicktextinput/qquicktextinput.pro
+++ b/tests/auto/quick/qquicktextinput/qquicktextinput.pro
@@ -14,5 +14,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private testlib
osx: LIBS += -framework AppKit
-
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquicktextmetrics/qquicktextmetrics.pro b/tests/auto/quick/qquicktextmetrics/qquicktextmetrics.pro
index 6ef68db8e2..a5c088d454 100644
--- a/tests/auto/quick/qquicktextmetrics/qquicktextmetrics.pro
+++ b/tests/auto/quick/qquicktextmetrics/qquicktextmetrics.pro
@@ -4,7 +4,4 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qquicktextmetrics.cpp
-CONFIG += parallel_test
-
QT += core gui qml quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquicktimeline/qquicktimeline.pro b/tests/auto/quick/qquicktimeline/qquicktimeline.pro
index 3fafc33505..489fc7e081 100644
--- a/tests/auto/quick/qquicktimeline/qquicktimeline.pro
+++ b/tests/auto/quick/qquicktimeline/qquicktimeline.pro
@@ -1,9 +1,7 @@
CONFIG += testcase
-CONFIG += parallel_test
TARGET = tst_qquicktimeline
macx:CONFIG -= app_bundle
SOURCES += tst_qquicktimeline.cpp
QT += core-private gui-private qml quick qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickview/qquickview.pro b/tests/auto/quick/qquickview/qquickview.pro
index 3e9c39e2ce..1302908bf7 100644
--- a/tests/auto/quick/qquickview/qquickview.pro
+++ b/tests/auto/quick/qquickview/qquickview.pro
@@ -1,5 +1,4 @@
CONFIG += testcase
-CONFIG += parallel_test
TARGET = tst_qquickview
macx:CONFIG -= app_bundle
@@ -10,4 +9,3 @@ include (../../shared/util.pri)
TESTDATA = data/*
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickvisualdatamodel/qquickvisualdatamodel.pro b/tests/auto/quick/qquickvisualdatamodel/qquickvisualdatamodel.pro
index d9aff688ab..9222e39477 100644
--- a/tests/auto/quick/qquickvisualdatamodel/qquickvisualdatamodel.pro
+++ b/tests/auto/quick/qquickvisualdatamodel/qquickvisualdatamodel.pro
@@ -11,4 +11,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private testlib
qtHaveModule(widgets): QT += widgets
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
index d578a0900c..a1d8779555 100644
--- a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
+++ b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
@@ -102,15 +102,20 @@ public:
};
SingleRoleModel(const QStringList &list = QStringList(), const QByteArray &role = "name", QObject *parent = 0)
- : QAbstractItemModel(parent) {
- QHash<int, QByteArray> roles;
- roles.insert(Qt::DisplayRole , role);
- setRoleNames(roles);
+ : QAbstractItemModel(parent), m_role(role)
+ {
foreach (const QString &string, list)
trunk.children.append(Node(string));
}
~SingleRoleModel() {}
+ QHash<int,QByteArray> roleNames() const
+ {
+ QHash<int,QByteArray> roles;
+ roles.insert(Qt::DisplayRole, m_role);
+ return roles;
+ }
+
Branch *branchForIndex(const QModelIndex &index) const {
return index.isValid()
? static_cast<Branch *>(index.internalPointer())->children.at(index.row()).branch
@@ -235,6 +240,7 @@ public slots:
}
private:
+ const QByteArray m_role;
Branch trunk;
};
diff --git a/tests/auto/quick/qquickwindow/qquickwindow.pro b/tests/auto/quick/qquickwindow/qquickwindow.pro
index e95b7dbb10..f0d287f30f 100644
--- a/tests/auto/quick/qquickwindow/qquickwindow.pro
+++ b/tests/auto/quick/qquickwindow/qquickwindow.pro
@@ -17,5 +17,3 @@ OTHER_FILES += \
data/Headless.qml \
data/showHideAnimate.qml \
data/windoworder.qml
-
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
index f53ade9541..b16b7b3686 100644
--- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
@@ -397,7 +397,7 @@ void tst_qquickwindow::openglContextCreatedSignal()
QVERIFY(spy.size() > 0);
QVariant ctx = spy.at(0).at(0);
- QCOMPARE(qVariantValue<QOpenGLContext *>(ctx), window.openglContext());
+ QCOMPARE(qvariant_cast<QOpenGLContext *>(ctx), window.openglContext());
}
void tst_qquickwindow::aboutToStopSignal()
diff --git a/tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro b/tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro
index 574481c456..642345a4bb 100644
--- a/tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro
+++ b/tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro
@@ -8,10 +8,7 @@ include (../../shared/util.pri)
TESTDATA = data/*
-CONFIG += parallel_test
-
QT += core-private gui-private qml-private network testlib xmlpatterns
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
OTHER_FILES += \
data/groups.qml
diff --git a/tests/auto/quick/rendernode/rendernode.pro b/tests/auto/quick/rendernode/rendernode.pro
index bedcefde86..e4397713d9 100644
--- a/tests/auto/quick/rendernode/rendernode.pro
+++ b/tests/auto/quick/rendernode/rendernode.pro
@@ -8,7 +8,6 @@ TESTDATA = data/*
include(../../shared/util.pri)
-CONFIG += parallel_test
QT += core-private gui-private qml-private quick-private testlib
OTHER_FILES += \
@@ -16,4 +15,3 @@ OTHER_FILES += \
data/MessUpState.qml \
data/matrix.qml
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/scenegraph/scenegraph.pro b/tests/auto/quick/scenegraph/scenegraph.pro
index 0ad13a086f..320228bd08 100644
--- a/tests/auto/quick/scenegraph/scenegraph.pro
+++ b/tests/auto/quick/scenegraph/scenegraph.pro
@@ -8,7 +8,6 @@ macx:CONFIG -= app_bundle
QT += core-private gui-private qml-private quick-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
OTHER_FILES += \
data/render_OutOfFloatRange.qml \
diff --git a/tests/auto/quick/shared/viewtestutil.cpp b/tests/auto/quick/shared/viewtestutil.cpp
index 1330cbccc9..9121314420 100644
--- a/tests/auto/quick/shared/viewtestutil.cpp
+++ b/tests/auto/quick/shared/viewtestutil.cpp
@@ -148,10 +148,6 @@ QList<int> QQuickViewTestUtil::adjustIndexesForRemoveDisplaced(const QList<int>
QQuickViewTestUtil::QaimModel::QaimModel(QObject *parent)
: QAbstractListModel(parent)
{
- QHash<int, QByteArray> roles;
- roles[Name] = "name";
- roles[Number] = "number";
- setRoleNames(roles);
}
int QQuickViewTestUtil::QaimModel::rowCount(const QModelIndex &parent) const
@@ -160,6 +156,14 @@ int QQuickViewTestUtil::QaimModel::rowCount(const QModelIndex &parent) const
return list.count();
}
+QHash<int,QByteArray> QQuickViewTestUtil::QaimModel::roleNames() const
+{
+ QHash<int,QByteArray> roles = QAbstractListModel::roleNames();
+ roles.insert(Name, "name");
+ roles.insert(Number, "number");
+ return roles;
+}
+
QVariant QQuickViewTestUtil::QaimModel::data(const QModelIndex &index, int role) const
{
QVariant rv;
diff --git a/tests/auto/quick/shared/viewtestutil.h b/tests/auto/quick/shared/viewtestutil.h
index 1643eca979..1de2f54d8a 100644
--- a/tests/auto/quick/shared/viewtestutil.h
+++ b/tests/auto/quick/shared/viewtestutil.h
@@ -80,6 +80,7 @@ namespace QQuickViewTestUtil
int rowCount(const QModelIndex &parent=QModelIndex()) const;
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const;
+ QHash<int,QByteArray> roleNames() const;
int count() const;
QString name(int index) const;
diff --git a/tests/auto/quick/touchmouse/touchmouse.pro b/tests/auto/quick/touchmouse/touchmouse.pro
index 7d23dfc0ae..0df9bc53d3 100644
--- a/tests/auto/quick/touchmouse/touchmouse.pro
+++ b/tests/auto/quick/touchmouse/touchmouse.pro
@@ -14,4 +14,3 @@ TESTDATA = data/*
# OTHER_FILES += data/foo.qml
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quickwidgets/qquickwidget/qquickwidget.pro b/tests/auto/quickwidgets/qquickwidget/qquickwidget.pro
index 069270da3c..aeeff8b479 100644
--- a/tests/auto/quickwidgets/qquickwidget/qquickwidget.pro
+++ b/tests/auto/quickwidgets/qquickwidget/qquickwidget.pro
@@ -16,4 +16,3 @@ OTHER_FILES += \
rectangle.qml \
resizemodeitem.qml
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/toolsupport/toolsupport.pro b/tests/auto/toolsupport/toolsupport.pro
index 40dd7c5200..89de3086c3 100644
--- a/tests/auto/toolsupport/toolsupport.pro
+++ b/tests/auto/toolsupport/toolsupport.pro
@@ -1,4 +1,4 @@
-CONFIG += testcase parallel_test
+CONFIG += testcase
TARGET = tst_toolsupport
QT = testlib core-private qml-private
SOURCES = $$PWD/tst_toolsupport.cpp
diff --git a/tests/benchmarks/particles/affectors/affectors.pro b/tests/benchmarks/particles/affectors/affectors.pro
index 112c4ea3ec..88d260591e 100644
--- a/tests/benchmarks/particles/affectors/affectors.pro
+++ b/tests/benchmarks/particles/affectors/affectors.pro
@@ -8,4 +8,3 @@ testDataFiles.path = .
DEPLOYMENT += testDataFiles
QT += quickparticles-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/benchmarks/particles/emission/emission.pro b/tests/benchmarks/particles/emission/emission.pro
index 0ebd75b738..3a49405730 100644
--- a/tests/benchmarks/particles/emission/emission.pro
+++ b/tests/benchmarks/particles/emission/emission.pro
@@ -8,4 +8,3 @@ testDataFiles.path = .
DEPLOYMENT += testDataFiles
QT += quickparticles-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/benchmarks/qml/animation/animation.pro b/tests/benchmarks/qml/animation/animation.pro
index e089884a7e..6369ecddd1 100644
--- a/tests/benchmarks/qml/animation/animation.pro
+++ b/tests/benchmarks/qml/animation/animation.pro
@@ -7,4 +7,3 @@ macx:CONFIG -= app_bundle
SOURCES += tst_animation.cpp
DEFINES += SRCDIR=\\\"$$PWD\\\"
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/benchmarks/qml/binding/binding.pro b/tests/benchmarks/qml/binding/binding.pro
index fc0f731da6..776c8390a3 100644
--- a/tests/benchmarks/qml/binding/binding.pro
+++ b/tests/benchmarks/qml/binding/binding.pro
@@ -9,4 +9,3 @@ HEADERS += testtypes.h
# Define SRCDIR equal to test's source directory
DEFINES += SRCDIR=\\\"$$PWD\\\"
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/benchmarks/qml/compilation/compilation.pro b/tests/benchmarks/qml/compilation/compilation.pro
index a55864f696..31abb23e69 100644
--- a/tests/benchmarks/qml/compilation/compilation.pro
+++ b/tests/benchmarks/qml/compilation/compilation.pro
@@ -9,4 +9,3 @@ CONFIG += release
SOURCES += tst_compilation.cpp
DEFINES += SRCDIR=\\\"$$PWD\\\"
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/benchmarks/qml/creation/creation.pro b/tests/benchmarks/qml/creation/creation.pro
index 0cfac64d5f..ef7a8cf2ce 100644
--- a/tests/benchmarks/qml/creation/creation.pro
+++ b/tests/benchmarks/qml/creation/creation.pro
@@ -7,4 +7,3 @@ macx:CONFIG -= app_bundle
SOURCES += tst_creation.cpp
DEFINES += SRCDIR=\\\"$$PWD\\\"
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/benchmarks/qml/holistic/holistic.pro b/tests/benchmarks/qml/holistic/holistic.pro
index 8fd87c88bd..82f2ef6e4e 100644
--- a/tests/benchmarks/qml/holistic/holistic.pro
+++ b/tests/benchmarks/qml/holistic/holistic.pro
@@ -11,4 +11,3 @@ SOURCES += tst_holistic.cpp \
HEADERS += testtypes.h
DEFINES += SRCDIR=\\\"$$PWD\\\"
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/benchmarks/qml/javascript/javascript.pro b/tests/benchmarks/qml/javascript/javascript.pro
index b8f23f47d5..281bbd0069 100644
--- a/tests/benchmarks/qml/javascript/javascript.pro
+++ b/tests/benchmarks/qml/javascript/javascript.pro
@@ -9,4 +9,3 @@ HEADERS += testtypes.h
# Define SRCDIR equal to test's source directory
DEFINES += SRCDIR=\\\"$$PWD\\\"
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/benchmarks/qml/js/qjsengine/qjsengine.pro b/tests/benchmarks/qml/js/qjsengine/qjsengine.pro
index f736e59222..f8f2874a63 100644
--- a/tests/benchmarks/qml/js/qjsengine/qjsengine.pro
+++ b/tests/benchmarks/qml/js/qjsengine/qjsengine.pro
@@ -5,4 +5,3 @@ TARGET = tst_bench_qjsengine
SOURCES += tst_qjsengine.cpp
QT += qml testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/benchmarks/qml/js/qjsvalue/qjsvalue.pro b/tests/benchmarks/qml/js/qjsvalue/qjsvalue.pro
index 7b8363b6c4..772aa5da8c 100644
--- a/tests/benchmarks/qml/js/qjsvalue/qjsvalue.pro
+++ b/tests/benchmarks/qml/js/qjsvalue/qjsvalue.pro
@@ -5,4 +5,3 @@ TARGET = tst_bench_qjsvalue
SOURCES += tst_qjsvalue.cpp
QT += qml testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/benchmarks/qml/js/qjsvalueiterator/qjsvalueiterator.pro b/tests/benchmarks/qml/js/qjsvalueiterator/qjsvalueiterator.pro
index 34ed9caa15..7601789ca9 100644
--- a/tests/benchmarks/qml/js/qjsvalueiterator/qjsvalueiterator.pro
+++ b/tests/benchmarks/qml/js/qjsvalueiterator/qjsvalueiterator.pro
@@ -5,4 +5,3 @@ TARGET = tst_bench_qjsvalueiterator
SOURCES += tst_qjsvalueiterator.cpp
QT = core qml testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/benchmarks/qml/painting/painting.pro b/tests/benchmarks/qml/painting/painting.pro
index bde891e12d..7e97915f43 100644
--- a/tests/benchmarks/qml/painting/painting.pro
+++ b/tests/benchmarks/qml/painting/painting.pro
@@ -5,4 +5,3 @@ CONFIG += console
macx:CONFIG -= app_bundle
SOURCES += paintbenchmark.cpp
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/benchmarks/qml/pointers/pointers.pro b/tests/benchmarks/qml/pointers/pointers.pro
index ccf85d659a..a2c9a0828f 100644
--- a/tests/benchmarks/qml/pointers/pointers.pro
+++ b/tests/benchmarks/qml/pointers/pointers.pro
@@ -5,5 +5,3 @@ TARGET = tst_pointers
macx:CONFIG -= app_bundle
SOURCES += tst_pointers.cpp
-
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/benchmarks/qml/pointers/tst_pointers.cpp b/tests/benchmarks/qml/pointers/tst_pointers.cpp
index 8b981f4532..1fec42ca42 100644
--- a/tests/benchmarks/qml/pointers/tst_pointers.cpp
+++ b/tests/benchmarks/qml/pointers/tst_pointers.cpp
@@ -60,7 +60,7 @@ void tst_pointers::weakPointer()
{
QObject *obj = new QObject;
QBENCHMARK {
- QWeakPointer<QObject> guardedObject;
+ QPointer<QObject> guardedObject;
guardedObject = obj;
}
}
diff --git a/tests/benchmarks/qml/qmltime/qmltime.pro b/tests/benchmarks/qml/qmltime/qmltime.pro
index 4e3e9471a4..57966be7a2 100644
--- a/tests/benchmarks/qml/qmltime/qmltime.pro
+++ b/tests/benchmarks/qml/qmltime/qmltime.pro
@@ -6,4 +6,3 @@ macx:CONFIG -= app_bundle
SOURCES += qmltime.cpp
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/benchmarks/qml/qqmlcomponent/qqmlcomponent.pro b/tests/benchmarks/qml/qqmlcomponent/qqmlcomponent.pro
index 12a53f5e20..ba41f5a95b 100644
--- a/tests/benchmarks/qml/qqmlcomponent/qqmlcomponent.pro
+++ b/tests/benchmarks/qml/qqmlcomponent/qqmlcomponent.pro
@@ -9,4 +9,3 @@ HEADERS += testtypes.h
# Define SRCDIR equal to test's source directory
DEFINES += SRCDIR=\\\"$$PWD\\\"
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/benchmarks/qml/qqmldebugtrace/qqmldebugtrace.pro b/tests/benchmarks/qml/qqmldebugtrace/qqmldebugtrace.pro
index 4cf6bbe4bc..ebf0ae074f 100644
--- a/tests/benchmarks/qml/qqmldebugtrace/qqmldebugtrace.pro
+++ b/tests/benchmarks/qml/qqmldebugtrace/qqmldebugtrace.pro
@@ -6,4 +6,3 @@ macx:CONFIG -= app_bundle
SOURCES += tst_qqmldebugtrace.cpp
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/benchmarks/qml/qqmlimage/qqmlimage.pro b/tests/benchmarks/qml/qqmlimage/qqmlimage.pro
index 6a94052898..21d3efdd1f 100644
--- a/tests/benchmarks/qml/qqmlimage/qqmlimage.pro
+++ b/tests/benchmarks/qml/qqmlimage/qqmlimage.pro
@@ -9,4 +9,3 @@ SOURCES += tst_qqmlimage.cpp
DEFINES += SRCDIR=\\\"$$PWD\\\"
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/benchmarks/qml/qqmlmetaproperty/qqmlmetaproperty.pro b/tests/benchmarks/qml/qqmlmetaproperty/qqmlmetaproperty.pro
index ce66e1e51f..b80b88f4bc 100644
--- a/tests/benchmarks/qml/qqmlmetaproperty/qqmlmetaproperty.pro
+++ b/tests/benchmarks/qml/qqmlmetaproperty/qqmlmetaproperty.pro
@@ -8,4 +8,3 @@ SOURCES += tst_qqmlmetaproperty.cpp
# Define SRCDIR equal to test's source directory
DEFINES += SRCDIR=\\\"$$PWD\\\"
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/benchmarks/qml/qquickwindow/qquickwindow.pro b/tests/benchmarks/qml/qquickwindow/qquickwindow.pro
index 0676405e23..50f956f220 100644
--- a/tests/benchmarks/qml/qquickwindow/qquickwindow.pro
+++ b/tests/benchmarks/qml/qquickwindow/qquickwindow.pro
@@ -8,4 +8,3 @@ testDataFiles.path = .
DEPLOYMENT += testDataFiles
QT += core-private gui-private qml-private quick-private opengl-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 \ No newline at end of file
diff --git a/tests/benchmarks/qml/typeimports/typeimports.pro b/tests/benchmarks/qml/typeimports/typeimports.pro
index b8db7bd134..dc58e4044b 100644
--- a/tests/benchmarks/qml/typeimports/typeimports.pro
+++ b/tests/benchmarks/qml/typeimports/typeimports.pro
@@ -7,4 +7,3 @@ macx:CONFIG -= app_bundle
SOURCES += tst_typeimports.cpp
DEFINES += SRCDIR=\\\"$$PWD\\\"
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/benchmarks/script/qjsvalue/qjsvalue.pro b/tests/benchmarks/script/qjsvalue/qjsvalue.pro
index b0134b085a..03b877ae9d 100644
--- a/tests/benchmarks/script/qjsvalue/qjsvalue.pro
+++ b/tests/benchmarks/script/qjsvalue/qjsvalue.pro
@@ -8,4 +8,3 @@ CONFIG += release
SOURCES += tst_qjsvalue.cpp
QT += core-private qml-private testlib
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tools/qmleasing/splineeditor.cpp b/tools/qmleasing/splineeditor.cpp
index 9e35af6189..2ae4d11309 100644
--- a/tools/qmleasing/splineeditor.cpp
+++ b/tools/qmleasing/splineeditor.cpp
@@ -228,6 +228,7 @@ void SplineEditor::mouseReleaseEvent(QMouseEvent *e)
}
}
+#ifndef QT_NO_CONTEXTMENU
void SplineEditor::contextMenuEvent(QContextMenuEvent *e)
{
int index = findControlPoint(e->pos());
@@ -247,6 +248,7 @@ void SplineEditor::contextMenuEvent(QContextMenuEvent *e)
addPoint(e->pos());
}
}
+#endif // QT_NO_CONTEXTMENU
void SplineEditor::invalidate()
{
diff --git a/tools/qmleasing/splineeditor.h b/tools/qmleasing/splineeditor.h
index 595580bba2..4b9da14a7a 100644
--- a/tools/qmleasing/splineeditor.h
+++ b/tools/qmleasing/splineeditor.h
@@ -84,7 +84,9 @@ protected:
void mousePressEvent(QMouseEvent *);
void mouseMoveEvent(QMouseEvent *);
void mouseReleaseEvent(QMouseEvent *);
+#ifndef QT_NO_CONTEXTMENU
void contextMenuEvent(QContextMenuEvent *);
+#endif // QT_NO_CONTEXTMENU
void invalidate();
void invalidateSmoothList();
diff --git a/tools/qmlmin/main.cpp b/tools/qmlmin/main.cpp
index a3f2b92bde..82fdb92801 100644
--- a/tools/qmlmin/main.cpp
+++ b/tools/qmlmin/main.cpp
@@ -590,7 +590,7 @@ int runQmlmin(int argc, char *argv[])
}
} else if (arg.startsWith(QLatin1String("-w"))) {
bool ok;
- width = arg.mid(2).toInt(&ok);
+ width = arg.midRef(2).toInt(&ok);
if (!ok) {
std::cerr << "qmlmin: argument to '-w' is invalid" << std::endl;
diff --git a/tools/qmlprofiler/qmlprofiler.pro b/tools/qmlprofiler/qmlprofiler.pro
index 4fa36f5127..a65e25c657 100644
--- a/tools/qmlprofiler/qmlprofiler.pro
+++ b/tools/qmlprofiler/qmlprofiler.pro
@@ -1,22 +1,17 @@
-QT = qml qml-private network core-private
+QT = qml-private network core qmldebug-private
CONFIG += no_import_scan
SOURCES += main.cpp \
qmlprofilerapplication.cpp \
commandlistener.cpp \
- qqmldebugclient.cpp \
qmlprofilerdata.cpp \
- qmlprofilerclient.cpp \
- qpacketprotocol.cpp
+ qmlprofilerclient.cpp
HEADERS += \
qmlprofilerapplication.h \
commandlistener.h \
constants.h \
qmlprofilerdata.h \
- qmlprofilerclient.h \
- qmlprofilereventlocation.h \
- qqmldebugclient.h \
- qpacketprotocol.h
+ qmlprofilerclient.h
load(qt_tool)
diff --git a/tools/qmlprofiler/qmlprofilerapplication.cpp b/tools/qmlprofiler/qmlprofilerapplication.cpp
index 347e7d3b55..455faeb1c0 100644
--- a/tools/qmlprofiler/qmlprofilerapplication.cpp
+++ b/tools/qmlprofiler/qmlprofilerapplication.cpp
@@ -41,6 +41,7 @@
#include <QtCore/QFileInfo>
#include <QtCore/QDebug>
#include <QtCore/QCommandLineParser>
+#include <QtCore/QTemporaryFile>
static const char commandTextC[] =
"The following commands are available:\n"
@@ -70,60 +71,35 @@ static const char *features[] = {
"creating",
"binding",
"handlingsignal",
- "inputevents"
+ "inputevents",
+ "debugmessages"
};
+Q_STATIC_ASSERT(sizeof(features) ==
+ QQmlProfilerDefinitions::MaximumProfileFeature * sizeof(char *));
+
QmlProfilerApplication::QmlProfilerApplication(int &argc, char **argv) :
QCoreApplication(argc, argv),
m_runMode(LaunchMode),
m_process(0),
m_hostName(QLatin1String("127.0.0.1")),
- m_port(3768),
+ m_port(0),
m_pendingRequest(REQUEST_NONE),
m_verbose(false),
m_recording(true),
m_interactive(false),
- m_qmlProfilerClient(&m_connection),
- m_v8profilerClient(&m_connection),
- m_connectionAttempts(0),
- m_qmlDataReady(false),
- m_v8DataReady(false)
+ m_qmlProfilerClient(&m_connection, &m_profilerData),
+ m_connectionAttempts(0)
{
m_connectTimer.setInterval(1000);
connect(&m_connectTimer, SIGNAL(timeout()), this, SLOT(tryToConnect()));
connect(&m_connection, SIGNAL(connected()), this, SLOT(connected()));
- connect(&m_connection, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(connectionStateChanged(QAbstractSocket::SocketState)));
- connect(&m_connection, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(connectionError(QAbstractSocket::SocketError)));
-
- connect(&m_qmlProfilerClient, SIGNAL(enabledChanged()), this, SLOT(traceClientEnabled()));
- connect(&m_qmlProfilerClient, SIGNAL(range(QQmlProfilerDefinitions::RangeType,QQmlProfilerDefinitions::BindingType,qint64,qint64,QStringList,QmlEventLocation)),
- &m_profilerData, SLOT(addQmlEvent(QQmlProfilerDefinitions::RangeType,QQmlProfilerDefinitions::BindingType,qint64,qint64,QStringList,QmlEventLocation)));
- connect(&m_qmlProfilerClient, SIGNAL(traceFinished(qint64)), &m_profilerData, SLOT(setTraceEndTime(qint64)));
- connect(&m_qmlProfilerClient, SIGNAL(traceStarted(qint64)), &m_profilerData, SLOT(setTraceStartTime(qint64)));
- connect(&m_qmlProfilerClient, SIGNAL(traceStarted(qint64)), this, SLOT(notifyTraceStarted()));
- connect(&m_qmlProfilerClient, SIGNAL(frame(qint64,int,int,int)), &m_profilerData, SLOT(addFrameEvent(qint64,int,int,int)));
- connect(&m_qmlProfilerClient, SIGNAL(sceneGraphFrame(QQmlProfilerDefinitions::SceneGraphFrameType,
- qint64,qint64,qint64,qint64,qint64,qint64)),
- &m_profilerData, SLOT(addSceneGraphFrameEvent(QQmlProfilerDefinitions::SceneGraphFrameType,
- qint64,qint64,qint64,qint64,qint64,qint64)));
- connect(&m_qmlProfilerClient, SIGNAL(pixmapCache(QQmlProfilerDefinitions::PixmapEventType,qint64,
- QmlEventLocation,int,int,int)),
- &m_profilerData, SLOT(addPixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType,qint64,
- QmlEventLocation,int,int,int)));
- connect(&m_qmlProfilerClient, SIGNAL(memoryAllocation(QQmlProfilerDefinitions::MemoryType,qint64,
- qint64)),
- &m_profilerData, SLOT(addMemoryEvent(QQmlProfilerDefinitions::MemoryType,qint64,
- qint64)));
- connect(&m_qmlProfilerClient, SIGNAL(inputEvent(QQmlProfilerDefinitions::EventType,qint64)),
- &m_profilerData, SLOT(addInputEvent(QQmlProfilerDefinitions::EventType,qint64)));
-
- connect(&m_qmlProfilerClient, SIGNAL(complete()), this, SLOT(qmlComplete()));
-
- connect(&m_v8profilerClient, SIGNAL(enabledChanged()), this, SLOT(profilerClientEnabled()));
- connect(&m_v8profilerClient, SIGNAL(range(int,QString,QString,int,double,double)),
- &m_profilerData, SLOT(addV8Event(int,QString,QString,int,double,double)));
- connect(&m_v8profilerClient, SIGNAL(complete()), this, SLOT(v8Complete()));
+
+ connect(&m_qmlProfilerClient, SIGNAL(enabledChanged(bool)),
+ this, SLOT(traceClientEnabledChanged(bool)));
+ connect(&m_qmlProfilerClient, SIGNAL(recordingStarted()), this, SLOT(notifyTraceStarted()));
+ connect(&m_qmlProfilerClient, SIGNAL(error(QString)), this, SLOT(logError(QString)));
connect(&m_profilerData, SIGNAL(error(QString)), this, SLOT(logError(QString)));
connect(&m_profilerData, SIGNAL(dataReady()), this, SLOT(traceFinished()));
@@ -228,6 +204,7 @@ void QmlProfilerApplication::parseArguments()
if (parser.isSet(attach)) {
m_hostName = parser.value(attach);
m_runMode = AttachMode;
+ m_port = 3768;
}
if (parser.isSet(port)) {
@@ -237,6 +214,10 @@ void QmlProfilerApplication::parseArguments()
logError(tr("'%1' is not a valid port.").arg(parser.value(port)));
parser.showHelp(1);
}
+ } else if (m_port == 0) {
+ QTemporaryFile file;
+ if (file.open())
+ m_socketFile = file.fileName();
}
m_outputFile = parser.value(output);
@@ -316,7 +297,6 @@ void QmlProfilerApplication::flush()
if (m_recording) {
m_pendingRequest = REQUEST_FLUSH;
m_qmlProfilerClient.sendRecordingStatus(false);
- m_v8profilerClient.sendRecordingStatus(false);
} else {
if (m_profilerData.save(m_interactiveOutputFile)) {
m_profilerData.clear();
@@ -407,7 +387,6 @@ void QmlProfilerApplication::userCommand(const QString &command)
if (cmd == Constants::CMD_RECORD || cmd == Constants::CMD_RECORD2) {
m_pendingRequest = REQUEST_TOGGLE_RECORDING;
m_qmlProfilerClient.sendRecordingStatus(!m_recording);
- m_v8profilerClient.sendRecordingStatus(!m_recording);
} else if (cmd == Constants::CMD_QUIT || cmd == Constants::CMD_QUIT2) {
m_pendingRequest = REQUEST_QUIT;
if (m_recording) {
@@ -474,10 +453,15 @@ void QmlProfilerApplication::outputData()
void QmlProfilerApplication::run()
{
if (m_runMode == LaunchMode) {
+ if (!m_socketFile.isEmpty()) {
+ logStatus(QString::fromLatin1("Listening on %1 ...").arg(m_socketFile));
+ m_connection.startLocalServer(m_socketFile);
+ }
m_process = new QProcess(this);
QStringList arguments;
- arguments << QString::fromLatin1("-qmljsdebugger=port:%1,block,services:CanvasFrameRate")
- .arg(m_port);
+ arguments << QString::fromLatin1("-qmljsdebugger=%1:%2,block,services:CanvasFrameRate")
+ .arg(QLatin1String(m_socketFile.isEmpty() ? "port" : "file"))
+ .arg(m_socketFile.isEmpty() ? QString::number(m_port) : m_socketFile);
arguments << m_programArguments;
m_process->setProcessChannelMode(QProcess::MergedChannels);
@@ -492,7 +476,6 @@ void QmlProfilerApplication::run()
m_process->errorString()));
exit(1);
}
-
}
m_connectTimer.start();
}
@@ -503,15 +486,18 @@ void QmlProfilerApplication::tryToConnect()
++ m_connectionAttempts;
if (!m_verbose && !(m_connectionAttempts % 5)) {// print every 5 seconds
- if (!m_verbose)
- logError(QString("Could not connect to %1:%2 for %3 seconds ...").arg(
- m_hostName, QString::number(m_port),
- QString::number(m_connectionAttempts)));
+ if (m_verbose) {
+ if (m_socketFile.isEmpty())
+ logError(QString::fromLatin1("Could not connect to %1:%2 for %3 seconds ...")
+ .arg(m_hostName).arg(m_port).arg(m_connectionAttempts));
+ else
+ logError(QString::fromLatin1("No connection received on %1 for %2 seconds ...")
+ .arg(m_socketFile).arg(m_connectionAttempts));
+ }
}
- if (m_connection.state() == QAbstractSocket::UnconnectedState) {
- logStatus(QString("Connecting to %1:%2 ...").arg(m_hostName,
- QString::number(m_port)));
+ if (m_socketFile.isEmpty()) {
+ logStatus(QString::fromLatin1("Connecting to %1:%2 ...").arg(m_hostName).arg(m_port));
m_connection.connectToHost(m_hostName, m_port);
}
}
@@ -519,22 +505,12 @@ void QmlProfilerApplication::tryToConnect()
void QmlProfilerApplication::connected()
{
m_connectTimer.stop();
- prompt(tr("Connected to host:port %1:%2. Wait for profile data or type a command (type 'help' "
- "to show list of commands).\nRecording Status: %3")
- .arg(m_hostName).arg((m_port)).arg(m_recording ? tr("on") : tr("off")));
-}
-
-void QmlProfilerApplication::connectionStateChanged(
- QAbstractSocket::SocketState state)
-{
- if (m_verbose)
- qDebug() << state;
-}
-
-void QmlProfilerApplication::connectionError(QAbstractSocket::SocketError error)
-{
- if (m_verbose)
- qDebug() << error;
+ QString endpoint = m_socketFile.isEmpty() ?
+ QString::fromLatin1("%1:%2").arg(m_hostName).arg(m_port) :
+ m_socketFile;
+ prompt(tr("Connected to %1. Wait for profile data or type a command (type 'help' to show list "
+ "of commands).\nRecording Status: %2")
+ .arg(endpoint).arg(m_recording ? tr("on") : tr("off")));
}
void QmlProfilerApplication::processHasOutput()
@@ -562,35 +538,24 @@ void QmlProfilerApplication::processFinished()
}
if (!m_interactive)
exit(exitCode);
+ else
+ m_qmlProfilerClient.clearPendingData();
}
-void QmlProfilerApplication::traceClientEnabled()
+void QmlProfilerApplication::traceClientEnabledChanged(bool enabled)
{
- logStatus("Trace client is attached.");
- // blocked server is waiting for recording message from both clients
- // once the last one is connected, both messages should be sent
- m_qmlProfilerClient.sendRecordingStatus(m_recording);
- m_v8profilerClient.sendRecordingStatus(m_recording);
-}
-
-void QmlProfilerApplication::profilerClientEnabled()
-{
- logStatus("Profiler client is attached.");
-
- // blocked server is waiting for recording message from both clients
- // once the last one is connected, both messages should be sent
- m_qmlProfilerClient.sendRecordingStatus(m_recording);
- m_v8profilerClient.sendRecordingStatus(m_recording);
+ if (enabled) {
+ logStatus("Trace client is attached.");
+ // blocked server is waiting for recording message from both clients
+ // once the last one is connected, both messages should be sent
+ m_qmlProfilerClient.sendRecordingStatus(m_recording);
+ }
}
void QmlProfilerApplication::traceFinished()
{
m_recording = false; // only on "Complete" we know that the trace is really finished.
- // after receiving both notifications, reset the flags
- m_qmlDataReady = false;
- m_v8DataReady = false;
-
if (m_pendingRequest == REQUEST_FLUSH) {
flush();
} else if (m_pendingRequest == REQUEST_TOGGLE_RECORDING) {
@@ -599,6 +564,8 @@ void QmlProfilerApplication::traceFinished()
} else {
prompt(tr("Application stopped recording."), false);
}
+
+ m_qmlProfilerClient.clearPendingData();
}
void QmlProfilerApplication::prompt(const QString &line, bool ready)
@@ -626,21 +593,3 @@ void QmlProfilerApplication::logStatus(const QString &status)
QTextStream err(stderr);
err << status << endl;
}
-
-void QmlProfilerApplication::qmlComplete()
-{
- m_qmlDataReady = true;
- if (m_v8profilerClient.state() != QQmlDebugClient::Enabled ||
- m_v8DataReady) {
- m_profilerData.complete();
- }
-}
-
-void QmlProfilerApplication::v8Complete()
-{
- m_v8DataReady = true;
- if (m_qmlProfilerClient.state() != QQmlDebugClient::Enabled ||
- m_qmlDataReady) {
- m_profilerData.complete();
- }
-}
diff --git a/tools/qmlprofiler/qmlprofilerapplication.h b/tools/qmlprofiler/qmlprofilerapplication.h
index f1bf6c3e93..ef79a902e7 100644
--- a/tools/qmlprofiler/qmlprofilerapplication.h
+++ b/tools/qmlprofiler/qmlprofilerapplication.h
@@ -34,13 +34,16 @@
#ifndef QMLPROFILERAPPLICATION_H
#define QMLPROFILERAPPLICATION_H
-#include <QtCore/QCoreApplication>
-#include <QtCore/QProcess>
-#include <QtCore/QTimer>
-
#include "qmlprofilerclient.h"
#include "qmlprofilerdata.h"
+#include <private/qqmldebugconnection_p.h>
+
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qprocess.h>
+#include <QtCore/qtimer.h>
+#include <QtNetwork/qabstractsocket.h>
+
enum PendingRequest {
REQUEST_QUIT,
REQUEST_FLUSH_FILE,
@@ -73,22 +76,16 @@ private slots:
void run();
void tryToConnect();
void connected();
- void connectionStateChanged(QAbstractSocket::SocketState state);
- void connectionError(QAbstractSocket::SocketError error);
void processHasOutput();
void processFinished();
- void traceClientEnabled();
- void profilerClientEnabled();
+ void traceClientEnabledChanged(bool enabled);
void traceFinished();
void prompt(const QString &line = QString(), bool ready = true);
void logError(const QString &error);
void logStatus(const QString &status);
- void qmlComplete();
- void v8Complete();
-
private:
quint64 parseFeatures(const QStringList &featureList, const QString &values, bool exclude);
bool checkOutputFile(PendingRequest pending);
@@ -105,6 +102,7 @@ private:
QStringList m_programArguments;
QProcess *m_process;
+ QString m_socketFile;
QString m_hostName;
quint16 m_port;
QString m_outputFile;
@@ -117,13 +115,9 @@ private:
QQmlDebugConnection m_connection;
QmlProfilerClient m_qmlProfilerClient;
- V8ProfilerClient m_v8profilerClient;
QmlProfilerData m_profilerData;
QTimer m_connectTimer;
uint m_connectionAttempts;
-
- bool m_qmlDataReady;
- bool m_v8DataReady;
};
#endif // QMLPROFILERAPPLICATION_H
diff --git a/tools/qmlprofiler/qmlprofilerclient.cpp b/tools/qmlprofiler/qmlprofilerclient.cpp
index b4768e6934..4a0dfb8394 100644
--- a/tools/qmlprofiler/qmlprofilerclient.cpp
+++ b/tools/qmlprofiler/qmlprofilerclient.cpp
@@ -32,317 +32,174 @@
****************************************************************************/
#include "qmlprofilerclient.h"
+#include "qmlprofilerdata.h"
+
+#include <private/qqmlprofilerclient_p_p.h>
#include <QtCore/QStack>
#include <QtCore/QStringList>
-#include <QtCore/QDataStream>
#include <limits>
-ProfilerClient::ProfilerClient(const QString &clientName,
- QQmlDebugConnection *client)
- : QQmlDebugClient(clientName, client),
- m_enabled(false)
-{
-}
-
-ProfilerClient::~ProfilerClient()
-{
-}
-
-void ProfilerClient::clearData()
-{
- emit cleared();
-}
-
-bool ProfilerClient::isEnabled() const
-{
- return m_enabled;
-}
-
-void ProfilerClient::stateChanged(State status)
-{
- if ((m_enabled && status != Enabled) ||
- (!m_enabled && status == Enabled))
- emit enabledChanged();
-
- m_enabled = status == Enabled;
-
-}
-
-class QmlProfilerClientPrivate
+class QmlProfilerClientPrivate : public QQmlProfilerClientPrivate
{
+ Q_DECLARE_PUBLIC(QmlProfilerClient)
public:
- QmlProfilerClientPrivate()
- : inProgressRanges(0) , features(std::numeric_limits<quint64>::max())
- {
- ::memset(rangeCount, 0, QQmlProfilerDefinitions::MaximumRangeType * sizeof(int));
- }
+ QmlProfilerClientPrivate(QQmlDebugConnection *connection, QmlProfilerData *data);
+
+ QmlProfilerData *data;
qint64 inProgressRanges;
QStack<qint64> rangeStartTimes[QQmlProfilerDefinitions::MaximumRangeType];
QStack<QStringList> rangeDatas[QQmlProfilerDefinitions::MaximumRangeType];
- QStack<QmlEventLocation> rangeLocations[QQmlProfilerDefinitions::MaximumRangeType];
- QStack<QQmlProfilerDefinitions::BindingType> bindingTypes;
+ QStack<QQmlEventLocation> rangeLocations[QQmlProfilerDefinitions::MaximumRangeType];
int rangeCount[QQmlProfilerDefinitions::MaximumRangeType];
- quint64 features;
+ bool enabled;
};
-QmlProfilerClient::QmlProfilerClient(
- QQmlDebugConnection *client)
- : ProfilerClient(QStringLiteral("CanvasFrameRate"), client),
- d(new QmlProfilerClientPrivate)
+QmlProfilerClientPrivate::QmlProfilerClientPrivate(QQmlDebugConnection *connection,
+ QmlProfilerData *data) :
+ QQmlProfilerClientPrivate(connection), data(data), inProgressRanges(0), enabled(false)
{
+ ::memset(rangeCount, 0, QQmlProfilerDefinitions::MaximumRangeType * sizeof(int));
}
-QmlProfilerClient::~QmlProfilerClient()
+QmlProfilerClient::QmlProfilerClient(QQmlDebugConnection *connection, QmlProfilerData *data) :
+ QQmlProfilerClient(*(new QmlProfilerClientPrivate(connection, data)))
{
- delete d;
}
-void QmlProfilerClient::setFeatures(quint64 features)
+void QmlProfilerClient::clearPendingData()
{
- d->features = features;
+ Q_D(QmlProfilerClient);
+ for (int i = 0; i < QQmlProfilerDefinitions::MaximumRangeType; ++i) {
+ d->rangeCount[i] = 0;
+ d->rangeDatas[i].clear();
+ d->rangeLocations[i].clear();
+ }
}
-void QmlProfilerClient::clearData()
+void QmlProfilerClient::stateChanged(State state)
{
- ::memset(d->rangeCount, 0, QQmlProfilerDefinitions::MaximumRangeType * sizeof(int));
- d->bindingTypes.clear();
- ProfilerClient::clearData();
+ Q_D(QmlProfilerClient);
+ if ((d->enabled && state != Enabled) || (!d->enabled && state == Enabled)) {
+ d->enabled = (state == Enabled);
+ emit enabledChanged(d->enabled);
+ }
}
-void QmlProfilerClient::sendRecordingStatus(bool record)
+void QmlProfilerClient::traceStarted(qint64 time, int engineId)
{
- QByteArray ba;
- QDataStream stream(&ba, QIODevice::WriteOnly);
- stream.setVersion(QDataStream::Qt_4_7);
- stream << record << -1 << d->features;
- sendMessage(ba);
+ Q_UNUSED(engineId);
+ Q_D(QmlProfilerClient);
+ d->data->setTraceStartTime(time);
+ emit recordingStarted();
}
-inline QQmlProfilerDefinitions::ProfileFeature featureFromRangeType(
- QQmlProfilerDefinitions::RangeType range)
+void QmlProfilerClient::traceFinished(qint64 time, int engineId)
{
- switch (range) {
- case QQmlProfilerDefinitions::Painting:
- return QQmlProfilerDefinitions::ProfilePainting;
- case QQmlProfilerDefinitions::Compiling:
- return QQmlProfilerDefinitions::ProfileCompiling;
- case QQmlProfilerDefinitions::Creating:
- return QQmlProfilerDefinitions::ProfileCreating;
- case QQmlProfilerDefinitions::Binding:
- return QQmlProfilerDefinitions::ProfileBinding;
- case QQmlProfilerDefinitions::HandlingSignal:
- return QQmlProfilerDefinitions::ProfileHandlingSignal;
- case QQmlProfilerDefinitions::Javascript:
- return QQmlProfilerDefinitions::ProfileJavaScript;
- default:
- return QQmlProfilerDefinitions::MaximumProfileFeature;
- }
+ Q_UNUSED(engineId);
+ Q_D(QmlProfilerClient);
+ d->data->setTraceEndTime(time);
}
-void QmlProfilerClient::messageReceived(const QByteArray &data)
+void QmlProfilerClient::rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime)
{
- QByteArray rwData = data;
- QDataStream stream(&rwData, QIODevice::ReadOnly);
- stream.setVersion(QDataStream::Qt_4_7);
+ Q_D(QmlProfilerClient);
+ d->rangeStartTimes[type].push(startTime);
+ d->inProgressRanges |= (static_cast<qint64>(1) << type);
+ ++d->rangeCount[type];
+}
- // Force all the 1 << <FLAG> expressions to be done in 64 bit, to silence some warnings
- const quint64 one = static_cast<quint64>(1);
+void QmlProfilerClient::rangeData(QQmlProfilerDefinitions::RangeType type, qint64 time,
+ const QString &data)
+{
+ Q_UNUSED(time);
+ Q_D(QmlProfilerClient);
+ int count = d->rangeCount[type];
+ if (count > 0) {
+ while (d->rangeDatas[type].count() < count)
+ d->rangeDatas[type].push(QStringList());
+ d->rangeDatas[type][count - 1] << data;
+ }
+}
- qint64 time;
- int messageType;
+void QmlProfilerClient::rangeLocation(QQmlProfilerDefinitions::RangeType type, qint64 time,
+ const QQmlEventLocation &location)
+{
+ Q_UNUSED(time);
+ Q_D(QmlProfilerClient);
+ if (d->rangeCount[type] > 0)
+ d->rangeLocations[type].push(location);
+}
- stream >> time >> messageType;
+void QmlProfilerClient::rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime)
+{
+ Q_D(QmlProfilerClient);
- if (messageType >= QQmlProfilerDefinitions::MaximumMessage)
+ if (d->rangeCount[type] == 0) {
+ emit error(tr("Spurious range end detected."));
return;
+ }
- if (messageType == QQmlProfilerDefinitions::Event) {
- int event;
- stream >> event;
-
- if (event == QQmlProfilerDefinitions::EndTrace) {
- emit this->traceFinished(time);
- } else if (event == QQmlProfilerDefinitions::AnimationFrame) {
- if (!(d->features & one << QQmlProfilerDefinitions::ProfileAnimations))
- return;
- int frameRate, animationCount;
- int threadId = 0;
- stream >> frameRate >> animationCount;
- if (!stream.atEnd())
- stream >> threadId;
- emit this->frame(time, frameRate, animationCount, threadId);
- } else if (event == QQmlProfilerDefinitions::StartTrace) {
- emit this->traceStarted(time);
- } else if (event == QQmlProfilerDefinitions::Key ||
- event == QQmlProfilerDefinitions::Mouse) {
- if (!(d->features & one << QQmlProfilerDefinitions::ProfileInputEvents))
- return;
- emit this->inputEvent((QQmlProfilerDefinitions::EventType)event, time);
- }
- } else if (messageType == QQmlProfilerDefinitions::Complete) {
- emit complete();
- } else if (messageType == QQmlProfilerDefinitions::SceneGraphFrame) {
- if (!(d->features & one << QQmlProfilerDefinitions::ProfileSceneGraph))
- return;
- int sgEventType;
- int count = 0;
- qint64 params[5];
-
- stream >> sgEventType;
- while (!stream.atEnd()) {
- stream >> params[count++];
- }
- while (count<5)
- params[count++] = 0;
- emit sceneGraphFrame((QQmlProfilerDefinitions::SceneGraphFrameType)sgEventType, time,
- params[0], params[1], params[2], params[3], params[4]);
- } else if (messageType == QQmlProfilerDefinitions::PixmapCacheEvent) {
- if (!(d->features & one << QQmlProfilerDefinitions::ProfilePixmapCache))
- return;
- int pixEvTy, width = 0, height = 0, refcount = 0;
- QString pixUrl;
- stream >> pixEvTy >> pixUrl;
- if (pixEvTy == (int)QQmlProfilerDefinitions::PixmapReferenceCountChanged ||
- pixEvTy == (int)QQmlProfilerDefinitions::PixmapCacheCountChanged) {
- stream >> refcount;
- } else if (pixEvTy == (int)QQmlProfilerDefinitions::PixmapSizeKnown) {
- stream >> width >> height;
- refcount = 1;
- }
- emit pixmapCache((QQmlProfilerDefinitions::PixmapEventType)pixEvTy, time,
- QmlEventLocation(pixUrl,0,0), width, height, refcount);
- } else if (messageType == QQmlProfilerDefinitions::MemoryAllocation) {
- if (!(d->features & one << QQmlProfilerDefinitions::ProfileMemory))
- return;
- int type;
- qint64 delta;
- stream >> type >> delta;
- emit memoryAllocation((QQmlProfilerDefinitions::MemoryType)type, time, delta);
- } else {
- int range;
- stream >> range;
-
- if (range >= QQmlProfilerDefinitions::MaximumRangeType)
- return;
-
- if (!(d->features & one << featureFromRangeType(
- static_cast<QQmlProfilerDefinitions::RangeType>(range))))
- return;
-
- if (messageType == QQmlProfilerDefinitions::RangeStart) {
- d->rangeStartTimes[range].push(time);
- d->inProgressRanges |= (static_cast<qint64>(1) << range);
- ++d->rangeCount[range];
-
- // read binding type
- if (range == (int)QQmlProfilerDefinitions::Binding) {
- int bindingType = (int)QQmlProfilerDefinitions::QmlBinding;
- if (!stream.atEnd())
- stream >> bindingType;
- d->bindingTypes.push((QQmlProfilerDefinitions::BindingType)bindingType);
- }
- } else if (messageType == QQmlProfilerDefinitions::RangeData) {
- QString data;
- stream >> data;
-
- int count = d->rangeCount[range];
- if (count > 0) {
- while (d->rangeDatas[range].count() < count)
- d->rangeDatas[range].push(QStringList());
- d->rangeDatas[range][count-1] << data;
- }
-
- } else if (messageType == QQmlProfilerDefinitions::RangeLocation) {
- QString fileName;
- int line;
- int column = -1;
- stream >> fileName >> line;
-
- if (!stream.atEnd())
- stream >> column;
-
- if (d->rangeCount[range] > 0) {
- d->rangeLocations[range].push(QmlEventLocation(fileName, line,
- column));
- }
- } else {
- if (d->rangeCount[range] > 0) {
- --d->rangeCount[range];
- if (d->inProgressRanges & (static_cast<qint64>(1) << range))
- d->inProgressRanges &= ~(static_cast<qint64>(1) << range);
-
- QStringList data = d->rangeDatas[range].count() ?
- d->rangeDatas[range].pop() : QStringList();
- QmlEventLocation location = d->rangeLocations[range].count() ?
- d->rangeLocations[range].pop() : QmlEventLocation();
-
- qint64 startTime = d->rangeStartTimes[range].pop();
- QQmlProfilerDefinitions::BindingType bindingType =
- QQmlProfilerDefinitions::QmlBinding;
- if (range == (int)QQmlProfilerDefinitions::Binding)
- bindingType = d->bindingTypes.pop();
- emit this->range((QQmlProfilerDefinitions::RangeType)range,
- bindingType, startTime, time - startTime, data, location);
- if (d->rangeCount[range] == 0) {
- int count = d->rangeDatas[range].count() +
- d->rangeStartTimes[range].count() +
- d->rangeLocations[range].count();
- if (count != 0)
- qWarning() << "incorrectly nested data";
- }
- }
- }
+ --d->rangeCount[type];
+ if (d->inProgressRanges & (static_cast<qint64>(1) << type))
+ d->inProgressRanges &= ~(static_cast<qint64>(1) << type);
+ QStringList data = d->rangeDatas[type].count() ? d->rangeDatas[type].pop() : QStringList();
+ QQmlEventLocation location = d->rangeLocations[type].count() ? d->rangeLocations[type].pop() :
+ QQmlEventLocation();
+ qint64 startTime = d->rangeStartTimes[type].pop();
+
+ if (d->rangeCount[type] == 0 && d->rangeDatas[type].count() + d->rangeStartTimes[type].count()
+ + d->rangeLocations[type].count() != 0) {
+ emit error(tr("Incorrectly nested range data"));
+ return;
}
+
+ d->data->addQmlEvent(type, QQmlProfilerDefinitions::QmlBinding, startTime, endTime - startTime,
+ data, location);
}
-V8ProfilerClient::V8ProfilerClient(QQmlDebugConnection *client)
- : ProfilerClient(QStringLiteral("V8Profiler"), client)
+void QmlProfilerClient::animationFrame(qint64 time, int frameRate, int animationCount, int threadId)
{
+ Q_D(QmlProfilerClient);
+ d->data->addFrameEvent(time, frameRate, animationCount, threadId);
}
-V8ProfilerClient::~V8ProfilerClient()
+void QmlProfilerClient::sceneGraphEvent(QQmlProfilerDefinitions::SceneGraphFrameType type,
+ qint64 time, qint64 numericData1, qint64 numericData2,
+ qint64 numericData3, qint64 numericData4,
+ qint64 numericData5)
{
+ Q_D(QmlProfilerClient);
+ d->data->addSceneGraphFrameEvent(type, time, numericData1, numericData2, numericData3,
+ numericData4, numericData5);
}
-void V8ProfilerClient::sendRecordingStatus(bool record)
+void QmlProfilerClient::pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type, qint64 time,
+ const QString &url, int numericData1, int numericData2)
{
- QByteArray ba;
- QDataStream stream(&ba, QIODevice::WriteOnly);
- QByteArray cmd("V8PROFILER");
- QByteArray option(record ? "start" : "stop");
- QByteArray title("");
-
- stream << cmd << option << title;
- sendMessage(ba);
+ Q_D(QmlProfilerClient);
+ d->data->addPixmapCacheEvent(type, time, url, numericData1, numericData2);
}
-void V8ProfilerClient::messageReceived(const QByteArray &data)
+void QmlProfilerClient::memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time,
+ qint64 amount)
{
- QByteArray rwData = data;
- QDataStream stream(&rwData, QIODevice::ReadOnly);
-
- int messageType;
-
- stream >> messageType;
-
- if (messageType == V8Complete) {
- emit complete();
- } else if (messageType == V8Entry) {
- QString filename;
- QString function;
- int lineNumber;
- double totalTime;
- double selfTime;
- int depth;
+ Q_D(QmlProfilerClient);
+ d->data->addMemoryEvent(type, time, amount);
+}
- stream >> filename >> function >> lineNumber >> totalTime >>
- selfTime >> depth;
- emit this->range(depth, function, filename, lineNumber, totalTime,
- selfTime);
- }
+void QmlProfilerClient::inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time,
+ int a, int b)
+{
+ Q_D(QmlProfilerClient);
+ d->data->addInputEvent(type, time, a, b);
}
+void QmlProfilerClient::complete()
+{
+ Q_D(QmlProfilerClient);
+ d->data->complete();
+}
diff --git a/tools/qmlprofiler/qmlprofilerclient.h b/tools/qmlprofiler/qmlprofilerclient.h
index 731ab99973..fc4dad639d 100644
--- a/tools/qmlprofiler/qmlprofilerclient.h
+++ b/tools/qmlprofiler/qmlprofilerclient.h
@@ -34,100 +34,45 @@
#ifndef QMLPROFILERCLIENT_H
#define QMLPROFILERCLIENT_H
-#include "qqmldebugclient.h"
-#include "qmlprofilereventlocation.h"
-#include <QtQml/private/qqmlprofilerdefinitions_p.h>
+#include <private/qqmleventlocation_p.h>
+#include <private/qqmlprofilerclient_p.h>
+#include <private/qqmlprofilerdefinitions_p.h>
-class ProfilerClientPrivate;
-class ProfilerClient : public QQmlDebugClient
+class QmlProfilerData;
+class QmlProfilerClientPrivate;
+class QmlProfilerClient : public QQmlProfilerClient
{
Q_OBJECT
+ Q_DECLARE_PRIVATE(QmlProfilerClient)
- Q_PROPERTY(bool enabled READ isEnabled NOTIFY enabledChanged)
public:
- ProfilerClient(const QString &clientName,
- QQmlDebugConnection *client);
- ~ProfilerClient();
-
- bool isEnabled() const;
-
-public slots:
- virtual void clearData();
+ QmlProfilerClient(QQmlDebugConnection *connection, QmlProfilerData *data);
+ void clearPendingData();
signals:
- void complete();
- void enabledChanged();
- void cleared();
-
-protected:
- virtual void stateChanged(State);
-
-protected:
- bool m_enabled;
-};
-
-class QmlProfilerClient : public ProfilerClient
-{
- Q_OBJECT
-
-public:
- QmlProfilerClient(QQmlDebugConnection *client);
- ~QmlProfilerClient();
-
- void setFeatures(quint64 features);
+ void enabledChanged(bool enabled);
+ void recordingStarted();
+ void error(const QString &error);
-public slots:
- void clearData();
- void sendRecordingStatus(bool record);
-
-signals:
- void traceFinished( qint64 time );
- void traceStarted( qint64 time );
- void range(QQmlProfilerDefinitions::RangeType type,
- QQmlProfilerDefinitions::BindingType bindingType,
- qint64 startTime, qint64 length,
- const QStringList &data,
- const QmlEventLocation &location);
- void frame(qint64 time, int frameRate, int animationCount, int threadId);
- void sceneGraphFrame(QQmlProfilerDefinitions::SceneGraphFrameType type, qint64 time,
+private:
+ virtual void stateChanged(State state);
+
+ void traceStarted(qint64 time, int engineId);
+ void traceFinished(qint64 time, int engineId);
+ void rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime);
+ void rangeData(QQmlProfilerDefinitions::RangeType type, qint64 time, const QString &data);
+ void rangeLocation(QQmlProfilerDefinitions::RangeType type, qint64 time,
+ const QQmlEventLocation &location);
+ void rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime);
+ void animationFrame(qint64 time, int frameRate, int animationCount, int threadId);
+ void sceneGraphEvent(QQmlProfilerDefinitions::SceneGraphFrameType type, qint64 time,
qint64 numericData1, qint64 numericData2, qint64 numericData3,
qint64 numericData4, qint64 numericData5);
- void pixmapCache(QQmlProfilerDefinitions::PixmapEventType, qint64 time,
- const QmlEventLocation &location, int width, int height, int refCount);
+ void pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type, qint64 time,
+ const QString &url, int numericData1, int numericData2);
void memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time, qint64 amount);
- void inputEvent(QQmlProfilerDefinitions::EventType, qint64 time);
-
-protected:
- virtual void messageReceived(const QByteArray &);
-
-private:
- class QmlProfilerClientPrivate *d;
-};
-
-class V8ProfilerClient : public ProfilerClient
-{
- Q_OBJECT
-
-public:
- enum Message {
- V8Entry,
- V8Complete,
-
- V8MaximumMessage
- };
-
- V8ProfilerClient(QQmlDebugConnection *client);
- ~V8ProfilerClient();
-
-public slots:
- void sendRecordingStatus(bool record);
-
-signals:
- void range(int depth, const QString &function, const QString &filename,
- int lineNumber, double totalTime, double selfTime);
-
-protected:
- virtual void messageReceived(const QByteArray &);
+ void inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time, int a, int b);
+ void complete();
};
#endif // QMLPROFILERCLIENT_H
diff --git a/tools/qmlprofiler/qmlprofilerdata.cpp b/tools/qmlprofiler/qmlprofilerdata.cpp
index 307b9d3686..dd7e5d561b 100644
--- a/tools/qmlprofiler/qmlprofilerdata.cpp
+++ b/tools/qmlprofiler/qmlprofilerdata.cpp
@@ -73,14 +73,14 @@ Q_STATIC_ASSERT(sizeof(MESSAGE_STRINGS) ==
struct QmlRangeEventData {
QmlRangeEventData() {} // never called
QmlRangeEventData(const QString &_displayName, int _detailType, const QString &_eventHashStr,
- const QmlEventLocation &_location, const QString &_details,
+ const QQmlEventLocation &_location, const QString &_details,
QQmlProfilerDefinitions::Message _message,
QQmlProfilerDefinitions::RangeType _rangeType)
: displayName(_displayName), eventHashStr(_eventHashStr), location(_location),
details(_details), message(_message), rangeType(_rangeType), detailType(_detailType) {}
QString displayName;
QString eventHashStr;
- QmlEventLocation location;
+ QQmlEventLocation location;
QString details;
QQmlProfilerDefinitions::Message message;
QQmlProfilerDefinitions::RangeType rangeType;
@@ -107,14 +107,17 @@ struct QmlRangeEventStartInstance {
qint64 duration;
union {
int frameRate;
+ int inputType;
qint64 numericData1;
};
union {
int animationCount;
+ int inputA;
qint64 numericData2;
};
union {
int threadId;
+ int inputB;
qint64 numericData3;
};
qint64 numericData4;
@@ -127,18 +130,6 @@ Q_DECLARE_TYPEINFO(QmlRangeEventData, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(QmlRangeEventStartInstance, Q_MOVABLE_TYPE);
QT_END_NAMESPACE
-struct QV8EventInfo {
- QString displayName;
- QString eventHashStr;
- QString functionName;
- QString fileName;
- int line;
- qint64 totalTime;
- qint64 selfTime;
-
- QHash<QString, qint64> v8children;
-};
-
/////////////////////////////////////////////////////////////////
class QmlProfilerDataPrivate
{
@@ -148,18 +139,12 @@ public:
// data storage
QHash<QString, QmlRangeEventData *> eventDescriptions;
QVector<QmlRangeEventStartInstance> startInstanceList;
- QHash<QString, QV8EventInfo *> v8EventHash;
qint64 traceStartTime;
qint64 traceEndTime;
// internal state while collecting events
qint64 qmlMeasuredTime;
- qint64 v8MeasuredTime;
- QHash<int, QV8EventInfo *> v8parents;
- void clearV8RootEvent();
- QV8EventInfo v8RootEvent;
-
QmlProfilerData::State state;
};
@@ -183,12 +168,6 @@ void QmlProfilerData::clear()
d->eventDescriptions.clear();
d->startInstanceList.clear();
- qDeleteAll(d->v8EventHash);
- d->v8EventHash.clear();
- d->v8parents.clear();
- d->clearV8RootEvent();
- d->v8MeasuredTime = 0;
-
d->traceEndTime = std::numeric_limits<qint64>::min();
d->traceStartTime = std::numeric_limits<qint64>::max();
d->qmlMeasuredTime = 0;
@@ -196,7 +175,7 @@ void QmlProfilerData::clear()
setState(Empty);
}
-QString QmlProfilerData::getHashStringForQmlEvent(const QmlEventLocation &location, int eventType)
+QString QmlProfilerData::getHashStringForQmlEvent(const QQmlEventLocation &location, int eventType)
{
return QString(QStringLiteral("%1:%2:%3:%4")).arg(
location.filename,
@@ -205,14 +184,9 @@ QString QmlProfilerData::getHashStringForQmlEvent(const QmlEventLocation &locati
QString::number(eventType));
}
-QString QmlProfilerData::getHashStringForV8Event(const QString &displayName, const QString &function)
-{
- return QString(QStringLiteral("%1:%2")).arg(displayName, function);
-}
-
QString QmlProfilerData::qmlRangeTypeAsString(QQmlProfilerDefinitions::RangeType type)
{
- if (type * sizeof(QString) < sizeof(RANGE_TYPE_STRINGS))
+ if (type * sizeof(char *) < sizeof(RANGE_TYPE_STRINGS))
return QLatin1String(RANGE_TYPE_STRINGS[type]);
else
return QString::number(type);
@@ -220,7 +194,7 @@ QString QmlProfilerData::qmlRangeTypeAsString(QQmlProfilerDefinitions::RangeType
QString QmlProfilerData::qmlMessageAsString(QQmlProfilerDefinitions::Message type)
{
- if (type * sizeof(QString) < sizeof(MESSAGE_STRINGS))
+ if (type * sizeof(char *) < sizeof(MESSAGE_STRINGS))
return QLatin1String(MESSAGE_STRINGS[type]);
else
return QString::number(type);
@@ -253,15 +227,13 @@ void QmlProfilerData::addQmlEvent(QQmlProfilerDefinitions::RangeType type,
qint64 startTime,
qint64 duration,
const QStringList &data,
- const QmlEventLocation &location)
+ const QQmlEventLocation &location)
{
setState(AcquiringData);
QString details;
// generate details string
- if (data.isEmpty())
- details = tr("Source code not available");
- else {
+ if (!data.isEmpty()) {
details = data.join(QLatin1Char(' ')).replace(
QLatin1Char('\n'), QLatin1Char(' ')).simplified();
QRegExp rewrite(QStringLiteral("\\(function \\$(\\w+)\\(\\) \\{ (return |)(.+) \\}\\)"));
@@ -273,7 +245,7 @@ void QmlProfilerData::addQmlEvent(QQmlProfilerDefinitions::RangeType type,
details = details.mid(details.lastIndexOf(QLatin1Char('/')) + 1);
}
- QmlEventLocation eventLocation = location;
+ QQmlEventLocation eventLocation = location;
QString displayName, eventHashStr;
// generate hash
if (eventLocation.filename.isEmpty()) {
@@ -315,7 +287,7 @@ void QmlProfilerData::addFrameEvent(qint64 time, int framerate, int animationcou
} else {
newEvent = new QmlRangeEventData(displayName, QQmlProfilerDefinitions::AnimationFrame,
eventHashStr,
- QmlEventLocation(), details,
+ QQmlEventLocation(), details,
QQmlProfilerDefinitions::Event,
QQmlProfilerDefinitions::MaximumRangeType);
d->eventDescriptions.insert(eventHashStr, newEvent);
@@ -340,7 +312,7 @@ void QmlProfilerData::addSceneGraphFrameEvent(QQmlProfilerDefinitions::SceneGrap
newEvent = d->eventDescriptions[eventHashStr];
} else {
newEvent = new QmlRangeEventData(QStringLiteral("<SceneGraph>"), type, eventHashStr,
- QmlEventLocation(), QString(),
+ QQmlEventLocation(), QString(),
QQmlProfilerDefinitions::SceneGraphFrame,
QQmlProfilerDefinitions::MaximumRangeType);
d->eventDescriptions.insert(eventHashStr, newEvent);
@@ -353,12 +325,12 @@ void QmlProfilerData::addSceneGraphFrameEvent(QQmlProfilerDefinitions::SceneGrap
}
void QmlProfilerData::addPixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type,
- qint64 time, const QmlEventLocation &location,
- int width, int height, int refcount)
+ qint64 time, const QString &location,
+ int numericData1, int numericData2)
{
setState(AcquiringData);
- QString filePath = QUrl(location.filename).path();
+ QString filePath = QUrl(location).path();
QString eventHashStr = filePath.mid(filePath.lastIndexOf(QLatin1Char('/')) + 1) +
QStringLiteral(":") + QString::number(type);
@@ -366,13 +338,14 @@ void QmlProfilerData::addPixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventTy
if (d->eventDescriptions.contains(eventHashStr)) {
newEvent = d->eventDescriptions[eventHashStr];
} else {
- newEvent = new QmlRangeEventData(eventHashStr, type, eventHashStr, location, QString(),
+ newEvent = new QmlRangeEventData(eventHashStr, type, eventHashStr,
+ QQmlEventLocation(location, -1, -1), QString(),
QQmlProfilerDefinitions::PixmapCacheEvent,
QQmlProfilerDefinitions::MaximumRangeType);
d->eventDescriptions.insert(eventHashStr, newEvent);
}
- QmlRangeEventStartInstance rangeEventStartInstance(time, width, height, refcount, 0, 0,
+ QmlRangeEventStartInstance rangeEventStartInstance(time, numericData1, numericData2, 0, 0, 0,
newEvent);
d->startInstanceList.append(rangeEventStartInstance);
}
@@ -386,7 +359,7 @@ void QmlProfilerData::addMemoryEvent(QQmlProfilerDefinitions::MemoryType type, q
if (d->eventDescriptions.contains(eventHashStr)) {
newEvent = d->eventDescriptions[eventHashStr];
} else {
- newEvent = new QmlRangeEventData(eventHashStr, type, eventHashStr, QmlEventLocation(),
+ newEvent = new QmlRangeEventData(eventHashStr, type, eventHashStr, QQmlEventLocation(),
QString(), QQmlProfilerDefinitions::MemoryAllocation,
QQmlProfilerDefinitions::MaximumRangeType);
d->eventDescriptions.insert(eventHashStr, newEvent);
@@ -395,93 +368,36 @@ void QmlProfilerData::addMemoryEvent(QQmlProfilerDefinitions::MemoryType type, q
d->startInstanceList.append(rangeEventStartInstance);
}
-void QmlProfilerData::addInputEvent(QQmlProfilerDefinitions::EventType type, qint64 time)
+void QmlProfilerData::addInputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time,
+ int a, int b)
{
setState(AcquiringData);
- QString eventHashStr = QString::fromLatin1("Input:%1").arg(type);
+ QQmlProfilerDefinitions::EventType eventType;
+ switch (type) {
+ case QQmlProfilerDefinitions::InputKeyPress:
+ case QQmlProfilerDefinitions::InputKeyRelease:
+ case QQmlProfilerDefinitions::InputKeyUnknown:
+ eventType = QQmlProfilerDefinitions::Key;
+ break;
+ default:
+ eventType = QQmlProfilerDefinitions::Mouse;
+ break;
+ }
+
+ QString eventHashStr = QString::fromLatin1("Input:%1").arg(eventType);
QmlRangeEventData *newEvent;
if (d->eventDescriptions.contains(eventHashStr)) {
newEvent = d->eventDescriptions[eventHashStr];
} else {
- newEvent = new QmlRangeEventData(QString(), type, eventHashStr, QmlEventLocation(),
+ newEvent = new QmlRangeEventData(QString(), eventType, eventHashStr, QQmlEventLocation(),
QString(), QQmlProfilerDefinitions::Event,
QQmlProfilerDefinitions::MaximumRangeType);
d->eventDescriptions.insert(eventHashStr, newEvent);
}
- d->startInstanceList.append(QmlRangeEventStartInstance(time, -1, 0, 0, 0, newEvent));
-}
-
-QString QmlProfilerData::rootEventName()
-{
- return tr("<program>");
-}
-
-QString QmlProfilerData::rootEventDescription()
-{
- return tr("Main Program");
-}
-
-void QmlProfilerDataPrivate::clearV8RootEvent()
-{
- v8RootEvent.displayName = QmlProfilerData::rootEventName();
- v8RootEvent.eventHashStr = QmlProfilerData::rootEventName();
- v8RootEvent.functionName = QmlProfilerData::rootEventDescription();
- v8RootEvent.line = -1;
- v8RootEvent.totalTime = 0;
- v8RootEvent.selfTime = 0;
- v8RootEvent.v8children.clear();
-}
-
-void QmlProfilerData::addV8Event(int depth, const QString &function, const QString &filename,
- int lineNumber, double totalTime, double selfTime)
-{
- QString displayName = filename.mid(filename.lastIndexOf(QLatin1Char('/')) + 1) +
- QLatin1Char(':') + QString::number(lineNumber);
- QString hashStr = getHashStringForV8Event(displayName, function);
-
- setState(AcquiringData);
-
- // time is given in milliseconds, but internally we store it in microseconds
- totalTime *= 1e6;
- selfTime *= 1e6;
-
- // accumulate information
- QV8EventInfo *eventData = d->v8EventHash[hashStr];
- if (!eventData) {
- eventData = new QV8EventInfo;
- eventData->displayName = displayName;
- eventData->eventHashStr = hashStr;
- eventData->fileName = filename;
- eventData->functionName = function;
- eventData->line = lineNumber;
- eventData->totalTime = totalTime;
- eventData->selfTime = selfTime;
- d->v8EventHash[hashStr] = eventData;
- } else {
- eventData->totalTime += totalTime;
- eventData->selfTime += selfTime;
- }
- d->v8parents[depth] = eventData;
-
- QV8EventInfo *parentEvent = 0;
- if (depth == 0) {
- parentEvent = &d->v8RootEvent;
- d->v8MeasuredTime += totalTime;
- }
- if (depth > 0 && d->v8parents.contains(depth-1)) {
- parentEvent = d->v8parents.value(depth-1);
- }
-
- if (parentEvent != 0) {
- if (!parentEvent->v8children.contains(eventData->eventHashStr)) {
- parentEvent->v8children[eventData->eventHashStr] = totalTime;
- } else {
- parentEvent->v8children[eventData->eventHashStr] += totalTime;
- }
- }
+ d->startInstanceList.append(QmlRangeEventStartInstance(time, -1, type, a, b, newEvent));
}
void QmlProfilerData::computeQmlTime()
@@ -532,7 +448,7 @@ void QmlProfilerData::sortStartTimes()
// find block to sort
while ( itFrom != d->startInstanceList.begin()
&& itTo->startTime > itFrom->startTime ) {
- itTo--;
+ --itTo;
itFrom = itTo - 1;
}
@@ -543,7 +459,7 @@ void QmlProfilerData::sortStartTimes()
// find block length
while ( itFrom != d->startInstanceList.begin()
&& itTo->startTime <= itFrom->startTime )
- itFrom--;
+ --itFrom;
if (itTo->startTime <= itFrom->startTime)
std::sort(itFrom, itTo + 1, compareStartTimes);
@@ -567,7 +483,7 @@ void QmlProfilerData::complete()
bool QmlProfilerData::isEmpty() const
{
- return d->startInstanceList.isEmpty() && d->v8EventHash.isEmpty();
+ return d->startInstanceList.isEmpty();
}
bool QmlProfilerData::save(const QString &filename)
@@ -608,21 +524,24 @@ bool QmlProfilerData::save(const QString &filename)
stream.writeStartElement(QStringLiteral("event"));
stream.writeAttribute(QStringLiteral("index"), QString::number(
d->eventDescriptions.keys().indexOf(eventData->eventHashStr)));
- stream.writeTextElement(QStringLiteral("displayname"), eventData->displayName);
+ if (!eventData->displayName.isEmpty())
+ stream.writeTextElement(QStringLiteral("displayname"), eventData->displayName);
if (eventData->rangeType != QQmlProfilerDefinitions::MaximumRangeType)
stream.writeTextElement(QStringLiteral("type"),
qmlRangeTypeAsString(eventData->rangeType));
else
stream.writeTextElement(QStringLiteral("type"),
qmlMessageAsString(eventData->message));
- if (!eventData->location.filename.isEmpty()) {
+ if (!eventData->location.filename.isEmpty())
stream.writeTextElement(QStringLiteral("filename"), eventData->location.filename);
+ if (eventData->location.line >= 0)
stream.writeTextElement(QStringLiteral("line"),
QString::number(eventData->location.line));
+ if (eventData->location.column >= 0)
stream.writeTextElement(QStringLiteral("column"),
QString::number(eventData->location.column));
- }
- stream.writeTextElement(QStringLiteral("details"), eventData->details);
+ if (!eventData->details.isEmpty())
+ stream.writeTextElement(QStringLiteral("details"), eventData->details);
if (eventData->rangeType == QQmlProfilerDefinitions::Binding)
stream.writeTextElement(QStringLiteral("bindingType"),
QString::number((int)eventData->detailType));
@@ -663,13 +582,23 @@ bool QmlProfilerData::save(const QString &filename)
QString::number(event.duration));
stream.writeAttribute(QStringLiteral("eventIndex"), QString::number(
d->eventDescriptions.keys().indexOf(event.data->eventHashStr)));
- if (event.data->message == QQmlProfilerDefinitions::Event &&
- event.data->detailType == QQmlProfilerDefinitions::AnimationFrame) {
- // special: animation frame
- stream.writeAttribute(QStringLiteral("framerate"), QString::number(event.frameRate));
- stream.writeAttribute(QStringLiteral("animationcount"),
- QString::number(event.animationCount));
- stream.writeAttribute(QStringLiteral("thread"), QString::number(event.threadId));
+ if (event.data->message == QQmlProfilerDefinitions::Event) {
+ if (event.data->detailType == QQmlProfilerDefinitions::AnimationFrame) {
+ // special: animation frame
+ stream.writeAttribute(QStringLiteral("framerate"), QString::number(event.frameRate));
+ stream.writeAttribute(QStringLiteral("animationcount"),
+ QString::number(event.animationCount));
+ stream.writeAttribute(QStringLiteral("thread"), QString::number(event.threadId));
+ } else if (event.data->detailType == QQmlProfilerDefinitions::Key ||
+ event.data->detailType == QQmlProfilerDefinitions::Mouse) {
+ // numerical value here, to keep the format a bit more compact
+ stream.writeAttribute(QStringLiteral("type"),
+ QString::number(event.inputType));
+ stream.writeAttribute(QStringLiteral("data1"),
+ QString::number(event.inputA));
+ stream.writeAttribute(QStringLiteral("data2"),
+ QString::number(event.inputB));
+ }
} else if (event.data->message == QQmlProfilerDefinitions::PixmapCacheEvent) {
// special: pixmap cache event
if (event.data->detailType == QQmlProfilerDefinitions::PixmapSizeKnown) {
@@ -682,7 +611,7 @@ bool QmlProfilerData::save(const QString &filename)
event.data->detailType ==
QQmlProfilerDefinitions::PixmapCacheCountChanged) {
stream.writeAttribute(QStringLiteral("refCount"),
- QString::number(event.numericData3));
+ QString::number(event.numericData1));
}
} else if (event.data->message == QQmlProfilerDefinitions::SceneGraphFrame) {
// special: scenegraph frame events
@@ -708,38 +637,6 @@ bool QmlProfilerData::save(const QString &filename)
}
stream.writeEndElement(); // profilerDataModel
- stream.writeStartElement(QStringLiteral("v8profile")); // v8 profiler output
- stream.writeAttribute(QStringLiteral("totalTime"), QString::number(d->v8MeasuredTime));
- foreach (QV8EventInfo *v8event, d->v8EventHash.values()) {
- stream.writeStartElement(QStringLiteral("event"));
- stream.writeAttribute(QStringLiteral("index"),QString::number(
- d->v8EventHash.keys().indexOf(v8event->eventHashStr)));
- stream.writeTextElement(QStringLiteral("displayname"), v8event->displayName);
- stream.writeTextElement(QStringLiteral("functionname"), v8event->functionName);
- if (!v8event->fileName.isEmpty()) {
- stream.writeTextElement(QStringLiteral("filename"), v8event->fileName);
- stream.writeTextElement(QStringLiteral("line"), QString::number(v8event->line));
- }
- stream.writeTextElement(QStringLiteral("totalTime"), QString::number(v8event->totalTime));
- stream.writeTextElement(QStringLiteral("selfTime"), QString::number(v8event->selfTime));
- if (!v8event->v8children.isEmpty()) {
- stream.writeStartElement(QStringLiteral("childrenEvents"));
- QStringList childrenIndexes;
- QStringList childrenTimes;
- foreach (const QString &childHash, v8event->v8children.keys()) {
- childrenIndexes << QString::number(v8EventIndex(childHash));
- childrenTimes << QString::number(v8event->v8children[childHash]);
- }
-
- stream.writeAttribute(QStringLiteral("list"), childrenIndexes.join(QString(", ")));
- stream.writeAttribute(QStringLiteral("childrenTimes"),
- childrenTimes.join(QString(", ")));
- stream.writeEndElement();
- }
- stream.writeEndElement();
- }
- stream.writeEndElement(); // v8 profiler output
-
stream.writeEndElement(); // trace
stream.writeEndDocument();
@@ -747,15 +644,6 @@ bool QmlProfilerData::save(const QString &filename)
return true;
}
-int QmlProfilerData::v8EventIndex(const QString &hashStr)
-{
- if (!d->v8EventHash.contains(hashStr)) {
- emit error("Trying to index nonexisting v8 event");
- return -1;
- }
- return d->v8EventHash.keys().indexOf( hashStr );
-}
-
void QmlProfilerData::setState(QmlProfilerData::State state)
{
// It's not an error, we are continuously calling "AcquiringData" for example
diff --git a/tools/qmlprofiler/qmlprofilerdata.h b/tools/qmlprofiler/qmlprofilerdata.h
index 91c16c3222..345f7f2d12 100644
--- a/tools/qmlprofiler/qmlprofilerdata.h
+++ b/tools/qmlprofiler/qmlprofilerdata.h
@@ -34,9 +34,9 @@
#ifndef QMLPROFILERDATA_H
#define QMLPROFILERDATA_H
-#include "qmlprofilereventlocation.h"
+#include <private/qqmleventlocation_p.h>
+#include <private/qqmlprofilerdefinitions_p.h>
-#include <QtQml/private/qqmlprofilerdefinitions_p.h>
#include <QObject>
class QmlProfilerDataPrivate;
@@ -54,12 +54,9 @@ public:
explicit QmlProfilerData(QObject *parent = 0);
~QmlProfilerData();
- static QString getHashStringForQmlEvent(const QmlEventLocation &location, int eventType);
- static QString getHashStringForV8Event(const QString &displayName, const QString &function);
+ static QString getHashStringForQmlEvent(const QQmlEventLocation &location, int eventType);
static QString qmlRangeTypeAsString(QQmlProfilerDefinitions::RangeType type);
static QString qmlMessageAsString(QQmlProfilerDefinitions::Message type);
- static QString rootEventName();
- static QString rootEventDescription();
qint64 traceStartTime() const;
qint64 traceEndTime() const;
@@ -78,24 +75,21 @@ public slots:
void addQmlEvent(QQmlProfilerDefinitions::RangeType type,
QQmlProfilerDefinitions::BindingType bindingType,
qint64 startTime, qint64 duration, const QStringList &data,
- const QmlEventLocation &location);
- void addV8Event(int depth, const QString &function, const QString &filename,
- int lineNumber, double totalTime, double selfTime);
+ const QQmlEventLocation &location);
void addFrameEvent(qint64 time, int framerate, int animationcount, int threadId);
void addSceneGraphFrameEvent(QQmlProfilerDefinitions::SceneGraphFrameType type, qint64 time,
qint64 numericData1, qint64 numericData2, qint64 numericData3,
qint64 numericData4, qint64 numericData5);
void addPixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type, qint64 time,
- const QmlEventLocation &location, int width, int height, int refcount);
+ const QString &location, int numericData1, int numericData2);
void addMemoryEvent(QQmlProfilerDefinitions::MemoryType type, qint64 time, qint64 size);
- void addInputEvent(QQmlProfilerDefinitions::EventType type, qint64 time);
+ void addInputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time, int a, int b);
void complete();
bool save(const QString &filename);
private:
void sortStartTimes();
- int v8EventIndex(const QString &hashStr);
void computeQmlTime();
void setState(QmlProfilerData::State state);
diff --git a/tools/qmlprofiler/qpacketprotocol.cpp b/tools/qmlprofiler/qpacketprotocol.cpp
deleted file mode 100644
index 096bc142c5..0000000000
--- a/tools/qmlprofiler/qpacketprotocol.cpp
+++ /dev/null
@@ -1,527 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpacketprotocol.h"
-
-#include <QtCore/QBuffer>
-#include <QtCore/QElapsedTimer>
-#include <private/qiodevice_p.h> // for qt_subtract_from_timeout
-
-static const unsigned int MAX_PACKET_SIZE = 0x7FFFFFFF;
-
-/*!
- \class QPacketProtocol
- \internal
-
- \brief The QPacketProtocol class encapsulates communicating discrete packets
- across fragmented IO channels, such as TCP sockets.
-
- QPacketProtocol makes it simple to send arbitrary sized data "packets" across
- fragmented transports such as TCP and UDP.
-
- As transmission boundaries are not respected, sending packets over protocols
- like TCP frequently involves "stitching" them back together at the receiver.
- QPacketProtocol makes this easier by performing this task for you. Packet
- data sent using QPacketProtocol is prepended with a 4-byte size header
- allowing the receiving QPacketProtocol to buffer the packet internally until
- it has all been received. QPacketProtocol does not perform any sanity
- checking on the size or on the data, so this class should only be used in
- prototyping or trusted situations where DOS attacks are unlikely.
-
- QPacketProtocol does not perform any communications itself. Instead it can
- operate on any QIODevice that supports the QIODevice::readyRead() signal. A
- logical "packet" is encapsulated by the companion QPacket class. The
- following example shows two ways to send data using QPacketProtocol. The
- transmitted data is equivalent in both.
-
- \code
- QTcpSocket socket;
- // ... connect socket ...
-
- QPacketProtocol protocol(&socket);
-
- // Send packet the quick way
- protocol.send() << "Hello world" << 123;
-
- // Send packet the longer way
- QPacket packet;
- packet << "Hello world" << 123;
- protocol.send(packet);
- \endcode
-
- Likewise, the following shows how to read data from QPacketProtocol, assuming
- that the QPacketProtocol::readyRead() signal has been emitted.
-
- \code
- // ... QPacketProtocol::readyRead() is emitted ...
-
- int a;
- QByteArray b;
-
- // Receive packet the quick way
- protocol.read() >> a >> b;
-
- // Receive packet the longer way
- QPacket packet = protocol.read();
- p >> a >> b;
- \endcode
-
- \ingroup io
- \sa QPacket
-*/
-
-class QPacketProtocolPrivate : public QObject
-{
- Q_OBJECT
-public:
- QPacketProtocolPrivate(QPacketProtocol *parent, QIODevice *_dev)
- : QObject(parent), inProgressSize(-1), maxPacketSize(MAX_PACKET_SIZE),
- waitingForPacket(false), dev(_dev)
- {
- Q_ASSERT(4 == sizeof(qint32));
-
- QObject::connect(this, SIGNAL(readyRead()),
- parent, SIGNAL(readyRead()));
- QObject::connect(this, SIGNAL(packetWritten()),
- parent, SIGNAL(packetWritten()));
- QObject::connect(this, SIGNAL(invalidPacket()),
- parent, SIGNAL(invalidPacket()));
- QObject::connect(dev, SIGNAL(readyRead()),
- this, SLOT(readyToRead()));
- QObject::connect(dev, SIGNAL(aboutToClose()),
- this, SLOT(aboutToClose()));
- QObject::connect(dev, SIGNAL(bytesWritten(qint64)),
- this, SLOT(bytesWritten(qint64)));
- }
-
-Q_SIGNALS:
- void readyRead();
- void packetWritten();
- void invalidPacket();
-
-public Q_SLOTS:
- void aboutToClose()
- {
- inProgress.clear();
- sendingPackets.clear();
- inProgressSize = -1;
- }
-
- void bytesWritten(qint64 bytes)
- {
- Q_ASSERT(!sendingPackets.isEmpty());
-
- while (bytes) {
- if (sendingPackets.at(0) > bytes) {
- sendingPackets[0] -= bytes;
- bytes = 0;
- } else {
- bytes -= sendingPackets.at(0);
- sendingPackets.removeFirst();
- emit packetWritten();
- }
- }
- }
-
- void readyToRead()
- {
- while (true) {
- // Need to get trailing data
- if (-1 == inProgressSize) {
- // We need a size header of sizeof(qint32)
- if (sizeof(qint32) > (uint)dev->bytesAvailable())
- return;
-
- // Read size header
- int read = dev->read((char *)&inProgressSize, sizeof(qint32));
- Q_ASSERT(read == sizeof(qint32));
- Q_UNUSED(read);
-
- // Check sizing constraints
- if (inProgressSize > maxPacketSize) {
- QObject::disconnect(dev, SIGNAL(readyRead()),
- this, SLOT(readyToRead()));
- QObject::disconnect(dev, SIGNAL(aboutToClose()),
- this, SLOT(aboutToClose()));
- QObject::disconnect(dev, SIGNAL(bytesWritten(qint64)),
- this, SLOT(bytesWritten(qint64)));
- dev = 0;
- emit invalidPacket();
- return;
- }
-
- inProgressSize -= sizeof(qint32);
- } else {
- inProgress.append(dev->read(inProgressSize - inProgress.size()));
-
- if (inProgressSize == inProgress.size()) {
- // Packet has arrived!
- packets.append(inProgress);
- inProgressSize = -1;
- inProgress.clear();
-
- waitingForPacket = false;
- emit readyRead();
- } else
- return;
- }
- }
- }
-
-public:
- QList<qint64> sendingPackets;
- QList<QByteArray> packets;
- QByteArray inProgress;
- qint32 inProgressSize;
- qint32 maxPacketSize;
- bool waitingForPacket;
- QIODevice *dev;
-};
-
-/*!
- Construct a QPacketProtocol instance that works on \a dev with the
- specified \a parent.
- */
-QPacketProtocol::QPacketProtocol(QIODevice *dev, QObject *parent)
- : QObject(parent), d(new QPacketProtocolPrivate(this, dev))
-{
- Q_ASSERT(dev);
-}
-
-/*!
- Destroys the QPacketProtocol instance.
- */
-QPacketProtocol::~QPacketProtocol()
-{
-}
-
-/*!
- Returns the maximum packet size allowed. By default this is
- 2,147,483,647 bytes.
-
- If a packet claiming to be larger than the maximum packet size is received,
- the QPacketProtocol::invalidPacket() signal is emitted.
-
- \sa QPacketProtocol::setMaximumPacketSize()
- */
-qint32 QPacketProtocol::maximumPacketSize() const
-{
- return d->maxPacketSize;
-}
-
-/*!
- Sets the maximum allowable packet size to \a max.
-
- \sa QPacketProtocol::maximumPacketSize()
- */
-qint32 QPacketProtocol::setMaximumPacketSize(qint32 max)
-{
- if (max > (signed)sizeof(qint32))
- d->maxPacketSize = max;
- return d->maxPacketSize;
-}
-
-/*!
- Returns a streamable object that is transmitted on destruction. For example
-
- \code
- protocol.send() << "Hello world" << 123;
- \endcode
-
- will send a packet containing "Hello world" and 123. To construct more
- complex packets, explicitly construct a QPacket instance.
- */
-QPacketAutoSend QPacketProtocol::send()
-{
- return QPacketAutoSend(this);
-}
-
-/*!
- \fn void QPacketProtocol::send(const QPacket & packet)
-
- Transmit the \a packet.
- */
-void QPacketProtocol::send(const QPacket & p)
-{
- if (p.b.isEmpty())
- return; // We don't send empty packets
-
- qint64 sendSize = p.b.size() + sizeof(qint32);
-
- d->sendingPackets.append(sendSize);
- qint32 sendSize32 = sendSize;
- qint64 writeBytes = d->dev->write((char *)&sendSize32, sizeof(qint32));
- Q_UNUSED(writeBytes);
- Q_ASSERT(writeBytes == sizeof(qint32));
- writeBytes = d->dev->write(p.b);
- Q_ASSERT(writeBytes == p.b.size());
-}
-
-/*!
- Returns the number of received packets yet to be read.
- */
-qint64 QPacketProtocol::packetsAvailable() const
-{
- return d->packets.count();
-}
-
-/*!
- Discard any unread packets.
- */
-void QPacketProtocol::clear()
-{
- d->packets.clear();
-}
-
-/*!
- Return the next unread packet, or an invalid QPacket instance if no packets
- are available. This method does NOT block.
- */
-QPacket QPacketProtocol::read()
-{
- if (0 == d->packets.count())
- return QPacket();
-
- QPacket rv(d->packets.at(0));
- d->packets.removeFirst();
- return rv;
-}
-
-/*!
- This function locks until a new packet is available for reading and the
- \l{QIODevice::}{readyRead()} signal has been emitted. The function
- will timeout after \a msecs milliseconds; the default timeout is
- 30000 milliseconds.
-
- The function returns true if the readyRead() signal is emitted and
- there is new data available for reading; otherwise it returns false
- (if an error occurred or the operation timed out).
- */
-
-bool QPacketProtocol::waitForReadyRead(int msecs)
-{
- if (!d->packets.isEmpty())
- return true;
-
- QElapsedTimer stopWatch;
- stopWatch.start();
-
- d->waitingForPacket = true;
- do {
- if (!d->dev->waitForReadyRead(msecs))
- return false;
- if (!d->waitingForPacket)
- return true;
- msecs = qt_subtract_from_timeout(msecs, stopWatch.elapsed());
- } while (true);
-}
-
-/*!
- Return the QIODevice passed to the QPacketProtocol constructor.
-*/
-QIODevice *QPacketProtocol::device()
-{
- return d->dev;
-}
-
-/*!
- \fn void QPacketProtocol::readyRead()
-
- Emitted whenever a new packet is received. Applications may use
- QPacketProtocol::read() to retrieve this packet.
- */
-
-/*!
- \fn void QPacketProtocol::invalidPacket()
-
- A packet larger than the maximum allowable packet size was received. The
- packet will be discarded and, as it indicates corruption in the protocol, no
- further packets will be received.
- */
-
-/*!
- \fn void QPacketProtocol::packetWritten()
-
- Emitted each time a packet is completing written to the device. This signal
- may be used for communications flow control.
- */
-
-/*!
- \class QPacket
- \internal
-
- \brief The QPacket class encapsulates an unfragmentable packet of data to be
- transmitted by QPacketProtocol.
-
- The QPacket class works together with QPacketProtocol to make it simple to
- send arbitrary sized data "packets" across fragmented transports such as TCP
- and UDP.
-
- QPacket provides a QDataStream interface to an unfragmentable packet.
- Applications should construct a QPacket, propagate it with data and then
- transmit it over a QPacketProtocol instance. For example:
- \code
- QPacketProtocol protocol(...);
-
- QPacket myPacket;
- myPacket << "Hello world!" << 123;
- protocol.send(myPacket);
- \endcode
-
- As long as both ends of the connection are using the QPacketProtocol class,
- the data within this packet will be delivered unfragmented at the other end,
- ready for extraction.
-
- \code
- QByteArray greeting;
- int count;
-
- QPacket myPacket = protocol.read();
-
- myPacket >> greeting >> count;
- \endcode
-
- Only packets returned from QPacketProtocol::read() may be read from. QPacket
- instances constructed by directly by applications are for transmission only
- and are considered "write only". Attempting to read data from them will
- result in undefined behavior.
-
- \ingroup io
- \sa QPacketProtocol
- */
-
-/*!
- Constructs an empty write-only packet.
- */
-QPacket::QPacket()
- : QDataStream(), buf(0)
-{
- buf = new QBuffer(&b);
- buf->open(QIODevice::WriteOnly);
- setDevice(buf);
- setVersion(QDataStream::Qt_4_7);
-}
-
-/*!
- Destroys the QPacket instance.
- */
-QPacket::~QPacket()
-{
- if (buf) {
- delete buf;
- buf = 0;
- }
-}
-
-/*!
- Creates a copy of \a other. The initial stream positions are shared, but the
- two packets are otherwise independent.
- */
-QPacket::QPacket(const QPacket & other)
- : QDataStream(), b(other.b), buf(0)
-{
- buf = new QBuffer(&b);
- buf->open(other.buf->openMode());
- setDevice(buf);
-}
-
-/*!
- \internal
- */
-QPacket::QPacket(const QByteArray & ba)
- : QDataStream(), b(ba), buf(0)
-{
- buf = new QBuffer(&b);
- buf->open(QIODevice::ReadOnly);
- setDevice(buf);
-}
-
-/*!
- Returns true if this packet is empty - that is, contains no data.
- */
-bool QPacket::isEmpty() const
-{
- return b.isEmpty();
-}
-
-/*!
- Returns raw packet data.
- */
-QByteArray QPacket::data() const
-{
- return b;
-}
-
-/*!
- Clears data in the packet. This is useful for reusing one writable packet.
- For example
- \code
- QPacketProtocol protocol(...);
-
- QPacket packet;
-
- packet << "Hello world!" << 123;
- protocol.send(packet);
-
- packet.clear();
- packet << "Goodbyte world!" << 789;
- protocol.send(packet);
- \endcode
- */
-void QPacket::clear()
-{
- QBuffer::OpenMode oldMode = buf->openMode();
- buf->close();
- b.clear();
- buf->setBuffer(&b); // reset QBuffer internals with new size of b.
- buf->open(oldMode);
-}
-
-/*!
- \class QPacketAutoSend
- \internal
-
- \internal
- */
-QPacketAutoSend::QPacketAutoSend(QPacketProtocol *_p)
- : QPacket(), p(_p)
-{
-}
-
-QPacketAutoSend::~QPacketAutoSend()
-{
- if (!b.isEmpty())
- p->send(*this);
-}
-
-#include <qpacketprotocol.moc>
diff --git a/tools/qmlprofiler/qqmldebugclient.cpp b/tools/qmlprofiler/qqmldebugclient.cpp
deleted file mode 100644
index f87d4b0a7c..0000000000
--- a/tools/qmlprofiler/qqmldebugclient.cpp
+++ /dev/null
@@ -1,403 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqmldebugclient.h"
-#include "qpacketprotocol.h"
-
-#include <QtCore/qdebug.h>
-#include <QtCore/qstringlist.h>
-#include <QtNetwork/qnetworkproxy.h>
-
-const int protocolVersion = 1;
-const QString serverId = QLatin1String("QDeclarativeDebugServer");
-const QString clientId = QLatin1String("QDeclarativeDebugClient");
-
-class QQmlDebugClientPrivate
-{
-public:
- QQmlDebugClientPrivate();
-
- QString name;
- QQmlDebugConnection *connection;
-};
-
-class QQmlDebugConnectionPrivate : public QObject
-{
- Q_OBJECT
-public:
- QQmlDebugConnectionPrivate(QQmlDebugConnection *c);
- QQmlDebugConnection *q;
- QPacketProtocol *protocol;
- QIODevice *device;
-
- bool gotHello;
- QHash <QString, float> serverPlugins;
- QHash<QString, QQmlDebugClient *> plugins;
-
- void advertisePlugins();
- void connectDeviceSignals();
-
-public Q_SLOTS:
- void connected();
- void readyRead();
- void deviceAboutToClose();
-};
-
-QQmlDebugConnectionPrivate::QQmlDebugConnectionPrivate(QQmlDebugConnection *c)
- : QObject(c), q(c), protocol(0), device(0), gotHello(false)
-{
- protocol = new QPacketProtocol(q, this);
- QObject::connect(c, SIGNAL(connected()), this, SLOT(connected()));
- QObject::connect(protocol, SIGNAL(readyRead()), this, SLOT(readyRead()));
-}
-
-void QQmlDebugConnectionPrivate::advertisePlugins()
-{
- if (!q->isConnected())
- return;
-
- QPacket pack;
- pack << serverId << 1 << plugins.keys();
- protocol->send(pack);
- q->flush();
-}
-
-void QQmlDebugConnectionPrivate::connected()
-{
- QPacket pack;
- pack << serverId << 0 << protocolVersion << plugins.keys();
- protocol->send(pack);
- q->flush();
-}
-
-void QQmlDebugConnectionPrivate::readyRead()
-{
- if (!gotHello) {
- QPacket pack = protocol->read();
- QString name;
-
- pack >> name;
-
- bool validHello = false;
- if (name == clientId) {
- int op = -1;
- pack >> op;
- if (op == 0) {
- int version = -1;
- pack >> version;
- if (version == protocolVersion) {
- QStringList pluginNames;
- QList<float> pluginVersions;
- pack >> pluginNames;
- if (!pack.isEmpty())
- pack >> pluginVersions;
-
- const int pluginNamesSize = pluginNames.size();
- const int pluginVersionsSize = pluginVersions.size();
- for (int i = 0; i < pluginNamesSize; ++i) {
- float pluginVersion = 1.0;
- if (i < pluginVersionsSize)
- pluginVersion = pluginVersions.at(i);
- serverPlugins.insert(pluginNames.at(i), pluginVersion);
- }
-
- validHello = true;
- }
- }
- }
-
- if (!validHello) {
- qWarning("QQmlDebugConnection: Invalid hello message");
- QObject::disconnect(protocol, SIGNAL(readyRead()), this, SLOT(readyRead()));
- return;
- }
- gotHello = true;
-
- QHash<QString, QQmlDebugClient *>::Iterator iter = plugins.begin();
- for (; iter != plugins.end(); ++iter) {
- QQmlDebugClient::State newState = QQmlDebugClient::Unavailable;
- if (serverPlugins.contains(iter.key()))
- newState = QQmlDebugClient::Enabled;
- iter.value()->stateChanged(newState);
- }
- }
-
- while (protocol->packetsAvailable()) {
- QPacket pack = protocol->read();
- QString name;
- pack >> name;
-
- if (name == clientId) {
- int op = -1;
- pack >> op;
-
- if (op == 1) {
- // Service Discovery
- QHash<QString, float> oldServerPlugins = serverPlugins;
- serverPlugins.clear();
-
- QStringList pluginNames;
- QList<float> pluginVersions;
- pack >> pluginNames;
- if (!pack.isEmpty())
- pack >> pluginVersions;
-
- const int pluginNamesSize = pluginNames.size();
- const int pluginVersionsSize = pluginVersions.size();
- for (int i = 0; i < pluginNamesSize; ++i) {
- float pluginVersion = 1.0;
- if (i < pluginVersionsSize)
- pluginVersion = pluginVersions.at(i);
- serverPlugins.insert(pluginNames.at(i), pluginVersion);
- }
-
- QHash<QString, QQmlDebugClient *>::Iterator iter = plugins.begin();
- for (; iter != plugins.end(); ++iter) {
- const QString pluginName = iter.key();
- QQmlDebugClient::State newSate = QQmlDebugClient::Unavailable;
- if (serverPlugins.contains(pluginName))
- newSate = QQmlDebugClient::Enabled;
-
- if (oldServerPlugins.contains(pluginName)
- != serverPlugins.contains(pluginName)) {
- iter.value()->stateChanged(newSate);
- }
- }
- } else {
- qWarning() << "QQmlDebugConnection: Unknown control message id" << op;
- }
- } else {
- QByteArray message;
- pack >> message;
-
- QHash<QString, QQmlDebugClient *>::Iterator iter =
- plugins.find(name);
- if (iter == plugins.end()) {
- qWarning() << "QQmlDebugConnection: Message received for missing plugin" << name;
- } else {
- (*iter)->messageReceived(message);
- }
- }
- }
-}
-
-void QQmlDebugConnectionPrivate::deviceAboutToClose()
-{
- // This is nasty syntax but we want to emit our own aboutToClose signal (by calling QIODevice::close())
- // without calling the underlying device close fn as that would cause an infinite loop
- q->QIODevice::close();
-}
-
-QQmlDebugConnection::QQmlDebugConnection(QObject *parent)
- : QIODevice(parent), d(new QQmlDebugConnectionPrivate(this))
-{
-}
-
-QQmlDebugConnection::~QQmlDebugConnection()
-{
- QHash<QString, QQmlDebugClient*>::iterator iter = d->plugins.begin();
- for (; iter != d->plugins.end(); ++iter) {
- iter.value()->d->connection = 0;
- iter.value()->stateChanged(QQmlDebugClient::NotConnected);
- }
-}
-
-bool QQmlDebugConnection::isConnected() const
-{
- return state() == QAbstractSocket::ConnectedState;
-}
-
-qint64 QQmlDebugConnection::readData(char *data, qint64 maxSize)
-{
- return d->device->read(data, maxSize);
-}
-
-qint64 QQmlDebugConnection::writeData(const char *data, qint64 maxSize)
-{
- return d->device->write(data, maxSize);
-}
-
-qint64 QQmlDebugConnection::bytesAvailable() const
-{
- return d->device->bytesAvailable();
-}
-
-bool QQmlDebugConnection::isSequential() const
-{
- return true;
-}
-
-void QQmlDebugConnection::close()
-{
- if (isOpen()) {
- QIODevice::close();
- d->device->close();
- emit stateChanged(QAbstractSocket::UnconnectedState);
-
- QHash<QString, QQmlDebugClient*>::iterator iter = d->plugins.begin();
- for (; iter != d->plugins.end(); ++iter) {
- iter.value()->stateChanged(QQmlDebugClient::NotConnected);
- }
- }
-}
-
-bool QQmlDebugConnection::waitForConnected(int msecs)
-{
- QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(d->device);
- if (socket)
- return socket->waitForConnected(msecs);
- return false;
-}
-
-QAbstractSocket::SocketState QQmlDebugConnection::state() const
-{
- QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(d->device);
- if (socket)
- return socket->state();
-
- return QAbstractSocket::UnconnectedState;
-}
-
-void QQmlDebugConnection::flush()
-{
- QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(d->device);
- if (socket) {
- socket->flush();
- return;
- }
-}
-
-void QQmlDebugConnection::connectToHost(const QString &hostName, quint16 port)
-{
- QTcpSocket *socket = new QTcpSocket(d);
-#ifndef QT_NO_NETWORKPROXY
- socket->setProxy(QNetworkProxy::NoProxy);
-#endif
- d->device = socket;
- d->connectDeviceSignals();
- d->gotHello = false;
- connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SIGNAL(stateChanged(QAbstractSocket::SocketState)));
- connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SIGNAL(error(QAbstractSocket::SocketError)));
- connect(socket, SIGNAL(connected()), this, SIGNAL(connected()));
- socket->connectToHost(hostName, port);
- QIODevice::open(ReadWrite | Unbuffered);
-}
-
-void QQmlDebugConnectionPrivate::connectDeviceSignals()
-{
- connect(device, SIGNAL(bytesWritten(qint64)), q, SIGNAL(bytesWritten(qint64)));
- connect(device, SIGNAL(readyRead()), q, SIGNAL(readyRead()));
- connect(device, SIGNAL(aboutToClose()), this, SLOT(deviceAboutToClose()));
-}
-
-//
-
-QQmlDebugClientPrivate::QQmlDebugClientPrivate()
- : connection(0)
-{
-}
-
-QQmlDebugClient::QQmlDebugClient(const QString &name,
- QQmlDebugConnection *parent)
- : QObject(parent),
- d(new QQmlDebugClientPrivate)
-{
- d->name = name;
- d->connection = parent;
-
- if (!d->connection)
- return;
-
- if (d->connection->d->plugins.contains(name)) {
- qWarning() << "QQmlDebugClient: Conflicting plugin name" << name;
- d->connection = 0;
- } else {
- d->connection->d->plugins.insert(name, this);
- d->connection->d->advertisePlugins();
- }
-}
-
-QQmlDebugClient::~QQmlDebugClient()
-{
- if (d->connection && d->connection->d) {
- d->connection->d->plugins.remove(d->name);
- d->connection->d->advertisePlugins();
- }
- delete d;
-}
-
-QString QQmlDebugClient::name() const
-{
- return d->name;
-}
-
-float QQmlDebugClient::serviceVersion() const
-{
- if (d->connection->d->serverPlugins.contains(d->name))
- return d->connection->d->serverPlugins.value(d->name);
- return -1;
-}
-
-QQmlDebugClient::State QQmlDebugClient::state() const
-{
- if (!d->connection
- || !d->connection->isConnected()
- || !d->connection->d->gotHello)
- return NotConnected;
-
- if (d->connection->d->serverPlugins.contains(d->name))
- return Enabled;
-
- return Unavailable;
-}
-
-void QQmlDebugClient::sendMessage(const QByteArray &message)
-{
- if (state() != Enabled)
- return;
-
- QPacket pack;
- pack << d->name << message;
- d->connection->d->protocol->send(pack);
- d->connection->flush();
-}
-
-void QQmlDebugClient::stateChanged(State)
-{
-}
-
-void QQmlDebugClient::messageReceived(const QByteArray &)
-{
-}
-
-#include <qqmldebugclient.moc>