qtbindings 4.8.6.3 → 4.8.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/COPYING.LIB.txt +510 -510
- data/COPYING.txt +286 -286
- data/KNOWN_ISSUES.txt +17 -17
- data/bin/rbqtapi +0 -0
- data/bin/rbrcc +0 -0
- data/bin/rbuic4 +0 -0
- data/bin/smokeapi +0 -0
- data/bin/smokedeptool +0 -0
- data/examples/designer/calculatorbuilder/calculatorbuilder.qrc +5 -5
- data/examples/designer/calculatorbuilder/calculatorform.rb +60 -60
- data/examples/designer/calculatorbuilder/calculatorform.ui +299 -299
- data/examples/designer/calculatorbuilder/main.rb +34 -34
- data/examples/designer/calculatorbuilder/makefile +2 -2
- data/examples/designer/calculatorform/calculatorform.rb +46 -46
- data/examples/designer/calculatorform/calculatorform.ui +277 -277
- data/examples/designer/calculatorform/main.rb +32 -32
- data/examples/designer/calculatorform/makefile +3 -3
- data/examples/desktop/screenshot/main.rb +32 -32
- data/examples/desktop/screenshot/screenshot.rb +157 -157
- data/examples/desktop/systray/images/bad.svg +64 -64
- data/examples/desktop/systray/images/heart.svg +55 -55
- data/examples/desktop/systray/images/trash.svg +58 -58
- data/examples/desktop/systray/main.rb +41 -41
- data/examples/desktop/systray/makefile +2 -2
- data/examples/desktop/systray/systray.qrc +7 -7
- data/examples/desktop/systray/window.rb +219 -219
- data/examples/dialogs/complexwizard/complexwizard.rb +140 -140
- data/examples/dialogs/complexwizard/licensewizard.rb +294 -294
- data/examples/dialogs/complexwizard/main.rb +31 -31
- data/examples/dialogs/configdialog/configdialog.rb +109 -109
- data/examples/dialogs/configdialog/main.rb +31 -31
- data/examples/dialogs/configdialog/pages.rb +140 -140
- data/examples/dialogs/extension/finddialog.rb +89 -89
- data/examples/dialogs/extension/main.rb +31 -31
- data/examples/dialogs/findfiles/main.rb +32 -32
- data/examples/dialogs/findfiles/window.rb +177 -177
- data/examples/dialogs/simplewizard/classwizard.rb +374 -374
- data/examples/dialogs/simplewizard/main.rb +31 -31
- data/examples/dialogs/simplewizard/simplewizard.rb +110 -110
- data/examples/dialogs/standarddialogs/dialog.rb +340 -340
- data/examples/dialogs/standarddialogs/main.rb +31 -31
- data/examples/dialogs/tabdialog/main.rb +38 -38
- data/examples/dialogs/tabdialog/tabdialog.rb +178 -178
- data/examples/draganddrop/draggableicons/dragwidget.rb +125 -125
- data/examples/draganddrop/draggableicons/main.rb +41 -41
- data/examples/draganddrop/draggabletext/draglabel.rb +51 -51
- data/examples/draganddrop/draggabletext/dragwidget.rb +94 -94
- data/examples/draganddrop/draggabletext/main.rb +33 -33
- data/examples/draganddrop/draggabletext/words.txt +41 -41
- data/examples/draganddrop/dropsite/dropsitewidget.rb +99 -99
- data/examples/draganddrop/dropsite/dropsitewindow.rb +114 -114
- data/examples/draganddrop/dropsite/main.rb +33 -33
- data/examples/draganddrop/fridgemagnets/draglabel.rb +78 -78
- data/examples/draganddrop/fridgemagnets/dragwidget.rb +130 -130
- data/examples/draganddrop/fridgemagnets/main.rb +33 -33
- data/examples/draganddrop/fridgemagnets/words.txt +48 -48
- data/examples/draganddrop/puzzle/main.rb +33 -33
- data/examples/draganddrop/puzzle/mainwindow.rb +136 -136
- data/examples/draganddrop/puzzle/pieceslist.rb +95 -95
- data/examples/draganddrop/puzzle/puzzlewidget.rb +190 -190
- data/examples/graphicsview/collidingmice/main.rb +53 -53
- data/examples/graphicsview/collidingmice/makefile +2 -2
- data/examples/graphicsview/collidingmice/mice.qrc +5 -5
- data/examples/graphicsview/collidingmice/mouse.rb +176 -176
- data/examples/graphicsview/dragdroprobot/coloritem.rb +86 -86
- data/examples/graphicsview/dragdroprobot/main.rb +57 -57
- data/examples/graphicsview/dragdroprobot/makefile +2 -2
- data/examples/graphicsview/dragdroprobot/robot.qrc +5 -5
- data/examples/graphicsview/dragdroprobot/robot.rb +246 -246
- data/examples/itemviews/chart/chart.qrc +5 -5
- data/examples/itemviews/chart/main.rb +33 -33
- data/examples/itemviews/chart/mainwindow.rb +151 -151
- data/examples/itemviews/chart/makefile +2 -2
- data/examples/itemviews/chart/mydata.cht +8 -8
- data/examples/itemviews/chart/pieview.rb +516 -516
- data/examples/itemviews/chart/qtdata.cht +14 -14
- data/examples/itemviews/dirview/main.rb +39 -39
- data/examples/itemviews/pixelator/imagemodel.rb +51 -51
- data/examples/itemviews/pixelator/images.qrc +5 -5
- data/examples/itemviews/pixelator/main.rb +34 -34
- data/examples/itemviews/pixelator/mainwindow.rb +218 -218
- data/examples/itemviews/pixelator/makefile +3 -3
- data/examples/itemviews/pixelator/pixeldelegate.rb +67 -67
- data/examples/itemviews/puzzle/main.rb +36 -36
- data/examples/itemviews/puzzle/mainwindow.rb +143 -143
- data/examples/itemviews/puzzle/piecesmodel.rb +174 -174
- data/examples/itemviews/puzzle/puzzlewidget.rb +192 -192
- data/examples/itemviews/simpledommodel/domitem.rb +62 -62
- data/examples/itemviews/simpledommodel/dommodel.rb +139 -139
- data/examples/itemviews/simpledommodel/main.rb +33 -33
- data/examples/itemviews/simpledommodel/mainwindow.rb +66 -66
- data/examples/itemviews/simpletreemodel/default.txt +40 -40
- data/examples/itemviews/simpletreemodel/main.rb +41 -41
- data/examples/itemviews/simpletreemodel/makefile +2 -2
- data/examples/itemviews/simpletreemodel/simpletreemodel.qrc +5 -5
- data/examples/itemviews/simpletreemodel/treeitem.rb +67 -67
- data/examples/itemviews/simpletreemodel/treemodel.rb +164 -164
- data/examples/itemviews/sortingmodel/default.txt +40 -40
- data/examples/itemviews/sortingmodel/main.rb +53 -53
- data/examples/itemviews/sortingmodel/treeitem.rb +73 -73
- data/examples/itemviews/sortingmodel/treemodel.rb +166 -166
- data/examples/itemviews/spinboxdelegate/main.rb +47 -47
- data/examples/itemviews/spinboxdelegate/spinboxdelegate.rb +62 -62
- data/examples/killerfilter/killerfilter.rb +55 -55
- data/examples/layouts/basiclayouts/dialog.rb +110 -110
- data/examples/layouts/basiclayouts/main.rb +31 -31
- data/examples/layouts/borderlayout/borderlayout.rb +190 -190
- data/examples/layouts/borderlayout/main.rb +32 -32
- data/examples/layouts/borderlayout/window.rb +52 -52
- data/examples/layouts/flowlayouts/flowlayout.rb +108 -108
- data/examples/layouts/flowlayouts/main.rb +32 -32
- data/examples/layouts/flowlayouts/window.rb +43 -43
- data/examples/mainwindows/application/main.rb +32 -32
- data/examples/mainwindows/application/mainwindow.rb +285 -285
- data/examples/mainwindows/dockwidgets/main.rb +32 -32
- data/examples/mainwindows/dockwidgets/mainwindow.rb +302 -302
- data/examples/mainwindows/mdi/main.rb +32 -32
- data/examples/mainwindows/mdi/mainwindow.rb +363 -363
- data/examples/mainwindows/mdi/mdichild.rb +152 -152
- data/examples/mainwindows/menus/main.rb +32 -32
- data/examples/mainwindows/menus/mainwindow.rb +327 -327
- data/examples/mainwindows/recentfiles/main.rb +32 -32
- data/examples/mainwindows/recentfiles/mainwindow.rb +258 -258
- data/examples/mainwindows/sdi/main.rb +32 -32
- data/examples/mainwindows/sdi/mainwindow.rb +335 -335
- data/examples/network/broadcastreceiver/main.rb +32 -32
- data/examples/network/broadcastreceiver/receiver.rb +64 -64
- data/examples/network/broadcastsender/main.rb +32 -32
- data/examples/network/broadcastsender/sender.rb +72 -72
- data/examples/network/fortuneclient/client.rb +149 -149
- data/examples/network/fortuneclient/main.rb +32 -32
- data/examples/network/fortuneserver/main.rb +32 -32
- data/examples/network/fortuneserver/server.rb +88 -88
- data/examples/network/ftp/ftpwindow.rb +259 -259
- data/examples/network/ftp/main.rb +32 -32
- data/examples/network/http/httpwindow.rb +187 -187
- data/examples/network/http/main.rb +32 -32
- data/examples/network/loopback/dialog.rb +163 -163
- data/examples/network/loopback/main.rb +32 -32
- data/examples/opengl/grabber/glwidget.rb +265 -265
- data/examples/opengl/grabber/main.rb +32 -32
- data/examples/opengl/grabber/mainwindow.rb +189 -189
- data/examples/opengl/hellogl/glwidget.rb +226 -226
- data/examples/opengl/hellogl/main.rb +32 -32
- data/examples/opengl/hellogl/window.rb +66 -66
- data/examples/opengl/textures/glwidget.rb +151 -151
- data/examples/opengl/textures/main.rb +32 -32
- data/examples/opengl/textures/window.rb +77 -77
- data/examples/painting/basicdrawing/main.rb +32 -32
- data/examples/painting/basicdrawing/renderarea.rb +166 -166
- data/examples/painting/basicdrawing/window.rb +215 -215
- data/examples/painting/concentriccircles/circlewidget.rb +88 -88
- data/examples/painting/concentriccircles/main.rb +32 -32
- data/examples/painting/concentriccircles/window.rb +72 -72
- data/examples/painting/fontsampler/main.rb +32 -32
- data/examples/painting/fontsampler/mainwindow.rb +369 -369
- data/examples/painting/fontsampler/mainwindowbase.ui +136 -136
- data/examples/painting/fontsampler/makefile +8 -8
- data/examples/painting/fontsampler/previewdialog.rb +257 -257
- data/examples/painting/fontsampler/previewdialogbase.ui +224 -224
- data/examples/painting/fontsampler/previewlabel.rb +43 -43
- data/examples/painting/imagecomposition/imagecomposer.rb +152 -152
- data/examples/painting/imagecomposition/imagecomposition.qrc +6 -6
- data/examples/painting/imagecomposition/main.rb +33 -33
- data/examples/painting/imagecomposition/makefile +2 -2
- data/examples/painting/painterpaths/main.rb +32 -32
- data/examples/painting/painterpaths/renderarea.rb +97 -97
- data/examples/painting/painterpaths/window.rb +247 -247
- data/examples/painting/svgviewer/files/bubbles.svg +212 -212
- data/examples/painting/svgviewer/files/cubic.svg +77 -77
- data/examples/painting/svgviewer/files/spheres.svg +79 -79
- data/examples/painting/svgviewer/main.rb +38 -38
- data/examples/painting/svgviewer/mainwindow.rb +99 -99
- data/examples/painting/svgviewer/makefile +2 -2
- data/examples/painting/svgviewer/svgview.rb +156 -156
- data/examples/painting/svgviewer/svgviewer.qrc +6 -6
- data/examples/painting/svgviewer/svgwindow.rb +87 -87
- data/examples/painting/transformations/main.rb +32 -32
- data/examples/painting/transformations/renderarea.rb +127 -127
- data/examples/painting/transformations/window.rb +153 -153
- data/examples/passivepopup/passivepopup.rb +38 -38
- data/examples/qdbus/chat/chat.rb +146 -146
- data/examples/qdbus/chat/chat_adaptor.rb +12 -12
- data/examples/qdbus/chat/chat_interface.rb +13 -13
- data/examples/qdbus/chat/chatmainwindow.ui +184 -184
- data/examples/qdbus/chat/chatsetnickname.ui +145 -145
- data/examples/qdbus/chat/makefile +8 -8
- data/examples/qdbus/complexpingpong/complexping.rb +92 -92
- data/examples/qdbus/complexpingpong/complexpong.rb +83 -83
- data/examples/qdbus/complexpingpong/ping-common.rb +1 -1
- data/examples/qdbus/listnames/listnames.rb +69 -69
- data/examples/qdbus/pingpong/ping-common.rb +1 -1
- data/examples/qdbus/pingpong/ping.rb +52 -52
- data/examples/qdbus/pingpong/pong.rb +55 -55
- data/examples/qdbus/remotecontrolledcar/car/car.rb +151 -151
- data/examples/qdbus/remotecontrolledcar/car/main.rb +50 -50
- data/examples/qdbus/remotecontrolledcar/controller/controller.rb +66 -66
- data/examples/qdbus/remotecontrolledcar/controller/controller.ui +61 -61
- data/examples/qdbus/remotecontrolledcar/controller/main.rb +32 -32
- data/examples/qdbus/remotecontrolledcar/controller/makefile +2 -2
- data/examples/qtscribble/scribble.rb +270 -270
- data/examples/richtext/calendar/main.rb +33 -33
- data/examples/richtext/calendar/mainwindow.rb +173 -173
- data/examples/richtext/orderform/detailsdialog.rb +130 -130
- data/examples/richtext/orderform/main.rb +34 -34
- data/examples/richtext/orderform/mainwindow.rb +194 -194
- data/examples/richtext/syntaxhighlighter/examples/example +79 -79
- data/examples/richtext/syntaxhighlighter/highlighter.rb +90 -90
- data/examples/richtext/syntaxhighlighter/main.rb +34 -34
- data/examples/richtext/syntaxhighlighter/mainwindow.rb +105 -105
- data/examples/ruboids/LICENSE.txt +58 -58
- data/examples/ruboids/Manifest +26 -26
- data/examples/ruboids/README +53 -53
- data/examples/ruboids/TODO +29 -29
- data/examples/ruboids/boids.properties +33 -33
- data/examples/ruboids/generateManifest.rb +42 -42
- data/examples/ruboids/release.rb +152 -152
- data/examples/ruboids/ruboids/Boid.rb +141 -141
- data/examples/ruboids/ruboids/BoidView.rb +159 -159
- data/examples/ruboids/ruboids/Camera.rb +24 -24
- data/examples/ruboids/ruboids/CameraDialog.rb +218 -218
- data/examples/ruboids/ruboids/Canvas.rb +143 -143
- data/examples/ruboids/ruboids/Cloud.rb +61 -61
- data/examples/ruboids/ruboids/CloudView.rb +54 -54
- data/examples/ruboids/ruboids/Flock.rb +47 -47
- data/examples/ruboids/ruboids/Graphics.rb +278 -278
- data/examples/ruboids/ruboids/Params.rb +87 -87
- data/examples/ruboids/ruboids/Point.rb +153 -153
- data/examples/ruboids/ruboids/Thing.rb +34 -34
- data/examples/ruboids/ruboids/Triangle.rb +21 -21
- data/examples/ruboids/ruboids/View.rb +88 -88
- data/examples/ruboids/ruboids/World.rb +82 -82
- data/examples/ruboids/ruboids/WorldWindow.rb +52 -52
- data/examples/ruboids/ruboids/info.rb +12 -12
- data/examples/ruboids/ruboids/ruboids.rb +29 -29
- data/examples/threading/main_thread.rb +19 -19
- data/examples/tutorial/t1/t1.rb +10 -10
- data/examples/tutorial/t10/cannon.rb +72 -72
- data/examples/tutorial/t10/lcdrange.rb +45 -45
- data/examples/tutorial/t10/t10.rb +55 -55
- data/examples/tutorial/t11/cannon.rb +123 -124
- data/examples/tutorial/t11/lcdrange.rb +45 -45
- data/examples/tutorial/t11/t11.rb +65 -65
- data/examples/tutorial/t12/cannon.rb +157 -158
- data/examples/tutorial/t12/lcdrange.rb +58 -59
- data/examples/tutorial/t12/t12.rb +65 -66
- data/examples/tutorial/t13/cannon.rb +206 -208
- data/examples/tutorial/t13/gamebrd.rb +112 -113
- data/examples/tutorial/t13/lcdrange.rb +59 -60
- data/examples/tutorial/t13/t13.rb +11 -11
- data/examples/tutorial/t14/cannon.rb +262 -263
- data/examples/tutorial/t14/gamebrd.rb +122 -123
- data/examples/tutorial/t14/lcdrange.rb +61 -63
- data/examples/tutorial/t14/t14.rb +11 -11
- data/examples/tutorial/t2/t2.rb +16 -16
- data/examples/tutorial/t3/t3.rb +17 -18
- data/examples/tutorial/t4/t4.rb +23 -25
- data/examples/tutorial/t5/t5.rb +35 -37
- data/examples/tutorial/t6/t6.rb +48 -52
- data/examples/tutorial/t7/lcdrange.rb +32 -32
- data/examples/tutorial/t7/t7.rb +40 -42
- data/examples/tutorial/t8/cannon.rb +37 -38
- data/examples/tutorial/t8/lcdrange.rb +45 -45
- data/examples/tutorial/t8/t8.rb +43 -43
- data/examples/tutorial/t9/cannon.rb +44 -45
- data/examples/tutorial/t9/lcdrange.rb +46 -46
- data/examples/tutorial/t9/t9.rb +43 -43
- data/examples/widgets/analogclock/analogclock.rb +94 -94
- data/examples/widgets/analogclock/main.rb +9 -9
- data/examples/widgets/calculator/button.rb +45 -45
- data/examples/widgets/calculator/calculator.rb +382 -382
- data/examples/widgets/calculator/main.rb +32 -32
- data/examples/widgets/charactermap/characterwidget.rb +109 -109
- data/examples/widgets/charactermap/main.rb +32 -32
- data/examples/widgets/charactermap/mainwindow.rb +118 -118
- data/examples/widgets/digitalclock/digitalclock.rb +30 -30
- data/examples/widgets/digitalclock/main.rb +9 -9
- data/examples/widgets/groupbox/main.rb +32 -32
- data/examples/widgets/groupbox/window.rb +134 -134
- data/examples/widgets/icons/iconpreviewarea.rb +110 -110
- data/examples/widgets/icons/iconsizespinbox.rb +39 -39
- data/examples/widgets/icons/imagedelegate.rb +73 -73
- data/examples/widgets/icons/main.rb +32 -32
- data/examples/widgets/icons/mainwindow.rb +351 -351
- data/examples/widgets/imageviewer/imageviewer.rb +219 -219
- data/examples/widgets/imageviewer/main.rb +32 -32
- data/examples/widgets/lineedits/main.rb +32 -32
- data/examples/widgets/lineedits/window.rb +199 -199
- data/examples/widgets/movie/main.rb +32 -32
- data/examples/widgets/movie/movieplayer.rb +201 -201
- data/examples/widgets/screenshot/main.rb +32 -32
- data/examples/widgets/screenshot/screenshot.rb +154 -154
- data/examples/widgets/scribble/main.rb +32 -32
- data/examples/widgets/scribble/mainwindow.rb +202 -202
- data/examples/widgets/scribble/scribblearea.rb +154 -154
- data/examples/widgets/sliders/main.rb +32 -32
- data/examples/widgets/sliders/slidersgroup.rb +97 -97
- data/examples/widgets/sliders/window.rb +124 -124
- data/examples/widgets/spinboxes/main.rb +32 -32
- data/examples/widgets/spinboxes/window.rb +213 -213
- data/examples/widgets/tetrix/main.rb +33 -33
- data/examples/widgets/tetrix/tetrixboard.rb +346 -346
- data/examples/widgets/tetrix/tetrixpiece.rb +135 -135
- data/examples/widgets/tetrix/tetrixwindow.rb +88 -88
- data/examples/widgets/tooltips/main.rb +32 -32
- data/examples/widgets/tooltips/shapeitem.rb +31 -31
- data/examples/widgets/tooltips/sortingbox.rb +222 -222
- data/examples/widgets/wiggly/dialog.rb +48 -48
- data/examples/widgets/wiggly/main.rb +9 -9
- data/examples/widgets/wiggly/wigglywidget.rb +75 -75
- data/examples/widgets/windowflags/controllerwindow.rb +195 -195
- data/examples/widgets/windowflags/main.rb +32 -32
- data/examples/widgets/windowflags/previewwindow.rb +103 -103
- data/examples/xml/dombookmarks/frank.xbel +230 -230
- data/examples/xml/dombookmarks/jennifer.xbel +93 -93
- data/examples/xml/dombookmarks/main.rb +34 -34
- data/examples/xml/dombookmarks/mainwindow.rb +129 -129
- data/examples/xml/dombookmarks/xbeltree.rb +172 -172
- data/examples/xml/saxbookmarks/frank.xbel +230 -230
- data/examples/xml/saxbookmarks/jennifer.xbel +93 -93
- data/examples/xml/saxbookmarks/main.rb +34 -34
- data/examples/xml/saxbookmarks/mainwindow.rb +144 -144
- data/examples/xml/saxbookmarks/xbelgenerator.rb +95 -95
- data/examples/xml/saxbookmarks/xbelhandler.rb +122 -122
- data/ext/cmake/modules/BasicFindPackageVersion.cmake.in +30 -30
- data/ext/cmake/modules/CMakeCSharpCompiler.cmake.in +7 -7
- data/ext/cmake/modules/CMakeCSharpInformation.cmake +366 -366
- data/ext/cmake/modules/CMakeDetermineCSharpCompiler.cmake +85 -85
- data/ext/cmake/modules/CMakeTestCSharpCompiler.cmake +1 -1
- data/ext/cmake/modules/FindLibraryWithDebug.cmake +113 -113
- data/ext/cmake/modules/FindMono.cmake +36 -36
- data/ext/cmake/modules/FindPHP5.cmake +179 -179
- data/ext/cmake/modules/FindPerlMore.cmake +78 -78
- data/ext/cmake/modules/FindPhonon.cmake +71 -71
- data/ext/cmake/modules/FindQImageBlitz.cmake +51 -51
- data/ext/cmake/modules/FindQScintilla.cmake +57 -57
- data/ext/cmake/modules/FindQwt5.cmake +104 -104
- data/ext/cmake/modules/FindRuby.cmake +279 -279
- data/ext/cmake/modules/FindSmoke.cmake +78 -78
- data/ext/cmake/modules/MacroLogFeature.cmake +146 -146
- data/ext/cmake/modules/MacroOptionalAddBindings.cmake +47 -47
- data/ext/cmake/modules/MacroOptionalFindPackage.cmake +28 -28
- data/ext/cmake/modules/MacroPushRequiredVars.cmake +47 -47
- data/ext/cmake/modules/MacroWriteBasicCMakeVersionFile.cmake +22 -22
- data/ext/cmake/modules/SmokeConfig.cmake.in +109 -109
- data/ext/generator/CMakeLists.txt +38 -38
- data/ext/generator/cmake/BasicFindPackageVersion.cmake.in +30 -30
- data/ext/generator/cmake/CMakeLists.txt +24 -24
- data/ext/generator/cmake/FindLibraryWithDebug.cmake +113 -113
- data/ext/generator/cmake/FindPhonon.cmake +71 -71
- data/ext/generator/cmake/FindQImageBlitz.cmake +51 -51
- data/ext/generator/cmake/FindQScintilla.cmake +57 -57
- data/ext/generator/cmake/FindQwt5.cmake +104 -104
- data/ext/generator/cmake/HandleImportedTargetsInCMakeRequiredLibraries.cmake +85 -85
- data/ext/generator/cmake/MacroLogFeature.cmake +146 -146
- data/ext/generator/cmake/MacroOptionalAddBindings.cmake +47 -47
- data/ext/generator/cmake/MacroOptionalFindPackage.cmake +28 -28
- data/ext/generator/cmake/MacroWriteBasicCMakeVersionFile.cmake +22 -22
- data/ext/generator/cmake/SmokeConfig.cmake.in +109 -109
- data/ext/generator/config.h +25 -25
- data/ext/generator/generator_export.h +31 -31
- data/ext/generator/generatorenvironment.cpp +52 -52
- data/ext/generator/generatorenvironment.h +35 -35
- data/ext/generator/generatorpreprocessor.cpp +303 -303
- data/ext/generator/generatorpreprocessor.h +83 -83
- data/ext/generator/generators/CMakeLists.txt +4 -4
- data/ext/generator/generators/dump/CMakeLists.txt +15 -15
- data/ext/generator/generators/dump/generator_dump.cpp +36 -36
- data/ext/generator/generators/smoke/CMakeLists.txt +18 -18
- data/ext/generator/generators/smoke/generator_smoke.cpp +240 -240
- data/ext/generator/generators/smoke/globals.h +140 -140
- data/ext/generator/generators/smoke/helpers.cpp +793 -793
- data/ext/generator/generators/smoke/writeClasses.cpp +502 -502
- data/ext/generator/generators/smoke/writeSmokeDataFile.cpp +754 -754
- data/ext/generator/generatorvisitor.cpp +922 -922
- data/ext/generator/generatorvisitor.h +119 -119
- data/ext/generator/name_compiler.cpp +205 -205
- data/ext/generator/name_compiler.h +76 -76
- data/ext/generator/options.cpp +33 -33
- data/ext/generator/options.h +46 -46
- data/ext/generator/parser/CMakeLists.txt +50 -50
- data/ext/generator/parser/ast.cpp +21 -21
- data/ext/generator/parser/ast.h +923 -923
- data/ext/generator/parser/astutilities.h +65 -65
- data/ext/generator/parser/codegenerator.cpp +867 -867
- data/ext/generator/parser/codegenerator.h +180 -180
- data/ext/generator/parser/codemodel_fwd.h +76 -76
- data/ext/generator/parser/commentformatter.cpp +54 -54
- data/ext/generator/parser/commentformatter.h +45 -45
- data/ext/generator/parser/commentparser.cpp +109 -109
- data/ext/generator/parser/commentparser.h +84 -84
- data/ext/generator/parser/control.cpp +40 -40
- data/ext/generator/parser/control.h +51 -51
- data/ext/generator/parser/cppparser_export.h +33 -33
- data/ext/generator/parser/default_visitor.cpp +470 -470
- data/ext/generator/parser/default_visitor.h +116 -116
- data/ext/generator/parser/dumptree.cpp +146 -146
- data/ext/generator/parser/dumptree.h +50 -50
- data/ext/generator/parser/indexedstring.cpp +213 -213
- data/ext/generator/parser/indexedstring.h +147 -147
- data/ext/generator/parser/kdevelop-parser-rev +1 -1
- data/ext/generator/parser/kdevvarlengtharray.h +346 -346
- data/ext/generator/parser/lexer.cpp +964 -964
- data/ext/generator/parser/lexer.h +308 -308
- data/ext/generator/parser/listnode.cpp +20 -20
- data/ext/generator/parser/listnode.h +97 -97
- data/ext/generator/parser/memorypool.cpp +20 -20
- data/ext/generator/parser/memorypool.h +41 -41
- data/ext/generator/parser/name_compiler.cpp +190 -190
- data/ext/generator/parser/name_compiler.h +77 -77
- data/ext/generator/parser/parser.cpp +4708 -4708
- data/ext/generator/parser/parser.h +290 -290
- data/ext/generator/parser/parsesession.cpp +106 -106
- data/ext/generator/parser/parsesession.h +87 -87
- data/ext/generator/parser/problem.h +21 -21
- data/ext/generator/parser/rpp/CMakeLists.txt +45 -45
- data/ext/generator/parser/rpp/Makefile.am +13 -13
- data/ext/generator/parser/rpp/anchor.h +51 -51
- data/ext/generator/parser/rpp/appendedlist.h +363 -363
- data/ext/generator/parser/rpp/chartools.cpp +146 -146
- data/ext/generator/parser/rpp/chartools.h +99 -99
- data/ext/generator/parser/rpp/macrorepository.cpp +44 -44
- data/ext/generator/parser/rpp/macrorepository.h +59 -59
- data/ext/generator/parser/rpp/pp-configuration +86 -86
- data/ext/generator/parser/rpp/pp-engine.h +267 -267
- data/ext/generator/parser/rpp/pp-environment.cpp +271 -271
- data/ext/generator/parser/rpp/pp-environment.h +119 -119
- data/ext/generator/parser/rpp/pp-internal.cpp +38 -38
- data/ext/generator/parser/rpp/pp-internal.h +37 -37
- data/ext/generator/parser/rpp/pp-location.cpp +191 -191
- data/ext/generator/parser/rpp/pp-location.h +89 -89
- data/ext/generator/parser/rpp/pp-macro-expander.cpp +568 -568
- data/ext/generator/parser/rpp/pp-macro-expander.cpp.orig +558 -558
- data/ext/generator/parser/rpp/pp-macro-expander.h +130 -130
- data/ext/generator/parser/rpp/pp-macro.cpp +153 -153
- data/ext/generator/parser/rpp/pp-macro.h +176 -176
- data/ext/generator/parser/rpp/pp-scanner.cpp +311 -311
- data/ext/generator/parser/rpp/pp-scanner.h +97 -97
- data/ext/generator/parser/rpp/pp-stream.cpp +425 -425
- data/ext/generator/parser/rpp/pp-stream.h +183 -183
- data/ext/generator/parser/rpp/preprocessor.cpp +65 -65
- data/ext/generator/parser/rpp/preprocessor.h +80 -80
- data/ext/generator/parser/rpp/rpp.pri +2 -2
- data/ext/generator/parser/rpp/test/t001.cpp +23 -23
- data/ext/generator/parser/rpp/test/t002.cpp +15 -15
- data/ext/generator/parser/rpp/test/t003.cpp +10 -10
- data/ext/generator/parser/rpp/test/t004.cpp +9 -9
- data/ext/generator/parser/rpp/test/t005.cpp +10 -10
- data/ext/generator/parser/rpp/test/t006.cpp +10 -10
- data/ext/generator/parser/rpp/test/t007.cpp +6 -6
- data/ext/generator/parser/rpp/test/t008.cpp +6 -6
- data/ext/generator/parser/rpp/test/t009.cpp +5 -5
- data/ext/generator/parser/rpp/test/t010.cpp +15 -15
- data/ext/generator/parser/rpp/test/t011.cpp +9 -9
- data/ext/generator/parser/rpp/tests/CMakeLists.txt +17 -17
- data/ext/generator/parser/rpp/tests/main.cpp +69 -69
- data/ext/generator/parser/rxx.pri +50 -50
- data/ext/generator/parser/rxx_allocator.h +128 -128
- data/ext/generator/parser/safetycounter.h +57 -57
- data/ext/generator/parser/simplecursor.h +74 -74
- data/ext/generator/parser/stringhelpers.cpp +577 -577
- data/ext/generator/parser/stringhelpers.h +118 -118
- data/ext/generator/parser/symbol.h +140 -140
- data/ext/generator/parser/tests/CMakeLists.txt +46 -46
- data/ext/generator/parser/tests/test_generator.cpp +259 -259
- data/ext/generator/parser/tests/test_parser.cpp +474 -474
- data/ext/generator/parser/tests/test_pool.cpp +109 -109
- data/ext/generator/parser/tests/test_pool.h +35 -35
- data/ext/generator/parser/tests/testconfig.h.cmake +4 -4
- data/ext/generator/parser/tokens.cpp +367 -367
- data/ext/generator/parser/tokens.h +148 -148
- data/ext/generator/parser/type_compiler.cpp +135 -135
- data/ext/generator/parser/type_compiler.h +68 -68
- data/ext/generator/parser/visitor.cpp +115 -115
- data/ext/generator/parser/visitor.h +138 -138
- data/ext/generator/smoke.h +557 -557
- data/ext/generator/smokegen_string.h +43 -43
- data/ext/generator/type.cpp +204 -204
- data/ext/generator/type.h +497 -497
- data/ext/generator/type_compiler.cpp +277 -277
- data/ext/generator/type_compiler.h +80 -80
- data/ext/ruby/CMakeLists.txt +64 -64
- data/ext/ruby/qtdeclarative/CMakeLists.txt +17 -17
- data/ext/ruby/qtdeclarative/qtdeclarative.cpp +67 -67
- data/ext/ruby/qtdeclarative/qtdeclarative.rb +17 -17
- data/ext/ruby/qtdeclarative/qtdeclarativehandlers.cpp +36 -36
- data/ext/ruby/qtruby/AUTHORS +54 -54
- data/ext/ruby/qtruby/COPYING +355 -355
- data/ext/ruby/qtruby/COPYING.LIB +510 -510
- data/ext/ruby/qtruby/ChangeLog +3732 -3732
- data/ext/ruby/qtruby/INSTALL +79 -79
- data/ext/ruby/qtruby/README +264 -264
- data/ext/ruby/qtruby/TODO +8 -8
- data/ext/ruby/qtruby/bin/rbqtapi +152 -152
- data/ext/ruby/qtruby/rails_support/CMakeLists.txt +1 -1
- data/ext/ruby/qtruby/rails_support/active_item_model.rb +234 -234
- data/ext/ruby/qtruby/rails_support/active_table_model.rb +122 -122
- data/ext/ruby/qtruby/src/marshall_basetypes.h +208 -208
- data/ext/ruby/qtruby/src/marshall_complex.h +175 -175
- data/ext/ruby/qtruby/src/marshall_macros.h +647 -647
- data/ext/ruby/qtruby/src/marshall_types.cpp +815 -815
- data/ext/ruby/qtruby/src/marshall_types.h +240 -240
- data/ext/ruby/qtruby/src/qtruby.cpp +1 -1
- data/ext/ruby/qtruby/test/opoverloading.rb +46 -46
- data/ext/ruby/qtruby/test/unittests.rb +151 -151
- data/ext/ruby/qtruby/tools/rbrcc/main.cpp +173 -173
- data/ext/ruby/qtruby/tools/rbrcc/rbrcc.pro +14 -14
- data/ext/ruby/qtruby/tools/rbrcc/rcc.cpp +648 -648
- data/ext/ruby/qtruby/tools/rbrcc/rcc.h +165 -165
- data/ext/ruby/qtruby/tools/rbuic/LICENSE.GPL +280 -280
- data/ext/ruby/qtruby/tools/rbuic/TODO +4 -4
- data/ext/ruby/qtruby/tools/rbuic/customwidgetsinfo.cpp +106 -106
- data/ext/ruby/qtruby/tools/rbuic/customwidgetsinfo.h +95 -95
- data/ext/ruby/qtruby/tools/rbuic/databaseinfo.cpp +102 -102
- data/ext/ruby/qtruby/tools/rbuic/databaseinfo.h +85 -85
- data/ext/ruby/qtruby/tools/rbuic/driver.cpp +384 -384
- data/ext/ruby/qtruby/tools/rbuic/driver.h +141 -141
- data/ext/ruby/qtruby/tools/rbuic/rbuic.pri +23 -23
- data/ext/ruby/qtruby/tools/rbuic/rbuic4.pro +43 -43
- data/ext/ruby/qtruby/tools/rbuic/ruby/rbextractimages.cpp +150 -150
- data/ext/ruby/qtruby/tools/rbuic/ruby/rbextractimages.h +83 -83
- data/ext/ruby/qtruby/tools/rbuic/ruby/rbwritedeclaration.cpp +217 -217
- data/ext/ruby/qtruby/tools/rbuic/ruby/rbwritedeclaration.h +85 -85
- data/ext/ruby/qtruby/tools/rbuic/ruby/rbwriteicondata.cpp +185 -185
- data/ext/ruby/qtruby/tools/rbuic/ruby/rbwriteicondata.h +86 -86
- data/ext/ruby/qtruby/tools/rbuic/ruby/rbwriteicondeclaration.cpp +88 -88
- data/ext/ruby/qtruby/tools/rbuic/ruby/rbwriteicondeclaration.h +83 -83
- data/ext/ruby/qtruby/tools/rbuic/ruby/rbwriteiconinitialization.cpp +126 -126
- data/ext/ruby/qtruby/tools/rbuic/ruby/rbwriteiconinitialization.h +87 -87
- data/ext/ruby/qtruby/tools/rbuic/ruby/rbwriteinitialization.cpp +2478 -2478
- data/ext/ruby/qtruby/tools/rbuic/ruby/rbwriteinitialization.h +314 -314
- data/ext/ruby/qtruby/tools/rbuic/ruby/ruby.pri +18 -18
- data/ext/ruby/qtruby/tools/rbuic/treewalker.cpp +318 -318
- data/ext/ruby/qtruby/tools/rbuic/treewalker.h +139 -139
- data/ext/ruby/qtruby/tools/rbuic/ui4.cpp +7623 -7623
- data/ext/ruby/qtruby/tools/rbuic/ui4.h +3180 -3180
- data/ext/ruby/qtruby/tools/rbuic/utils.h +125 -125
- data/ext/ruby/qtruby/tools/rbuic/validator.cpp +100 -100
- data/ext/ruby/qtruby/tools/rbuic/validator.h +80 -80
- data/ext/ruby/qtscript/CMakeLists.txt +19 -19
- data/ext/ruby/qtscript/qtscript.cpp +83 -83
- data/ext/ruby/qtscript/qtscript.rb +40 -40
- data/ext/ruby/qtscript/qtscripthandlers.cpp +37 -37
- data/ext/ruby/qtscript/smokedata.cpp +1403 -1403
- data/ext/ruby/qttest/CMakeLists.txt +18 -18
- data/ext/ruby/qttest/ChangeLog +9 -9
- data/ext/ruby/qttest/examples/myfirsttest.rb +30 -30
- data/ext/ruby/qttest/qttest.cpp +83 -83
- data/ext/ruby/qttest/qttest.rb +166 -166
- data/ext/ruby/qttest/qttesthandlers.cpp +37 -37
- data/ext/ruby/qtuitools/CMakeLists.txt +16 -16
- data/ext/ruby/qtuitools/qtuitools.cpp +83 -83
- data/ext/ruby/qtuitools/qtuitools.rb +17 -17
- data/ext/ruby/qtuitools/qtuitoolshandlers.cpp +32 -32
- data/ext/ruby/qtwebkit/CMakeLists.txt +17 -17
- data/ext/ruby/qtwebkit/qtwebkit.cpp +67 -67
- data/ext/ruby/qtwebkit/qtwebkit.rb +17 -17
- data/ext/ruby/qtwebkit/qtwebkithandlers.cpp +40 -40
- data/ext/smoke/deptool/CMakeLists.txt +7 -7
- data/ext/smoke/deptool/main.cpp +128 -128
- data/ext/smoke/qtcore/CMakeLists.txt +88 -88
- data/ext/smoke/qtcore/QtGuess.txt +180 -180
- data/ext/smoke/qtcore/config.xml.cmake +10 -10
- data/ext/smoke/qtcore/qt-config.xml.cmake +21 -21
- data/ext/smoke/qtcore/qtcore_includes.h +1 -1
- data/ext/smoke/qtcore/smokeconfig.xml +193 -193
- data/ext/smoke/qtcore/tests/CMakeLists.txt +13 -13
- data/ext/smoke/qtcore/tests/test.cpp +846 -846
- data/ext/smoke/qtcore_smoke.h +16 -16
- data/ext/smoke/qtdbus/CMakeLists.txt +38 -38
- data/ext/smoke/qtdbus/config.xml.cmake +11 -11
- data/ext/smoke/qtdbus/qtdbus_includes.h +2 -2
- data/ext/smoke/qtdbus/smokeconfig.xml +65 -65
- data/ext/smoke/qtdbus_smoke.h +16 -16
- data/ext/smoke/qtdeclarative/CMakeLists.txt +45 -45
- data/ext/smoke/qtdeclarative/config.xml.cmake +12 -12
- data/ext/smoke/qtdeclarative/qtdeclarative_includes.h +3 -3
- data/ext/smoke/qtdeclarative/smokeconfig.xml +59 -59
- data/ext/smoke/qtdeclarative_smoke.h +16 -16
- data/ext/smoke/qtgui/CMakeLists.txt +76 -76
- data/ext/smoke/qtgui/config.xml.cmake +11 -11
- data/ext/smoke/qtgui/qtgui_includes.h +7 -7
- data/ext/smoke/qtgui/smokeconfig.xml +500 -500
- data/ext/smoke/qtgui_smoke.h +16 -16
- data/ext/smoke/qthelp/CMakeLists.txt +45 -45
- data/ext/smoke/qthelp/config.xml.cmake +13 -13
- data/ext/smoke/qthelp/qthelp_includes.h +3 -3
- data/ext/smoke/qthelp/smokeconfig.xml +54 -54
- data/ext/smoke/qthelp_smoke.h +16 -16
- data/ext/smoke/qtmultimedia/CMakeLists.txt +42 -42
- data/ext/smoke/qtmultimedia/config.xml.cmake +12 -12
- data/ext/smoke/qtmultimedia/qtmultimedia_includes.h +3 -3
- data/ext/smoke/qtmultimedia/smokeconfig.xml +51 -51
- data/ext/smoke/qtmultimedia_smoke.h +16 -16
- data/ext/smoke/qtnetwork/CMakeLists.txt +38 -38
- data/ext/smoke/qtnetwork/config.xml.cmake +11 -11
- data/ext/smoke/qtnetwork/qtnetwork_includes.h +2 -2
- data/ext/smoke/qtnetwork/smokeconfig.xml +81 -81
- data/ext/smoke/qtnetwork_smoke.h +16 -16
- data/ext/smoke/qtopengl/CMakeLists.txt +43 -43
- data/ext/smoke/qtopengl/config.xml.cmake +13 -13
- data/ext/smoke/qtopengl/qtopengl_includes.h +3 -3
- data/ext/smoke/qtopengl/smokeconfig.xml +58 -58
- data/ext/smoke/qtopengl_smoke.h +16 -16
- data/ext/smoke/qtscript/CMakeLists.txt +31 -31
- data/ext/smoke/qtscript/config.xml.cmake +11 -11
- data/ext/smoke/qtscript/qtscript_includes.h +14 -14
- data/ext/smoke/qtscript/smokeconfig.xml +39 -39
- data/ext/smoke/qtscript_smoke.h +16 -16
- data/ext/smoke/qtsql/CMakeLists.txt +45 -45
- data/ext/smoke/qtsql/config.xml.cmake +11 -11
- data/ext/smoke/qtsql/qtsql_includes.h +3 -3
- data/ext/smoke/qtsql/smokeconfig.xml +60 -60
- data/ext/smoke/qtsql_smoke.h +16 -16
- data/ext/smoke/qtsvg/CMakeLists.txt +43 -43
- data/ext/smoke/qtsvg/config.xml.cmake +12 -12
- data/ext/smoke/qtsvg/qtsvg_includes.h +3 -3
- data/ext/smoke/qtsvg/smokeconfig.xml +46 -46
- data/ext/smoke/qtsvg_smoke.h +16 -16
- data/ext/smoke/qttest/CMakeLists.txt +35 -35
- data/ext/smoke/qttest/config.xml.cmake +12 -12
- data/ext/smoke/qttest/qttest_includes.h +14 -14
- data/ext/smoke/qttest/smokeconfig.xml +36 -36
- data/ext/smoke/qttest_smoke.h +16 -16
- data/ext/smoke/qtuitools/CMakeLists.txt +30 -30
- data/ext/smoke/qtuitools/config.xml.cmake +12 -12
- data/ext/smoke/qtuitools/qtuitools_includes.h +1 -1
- data/ext/smoke/qtuitools/smokeconfig.xml +20 -20
- data/ext/smoke/qtuitools_smoke.h +16 -16
- data/ext/smoke/qtwebkit/CMakeLists.txt +36 -36
- data/ext/smoke/qtwebkit/config.xml.cmake +11 -11
- data/ext/smoke/qtwebkit/qtwebkit_includes.h +1 -1
- data/ext/smoke/qtwebkit/smokeconfig.xml +48 -48
- data/ext/smoke/qtwebkit_smoke.h +16 -16
- data/ext/smoke/qtxml/CMakeLists.txt +41 -41
- data/ext/smoke/qtxml/config.xml.cmake +11 -11
- data/ext/smoke/qtxml/qtxml_includes.h +2 -2
- data/ext/smoke/qtxml/smokeconfig.xml +70 -70
- data/ext/smoke/qtxml_smoke.h +16 -16
- data/ext/smoke/qtxmlpatterns/CMakeLists.txt +42 -42
- data/ext/smoke/qtxmlpatterns/config.xml.cmake +12 -12
- data/ext/smoke/qtxmlpatterns/qtxmlpatterns_includes.h +3 -3
- data/ext/smoke/qtxmlpatterns/smokeconfig.xml +80 -80
- data/ext/smoke/qtxmlpatterns_smoke.h +16 -16
- data/ext/smoke/smokeapi/CMakeLists.txt +9 -9
- data/ext/smoke/smokeapi/main.cpp +309 -309
- data/ext/smoke/smokebase/CMakeLists.txt +11 -11
- data/ext/smoke/smokebase/smokebase.cpp +6 -6
- data/ext/smoke/solid_smoke.h +16 -16
- data/lib/Qt.rb +1 -1
- data/lib/Qt4.rb +119 -111
- data/lib/qtbindings_version.rb +2 -2
- data/lib/qtdeclarative/qtdeclarative.rb +17 -17
- data/lib/qtscript/qtscript.rb +40 -40
- data/lib/qttest/qttest.rb +166 -166
- data/lib/qtuitools/qtuitools.rb +17 -17
- data/lib/qtwebkit/qtwebkit.rb +17 -17
- metadata +6 -7
|
@@ -1,922 +1,922 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Copyright (C) 2009 Arno Rehn <arno@arnorehn.de>
|
|
3
|
-
|
|
4
|
-
This program is free software; you can redistribute it and/or modify
|
|
5
|
-
it under the terms of the GNU General Public License as published by
|
|
6
|
-
the Free Software Foundation; either version 2 of the License, or
|
|
7
|
-
(at your option) any later version.
|
|
8
|
-
|
|
9
|
-
This program is distributed in the hope that it will be useful,
|
|
10
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
-
GNU General Public License for more details.
|
|
13
|
-
|
|
14
|
-
You should have received a copy of the GNU General Public License along
|
|
15
|
-
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
16
|
-
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
#include <ast.h>
|
|
20
|
-
#include <tokens.h>
|
|
21
|
-
#include "name_compiler.h"
|
|
22
|
-
#include "type_compiler.h"
|
|
23
|
-
|
|
24
|
-
#include "generatorvisitor.h"
|
|
25
|
-
#include "options.h"
|
|
26
|
-
|
|
27
|
-
#include <QtDebug>
|
|
28
|
-
|
|
29
|
-
GeneratorVisitor::GeneratorVisitor(ParseSession *session, const QString& header)
|
|
30
|
-
: m_session(session), m_header(header), createType(false), createTypedef(false),
|
|
31
|
-
inClass(0), inTemplate(false), isStatic(false), isVirtual(false), isExplicit(false), hasInitializer(false), currentTypeRef(0), inMethod(false)
|
|
32
|
-
{
|
|
33
|
-
nc = new NameCompiler(m_session, this);
|
|
34
|
-
tc = new TypeCompiler(m_session, this);
|
|
35
|
-
|
|
36
|
-
usingTypes.push(QStringList());
|
|
37
|
-
usingNamespaces.push(QStringList());
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
GeneratorVisitor::~GeneratorVisitor()
|
|
41
|
-
{
|
|
42
|
-
delete nc;
|
|
43
|
-
delete tc;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
QPair<bool, bool> GeneratorVisitor::parseCv(const ListNode<std::size_t> *cv)
|
|
47
|
-
{
|
|
48
|
-
QPair<bool, bool> ret(false, false);
|
|
49
|
-
if (!cv) return ret;
|
|
50
|
-
const ListNode<std::size_t> *it = cv->toFront(), *end = it;
|
|
51
|
-
do {
|
|
52
|
-
if (it->element) {
|
|
53
|
-
int _kind = m_session->token_stream->kind(it->element);
|
|
54
|
-
if (_kind == Token_const)
|
|
55
|
-
ret.first = true;
|
|
56
|
-
else if (_kind == Token_volatile)
|
|
57
|
-
ret.second = true;
|
|
58
|
-
}
|
|
59
|
-
it = it->next;
|
|
60
|
-
} while (end != it);
|
|
61
|
-
return ret;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
#define returnOnExistence(name) \
|
|
65
|
-
if (classes.contains(name)) { \
|
|
66
|
-
return &classes[name]; \
|
|
67
|
-
} else if (typedefs.contains(name)) { \
|
|
68
|
-
return &typedefs[name]; \
|
|
69
|
-
} else if (enums.contains(name)) { \
|
|
70
|
-
return &enums[name]; \
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
BasicTypeDeclaration* GeneratorVisitor::resolveTypeInSuperClasses(const Class* klass, const QString& name)
|
|
74
|
-
{
|
|
75
|
-
foreach (const Class::BaseClassSpecifier& bclass, klass->baseClasses()) {
|
|
76
|
-
QString _name = bclass.baseClass->toString() + "::" + name;
|
|
77
|
-
returnOnExistence(_name);
|
|
78
|
-
QStringList nspace = klass->nameSpace().split("::");
|
|
79
|
-
if (!klass->nameSpace().isEmpty() && nspace != this->nspace) {
|
|
80
|
-
do {
|
|
81
|
-
nspace.push_back(name);
|
|
82
|
-
QString n = nspace.join("::");
|
|
83
|
-
returnOnExistence(n);
|
|
84
|
-
nspace.pop_back();
|
|
85
|
-
if (!nspace.isEmpty())
|
|
86
|
-
nspace.pop_back();
|
|
87
|
-
} while (!nspace.isEmpty());
|
|
88
|
-
}
|
|
89
|
-
if (!bclass.baseClass->baseClasses().count())
|
|
90
|
-
continue;
|
|
91
|
-
BasicTypeDeclaration* decl = resolveTypeInSuperClasses(bclass.baseClass, name);
|
|
92
|
-
if (decl)
|
|
93
|
-
return decl;
|
|
94
|
-
}
|
|
95
|
-
return 0;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
BasicTypeDeclaration* GeneratorVisitor::resolveType(const QString & name)
|
|
99
|
-
{
|
|
100
|
-
QString _name = name;
|
|
101
|
-
return resolveType(_name);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// TODO: this might have to be improved for cases like 'Typedef::Nested foo'
|
|
105
|
-
BasicTypeDeclaration* GeneratorVisitor::resolveType(QString & name)
|
|
106
|
-
{
|
|
107
|
-
if (ParserOptions::qtMode && name.endsWith("::enum_type")) {
|
|
108
|
-
// strip off "::enum_type"
|
|
109
|
-
QString flags = name.left(name.length() - 11);
|
|
110
|
-
QHash<QString, Typedef>::iterator it = typedefs.find(flags);
|
|
111
|
-
if (it != typedefs.end()) {
|
|
112
|
-
QString enumType = it.value().resolve().toString().replace(QRegExp("QFlags<(.*)>"), "\\1");
|
|
113
|
-
QHash<QString, Enum>::iterator it = enums.find(enumType);
|
|
114
|
-
if (it != enums.end()) {
|
|
115
|
-
return &it.value();
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// check for 'using type;'
|
|
121
|
-
// if we use 'type', we can also access type::nested, take care of that
|
|
122
|
-
int index = name.indexOf("::");
|
|
123
|
-
QString first = name, rest;
|
|
124
|
-
if (index > -1) {
|
|
125
|
-
first = name.mid(0, index);
|
|
126
|
-
rest = name.mid(index);
|
|
127
|
-
}
|
|
128
|
-
foreach (const QStringList& list, usingTypes) {
|
|
129
|
-
foreach (const QString& string, list) {
|
|
130
|
-
QString complete = string + rest;
|
|
131
|
-
if (string.endsWith(first)) {
|
|
132
|
-
returnOnExistence(complete);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// check for the name in parent namespaces
|
|
138
|
-
QStringList nspace = this->nspace;
|
|
139
|
-
do {
|
|
140
|
-
nspace.push_back(name);
|
|
141
|
-
QString n = nspace.join("::");
|
|
142
|
-
returnOnExistence(n);
|
|
143
|
-
nspace.pop_back();
|
|
144
|
-
if (!nspace.isEmpty())
|
|
145
|
-
nspace.pop_back();
|
|
146
|
-
} while (!nspace.isEmpty());
|
|
147
|
-
|
|
148
|
-
// check for nested classes
|
|
149
|
-
for (int i = klass.count() - 1; i >= 0; i--) {
|
|
150
|
-
QString _name = klass[i]->toString() + "::" + name;
|
|
151
|
-
returnOnExistence(_name);
|
|
152
|
-
BasicTypeDeclaration* decl = resolveTypeInSuperClasses(klass[i], name);
|
|
153
|
-
if (decl)
|
|
154
|
-
return decl;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// maybe it's just 'there'
|
|
158
|
-
returnOnExistence(name);
|
|
159
|
-
|
|
160
|
-
// check for the name in any of the namespaces included by 'using namespace'
|
|
161
|
-
foreach (const QStringList& list, usingNamespaces) {
|
|
162
|
-
foreach (const QString& string, list) {
|
|
163
|
-
QString cname = string + "::" + name;
|
|
164
|
-
returnOnExistence(cname);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
QStringList parts = name.split("::");
|
|
169
|
-
if (parts.count() > 1) {
|
|
170
|
-
// try to resolve the first part - if that works simply append the last part.
|
|
171
|
-
BasicTypeDeclaration* decl = resolveType(parts.takeFirst());
|
|
172
|
-
if (!decl)
|
|
173
|
-
return 0;
|
|
174
|
-
parts.prepend(decl->toString());
|
|
175
|
-
name = parts.join("::");
|
|
176
|
-
returnOnExistence(name);
|
|
177
|
-
} else {
|
|
178
|
-
// maybe it's an enum value (as used for template args in phonon)
|
|
179
|
-
|
|
180
|
-
// look through all the enums of the parent classes
|
|
181
|
-
if (!klass.isEmpty()) {
|
|
182
|
-
const Class* clazz = klass.top();
|
|
183
|
-
while (clazz) {
|
|
184
|
-
foreach (BasicTypeDeclaration* decl, klass.top()->children()) {
|
|
185
|
-
Enum* e = 0;
|
|
186
|
-
if (!(e = dynamic_cast<Enum*>(decl)))
|
|
187
|
-
continue;
|
|
188
|
-
foreach (const EnumMember& member, e->members()) {
|
|
189
|
-
if (member.name() == name) {
|
|
190
|
-
name.prepend(klass.top()->toString() + "::");
|
|
191
|
-
return 0;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
clazz = clazz->parent();
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// look through all global enums in our namespace
|
|
200
|
-
QStringList nspace = this->nspace;
|
|
201
|
-
do {
|
|
202
|
-
QString n = nspace.join("::");
|
|
203
|
-
foreach (const Enum& e, enums.values()) {
|
|
204
|
-
if (e.parent())
|
|
205
|
-
continue;
|
|
206
|
-
|
|
207
|
-
if (e.nameSpace() == n) {
|
|
208
|
-
foreach (const EnumMember& member, e.members()) {
|
|
209
|
-
if (member.name() == name) {
|
|
210
|
-
name.prepend(n + "::");
|
|
211
|
-
return 0;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
if (!nspace.isEmpty())
|
|
217
|
-
nspace.pop_back();
|
|
218
|
-
} while (!nspace.isEmpty());
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
return 0;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
QString GeneratorVisitor::resolveEnumMember(const QString& name)
|
|
225
|
-
{
|
|
226
|
-
QString parent, member;
|
|
227
|
-
int idx = -1;
|
|
228
|
-
if ((idx = name.lastIndexOf("::")) != -1) {
|
|
229
|
-
parent = name.mid(0, idx);
|
|
230
|
-
member = name.mid(idx + 2);
|
|
231
|
-
} else {
|
|
232
|
-
member = name;
|
|
233
|
-
}
|
|
234
|
-
return resolveEnumMember(parent, member);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// TODO: This doesn't look for the enum in superclasses and parent classes yet - but it suffices for the moment.
|
|
238
|
-
QString GeneratorVisitor::resolveEnumMember(const QString& parent, const QString& name)
|
|
239
|
-
{
|
|
240
|
-
// is 'parent' a know class?
|
|
241
|
-
if (!parent.isEmpty()) {
|
|
242
|
-
BasicTypeDeclaration* decl = resolveType(parent);
|
|
243
|
-
if (decl)
|
|
244
|
-
return decl->toString() + "::" + name;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
// doesn't seem to be a class, so it's probably a part of a namespace name
|
|
248
|
-
QStringList nspace = this->nspace;
|
|
249
|
-
do {
|
|
250
|
-
QString n = nspace.join("::");
|
|
251
|
-
if (!n.isEmpty() && !parent.isEmpty()) n += "::";
|
|
252
|
-
n += parent;
|
|
253
|
-
|
|
254
|
-
foreach (const Enum& e, enums.values()) {
|
|
255
|
-
if (e.parent())
|
|
256
|
-
continue;
|
|
257
|
-
|
|
258
|
-
if (e.nameSpace() == n) {
|
|
259
|
-
foreach (const EnumMember& member, e.members()) {
|
|
260
|
-
if (member.name() == name) {
|
|
261
|
-
QString ret = n;
|
|
262
|
-
if (!ret.isEmpty())
|
|
263
|
-
ret += "::";
|
|
264
|
-
return ret + name;
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
if (!nspace.isEmpty())
|
|
271
|
-
nspace.pop_back();
|
|
272
|
-
} while (!nspace.isEmpty());
|
|
273
|
-
|
|
274
|
-
QStack<Class*> parentStack = klass;
|
|
275
|
-
while (!parentStack.isEmpty()) {
|
|
276
|
-
const Class* clazz = parentStack.pop();
|
|
277
|
-
foreach (const BasicTypeDeclaration* decl, clazz->children()) {
|
|
278
|
-
const Enum *e = 0;
|
|
279
|
-
if (!(e = dynamic_cast<const Enum*>(decl)))
|
|
280
|
-
continue;
|
|
281
|
-
foreach (const EnumMember& member, e->members()) {
|
|
282
|
-
if (member.name() == name) {
|
|
283
|
-
return clazz->toString() + "::" + name;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
return QString();
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
#undef returnOnExistence
|
|
293
|
-
|
|
294
|
-
void GeneratorVisitor::visitAccessSpecifier(AccessSpecifierAST* node)
|
|
295
|
-
{
|
|
296
|
-
static bool oldResolveTypedefs = ParserOptions::resolveTypedefs;
|
|
297
|
-
|
|
298
|
-
if (!inClass) {
|
|
299
|
-
DefaultVisitor::visitAccessSpecifier(node);
|
|
300
|
-
return;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
inSignals.top() = false;
|
|
304
|
-
inSlots.top() = false;
|
|
305
|
-
ParserOptions::resolveTypedefs = oldResolveTypedefs;
|
|
306
|
-
|
|
307
|
-
const ListNode<std::size_t> *it = node->specs->toFront(), *end = it;
|
|
308
|
-
do {
|
|
309
|
-
if (it->element) {
|
|
310
|
-
const Token& t = token(it->element);
|
|
311
|
-
if (t.kind == Token_public)
|
|
312
|
-
access.top() = Access_public;
|
|
313
|
-
else if (t.kind == Token_protected)
|
|
314
|
-
access.top() = Access_protected;
|
|
315
|
-
else if (t.kind == Token_private)
|
|
316
|
-
access.top() = Access_private;
|
|
317
|
-
|
|
318
|
-
// signal/slot handling; don't resolve typedefs in signals and slots
|
|
319
|
-
if (t.kind == Token_signals) {
|
|
320
|
-
access.top() = Access_protected;
|
|
321
|
-
inSignals.top() = true;
|
|
322
|
-
ParserOptions::resolveTypedefs = false;
|
|
323
|
-
} else if (t.kind == Token_slots) {
|
|
324
|
-
inSlots.top() = true;
|
|
325
|
-
ParserOptions::resolveTypedefs = false;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
it = it->next;
|
|
329
|
-
} while (end != it);
|
|
330
|
-
DefaultVisitor::visitAccessSpecifier(node);
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
void GeneratorVisitor::visitBaseSpecifier(BaseSpecifierAST* node)
|
|
334
|
-
{
|
|
335
|
-
Class::BaseClassSpecifier baseClass;
|
|
336
|
-
int _kind = token(node->access_specifier).kind;
|
|
337
|
-
if (_kind == Token_public) {
|
|
338
|
-
baseClass.access = Access_public;
|
|
339
|
-
} else if (_kind == Token_protected) {
|
|
340
|
-
baseClass.access = Access_protected;
|
|
341
|
-
} else {
|
|
342
|
-
baseClass.access = Access_private;
|
|
343
|
-
}
|
|
344
|
-
baseClass.isVirtual = (node->virt > 0);
|
|
345
|
-
nc->run(node->name);
|
|
346
|
-
BasicTypeDeclaration* base = resolveType(nc->qualifiedName().join("::"));
|
|
347
|
-
if (!base)
|
|
348
|
-
return;
|
|
349
|
-
Class* bptr = dynamic_cast<Class*>(base);
|
|
350
|
-
if (!bptr) {
|
|
351
|
-
Typedef* tdef = dynamic_cast<Typedef*>(base);
|
|
352
|
-
if (!tdef)
|
|
353
|
-
return;
|
|
354
|
-
bptr = tdef->resolve().getClass();
|
|
355
|
-
if (!bptr)
|
|
356
|
-
return;
|
|
357
|
-
}
|
|
358
|
-
baseClass.baseClass = bptr;
|
|
359
|
-
klass.top()->appendBaseClass(baseClass);
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
void GeneratorVisitor::visitClassSpecifier(ClassSpecifierAST* node)
|
|
363
|
-
{
|
|
364
|
-
if (klass.isEmpty())
|
|
365
|
-
return;
|
|
366
|
-
|
|
367
|
-
if (kind == Class::Kind_Class)
|
|
368
|
-
access.push(Access_private);
|
|
369
|
-
else
|
|
370
|
-
access.push(Access_public);
|
|
371
|
-
inSignals.push(false);
|
|
372
|
-
inSlots.push(false);
|
|
373
|
-
inClass++;
|
|
374
|
-
q_properties.push(QList<QProperty>());
|
|
375
|
-
|
|
376
|
-
klass.top()->setFileName(m_header);
|
|
377
|
-
klass.top()->setIsForwardDecl(false);
|
|
378
|
-
if (klass.count() > 1) {
|
|
379
|
-
// get the element before the last element, which is the parent
|
|
380
|
-
Class* parent = klass[klass.count() - 2];
|
|
381
|
-
parent->appendChild(klass.top());
|
|
382
|
-
}
|
|
383
|
-
DefaultVisitor::visitClassSpecifier(node);
|
|
384
|
-
q_properties.pop();
|
|
385
|
-
access.pop();
|
|
386
|
-
inSignals.pop();
|
|
387
|
-
inSlots.pop();
|
|
388
|
-
inClass--;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
// defined later on
|
|
392
|
-
static bool operator==(const Method& rhs, const Method& lhs);
|
|
393
|
-
|
|
394
|
-
void GeneratorVisitor::visitDeclarator(DeclaratorAST* node)
|
|
395
|
-
{
|
|
396
|
-
// TODO: get rid of this and add a proper typdef
|
|
397
|
-
bool typeCreated = false;
|
|
398
|
-
if (createType) {
|
|
399
|
-
// run it again on the list of pointer operators to add them to the type
|
|
400
|
-
tc->run(node);
|
|
401
|
-
currentType = tc->type();
|
|
402
|
-
currentTypeRef = Type::registerType(currentType);
|
|
403
|
-
createType = false;
|
|
404
|
-
typeCreated = true;
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
if (currentType.isFunctionPointer() && node->sub_declarator)
|
|
408
|
-
nc->run(node->sub_declarator->id);
|
|
409
|
-
else
|
|
410
|
-
nc->run(node->id);
|
|
411
|
-
const QString declName = nc->name();
|
|
412
|
-
|
|
413
|
-
if (createTypedef) {
|
|
414
|
-
if (!typeCreated)
|
|
415
|
-
return;
|
|
416
|
-
// we've just created the type that the typedef points to
|
|
417
|
-
// so we just need to get the new name and store it
|
|
418
|
-
Class* parent = klass.isEmpty() ? 0 : klass.top();
|
|
419
|
-
Typedef tdef = Typedef(currentTypeRef, declName, nspace.join("::"), parent);
|
|
420
|
-
tdef.setFileName(m_header);
|
|
421
|
-
QString name = tdef.toString();
|
|
422
|
-
if (!typedefs.contains(name)) {
|
|
423
|
-
QHash<QString, Typedef>::iterator it = typedefs.insert(name, tdef);
|
|
424
|
-
if (parent)
|
|
425
|
-
parent->appendChild(&it.value());
|
|
426
|
-
}
|
|
427
|
-
createTypedef = false;
|
|
428
|
-
return;
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
// we don't care about methods with ellipsis paramaters (i.e. 'foo(const char*, ...)') for now..
|
|
432
|
-
if (node->parameter_declaration_clause && node->parameter_declaration_clause->ellipsis)
|
|
433
|
-
return;
|
|
434
|
-
|
|
435
|
-
// only run this if we're not in a method. only checking for parameter_declaration_clause
|
|
436
|
-
// won't be enough because function pointer types also have that.
|
|
437
|
-
if (node->parameter_declaration_clause && !inMethod && inClass) {
|
|
438
|
-
// detect Q_PROPERTIES
|
|
439
|
-
if (ParserOptions::qtMode && declName == "__q_property") {
|
|
440
|
-
// this should _always_ work
|
|
441
|
-
PrimaryExpressionAST* primary = ast_cast<PrimaryExpressionAST*>(node->parameter_declaration_clause->parameter_declarations->at(0)->element->expression);
|
|
442
|
-
QByteArray literals;
|
|
443
|
-
const ListNode<std::size_t> *it = primary->literal->literals->toFront(), *end = it;
|
|
444
|
-
do {
|
|
445
|
-
if (it->element) {
|
|
446
|
-
literals.append(token(it->element).symbolByteArray());
|
|
447
|
-
}
|
|
448
|
-
it = it->next;
|
|
449
|
-
} while (end != it);
|
|
450
|
-
literals.replace("\"", "");
|
|
451
|
-
// this monster only matches "type name READ getMethod WRITE setMethod"
|
|
452
|
-
static QRegExp regexp("^([\\w:<>\\*]+)\\s+(\\w+)\\s+READ\\s+(\\w+)(\\s+WRITE\\s+\\w+)?");
|
|
453
|
-
static QRegExp typePtr(".*\\*$");
|
|
454
|
-
if (regexp.indexIn(literals) != -1) {
|
|
455
|
-
QProperty prop = { QMetaObject::normalizedType(regexp.cap(1).toLatin1()), (typePtr.indexIn(regexp.cap(1)) != -1), regexp.cap(2),
|
|
456
|
-
regexp.cap(3), regexp.cap(4).replace(QRegExp("\\s+WRITE\\s+"), QString()) };
|
|
457
|
-
q_properties.top().append(prop);
|
|
458
|
-
}
|
|
459
|
-
return;
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
bool isConstructor = (declName == klass.top()->name());
|
|
463
|
-
bool isDestructor = (declName == "~" + klass.top()->name());
|
|
464
|
-
Type* returnType = currentTypeRef;
|
|
465
|
-
if (isConstructor) {
|
|
466
|
-
// constructors return a pointer to the class they create
|
|
467
|
-
Type t(klass.top()); t.setPointerDepth(1);
|
|
468
|
-
returnType = Type::registerType(t);
|
|
469
|
-
} else if (isDestructor) {
|
|
470
|
-
// destructors don't have a return type.. so return void
|
|
471
|
-
returnType = const_cast<Type*>(Type::Void);
|
|
472
|
-
} else if (nc->isCastOperator()) {
|
|
473
|
-
returnType = Type::registerType(nc->castType());
|
|
474
|
-
}
|
|
475
|
-
currentMethod = Method(klass.top(), declName, returnType, access.top());
|
|
476
|
-
currentMethod.setIsConstructor(isConstructor);
|
|
477
|
-
currentMethod.setIsDestructor(isDestructor);
|
|
478
|
-
currentMethod.setIsSignal(inSignals.top());
|
|
479
|
-
currentMethod.setIsSlot(inSlots.top());
|
|
480
|
-
// build parameter list
|
|
481
|
-
inMethod = true;
|
|
482
|
-
visit(node->parameter_declaration_clause);
|
|
483
|
-
inMethod = false;
|
|
484
|
-
QPair<bool, bool> cv = parseCv(node->fun_cv);
|
|
485
|
-
// const & volatile modifiers
|
|
486
|
-
currentMethod.setIsConst(cv.first);
|
|
487
|
-
|
|
488
|
-
if (isVirtual) currentMethod.setFlag(Method::Virtual);
|
|
489
|
-
if (hasInitializer) currentMethod.setFlag(Method::PureVirtual);
|
|
490
|
-
if (isStatic) currentMethod.setFlag(Method::Static);
|
|
491
|
-
if (isExplicit) currentMethod.setFlag(Method::Explicit);
|
|
492
|
-
|
|
493
|
-
// the class already contains the method (probably imported by a 'using' statement)
|
|
494
|
-
if (klass.top()->methods().contains(currentMethod)) {
|
|
495
|
-
return;
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
// Q_PROPERTY accessor?
|
|
499
|
-
if (ParserOptions::qtMode) {
|
|
500
|
-
foreach (const QProperty& prop, q_properties.top()) {
|
|
501
|
-
if ( (currentMethod.parameters().count() == 0 && prop.read == currentMethod.name() && currentMethod.type()->toString().endsWith(prop.type)
|
|
502
|
-
&& (currentMethod.type()->pointerDepth() == 1) == prop.isPtr) // READ accessor?
|
|
503
|
-
|| (currentMethod.parameters().count() == 1 && prop.write == currentMethod.name()
|
|
504
|
-
&& currentMethod.parameters()[0].type()->toString().remove(QRegExp("^const ")).remove(QRegExp("\\&$")).endsWith(prop.type)
|
|
505
|
-
&& (currentMethod.parameters()[0].type()->pointerDepth() == 1) == prop.isPtr)) // or WRITE accessor?
|
|
506
|
-
{
|
|
507
|
-
currentMethod.setIsQPropertyAccessor(true);
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
if (node->exception_spec) {
|
|
513
|
-
currentMethod.setHasExceptionSpec(true);
|
|
514
|
-
if (node->exception_spec->type_ids) {
|
|
515
|
-
const ListNode<TypeIdAST*>* it = node->exception_spec->type_ids->toFront(), *end = it;
|
|
516
|
-
do {
|
|
517
|
-
tc->run(it->element->type_specifier, it->element->declarator);
|
|
518
|
-
currentMethod.appendExceptionType(tc->type());
|
|
519
|
-
it = it->next;
|
|
520
|
-
} while (it != end);
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
klass.top()->appendMethod(currentMethod);
|
|
525
|
-
return;
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
// global function
|
|
529
|
-
if (node->parameter_declaration_clause && !inMethod && !inClass) {
|
|
530
|
-
if (!declName.contains("::")) {
|
|
531
|
-
Type* returnType = currentTypeRef;
|
|
532
|
-
currentFunction = Function(declName, nspace.join("::"), returnType);
|
|
533
|
-
currentFunction.setFileName(m_header);
|
|
534
|
-
// build parameter list
|
|
535
|
-
inMethod = true;
|
|
536
|
-
visit(node->parameter_declaration_clause);
|
|
537
|
-
inMethod = false;
|
|
538
|
-
QString name = currentFunction.toString();
|
|
539
|
-
if (!functions.contains(name)) {
|
|
540
|
-
functions[name] = currentFunction;
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
return;
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
// field
|
|
547
|
-
if (!inMethod && !klass.isEmpty() && inClass) {
|
|
548
|
-
Field field = Field(klass.top(), declName, currentTypeRef, access.top());
|
|
549
|
-
if (isStatic) field.setFlag(Field::Static);
|
|
550
|
-
klass.top()->appendField(field);
|
|
551
|
-
return;
|
|
552
|
-
} else if (!inMethod && !inClass) {
|
|
553
|
-
// global variable
|
|
554
|
-
if (!globals.contains(declName)) {
|
|
555
|
-
GlobalVar var = GlobalVar(declName, nspace.join("::"), currentTypeRef);
|
|
556
|
-
var.setFileName(m_header);
|
|
557
|
-
globals[var.name()] = var;
|
|
558
|
-
}
|
|
559
|
-
return;
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
void GeneratorVisitor::visitElaboratedTypeSpecifier(ElaboratedTypeSpecifierAST* node)
|
|
564
|
-
{
|
|
565
|
-
tc->run(node);
|
|
566
|
-
createType = true;
|
|
567
|
-
DefaultVisitor::visitElaboratedTypeSpecifier(node);
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
void GeneratorVisitor::visitEnumSpecifier(EnumSpecifierAST* node)
|
|
571
|
-
{
|
|
572
|
-
nc->run(node->name);
|
|
573
|
-
Class* parent = klass.isEmpty() ? 0 : klass.top();
|
|
574
|
-
currentEnum = Enum(nc->name(), nspace.join("::"), parent);
|
|
575
|
-
Access a = (access.isEmpty() ? Access_public : access.top());
|
|
576
|
-
currentEnum.setAccess(a);
|
|
577
|
-
currentEnum.setFileName(m_header);
|
|
578
|
-
QHash<QString, Enum>::iterator it = enums.insert(currentEnum.toString(), currentEnum);
|
|
579
|
-
currentEnumRef = &it.value();
|
|
580
|
-
visitNodes(this, node->enumerators);
|
|
581
|
-
if (parent)
|
|
582
|
-
parent->appendChild(currentEnumRef);
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
void GeneratorVisitor::visitEnumerator(EnumeratorAST* node)
|
|
586
|
-
{
|
|
587
|
-
currentEnumRef->appendMember(EnumMember(currentEnumRef, token(node->id).symbolString(), QString()));
|
|
588
|
-
// DefaultVisitor::visitEnumerator(node);
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
void GeneratorVisitor::visitFunctionDefinition(FunctionDefinitionAST* node)
|
|
592
|
-
{
|
|
593
|
-
visit(node->type_specifier);
|
|
594
|
-
if (node->function_specifiers) {
|
|
595
|
-
const ListNode<std::size_t> *it = node->function_specifiers->toFront(), *end = it;
|
|
596
|
-
do {
|
|
597
|
-
if (it->element && m_session->token_stream->kind(it->element) == Token_virtual) {
|
|
598
|
-
// found virtual token
|
|
599
|
-
isVirtual = true;
|
|
600
|
-
} else if (it->element && m_session->token_stream->kind(it->element) == Token_explicit) {
|
|
601
|
-
isExplicit = true;
|
|
602
|
-
}
|
|
603
|
-
it = it->next;
|
|
604
|
-
} while (end != it);
|
|
605
|
-
}
|
|
606
|
-
if (node->storage_specifiers) {
|
|
607
|
-
const ListNode<std::size_t> *it = node->storage_specifiers->toFront(), *end = it;
|
|
608
|
-
do {
|
|
609
|
-
if (it->element && m_session->token_stream->kind(it->element) == Token_static) {
|
|
610
|
-
isStatic = true;
|
|
611
|
-
} else if (it->element && m_session->token_stream->kind(it->element) == Token_friend) {
|
|
612
|
-
// we're not interested in who's the friend of whom ;)
|
|
613
|
-
return;
|
|
614
|
-
}
|
|
615
|
-
it = it->next;
|
|
616
|
-
} while (end != it);
|
|
617
|
-
}
|
|
618
|
-
visit(node->init_declarator);
|
|
619
|
-
isStatic = isVirtual = isExplicit = hasInitializer = false;
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
void GeneratorVisitor::visitInitializerClause(InitializerClauseAST *)
|
|
623
|
-
{
|
|
624
|
-
// we don't care about initializers
|
|
625
|
-
return;
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
void GeneratorVisitor::visitNamespace(NamespaceAST* node)
|
|
629
|
-
{
|
|
630
|
-
usingTypes.push(QStringList());
|
|
631
|
-
usingNamespaces.push(QStringList());
|
|
632
|
-
|
|
633
|
-
QString name = token(node->namespace_name).symbolString();
|
|
634
|
-
nspace.push_back(name);
|
|
635
|
-
DefaultVisitor::visitNamespace(node);
|
|
636
|
-
nspace.pop_back();
|
|
637
|
-
// using directives in that namespace aren't interesting anymore :)
|
|
638
|
-
usingTypes.pop();
|
|
639
|
-
usingNamespaces.pop();
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
void GeneratorVisitor::visitParameterDeclaration(ParameterDeclarationAST* node)
|
|
643
|
-
{
|
|
644
|
-
tc->run(node->type_specifier);
|
|
645
|
-
QString name;
|
|
646
|
-
if (node->declarator) {
|
|
647
|
-
tc->run(node->declarator);
|
|
648
|
-
if (currentType.isFunctionPointer() && node->declarator->sub_declarator)
|
|
649
|
-
nc->run(node->declarator->sub_declarator->id);
|
|
650
|
-
else
|
|
651
|
-
nc->run(node->declarator->id);
|
|
652
|
-
name = nc->name();
|
|
653
|
-
}
|
|
654
|
-
currentType = tc->type();
|
|
655
|
-
currentTypeRef = Type::registerType(currentType);
|
|
656
|
-
|
|
657
|
-
// foo(void) is the same as foo()
|
|
658
|
-
if (currentTypeRef == Type::Void)
|
|
659
|
-
return;
|
|
660
|
-
|
|
661
|
-
QString defaultValue;
|
|
662
|
-
if (node->expression) {
|
|
663
|
-
// this parameter has a default value
|
|
664
|
-
ExpressionAST* expression = node->expression;
|
|
665
|
-
|
|
666
|
-
PostfixExpressionAST* postfix = 0;
|
|
667
|
-
PrimaryExpressionAST* primary = 0;
|
|
668
|
-
if ((postfix = ast_cast<PostfixExpressionAST*>(node->expression))
|
|
669
|
-
&& (postfix->sub_expressions->count() == 1
|
|
670
|
-
&& postfix->sub_expressions->at(0)->element->kind == AST::Kind_FunctionCall))
|
|
671
|
-
{
|
|
672
|
-
// We have a function call expression as default value, most probably something like 'const QString& foo = QString()'.
|
|
673
|
-
// Try to resolve the classname if it's a constructor call.
|
|
674
|
-
PrimaryExpressionAST* primary = ast_cast<PrimaryExpressionAST*>(postfix->expression);
|
|
675
|
-
expression = postfix->sub_expressions->at(0)->element;
|
|
676
|
-
|
|
677
|
-
nc->run(primary->name);
|
|
678
|
-
QStringList className = nc->qualifiedName();
|
|
679
|
-
BasicTypeDeclaration* decl = resolveType(className.join("::"));
|
|
680
|
-
if (decl)
|
|
681
|
-
className = decl->toString().split("::");
|
|
682
|
-
|
|
683
|
-
if (!decl && className.count() > 1) {
|
|
684
|
-
// Resolving failed, so this might also be a some static method (like Cursor::start() in KTextEditor).
|
|
685
|
-
// Pop the last element (probably the method name) and resolve the rest.
|
|
686
|
-
QString last = className.takeLast();
|
|
687
|
-
BasicTypeDeclaration* decl = resolveType(className.join("::"));
|
|
688
|
-
if (decl)
|
|
689
|
-
className = decl->toString().split("::");
|
|
690
|
-
className.append(last);
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
QMap<int, QList<Type> > map = nc->templateArguments();
|
|
694
|
-
for (QMap<int, QList<Type> >::const_iterator it = map.begin(); it != map.end(); it++) {
|
|
695
|
-
QString str("< ");
|
|
696
|
-
for (int i = 0; i < it.value().count(); i++) {
|
|
697
|
-
if (i > 0) str.append(',');
|
|
698
|
-
str.append(it.value()[i].toString());
|
|
699
|
-
}
|
|
700
|
-
str.append(" >");
|
|
701
|
-
className[it.key()].append(str);
|
|
702
|
-
}
|
|
703
|
-
defaultValue.append(className.join("::"));
|
|
704
|
-
} else if ((primary = ast_cast<PrimaryExpressionAST*>(node->expression))) {
|
|
705
|
-
if (primary->name) {
|
|
706
|
-
// don't build the default value twice
|
|
707
|
-
expression = 0;
|
|
708
|
-
// enum - try to resolve that
|
|
709
|
-
nc->run(primary->name);
|
|
710
|
-
|
|
711
|
-
QString name;
|
|
712
|
-
// build the name of the containing class/namespace
|
|
713
|
-
for (int i = 0; i < nc->qualifiedName().count() - 1; i++) {
|
|
714
|
-
if (i > 0) name.append("::");
|
|
715
|
-
name.append(nc->qualifiedName()[i]);
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
defaultValue = resolveEnumMember(name, nc->qualifiedName().last());
|
|
719
|
-
if (defaultValue.isEmpty()) {
|
|
720
|
-
defaultValue = nc->qualifiedName().join("::");
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
if (expression) {
|
|
726
|
-
for (int i = expression->start_token; i < expression->end_token; i++)
|
|
727
|
-
defaultValue.append(token(i).symbolByteArray());
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
if (inClass)
|
|
731
|
-
currentMethod.appendParameter(Parameter(name, currentTypeRef, defaultValue));
|
|
732
|
-
else
|
|
733
|
-
currentFunction.appendParameter(Parameter(name, currentTypeRef, defaultValue));
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
void GeneratorVisitor::visitSimpleDeclaration(SimpleDeclarationAST* node)
|
|
737
|
-
{
|
|
738
|
-
bool popKlass = false;
|
|
739
|
-
int _kind = token(node->start_token).kind;
|
|
740
|
-
if (_kind == Token_class) {
|
|
741
|
-
kind = Class::Kind_Class;
|
|
742
|
-
} else if (_kind == Token_struct) {
|
|
743
|
-
kind = Class::Kind_Struct;
|
|
744
|
-
}
|
|
745
|
-
if (_kind == Token_class || _kind == Token_struct) {
|
|
746
|
-
tc->run(node->type_specifier);
|
|
747
|
-
if (tc->qualifiedName().isEmpty()) return;
|
|
748
|
-
// for nested classes
|
|
749
|
-
Class* parent = klass.isEmpty() ? 0 : klass.top();
|
|
750
|
-
Class _class = Class(tc->qualifiedName().last(), nspace.join("::"), parent, kind);
|
|
751
|
-
Access a = (access.isEmpty() ? Access_public : access.top());
|
|
752
|
-
_class.setAccess(a);
|
|
753
|
-
QString name = _class.toString();
|
|
754
|
-
// This class has already been parsed.
|
|
755
|
-
if (classes.contains(name) && !classes[name].isForwardDecl())
|
|
756
|
-
return;
|
|
757
|
-
QHash<QString, Class>::iterator item = classes.insert(name, _class);
|
|
758
|
-
if (inTemplate) {
|
|
759
|
-
item.value().setIsTemplate(true);
|
|
760
|
-
return;
|
|
761
|
-
}
|
|
762
|
-
klass.push(&item.value());
|
|
763
|
-
popKlass = true;
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
if (node->function_specifiers) {
|
|
767
|
-
const ListNode<std::size_t> *it = node->function_specifiers->toFront(), *end = it;
|
|
768
|
-
do {
|
|
769
|
-
if (it->element && m_session->token_stream->kind(it->element) == Token_virtual) {
|
|
770
|
-
// found virtual token
|
|
771
|
-
isVirtual = true;
|
|
772
|
-
break;
|
|
773
|
-
}
|
|
774
|
-
it = it->next;
|
|
775
|
-
} while (end != it);
|
|
776
|
-
}
|
|
777
|
-
// look for initializers - if we find one, the method is pure virtual
|
|
778
|
-
if (node->init_declarators) {
|
|
779
|
-
const ListNode<InitDeclaratorAST*> *it = node->init_declarators->toFront(), *end = it;
|
|
780
|
-
do {
|
|
781
|
-
if (it->element && it->element->initializer) {
|
|
782
|
-
hasInitializer = true;
|
|
783
|
-
}
|
|
784
|
-
if (it->element && it->element->declarator && it->element->declarator->parameter_declaration_clause) {
|
|
785
|
-
if (popKlass) {
|
|
786
|
-
// This method return type has 'class' or 'struct' prepended to avoid a forward declaration.
|
|
787
|
-
// example: 'class KMultiTabBarTab *tab(...)'
|
|
788
|
-
QString oldClass = klass.top()->toString();
|
|
789
|
-
klass.top()->setParent(0);
|
|
790
|
-
klass.top()->setNameSpace(QString());
|
|
791
|
-
classes.insert(klass.top()->toString(), *klass.top());
|
|
792
|
-
classes.remove(oldClass);
|
|
793
|
-
klass.pop();
|
|
794
|
-
popKlass = false;
|
|
795
|
-
}
|
|
796
|
-
}
|
|
797
|
-
it = it->next;
|
|
798
|
-
} while (end != it);
|
|
799
|
-
}
|
|
800
|
-
if (node->storage_specifiers) {
|
|
801
|
-
const ListNode<std::size_t> *it = node->storage_specifiers->toFront(), *end = it;
|
|
802
|
-
do {
|
|
803
|
-
if (it->element && m_session->token_stream->kind(it->element) == Token_static) {
|
|
804
|
-
isStatic = true;
|
|
805
|
-
} else if (it->element && m_session->token_stream->kind(it->element) == Token_friend) {
|
|
806
|
-
// we're not interested in who's the friend of whom ;)
|
|
807
|
-
if (popKlass)
|
|
808
|
-
klass.pop();
|
|
809
|
-
isStatic = isVirtual = hasInitializer = false;
|
|
810
|
-
return;
|
|
811
|
-
}
|
|
812
|
-
it = it->next;
|
|
813
|
-
} while (end != it);
|
|
814
|
-
}
|
|
815
|
-
DefaultVisitor::visitSimpleDeclaration(node);
|
|
816
|
-
if (popKlass)
|
|
817
|
-
klass.pop();
|
|
818
|
-
isStatic = isVirtual = hasInitializer = false;
|
|
819
|
-
}
|
|
820
|
-
|
|
821
|
-
void GeneratorVisitor::visitSimpleTypeSpecifier(SimpleTypeSpecifierAST* node)
|
|
822
|
-
{
|
|
823
|
-
// first run on the type specifier to get the name of the type
|
|
824
|
-
tc->run(node);
|
|
825
|
-
createType = true;
|
|
826
|
-
DefaultVisitor::visitSimpleTypeSpecifier(node);
|
|
827
|
-
}
|
|
828
|
-
|
|
829
|
-
void GeneratorVisitor::visitTemplateDeclaration(TemplateDeclarationAST* node)
|
|
830
|
-
{
|
|
831
|
-
if (!node->declaration)
|
|
832
|
-
return;
|
|
833
|
-
int kind = token(node->declaration->start_token).kind;
|
|
834
|
-
if (kind == Token_class || kind == Token_struct) {
|
|
835
|
-
inTemplate = true;
|
|
836
|
-
visit(node->declaration);
|
|
837
|
-
inTemplate = false;
|
|
838
|
-
}
|
|
839
|
-
// skip template declarations
|
|
840
|
-
return;
|
|
841
|
-
}
|
|
842
|
-
|
|
843
|
-
void GeneratorVisitor::visitTemplateArgument(TemplateArgumentAST* node)
|
|
844
|
-
{
|
|
845
|
-
// skip template arguments - they're handled by TypeCompiler
|
|
846
|
-
return;
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
void GeneratorVisitor::visitTypedef(TypedefAST* node)
|
|
850
|
-
{
|
|
851
|
-
createTypedef = true;
|
|
852
|
-
DefaultVisitor::visitTypedef(node);
|
|
853
|
-
|
|
854
|
-
// TODO: probably has to be extended to cover structs and classes, too
|
|
855
|
-
// makes something like 'typedef enum { Bar } Foo;' look like a proper enum.
|
|
856
|
-
if (ast_cast<EnumSpecifierAST*>(node->type_specifier)) {
|
|
857
|
-
nc->run(node->init_declarators->at(0)->element->declarator->id);
|
|
858
|
-
currentEnumRef->setName(nc->name());
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
// don't make this public - it's just a utility function for the next method and probably not what you would expect it to be
|
|
863
|
-
static bool operator==(const Method& rhs, const Method& lhs)
|
|
864
|
-
{
|
|
865
|
-
// these have to be equal for methods to be the same
|
|
866
|
-
bool ok = (rhs.name() == lhs.name() && rhs.isConst() == lhs.isConst() &&
|
|
867
|
-
rhs.parameters().count() == lhs.parameters().count() && rhs.type() == lhs.type());
|
|
868
|
-
if (!ok)
|
|
869
|
-
return false;
|
|
870
|
-
|
|
871
|
-
// now check the parameter types for equality
|
|
872
|
-
for (int i = 0; i < rhs.parameters().count(); i++) {
|
|
873
|
-
if (rhs.parameters()[i].type() != lhs.parameters()[i].type())
|
|
874
|
-
return false;
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
return true;
|
|
878
|
-
}
|
|
879
|
-
|
|
880
|
-
void GeneratorVisitor::visitUsing(UsingAST* node)
|
|
881
|
-
{
|
|
882
|
-
nc->run(node->name);
|
|
883
|
-
if (inClass) {
|
|
884
|
-
// if we encounter 'using' in a class, it means we should import methods from another class
|
|
885
|
-
QStringList tmp = nc->qualifiedName();
|
|
886
|
-
const QString methodName = tmp.takeLast();
|
|
887
|
-
const QString className = tmp.join("::");
|
|
888
|
-
const BasicTypeDeclaration* decl = resolveType(className);
|
|
889
|
-
const Class* clazz = dynamic_cast<const Class*>(decl);
|
|
890
|
-
if (!clazz) {
|
|
891
|
-
const Typedef* tdef = dynamic_cast<const Typedef*>(decl);
|
|
892
|
-
if (tdef) {
|
|
893
|
-
clazz = tdef->resolve().getClass();
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
if (!clazz)
|
|
897
|
-
return;
|
|
898
|
-
|
|
899
|
-
foreach (const Method& meth, clazz->methods()) {
|
|
900
|
-
if (meth.name() != methodName)
|
|
901
|
-
continue;
|
|
902
|
-
|
|
903
|
-
// prevent importing of already overridden (pure) virtuals
|
|
904
|
-
if (klass.top()->methods().contains(meth))
|
|
905
|
-
continue;
|
|
906
|
-
|
|
907
|
-
Method copy = meth;
|
|
908
|
-
copy.setDeclaringType(klass.top());
|
|
909
|
-
copy.setAccess(access.top());
|
|
910
|
-
klass.top()->appendMethod(copy);
|
|
911
|
-
}
|
|
912
|
-
} else {
|
|
913
|
-
usingTypes.top() << nc->qualifiedName().join("::");
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
|
|
917
|
-
void GeneratorVisitor::visitUsingDirective(UsingDirectiveAST* node)
|
|
918
|
-
{
|
|
919
|
-
nc->run(node->name);
|
|
920
|
-
usingNamespaces.top() << nc->qualifiedName().join("::");
|
|
921
|
-
DefaultVisitor::visitUsingDirective(node);
|
|
922
|
-
}
|
|
1
|
+
/*
|
|
2
|
+
Copyright (C) 2009 Arno Rehn <arno@arnorehn.de>
|
|
3
|
+
|
|
4
|
+
This program is free software; you can redistribute it and/or modify
|
|
5
|
+
it under the terms of the GNU General Public License as published by
|
|
6
|
+
the Free Software Foundation; either version 2 of the License, or
|
|
7
|
+
(at your option) any later version.
|
|
8
|
+
|
|
9
|
+
This program is distributed in the hope that it will be useful,
|
|
10
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
GNU General Public License for more details.
|
|
13
|
+
|
|
14
|
+
You should have received a copy of the GNU General Public License along
|
|
15
|
+
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
16
|
+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
#include <ast.h>
|
|
20
|
+
#include <tokens.h>
|
|
21
|
+
#include "name_compiler.h"
|
|
22
|
+
#include "type_compiler.h"
|
|
23
|
+
|
|
24
|
+
#include "generatorvisitor.h"
|
|
25
|
+
#include "options.h"
|
|
26
|
+
|
|
27
|
+
#include <QtDebug>
|
|
28
|
+
|
|
29
|
+
GeneratorVisitor::GeneratorVisitor(ParseSession *session, const QString& header)
|
|
30
|
+
: m_session(session), m_header(header), createType(false), createTypedef(false),
|
|
31
|
+
inClass(0), inTemplate(false), isStatic(false), isVirtual(false), isExplicit(false), hasInitializer(false), currentTypeRef(0), inMethod(false)
|
|
32
|
+
{
|
|
33
|
+
nc = new NameCompiler(m_session, this);
|
|
34
|
+
tc = new TypeCompiler(m_session, this);
|
|
35
|
+
|
|
36
|
+
usingTypes.push(QStringList());
|
|
37
|
+
usingNamespaces.push(QStringList());
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
GeneratorVisitor::~GeneratorVisitor()
|
|
41
|
+
{
|
|
42
|
+
delete nc;
|
|
43
|
+
delete tc;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
QPair<bool, bool> GeneratorVisitor::parseCv(const ListNode<std::size_t> *cv)
|
|
47
|
+
{
|
|
48
|
+
QPair<bool, bool> ret(false, false);
|
|
49
|
+
if (!cv) return ret;
|
|
50
|
+
const ListNode<std::size_t> *it = cv->toFront(), *end = it;
|
|
51
|
+
do {
|
|
52
|
+
if (it->element) {
|
|
53
|
+
int _kind = m_session->token_stream->kind(it->element);
|
|
54
|
+
if (_kind == Token_const)
|
|
55
|
+
ret.first = true;
|
|
56
|
+
else if (_kind == Token_volatile)
|
|
57
|
+
ret.second = true;
|
|
58
|
+
}
|
|
59
|
+
it = it->next;
|
|
60
|
+
} while (end != it);
|
|
61
|
+
return ret;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
#define returnOnExistence(name) \
|
|
65
|
+
if (classes.contains(name)) { \
|
|
66
|
+
return &classes[name]; \
|
|
67
|
+
} else if (typedefs.contains(name)) { \
|
|
68
|
+
return &typedefs[name]; \
|
|
69
|
+
} else if (enums.contains(name)) { \
|
|
70
|
+
return &enums[name]; \
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
BasicTypeDeclaration* GeneratorVisitor::resolveTypeInSuperClasses(const Class* klass, const QString& name)
|
|
74
|
+
{
|
|
75
|
+
foreach (const Class::BaseClassSpecifier& bclass, klass->baseClasses()) {
|
|
76
|
+
QString _name = bclass.baseClass->toString() + "::" + name;
|
|
77
|
+
returnOnExistence(_name);
|
|
78
|
+
QStringList nspace = klass->nameSpace().split("::");
|
|
79
|
+
if (!klass->nameSpace().isEmpty() && nspace != this->nspace) {
|
|
80
|
+
do {
|
|
81
|
+
nspace.push_back(name);
|
|
82
|
+
QString n = nspace.join("::");
|
|
83
|
+
returnOnExistence(n);
|
|
84
|
+
nspace.pop_back();
|
|
85
|
+
if (!nspace.isEmpty())
|
|
86
|
+
nspace.pop_back();
|
|
87
|
+
} while (!nspace.isEmpty());
|
|
88
|
+
}
|
|
89
|
+
if (!bclass.baseClass->baseClasses().count())
|
|
90
|
+
continue;
|
|
91
|
+
BasicTypeDeclaration* decl = resolveTypeInSuperClasses(bclass.baseClass, name);
|
|
92
|
+
if (decl)
|
|
93
|
+
return decl;
|
|
94
|
+
}
|
|
95
|
+
return 0;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
BasicTypeDeclaration* GeneratorVisitor::resolveType(const QString & name)
|
|
99
|
+
{
|
|
100
|
+
QString _name = name;
|
|
101
|
+
return resolveType(_name);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// TODO: this might have to be improved for cases like 'Typedef::Nested foo'
|
|
105
|
+
BasicTypeDeclaration* GeneratorVisitor::resolveType(QString & name)
|
|
106
|
+
{
|
|
107
|
+
if (ParserOptions::qtMode && name.endsWith("::enum_type")) {
|
|
108
|
+
// strip off "::enum_type"
|
|
109
|
+
QString flags = name.left(name.length() - 11);
|
|
110
|
+
QHash<QString, Typedef>::iterator it = typedefs.find(flags);
|
|
111
|
+
if (it != typedefs.end()) {
|
|
112
|
+
QString enumType = it.value().resolve().toString().replace(QRegExp("QFlags<(.*)>"), "\\1");
|
|
113
|
+
QHash<QString, Enum>::iterator it = enums.find(enumType);
|
|
114
|
+
if (it != enums.end()) {
|
|
115
|
+
return &it.value();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// check for 'using type;'
|
|
121
|
+
// if we use 'type', we can also access type::nested, take care of that
|
|
122
|
+
int index = name.indexOf("::");
|
|
123
|
+
QString first = name, rest;
|
|
124
|
+
if (index > -1) {
|
|
125
|
+
first = name.mid(0, index);
|
|
126
|
+
rest = name.mid(index);
|
|
127
|
+
}
|
|
128
|
+
foreach (const QStringList& list, usingTypes) {
|
|
129
|
+
foreach (const QString& string, list) {
|
|
130
|
+
QString complete = string + rest;
|
|
131
|
+
if (string.endsWith(first)) {
|
|
132
|
+
returnOnExistence(complete);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// check for the name in parent namespaces
|
|
138
|
+
QStringList nspace = this->nspace;
|
|
139
|
+
do {
|
|
140
|
+
nspace.push_back(name);
|
|
141
|
+
QString n = nspace.join("::");
|
|
142
|
+
returnOnExistence(n);
|
|
143
|
+
nspace.pop_back();
|
|
144
|
+
if (!nspace.isEmpty())
|
|
145
|
+
nspace.pop_back();
|
|
146
|
+
} while (!nspace.isEmpty());
|
|
147
|
+
|
|
148
|
+
// check for nested classes
|
|
149
|
+
for (int i = klass.count() - 1; i >= 0; i--) {
|
|
150
|
+
QString _name = klass[i]->toString() + "::" + name;
|
|
151
|
+
returnOnExistence(_name);
|
|
152
|
+
BasicTypeDeclaration* decl = resolveTypeInSuperClasses(klass[i], name);
|
|
153
|
+
if (decl)
|
|
154
|
+
return decl;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// maybe it's just 'there'
|
|
158
|
+
returnOnExistence(name);
|
|
159
|
+
|
|
160
|
+
// check for the name in any of the namespaces included by 'using namespace'
|
|
161
|
+
foreach (const QStringList& list, usingNamespaces) {
|
|
162
|
+
foreach (const QString& string, list) {
|
|
163
|
+
QString cname = string + "::" + name;
|
|
164
|
+
returnOnExistence(cname);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
QStringList parts = name.split("::");
|
|
169
|
+
if (parts.count() > 1) {
|
|
170
|
+
// try to resolve the first part - if that works simply append the last part.
|
|
171
|
+
BasicTypeDeclaration* decl = resolveType(parts.takeFirst());
|
|
172
|
+
if (!decl)
|
|
173
|
+
return 0;
|
|
174
|
+
parts.prepend(decl->toString());
|
|
175
|
+
name = parts.join("::");
|
|
176
|
+
returnOnExistence(name);
|
|
177
|
+
} else {
|
|
178
|
+
// maybe it's an enum value (as used for template args in phonon)
|
|
179
|
+
|
|
180
|
+
// look through all the enums of the parent classes
|
|
181
|
+
if (!klass.isEmpty()) {
|
|
182
|
+
const Class* clazz = klass.top();
|
|
183
|
+
while (clazz) {
|
|
184
|
+
foreach (BasicTypeDeclaration* decl, klass.top()->children()) {
|
|
185
|
+
Enum* e = 0;
|
|
186
|
+
if (!(e = dynamic_cast<Enum*>(decl)))
|
|
187
|
+
continue;
|
|
188
|
+
foreach (const EnumMember& member, e->members()) {
|
|
189
|
+
if (member.name() == name) {
|
|
190
|
+
name.prepend(klass.top()->toString() + "::");
|
|
191
|
+
return 0;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
clazz = clazz->parent();
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// look through all global enums in our namespace
|
|
200
|
+
QStringList nspace = this->nspace;
|
|
201
|
+
do {
|
|
202
|
+
QString n = nspace.join("::");
|
|
203
|
+
foreach (const Enum& e, enums.values()) {
|
|
204
|
+
if (e.parent())
|
|
205
|
+
continue;
|
|
206
|
+
|
|
207
|
+
if (e.nameSpace() == n) {
|
|
208
|
+
foreach (const EnumMember& member, e.members()) {
|
|
209
|
+
if (member.name() == name) {
|
|
210
|
+
name.prepend(n + "::");
|
|
211
|
+
return 0;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (!nspace.isEmpty())
|
|
217
|
+
nspace.pop_back();
|
|
218
|
+
} while (!nspace.isEmpty());
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return 0;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
QString GeneratorVisitor::resolveEnumMember(const QString& name)
|
|
225
|
+
{
|
|
226
|
+
QString parent, member;
|
|
227
|
+
int idx = -1;
|
|
228
|
+
if ((idx = name.lastIndexOf("::")) != -1) {
|
|
229
|
+
parent = name.mid(0, idx);
|
|
230
|
+
member = name.mid(idx + 2);
|
|
231
|
+
} else {
|
|
232
|
+
member = name;
|
|
233
|
+
}
|
|
234
|
+
return resolveEnumMember(parent, member);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// TODO: This doesn't look for the enum in superclasses and parent classes yet - but it suffices for the moment.
|
|
238
|
+
QString GeneratorVisitor::resolveEnumMember(const QString& parent, const QString& name)
|
|
239
|
+
{
|
|
240
|
+
// is 'parent' a know class?
|
|
241
|
+
if (!parent.isEmpty()) {
|
|
242
|
+
BasicTypeDeclaration* decl = resolveType(parent);
|
|
243
|
+
if (decl)
|
|
244
|
+
return decl->toString() + "::" + name;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// doesn't seem to be a class, so it's probably a part of a namespace name
|
|
248
|
+
QStringList nspace = this->nspace;
|
|
249
|
+
do {
|
|
250
|
+
QString n = nspace.join("::");
|
|
251
|
+
if (!n.isEmpty() && !parent.isEmpty()) n += "::";
|
|
252
|
+
n += parent;
|
|
253
|
+
|
|
254
|
+
foreach (const Enum& e, enums.values()) {
|
|
255
|
+
if (e.parent())
|
|
256
|
+
continue;
|
|
257
|
+
|
|
258
|
+
if (e.nameSpace() == n) {
|
|
259
|
+
foreach (const EnumMember& member, e.members()) {
|
|
260
|
+
if (member.name() == name) {
|
|
261
|
+
QString ret = n;
|
|
262
|
+
if (!ret.isEmpty())
|
|
263
|
+
ret += "::";
|
|
264
|
+
return ret + name;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (!nspace.isEmpty())
|
|
271
|
+
nspace.pop_back();
|
|
272
|
+
} while (!nspace.isEmpty());
|
|
273
|
+
|
|
274
|
+
QStack<Class*> parentStack = klass;
|
|
275
|
+
while (!parentStack.isEmpty()) {
|
|
276
|
+
const Class* clazz = parentStack.pop();
|
|
277
|
+
foreach (const BasicTypeDeclaration* decl, clazz->children()) {
|
|
278
|
+
const Enum *e = 0;
|
|
279
|
+
if (!(e = dynamic_cast<const Enum*>(decl)))
|
|
280
|
+
continue;
|
|
281
|
+
foreach (const EnumMember& member, e->members()) {
|
|
282
|
+
if (member.name() == name) {
|
|
283
|
+
return clazz->toString() + "::" + name;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return QString();
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
#undef returnOnExistence
|
|
293
|
+
|
|
294
|
+
void GeneratorVisitor::visitAccessSpecifier(AccessSpecifierAST* node)
|
|
295
|
+
{
|
|
296
|
+
static bool oldResolveTypedefs = ParserOptions::resolveTypedefs;
|
|
297
|
+
|
|
298
|
+
if (!inClass) {
|
|
299
|
+
DefaultVisitor::visitAccessSpecifier(node);
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
inSignals.top() = false;
|
|
304
|
+
inSlots.top() = false;
|
|
305
|
+
ParserOptions::resolveTypedefs = oldResolveTypedefs;
|
|
306
|
+
|
|
307
|
+
const ListNode<std::size_t> *it = node->specs->toFront(), *end = it;
|
|
308
|
+
do {
|
|
309
|
+
if (it->element) {
|
|
310
|
+
const Token& t = token(it->element);
|
|
311
|
+
if (t.kind == Token_public)
|
|
312
|
+
access.top() = Access_public;
|
|
313
|
+
else if (t.kind == Token_protected)
|
|
314
|
+
access.top() = Access_protected;
|
|
315
|
+
else if (t.kind == Token_private)
|
|
316
|
+
access.top() = Access_private;
|
|
317
|
+
|
|
318
|
+
// signal/slot handling; don't resolve typedefs in signals and slots
|
|
319
|
+
if (t.kind == Token_signals) {
|
|
320
|
+
access.top() = Access_protected;
|
|
321
|
+
inSignals.top() = true;
|
|
322
|
+
ParserOptions::resolveTypedefs = false;
|
|
323
|
+
} else if (t.kind == Token_slots) {
|
|
324
|
+
inSlots.top() = true;
|
|
325
|
+
ParserOptions::resolveTypedefs = false;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
it = it->next;
|
|
329
|
+
} while (end != it);
|
|
330
|
+
DefaultVisitor::visitAccessSpecifier(node);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
void GeneratorVisitor::visitBaseSpecifier(BaseSpecifierAST* node)
|
|
334
|
+
{
|
|
335
|
+
Class::BaseClassSpecifier baseClass;
|
|
336
|
+
int _kind = token(node->access_specifier).kind;
|
|
337
|
+
if (_kind == Token_public) {
|
|
338
|
+
baseClass.access = Access_public;
|
|
339
|
+
} else if (_kind == Token_protected) {
|
|
340
|
+
baseClass.access = Access_protected;
|
|
341
|
+
} else {
|
|
342
|
+
baseClass.access = Access_private;
|
|
343
|
+
}
|
|
344
|
+
baseClass.isVirtual = (node->virt > 0);
|
|
345
|
+
nc->run(node->name);
|
|
346
|
+
BasicTypeDeclaration* base = resolveType(nc->qualifiedName().join("::"));
|
|
347
|
+
if (!base)
|
|
348
|
+
return;
|
|
349
|
+
Class* bptr = dynamic_cast<Class*>(base);
|
|
350
|
+
if (!bptr) {
|
|
351
|
+
Typedef* tdef = dynamic_cast<Typedef*>(base);
|
|
352
|
+
if (!tdef)
|
|
353
|
+
return;
|
|
354
|
+
bptr = tdef->resolve().getClass();
|
|
355
|
+
if (!bptr)
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
baseClass.baseClass = bptr;
|
|
359
|
+
klass.top()->appendBaseClass(baseClass);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
void GeneratorVisitor::visitClassSpecifier(ClassSpecifierAST* node)
|
|
363
|
+
{
|
|
364
|
+
if (klass.isEmpty())
|
|
365
|
+
return;
|
|
366
|
+
|
|
367
|
+
if (kind == Class::Kind_Class)
|
|
368
|
+
access.push(Access_private);
|
|
369
|
+
else
|
|
370
|
+
access.push(Access_public);
|
|
371
|
+
inSignals.push(false);
|
|
372
|
+
inSlots.push(false);
|
|
373
|
+
inClass++;
|
|
374
|
+
q_properties.push(QList<QProperty>());
|
|
375
|
+
|
|
376
|
+
klass.top()->setFileName(m_header);
|
|
377
|
+
klass.top()->setIsForwardDecl(false);
|
|
378
|
+
if (klass.count() > 1) {
|
|
379
|
+
// get the element before the last element, which is the parent
|
|
380
|
+
Class* parent = klass[klass.count() - 2];
|
|
381
|
+
parent->appendChild(klass.top());
|
|
382
|
+
}
|
|
383
|
+
DefaultVisitor::visitClassSpecifier(node);
|
|
384
|
+
q_properties.pop();
|
|
385
|
+
access.pop();
|
|
386
|
+
inSignals.pop();
|
|
387
|
+
inSlots.pop();
|
|
388
|
+
inClass--;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// defined later on
|
|
392
|
+
static bool operator==(const Method& rhs, const Method& lhs);
|
|
393
|
+
|
|
394
|
+
void GeneratorVisitor::visitDeclarator(DeclaratorAST* node)
|
|
395
|
+
{
|
|
396
|
+
// TODO: get rid of this and add a proper typdef
|
|
397
|
+
bool typeCreated = false;
|
|
398
|
+
if (createType) {
|
|
399
|
+
// run it again on the list of pointer operators to add them to the type
|
|
400
|
+
tc->run(node);
|
|
401
|
+
currentType = tc->type();
|
|
402
|
+
currentTypeRef = Type::registerType(currentType);
|
|
403
|
+
createType = false;
|
|
404
|
+
typeCreated = true;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
if (currentType.isFunctionPointer() && node->sub_declarator)
|
|
408
|
+
nc->run(node->sub_declarator->id);
|
|
409
|
+
else
|
|
410
|
+
nc->run(node->id);
|
|
411
|
+
const QString declName = nc->name();
|
|
412
|
+
|
|
413
|
+
if (createTypedef) {
|
|
414
|
+
if (!typeCreated)
|
|
415
|
+
return;
|
|
416
|
+
// we've just created the type that the typedef points to
|
|
417
|
+
// so we just need to get the new name and store it
|
|
418
|
+
Class* parent = klass.isEmpty() ? 0 : klass.top();
|
|
419
|
+
Typedef tdef = Typedef(currentTypeRef, declName, nspace.join("::"), parent);
|
|
420
|
+
tdef.setFileName(m_header);
|
|
421
|
+
QString name = tdef.toString();
|
|
422
|
+
if (!typedefs.contains(name)) {
|
|
423
|
+
QHash<QString, Typedef>::iterator it = typedefs.insert(name, tdef);
|
|
424
|
+
if (parent)
|
|
425
|
+
parent->appendChild(&it.value());
|
|
426
|
+
}
|
|
427
|
+
createTypedef = false;
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// we don't care about methods with ellipsis paramaters (i.e. 'foo(const char*, ...)') for now..
|
|
432
|
+
if (node->parameter_declaration_clause && node->parameter_declaration_clause->ellipsis)
|
|
433
|
+
return;
|
|
434
|
+
|
|
435
|
+
// only run this if we're not in a method. only checking for parameter_declaration_clause
|
|
436
|
+
// won't be enough because function pointer types also have that.
|
|
437
|
+
if (node->parameter_declaration_clause && !inMethod && inClass) {
|
|
438
|
+
// detect Q_PROPERTIES
|
|
439
|
+
if (ParserOptions::qtMode && declName == "__q_property") {
|
|
440
|
+
// this should _always_ work
|
|
441
|
+
PrimaryExpressionAST* primary = ast_cast<PrimaryExpressionAST*>(node->parameter_declaration_clause->parameter_declarations->at(0)->element->expression);
|
|
442
|
+
QByteArray literals;
|
|
443
|
+
const ListNode<std::size_t> *it = primary->literal->literals->toFront(), *end = it;
|
|
444
|
+
do {
|
|
445
|
+
if (it->element) {
|
|
446
|
+
literals.append(token(it->element).symbolByteArray());
|
|
447
|
+
}
|
|
448
|
+
it = it->next;
|
|
449
|
+
} while (end != it);
|
|
450
|
+
literals.replace("\"", "");
|
|
451
|
+
// this monster only matches "type name READ getMethod WRITE setMethod"
|
|
452
|
+
static QRegExp regexp("^([\\w:<>\\*]+)\\s+(\\w+)\\s+READ\\s+(\\w+)(\\s+WRITE\\s+\\w+)?");
|
|
453
|
+
static QRegExp typePtr(".*\\*$");
|
|
454
|
+
if (regexp.indexIn(literals) != -1) {
|
|
455
|
+
QProperty prop = { QMetaObject::normalizedType(regexp.cap(1).toLatin1()), (typePtr.indexIn(regexp.cap(1)) != -1), regexp.cap(2),
|
|
456
|
+
regexp.cap(3), regexp.cap(4).replace(QRegExp("\\s+WRITE\\s+"), QString()) };
|
|
457
|
+
q_properties.top().append(prop);
|
|
458
|
+
}
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
bool isConstructor = (declName == klass.top()->name());
|
|
463
|
+
bool isDestructor = (declName == "~" + klass.top()->name());
|
|
464
|
+
Type* returnType = currentTypeRef;
|
|
465
|
+
if (isConstructor) {
|
|
466
|
+
// constructors return a pointer to the class they create
|
|
467
|
+
Type t(klass.top()); t.setPointerDepth(1);
|
|
468
|
+
returnType = Type::registerType(t);
|
|
469
|
+
} else if (isDestructor) {
|
|
470
|
+
// destructors don't have a return type.. so return void
|
|
471
|
+
returnType = const_cast<Type*>(Type::Void);
|
|
472
|
+
} else if (nc->isCastOperator()) {
|
|
473
|
+
returnType = Type::registerType(nc->castType());
|
|
474
|
+
}
|
|
475
|
+
currentMethod = Method(klass.top(), declName, returnType, access.top());
|
|
476
|
+
currentMethod.setIsConstructor(isConstructor);
|
|
477
|
+
currentMethod.setIsDestructor(isDestructor);
|
|
478
|
+
currentMethod.setIsSignal(inSignals.top());
|
|
479
|
+
currentMethod.setIsSlot(inSlots.top());
|
|
480
|
+
// build parameter list
|
|
481
|
+
inMethod = true;
|
|
482
|
+
visit(node->parameter_declaration_clause);
|
|
483
|
+
inMethod = false;
|
|
484
|
+
QPair<bool, bool> cv = parseCv(node->fun_cv);
|
|
485
|
+
// const & volatile modifiers
|
|
486
|
+
currentMethod.setIsConst(cv.first);
|
|
487
|
+
|
|
488
|
+
if (isVirtual) currentMethod.setFlag(Method::Virtual);
|
|
489
|
+
if (hasInitializer) currentMethod.setFlag(Method::PureVirtual);
|
|
490
|
+
if (isStatic) currentMethod.setFlag(Method::Static);
|
|
491
|
+
if (isExplicit) currentMethod.setFlag(Method::Explicit);
|
|
492
|
+
|
|
493
|
+
// the class already contains the method (probably imported by a 'using' statement)
|
|
494
|
+
if (klass.top()->methods().contains(currentMethod)) {
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
// Q_PROPERTY accessor?
|
|
499
|
+
if (ParserOptions::qtMode) {
|
|
500
|
+
foreach (const QProperty& prop, q_properties.top()) {
|
|
501
|
+
if ( (currentMethod.parameters().count() == 0 && prop.read == currentMethod.name() && currentMethod.type()->toString().endsWith(prop.type)
|
|
502
|
+
&& (currentMethod.type()->pointerDepth() == 1) == prop.isPtr) // READ accessor?
|
|
503
|
+
|| (currentMethod.parameters().count() == 1 && prop.write == currentMethod.name()
|
|
504
|
+
&& currentMethod.parameters()[0].type()->toString().remove(QRegExp("^const ")).remove(QRegExp("\\&$")).endsWith(prop.type)
|
|
505
|
+
&& (currentMethod.parameters()[0].type()->pointerDepth() == 1) == prop.isPtr)) // or WRITE accessor?
|
|
506
|
+
{
|
|
507
|
+
currentMethod.setIsQPropertyAccessor(true);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
if (node->exception_spec) {
|
|
513
|
+
currentMethod.setHasExceptionSpec(true);
|
|
514
|
+
if (node->exception_spec->type_ids) {
|
|
515
|
+
const ListNode<TypeIdAST*>* it = node->exception_spec->type_ids->toFront(), *end = it;
|
|
516
|
+
do {
|
|
517
|
+
tc->run(it->element->type_specifier, it->element->declarator);
|
|
518
|
+
currentMethod.appendExceptionType(tc->type());
|
|
519
|
+
it = it->next;
|
|
520
|
+
} while (it != end);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
klass.top()->appendMethod(currentMethod);
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
// global function
|
|
529
|
+
if (node->parameter_declaration_clause && !inMethod && !inClass) {
|
|
530
|
+
if (!declName.contains("::")) {
|
|
531
|
+
Type* returnType = currentTypeRef;
|
|
532
|
+
currentFunction = Function(declName, nspace.join("::"), returnType);
|
|
533
|
+
currentFunction.setFileName(m_header);
|
|
534
|
+
// build parameter list
|
|
535
|
+
inMethod = true;
|
|
536
|
+
visit(node->parameter_declaration_clause);
|
|
537
|
+
inMethod = false;
|
|
538
|
+
QString name = currentFunction.toString();
|
|
539
|
+
if (!functions.contains(name)) {
|
|
540
|
+
functions[name] = currentFunction;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
// field
|
|
547
|
+
if (!inMethod && !klass.isEmpty() && inClass) {
|
|
548
|
+
Field field = Field(klass.top(), declName, currentTypeRef, access.top());
|
|
549
|
+
if (isStatic) field.setFlag(Field::Static);
|
|
550
|
+
klass.top()->appendField(field);
|
|
551
|
+
return;
|
|
552
|
+
} else if (!inMethod && !inClass) {
|
|
553
|
+
// global variable
|
|
554
|
+
if (!globals.contains(declName)) {
|
|
555
|
+
GlobalVar var = GlobalVar(declName, nspace.join("::"), currentTypeRef);
|
|
556
|
+
var.setFileName(m_header);
|
|
557
|
+
globals[var.name()] = var;
|
|
558
|
+
}
|
|
559
|
+
return;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
void GeneratorVisitor::visitElaboratedTypeSpecifier(ElaboratedTypeSpecifierAST* node)
|
|
564
|
+
{
|
|
565
|
+
tc->run(node);
|
|
566
|
+
createType = true;
|
|
567
|
+
DefaultVisitor::visitElaboratedTypeSpecifier(node);
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
void GeneratorVisitor::visitEnumSpecifier(EnumSpecifierAST* node)
|
|
571
|
+
{
|
|
572
|
+
nc->run(node->name);
|
|
573
|
+
Class* parent = klass.isEmpty() ? 0 : klass.top();
|
|
574
|
+
currentEnum = Enum(nc->name(), nspace.join("::"), parent);
|
|
575
|
+
Access a = (access.isEmpty() ? Access_public : access.top());
|
|
576
|
+
currentEnum.setAccess(a);
|
|
577
|
+
currentEnum.setFileName(m_header);
|
|
578
|
+
QHash<QString, Enum>::iterator it = enums.insert(currentEnum.toString(), currentEnum);
|
|
579
|
+
currentEnumRef = &it.value();
|
|
580
|
+
visitNodes(this, node->enumerators);
|
|
581
|
+
if (parent)
|
|
582
|
+
parent->appendChild(currentEnumRef);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
void GeneratorVisitor::visitEnumerator(EnumeratorAST* node)
|
|
586
|
+
{
|
|
587
|
+
currentEnumRef->appendMember(EnumMember(currentEnumRef, token(node->id).symbolString(), QString()));
|
|
588
|
+
// DefaultVisitor::visitEnumerator(node);
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
void GeneratorVisitor::visitFunctionDefinition(FunctionDefinitionAST* node)
|
|
592
|
+
{
|
|
593
|
+
visit(node->type_specifier);
|
|
594
|
+
if (node->function_specifiers) {
|
|
595
|
+
const ListNode<std::size_t> *it = node->function_specifiers->toFront(), *end = it;
|
|
596
|
+
do {
|
|
597
|
+
if (it->element && m_session->token_stream->kind(it->element) == Token_virtual) {
|
|
598
|
+
// found virtual token
|
|
599
|
+
isVirtual = true;
|
|
600
|
+
} else if (it->element && m_session->token_stream->kind(it->element) == Token_explicit) {
|
|
601
|
+
isExplicit = true;
|
|
602
|
+
}
|
|
603
|
+
it = it->next;
|
|
604
|
+
} while (end != it);
|
|
605
|
+
}
|
|
606
|
+
if (node->storage_specifiers) {
|
|
607
|
+
const ListNode<std::size_t> *it = node->storage_specifiers->toFront(), *end = it;
|
|
608
|
+
do {
|
|
609
|
+
if (it->element && m_session->token_stream->kind(it->element) == Token_static) {
|
|
610
|
+
isStatic = true;
|
|
611
|
+
} else if (it->element && m_session->token_stream->kind(it->element) == Token_friend) {
|
|
612
|
+
// we're not interested in who's the friend of whom ;)
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
it = it->next;
|
|
616
|
+
} while (end != it);
|
|
617
|
+
}
|
|
618
|
+
visit(node->init_declarator);
|
|
619
|
+
isStatic = isVirtual = isExplicit = hasInitializer = false;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
void GeneratorVisitor::visitInitializerClause(InitializerClauseAST *)
|
|
623
|
+
{
|
|
624
|
+
// we don't care about initializers
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
void GeneratorVisitor::visitNamespace(NamespaceAST* node)
|
|
629
|
+
{
|
|
630
|
+
usingTypes.push(QStringList());
|
|
631
|
+
usingNamespaces.push(QStringList());
|
|
632
|
+
|
|
633
|
+
QString name = token(node->namespace_name).symbolString();
|
|
634
|
+
nspace.push_back(name);
|
|
635
|
+
DefaultVisitor::visitNamespace(node);
|
|
636
|
+
nspace.pop_back();
|
|
637
|
+
// using directives in that namespace aren't interesting anymore :)
|
|
638
|
+
usingTypes.pop();
|
|
639
|
+
usingNamespaces.pop();
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
void GeneratorVisitor::visitParameterDeclaration(ParameterDeclarationAST* node)
|
|
643
|
+
{
|
|
644
|
+
tc->run(node->type_specifier);
|
|
645
|
+
QString name;
|
|
646
|
+
if (node->declarator) {
|
|
647
|
+
tc->run(node->declarator);
|
|
648
|
+
if (currentType.isFunctionPointer() && node->declarator->sub_declarator)
|
|
649
|
+
nc->run(node->declarator->sub_declarator->id);
|
|
650
|
+
else
|
|
651
|
+
nc->run(node->declarator->id);
|
|
652
|
+
name = nc->name();
|
|
653
|
+
}
|
|
654
|
+
currentType = tc->type();
|
|
655
|
+
currentTypeRef = Type::registerType(currentType);
|
|
656
|
+
|
|
657
|
+
// foo(void) is the same as foo()
|
|
658
|
+
if (currentTypeRef == Type::Void)
|
|
659
|
+
return;
|
|
660
|
+
|
|
661
|
+
QString defaultValue;
|
|
662
|
+
if (node->expression) {
|
|
663
|
+
// this parameter has a default value
|
|
664
|
+
ExpressionAST* expression = node->expression;
|
|
665
|
+
|
|
666
|
+
PostfixExpressionAST* postfix = 0;
|
|
667
|
+
PrimaryExpressionAST* primary = 0;
|
|
668
|
+
if ((postfix = ast_cast<PostfixExpressionAST*>(node->expression))
|
|
669
|
+
&& (postfix->sub_expressions->count() == 1
|
|
670
|
+
&& postfix->sub_expressions->at(0)->element->kind == AST::Kind_FunctionCall))
|
|
671
|
+
{
|
|
672
|
+
// We have a function call expression as default value, most probably something like 'const QString& foo = QString()'.
|
|
673
|
+
// Try to resolve the classname if it's a constructor call.
|
|
674
|
+
PrimaryExpressionAST* primary = ast_cast<PrimaryExpressionAST*>(postfix->expression);
|
|
675
|
+
expression = postfix->sub_expressions->at(0)->element;
|
|
676
|
+
|
|
677
|
+
nc->run(primary->name);
|
|
678
|
+
QStringList className = nc->qualifiedName();
|
|
679
|
+
BasicTypeDeclaration* decl = resolveType(className.join("::"));
|
|
680
|
+
if (decl)
|
|
681
|
+
className = decl->toString().split("::");
|
|
682
|
+
|
|
683
|
+
if (!decl && className.count() > 1) {
|
|
684
|
+
// Resolving failed, so this might also be a some static method (like Cursor::start() in KTextEditor).
|
|
685
|
+
// Pop the last element (probably the method name) and resolve the rest.
|
|
686
|
+
QString last = className.takeLast();
|
|
687
|
+
BasicTypeDeclaration* decl = resolveType(className.join("::"));
|
|
688
|
+
if (decl)
|
|
689
|
+
className = decl->toString().split("::");
|
|
690
|
+
className.append(last);
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
QMap<int, QList<Type> > map = nc->templateArguments();
|
|
694
|
+
for (QMap<int, QList<Type> >::const_iterator it = map.begin(); it != map.end(); it++) {
|
|
695
|
+
QString str("< ");
|
|
696
|
+
for (int i = 0; i < it.value().count(); i++) {
|
|
697
|
+
if (i > 0) str.append(',');
|
|
698
|
+
str.append(it.value()[i].toString());
|
|
699
|
+
}
|
|
700
|
+
str.append(" >");
|
|
701
|
+
className[it.key()].append(str);
|
|
702
|
+
}
|
|
703
|
+
defaultValue.append(className.join("::"));
|
|
704
|
+
} else if ((primary = ast_cast<PrimaryExpressionAST*>(node->expression))) {
|
|
705
|
+
if (primary->name) {
|
|
706
|
+
// don't build the default value twice
|
|
707
|
+
expression = 0;
|
|
708
|
+
// enum - try to resolve that
|
|
709
|
+
nc->run(primary->name);
|
|
710
|
+
|
|
711
|
+
QString name;
|
|
712
|
+
// build the name of the containing class/namespace
|
|
713
|
+
for (int i = 0; i < nc->qualifiedName().count() - 1; i++) {
|
|
714
|
+
if (i > 0) name.append("::");
|
|
715
|
+
name.append(nc->qualifiedName()[i]);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
defaultValue = resolveEnumMember(name, nc->qualifiedName().last());
|
|
719
|
+
if (defaultValue.isEmpty()) {
|
|
720
|
+
defaultValue = nc->qualifiedName().join("::");
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
if (expression) {
|
|
726
|
+
for (int i = expression->start_token; i < expression->end_token; i++)
|
|
727
|
+
defaultValue.append(token(i).symbolByteArray());
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
if (inClass)
|
|
731
|
+
currentMethod.appendParameter(Parameter(name, currentTypeRef, defaultValue));
|
|
732
|
+
else
|
|
733
|
+
currentFunction.appendParameter(Parameter(name, currentTypeRef, defaultValue));
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
void GeneratorVisitor::visitSimpleDeclaration(SimpleDeclarationAST* node)
|
|
737
|
+
{
|
|
738
|
+
bool popKlass = false;
|
|
739
|
+
int _kind = token(node->start_token).kind;
|
|
740
|
+
if (_kind == Token_class) {
|
|
741
|
+
kind = Class::Kind_Class;
|
|
742
|
+
} else if (_kind == Token_struct) {
|
|
743
|
+
kind = Class::Kind_Struct;
|
|
744
|
+
}
|
|
745
|
+
if (_kind == Token_class || _kind == Token_struct) {
|
|
746
|
+
tc->run(node->type_specifier);
|
|
747
|
+
if (tc->qualifiedName().isEmpty()) return;
|
|
748
|
+
// for nested classes
|
|
749
|
+
Class* parent = klass.isEmpty() ? 0 : klass.top();
|
|
750
|
+
Class _class = Class(tc->qualifiedName().last(), nspace.join("::"), parent, kind);
|
|
751
|
+
Access a = (access.isEmpty() ? Access_public : access.top());
|
|
752
|
+
_class.setAccess(a);
|
|
753
|
+
QString name = _class.toString();
|
|
754
|
+
// This class has already been parsed.
|
|
755
|
+
if (classes.contains(name) && !classes[name].isForwardDecl())
|
|
756
|
+
return;
|
|
757
|
+
QHash<QString, Class>::iterator item = classes.insert(name, _class);
|
|
758
|
+
if (inTemplate) {
|
|
759
|
+
item.value().setIsTemplate(true);
|
|
760
|
+
return;
|
|
761
|
+
}
|
|
762
|
+
klass.push(&item.value());
|
|
763
|
+
popKlass = true;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
if (node->function_specifiers) {
|
|
767
|
+
const ListNode<std::size_t> *it = node->function_specifiers->toFront(), *end = it;
|
|
768
|
+
do {
|
|
769
|
+
if (it->element && m_session->token_stream->kind(it->element) == Token_virtual) {
|
|
770
|
+
// found virtual token
|
|
771
|
+
isVirtual = true;
|
|
772
|
+
break;
|
|
773
|
+
}
|
|
774
|
+
it = it->next;
|
|
775
|
+
} while (end != it);
|
|
776
|
+
}
|
|
777
|
+
// look for initializers - if we find one, the method is pure virtual
|
|
778
|
+
if (node->init_declarators) {
|
|
779
|
+
const ListNode<InitDeclaratorAST*> *it = node->init_declarators->toFront(), *end = it;
|
|
780
|
+
do {
|
|
781
|
+
if (it->element && it->element->initializer) {
|
|
782
|
+
hasInitializer = true;
|
|
783
|
+
}
|
|
784
|
+
if (it->element && it->element->declarator && it->element->declarator->parameter_declaration_clause) {
|
|
785
|
+
if (popKlass) {
|
|
786
|
+
// This method return type has 'class' or 'struct' prepended to avoid a forward declaration.
|
|
787
|
+
// example: 'class KMultiTabBarTab *tab(...)'
|
|
788
|
+
QString oldClass = klass.top()->toString();
|
|
789
|
+
klass.top()->setParent(0);
|
|
790
|
+
klass.top()->setNameSpace(QString());
|
|
791
|
+
classes.insert(klass.top()->toString(), *klass.top());
|
|
792
|
+
classes.remove(oldClass);
|
|
793
|
+
klass.pop();
|
|
794
|
+
popKlass = false;
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
it = it->next;
|
|
798
|
+
} while (end != it);
|
|
799
|
+
}
|
|
800
|
+
if (node->storage_specifiers) {
|
|
801
|
+
const ListNode<std::size_t> *it = node->storage_specifiers->toFront(), *end = it;
|
|
802
|
+
do {
|
|
803
|
+
if (it->element && m_session->token_stream->kind(it->element) == Token_static) {
|
|
804
|
+
isStatic = true;
|
|
805
|
+
} else if (it->element && m_session->token_stream->kind(it->element) == Token_friend) {
|
|
806
|
+
// we're not interested in who's the friend of whom ;)
|
|
807
|
+
if (popKlass)
|
|
808
|
+
klass.pop();
|
|
809
|
+
isStatic = isVirtual = hasInitializer = false;
|
|
810
|
+
return;
|
|
811
|
+
}
|
|
812
|
+
it = it->next;
|
|
813
|
+
} while (end != it);
|
|
814
|
+
}
|
|
815
|
+
DefaultVisitor::visitSimpleDeclaration(node);
|
|
816
|
+
if (popKlass)
|
|
817
|
+
klass.pop();
|
|
818
|
+
isStatic = isVirtual = hasInitializer = false;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
void GeneratorVisitor::visitSimpleTypeSpecifier(SimpleTypeSpecifierAST* node)
|
|
822
|
+
{
|
|
823
|
+
// first run on the type specifier to get the name of the type
|
|
824
|
+
tc->run(node);
|
|
825
|
+
createType = true;
|
|
826
|
+
DefaultVisitor::visitSimpleTypeSpecifier(node);
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
void GeneratorVisitor::visitTemplateDeclaration(TemplateDeclarationAST* node)
|
|
830
|
+
{
|
|
831
|
+
if (!node->declaration)
|
|
832
|
+
return;
|
|
833
|
+
int kind = token(node->declaration->start_token).kind;
|
|
834
|
+
if (kind == Token_class || kind == Token_struct) {
|
|
835
|
+
inTemplate = true;
|
|
836
|
+
visit(node->declaration);
|
|
837
|
+
inTemplate = false;
|
|
838
|
+
}
|
|
839
|
+
// skip template declarations
|
|
840
|
+
return;
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
void GeneratorVisitor::visitTemplateArgument(TemplateArgumentAST* node)
|
|
844
|
+
{
|
|
845
|
+
// skip template arguments - they're handled by TypeCompiler
|
|
846
|
+
return;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
void GeneratorVisitor::visitTypedef(TypedefAST* node)
|
|
850
|
+
{
|
|
851
|
+
createTypedef = true;
|
|
852
|
+
DefaultVisitor::visitTypedef(node);
|
|
853
|
+
|
|
854
|
+
// TODO: probably has to be extended to cover structs and classes, too
|
|
855
|
+
// makes something like 'typedef enum { Bar } Foo;' look like a proper enum.
|
|
856
|
+
if (ast_cast<EnumSpecifierAST*>(node->type_specifier)) {
|
|
857
|
+
nc->run(node->init_declarators->at(0)->element->declarator->id);
|
|
858
|
+
currentEnumRef->setName(nc->name());
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
// don't make this public - it's just a utility function for the next method and probably not what you would expect it to be
|
|
863
|
+
static bool operator==(const Method& rhs, const Method& lhs)
|
|
864
|
+
{
|
|
865
|
+
// these have to be equal for methods to be the same
|
|
866
|
+
bool ok = (rhs.name() == lhs.name() && rhs.isConst() == lhs.isConst() &&
|
|
867
|
+
rhs.parameters().count() == lhs.parameters().count() && rhs.type() == lhs.type());
|
|
868
|
+
if (!ok)
|
|
869
|
+
return false;
|
|
870
|
+
|
|
871
|
+
// now check the parameter types for equality
|
|
872
|
+
for (int i = 0; i < rhs.parameters().count(); i++) {
|
|
873
|
+
if (rhs.parameters()[i].type() != lhs.parameters()[i].type())
|
|
874
|
+
return false;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
return true;
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
void GeneratorVisitor::visitUsing(UsingAST* node)
|
|
881
|
+
{
|
|
882
|
+
nc->run(node->name);
|
|
883
|
+
if (inClass) {
|
|
884
|
+
// if we encounter 'using' in a class, it means we should import methods from another class
|
|
885
|
+
QStringList tmp = nc->qualifiedName();
|
|
886
|
+
const QString methodName = tmp.takeLast();
|
|
887
|
+
const QString className = tmp.join("::");
|
|
888
|
+
const BasicTypeDeclaration* decl = resolveType(className);
|
|
889
|
+
const Class* clazz = dynamic_cast<const Class*>(decl);
|
|
890
|
+
if (!clazz) {
|
|
891
|
+
const Typedef* tdef = dynamic_cast<const Typedef*>(decl);
|
|
892
|
+
if (tdef) {
|
|
893
|
+
clazz = tdef->resolve().getClass();
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
if (!clazz)
|
|
897
|
+
return;
|
|
898
|
+
|
|
899
|
+
foreach (const Method& meth, clazz->methods()) {
|
|
900
|
+
if (meth.name() != methodName)
|
|
901
|
+
continue;
|
|
902
|
+
|
|
903
|
+
// prevent importing of already overridden (pure) virtuals
|
|
904
|
+
if (klass.top()->methods().contains(meth))
|
|
905
|
+
continue;
|
|
906
|
+
|
|
907
|
+
Method copy = meth;
|
|
908
|
+
copy.setDeclaringType(klass.top());
|
|
909
|
+
copy.setAccess(access.top());
|
|
910
|
+
klass.top()->appendMethod(copy);
|
|
911
|
+
}
|
|
912
|
+
} else {
|
|
913
|
+
usingTypes.top() << nc->qualifiedName().join("::");
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
void GeneratorVisitor::visitUsingDirective(UsingDirectiveAST* node)
|
|
918
|
+
{
|
|
919
|
+
nc->run(node->name);
|
|
920
|
+
usingNamespaces.top() << nc->qualifiedName().join("::");
|
|
921
|
+
DefaultVisitor::visitUsingDirective(node);
|
|
922
|
+
}
|