File indexing completed on 2024-05-12 05:41:02

0001 /*
0002     SPDX-FileCopyrightText: 2020 The Qt Company Ltd.
0003     SPDX-FileCopyrightText: 2020 Lucie Gerard <lucie.gerard@qt.io>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "qt6-header-fixes.h"
0009 #include "ClazyContext.h"
0010 #include "FixItUtils.h"
0011 #include "Utils.h"
0012 
0013 #include <clang/AST/Decl.h>
0014 #include <clang/AST/DeclCXX.h>
0015 #include <clang/AST/Expr.h>
0016 #include <clang/AST/ExprCXX.h>
0017 #include <clang/AST/Stmt.h>
0018 #include <clang/AST/Type.h>
0019 #include <clang/Basic/Diagnostic.h>
0020 #include <clang/Basic/LLVM.h>
0021 #include <clang/Basic/SourceLocation.h>
0022 #include <clang/Lex/Lexer.h>
0023 #include <llvm/ADT/ArrayRef.h>
0024 #include <llvm/ADT/StringRef.h>
0025 #include <llvm/Support/Casting.h>
0026 
0027 using namespace clang;
0028 
0029 static bool newOldHeaderFileMatch(const std::string &FileNameOld, std::string &FileNameNew)
0030 {
0031     static std::unordered_map<std::string, std::string> map = {
0032         {"ActiveQt/QAxAggregated", "QtAxServer/QAxAggregated"},
0033         {"ActiveQt/QAxBase", "QtAxContainer/QAxBase"},
0034         {"ActiveQt/QAxBindable", "QtAxServer/QAxBindable"},
0035         {"ActiveQt/QAxFactory", "QtAxServer/QAxFactory"},
0036         {"ActiveQt/QAxObject", "QtAxContainer/QAxObject"},
0037         {"ActiveQt/QAxScript", "QtAxContainer/QAxScript"},
0038         {"ActiveQt/QAxScriptEngine", "QtAxContainer/QAxScriptEngine"},
0039         {"ActiveQt/QAxScriptManager", "QtAxContainer/QAxScriptManager"},
0040         {"ActiveQt/QAxSelect", "QtAxContainer/QAxSelect"},
0041         {"ActiveQt/QAxWidget", "QtAxContainer/QAxWidget"},
0042         {"ActiveQt/qaxaggregated.h", "QtAxServer/qaxaggregated.h"},
0043         {"ActiveQt/qaxbase.h", "QtAxContainer/qaxbase.h"},
0044         {"ActiveQt/qaxbindable.h", "QtAxServer/qaxbindable.h"},
0045         {"ActiveQt/qaxfactory.h", "QtAxServer/qaxfactory.h"},
0046         {"ActiveQt/qaxobject.h", "QtAxContainer/qaxobject.h"},
0047         {"ActiveQt/qaxscript.h", "QtAxContainer/qaxscript.h"},
0048         {"ActiveQt/qaxselect.h", "QtAxContainer/qaxselect.h"},
0049         {"ActiveQt/qaxwidget.h", "QtAxContainer/qaxwidget.h"},
0050         {"Qt3DAnimation/QAbstractAnimation", "QtCore/QAbstractAnimation"},
0051         {"Qt3DAnimation/QAnimationGroup", "QtCore/QAnimationGroup"},
0052         {"Qt3DAnimation/qabstractanimation.h", "QtCore/qabstractanimation.h"},
0053         {"Qt3DAnimation/qanimationgroup.h", "QtCore/qanimationgroup.h"},
0054         {"Qt3DInput/QAction", "QtGui/QAction"},
0055         {"Qt3DInput/QKeyEvent", "QtGui/QKeyEvent"},
0056         {"Qt3DInput/QMouseEvent", "QtGui/QMouseEvent"},
0057         {"Qt3DInput/QWheelEvent", "QtGui/QWheelEvent"},
0058         {"Qt3DInput/qaction.h", "QtGui/qaction.h"},
0059         {"Qt3DRender/FunctorType", "Qt3DCore/FunctorType"},
0060         {"Qt3DRender/QAbstractFunctor", "Qt3DCore/QAbstractFunctor"},
0061         {"Qt3DRender/QAttribute", "Qt3DCore/QAttribute"},
0062         {"Qt3DRender/QBuffer", "QtCore/QBuffer"},
0063         {"Qt3DRender/QBufferPtr", "Qt3DCore/QBufferPtr"},
0064         {"Qt3DRender/QGeometry", "Qt3DCore/QGeometry"},
0065         {"Qt3DRender/QGeometryFactoryPtr", "Qt3DCore/QGeometryFactoryPtr"},
0066         {"Qt3DRender/QProximityFilter", "QtSensors/QProximityFilter"},
0067         {"Qt3DRender/qabstractfunctor.h", "Qt3DCore/qabstractfunctor.h"},
0068         {"Qt3DRender/qattribute.h", "Qt3DCore/qattribute.h"},
0069         {"Qt3DRender/qbuffer.h", "QtCore/qbuffer.h"},
0070         {"Qt3DRender/qgeometry.h", "Qt3DCore/qgeometry.h"},
0071         {"QtCore/QAbstractState", "QtStateMachine/QAbstractState"},
0072         {"QtCore/QAbstractTransition", "QtStateMachine/QAbstractTransition"},
0073         {"QtCore/QEventTransition", "QtStateMachine/QEventTransition"},
0074         {"QtCore/QFinalState", "QtStateMachine/QFinalState"},
0075         {"QtCore/QHistoryState", "QtStateMachine/QHistoryState"},
0076         {"QtCore/QSignalTransition", "QtStateMachine/QSignalTransition"},
0077         {"QtCore/QState", "QtStateMachine/QState"},
0078         {"QtCore/QStateMachine", "QtStateMachine/QStateMachine"},
0079         {"QtCore/qabstractstate.h", "QtStateMachine/qabstractstate.h"},
0080         {"QtCore/qabstracttransition.h", "QtStateMachine/qabstracttransition.h"},
0081         {"QtCore/qeventtransition.h", "QtStateMachine/qeventtransition.h"},
0082         {"QtCore/qfinalstate.h", "QtStateMachine/qfinalstate.h"},
0083         {"QtCore/qhistorystate.h", "QtStateMachine/qhistorystate.h"},
0084         {"QtCore/qsignaltransition.h", "QtStateMachine/qsignaltransition.h"},
0085         {"QtCore/qstate.h", "QtStateMachine/qstate.h"},
0086         {"QtCore/qstatemachine.h", "QtStateMachine/qstatemachine.h"},
0087         {"QtDesigner/QDesignerCustomWidgetCollectionInterface", "QtUiPlugin/QDesignerCustomWidgetCollectionInterface"},
0088         {"QtDesigner/QDesignerCustomWidgetInterface", "QtUiPlugin/QDesignerCustomWidgetInterface"},
0089         {"QtDesigner/QDesignerExportWidget", "QtUiPlugin/QDesignerExportWidget"},
0090         {"QtDesigner/customwidget.h", "QtUiPlugin/customwidget.h"},
0091         {"QtDesigner/qdesignerexportwidget.h", "QtUiPlugin/qdesignerexportwidget.h"},
0092         {"QtGui/QOpenGLBuffer", "QtOpenGL/QOpenGLBuffer"},
0093         {"QtGui/QOpenGLDebugLogger", "QtOpenGL/QOpenGLDebugLogger"},
0094         {"QtGui/QOpenGLDebugMessage", "QtOpenGL/QOpenGLDebugMessage"},
0095         {"QtGui/QOpenGLFramebufferObject", "QtOpenGL/QOpenGLFramebufferObject"},
0096         {"QtGui/QOpenGLFramebufferObjectFormat", "QtOpenGL/QOpenGLFramebufferObjectFormat"},
0097         {"QtGui/QOpenGLFunctions_1_0", "QtOpenGL/QOpenGLFunctions_1_0"},
0098         {"QtGui/QOpenGLFunctions_1_1", "QtOpenGL/QOpenGLFunctions_1_1"},
0099         {"QtGui/QOpenGLFunctions_1_2", "QtOpenGL/QOpenGLFunctions_1_2"},
0100         {"QtGui/QOpenGLFunctions_1_3", "QtOpenGL/QOpenGLFunctions_1_3"},
0101         {"QtGui/QOpenGLFunctions_1_4", "QtOpenGL/QOpenGLFunctions_1_4"},
0102         {"QtGui/QOpenGLFunctions_1_5", "QtOpenGL/QOpenGLFunctions_1_5"},
0103         {"QtGui/QOpenGLFunctions_2_0", "QtOpenGL/QOpenGLFunctions_2_0"},
0104         {"QtGui/QOpenGLFunctions_2_1", "QtOpenGL/QOpenGLFunctions_2_1"},
0105         {"QtGui/QOpenGLFunctions_3_0", "QtOpenGL/QOpenGLFunctions_3_0"},
0106         {"QtGui/QOpenGLFunctions_3_1", "QtOpenGL/QOpenGLFunctions_3_1"},
0107         {"QtGui/QOpenGLFunctions_3_2_Compatibility", "QtOpenGL/QOpenGLFunctions_3_2_Compatibility"},
0108         {"QtGui/QOpenGLFunctions_3_2_Core", "QtOpenGL/QOpenGLFunctions_3_2_Core"},
0109         {"QtGui/QOpenGLFunctions_3_3_Compatibility", "QtOpenGL/QOpenGLFunctions_3_3_Compatibility"},
0110         {"QtGui/QOpenGLFunctions_3_3_Core", "QtOpenGL/QOpenGLFunctions_3_3_Core"},
0111         {"QtGui/QOpenGLFunctions_4_0_Compatibility", "QtOpenGL/QOpenGLFunctions_4_0_Compatibility"},
0112         {"QtGui/QOpenGLFunctions_4_0_Core", "QtOpenGL/QOpenGLFunctions_4_0_Core"},
0113         {"QtGui/QOpenGLFunctions_4_1_Compatibility", "QtOpenGL/QOpenGLFunctions_4_1_Compatibility"},
0114         {"QtGui/QOpenGLFunctions_4_1_Core", "QtOpenGL/QOpenGLFunctions_4_1_Core"},
0115         {"QtGui/QOpenGLFunctions_4_2_Compatibility", "QtOpenGL/QOpenGLFunctions_4_2_Compatibility"},
0116         {"QtGui/QOpenGLFunctions_4_2_Core", "QtOpenGL/QOpenGLFunctions_4_2_Core"},
0117         {"QtGui/QOpenGLFunctions_4_3_Compatibility", "QtOpenGL/QOpenGLFunctions_4_3_Compatibility"},
0118         {"QtGui/QOpenGLFunctions_4_3_Core", "QtOpenGL/QOpenGLFunctions_4_3_Core"},
0119         {"QtGui/QOpenGLFunctions_4_4_Compatibility", "QtOpenGL/QOpenGLFunctions_4_4_Compatibility"},
0120         {"QtGui/QOpenGLFunctions_4_4_Core", "QtOpenGL/QOpenGLFunctions_4_4_Core"},
0121         {"QtGui/QOpenGLFunctions_4_5_Compatibility", "QtOpenGL/QOpenGLFunctions_4_5_Compatibility"},
0122         {"QtGui/QOpenGLFunctions_4_5_Core", "QtOpenGL/QOpenGLFunctions_4_5_Core"},
0123         {"QtGui/QOpenGLFunctions_ES2", "QtOpenGL/QOpenGLFunctions_ES2"},
0124         {"QtGui/QOpenGLPaintDevice", "QtOpenGL/QOpenGLPaintDevice"},
0125         {"QtGui/QOpenGLPixelTransferOptions", "QtOpenGL/QOpenGLPixelTransferOptions"},
0126         {"QtGui/QOpenGLShader", "QtOpenGL/QOpenGLShader"},
0127         {"QtGui/QOpenGLShaderProgram", "QtOpenGL/QOpenGLShaderProgram"},
0128         {"QtGui/QOpenGLTexture", "QtOpenGL/QOpenGLTexture"},
0129         {"QtGui/QOpenGLTextureBlitter", "QtOpenGL/QOpenGLTextureBlitter"},
0130         {"QtGui/QOpenGLTimeMonitor", "QtOpenGL/QOpenGLTimeMonitor"},
0131         {"QtGui/QOpenGLTimerQuery", "QtOpenGL/QOpenGLTimerQuery"},
0132         {"QtGui/QOpenGLVersionFunctions", "QtOpenGL/QOpenGLVersionFunctions"},
0133         {"QtGui/QOpenGLVersionProfile", "QtOpenGL/QOpenGLVersionProfile"},
0134         {"QtGui/QOpenGLVertexArrayObject", "QtOpenGL/QOpenGLVertexArrayObject"},
0135         {"QtGui/QOpenGLWindow", "QtOpenGL/QOpenGLWindow"},
0136         {"QtGui/qopenglbuffer.h", "QtOpenGL/qopenglbuffer.h"},
0137         {"QtGui/qopengldebug.h", "QtOpenGL/qopengldebug.h"},
0138         {"QtGui/qopenglframebufferobject.h", "QtOpenGL/qopenglframebufferobject.h"},
0139         {"QtGui/qopenglfunctions_1_0.h", "QtOpenGL/qopenglfunctions_1_0.h"},
0140         {"QtGui/qopenglfunctions_1_1.h", "QtOpenGL/qopenglfunctions_1_1.h"},
0141         {"QtGui/qopenglfunctions_1_2.h", "QtOpenGL/qopenglfunctions_1_2.h"},
0142         {"QtGui/qopenglfunctions_1_3.h", "QtOpenGL/qopenglfunctions_1_3.h"},
0143         {"QtGui/qopenglfunctions_1_4.h", "QtOpenGL/qopenglfunctions_1_4.h"},
0144         {"QtGui/qopenglfunctions_1_5.h", "QtOpenGL/qopenglfunctions_1_5.h"},
0145         {"QtGui/qopenglfunctions_2_0.h", "QtOpenGL/qopenglfunctions_2_0.h"},
0146         {"QtGui/qopenglfunctions_2_1.h", "QtOpenGL/qopenglfunctions_2_1.h"},
0147         {"QtGui/qopenglfunctions_3_0.h", "QtOpenGL/qopenglfunctions_3_0.h"},
0148         {"QtGui/qopenglfunctions_3_1.h", "QtOpenGL/qopenglfunctions_3_1.h"},
0149         {"QtGui/qopenglfunctions_3_2_compatibility.h", "QtOpenGL/qopenglfunctions_3_2_compatibility.h"},
0150         {"QtGui/qopenglfunctions_3_2_core.h", "QtOpenGL/qopenglfunctions_3_2_core.h"},
0151         {"QtGui/qopenglfunctions_3_3_compatibility.h", "QtOpenGL/qopenglfunctions_3_3_compatibility.h"},
0152         {"QtGui/qopenglfunctions_3_3_core.h", "QtOpenGL/qopenglfunctions_3_3_core.h"},
0153         {"QtGui/qopenglfunctions_4_0_compatibility.h", "QtOpenGL/qopenglfunctions_4_0_compatibility.h"},
0154         {"QtGui/qopenglfunctions_4_0_core.h", "QtOpenGL/qopenglfunctions_4_0_core.h"},
0155         {"QtGui/qopenglfunctions_4_1_compatibility.h", "QtOpenGL/qopenglfunctions_4_1_compatibility.h"},
0156         {"QtGui/qopenglfunctions_4_1_core.h", "QtOpenGL/qopenglfunctions_4_1_core.h"},
0157         {"QtGui/qopenglfunctions_4_2_compatibility.h", "QtOpenGL/qopenglfunctions_4_2_compatibility.h"},
0158         {"QtGui/qopenglfunctions_4_2_core.h", "QtOpenGL/qopenglfunctions_4_2_core.h"},
0159         {"QtGui/qopenglfunctions_4_3_compatibility.h", "QtOpenGL/qopenglfunctions_4_3_compatibility.h"},
0160         {"QtGui/qopenglfunctions_4_3_core.h", "QtOpenGL/qopenglfunctions_4_3_core.h"},
0161         {"QtGui/qopenglfunctions_4_4_compatibility.h", "QtOpenGL/qopenglfunctions_4_4_compatibility.h"},
0162         {"QtGui/qopenglfunctions_4_4_core.h", "QtOpenGL/qopenglfunctions_4_4_core.h"},
0163         {"QtGui/qopenglfunctions_4_5_compatibility.h", "QtOpenGL/qopenglfunctions_4_5_compatibility.h"},
0164         {"QtGui/qopenglfunctions_4_5_core.h", "QtOpenGL/qopenglfunctions_4_5_core.h"},
0165         {"QtGui/qopenglfunctions_es2.h", "QtOpenGL/qopenglfunctions_es2.h"},
0166         {"QtGui/qopenglpaintdevice.h", "QtOpenGL/qopenglpaintdevice.h"},
0167         {"QtGui/qopenglpixeltransferoptions.h", "QtOpenGL/qopenglpixeltransferoptions.h"},
0168         {"QtGui/qopenglshaderprogram.h", "QtOpenGL/qopenglshaderprogram.h"},
0169         {"QtGui/qopengltexture.h", "QtOpenGL/qopengltexture.h"},
0170         {"QtGui/qopengltextureblitter.h", "QtOpenGL/qopengltextureblitter.h"},
0171         {"QtGui/qopengltimerquery.h", "QtOpenGL/qopengltimerquery.h"},
0172         {"QtGui/qopenglversionfunctions.h", "QtOpenGL/qopenglversionfunctions.h"},
0173         {"QtGui/qopenglvertexarrayobject.h", "QtOpenGL/qopenglvertexarrayobject.h"},
0174         {"QtGui/qopenglwindow.h", "QtOpenGL/qopenglwindow.h"},
0175         {"QtSvg/QGraphicsSvgItem", "QtSvgWidgets/QGraphicsSvgItem"},
0176         {"QtSvg/QSvgWidget", "QtSvgWidgets/QSvgWidget"},
0177         {"QtSvg/qgraphicssvgitem.h", "QtSvgWidgets/qgraphicssvgitem.h"},
0178         {"QtSvg/qsvgwidget.h", "QtSvgWidgets/qsvgwidget.h"},
0179         {"QtWidgets/QAction", "QtGui/QAction"},
0180         {"QtWidgets/QActionGroup", "QtGui/QActionGroup"},
0181         {"QtWidgets/QFileSystemModel", "QtGui/QFileSystemModel"},
0182         {"QtWidgets/QKeyEventTransition", "QtStateMachine/QKeyEventTransition"},
0183         {"QtWidgets/QMouseEventTransition", "QtStateMachine/QMouseEventTransition"},
0184         {"QtWidgets/QOpenGLWidget", "QtOpenGLWidgets/QOpenGLWidget"},
0185         {"QtWidgets/QShortcut", "QtGui/QShortcut"},
0186         {"QtWidgets/QUndoCommand", "QtGui/QUndoCommand"},
0187         {"QtWidgets/QUndoGroup", "QtGui/QUndoGroup"},
0188         {"QtWidgets/QUndoStack", "QtGui/QUndoStack"},
0189         {"QtWidgets/qaction.h", "QtGui/qaction.h"},
0190         {"QtWidgets/qactiongroup.h", "QtGui/qactiongroup.h"},
0191         {"QtWidgets/qfilesystemmodel.h", "QtGui/qfilesystemmodel.h"},
0192         {"QtWidgets/qkeyeventtransition.h", "QtStateMachine/qkeyeventtransition.h"},
0193         {"QtWidgets/qmouseeventtransition.h", "QtStateMachine/qmouseeventtransition.h"},
0194         {"QtWidgets/qopenglwidget.h", "QtOpenGLWidgets/qopenglwidget.h"},
0195         {"QtWidgets/qshortcut.h", "QtGui/qshortcut.h"},
0196         {"QtWidgets/qundogroup.h", "QtGui/qundogroup.h"},
0197         {"QtWidgets/qundostack.h", "QtGui/qundostack.h"}};
0198 
0199     auto it = map.find(FileNameOld);
0200     if (it == map.cend()) {
0201         return false;
0202     }
0203 
0204     FileNameNew = it->second;
0205 
0206     return true;
0207 }
0208 
0209 Qt6HeaderFixes::Qt6HeaderFixes(const std::string &name, ClazyContext *context)
0210     : CheckBase(name, context, Option_CanIgnoreIncludes)
0211 {
0212     m_filesToIgnore = {"qeventtransition.h",
0213                        "qfinalstate.h",
0214                        "qhistorystate.h",
0215                        "qsignaltransition.h",
0216                        "qstate.h",
0217                        "qstatemachine.h",
0218                        "qopenglcontext.h",
0219                        "qopenglfunctions_1_0.h",
0220                        "qopenglfunctions_1_1.h",
0221                        "qopenglfunctions_1_2.h",
0222                        "qopenglfunctions_1_3.h",
0223                        "qopenglfunctions_1_4.h",
0224                        "qopenglfunctions_1_5.h",
0225                        "qopenglfunctions_2_0.h",
0226                        "qopenglfunctions_2_1.h",
0227                        "qopenglfunctions_3_0.h",
0228                        "qopenglfunctions_3_1.h",
0229                        "qopenglfunctions_3_2_compatibility.h",
0230                        "qopenglfunctions_3_2_core.h",
0231                        "qopenglfunctions_3_3_compatibility.h",
0232                        "qopenglfunctions_3_3_core.h",
0233                        "qopenglfunctions_4_0_compatibility.h",
0234                        "qopenglfunctions_4_0_core.h",
0235                        "qopenglfunctions_4_1_compatibility.h",
0236                        "qopenglfunctions_4_1_core.h",
0237                        "qopenglfunctions_4_2_compatibility.h",
0238                        "qopenglfunctions_4_2_core.h",
0239                        "qopenglfunctions_4_3_compatibility.h",
0240                        "qopenglfunctions_4_3_core.h",
0241                        "qopenglfunctions_4_4_compatibility.h",
0242                        "qopenglfunctions_4_4_core.h",
0243                        "qopenglfunctions_4_5_compatibility.h",
0244                        "qopenglfunctions_4_5_core.h"};
0245     enablePreProcessorCallbacks();
0246 }
0247 
0248 void Qt6HeaderFixes::VisitInclusionDirective(clang::SourceLocation HashLoc,
0249                                              const clang::Token & /*IncludeTok*/,
0250                                              clang::StringRef FileName,
0251                                              bool IsAngled,
0252                                              clang::CharSourceRange FilenameRange,
0253                                              clazy::OptionalFileEntryRef /*File*/,
0254                                              clang::StringRef /*SearchPath*/,
0255                                              clang::StringRef /*RelativePath*/,
0256                                              const clang::Module * /*Imported*/,
0257                                              clang::SrcMgr::CharacteristicKind /*FileType*/)
0258 {
0259     if (shouldIgnoreFile(HashLoc)) {
0260         return;
0261     }
0262 
0263     std::string newFileName;
0264     if (!newOldHeaderFileMatch(FileName.str(), newFileName)) {
0265         return;
0266     }
0267 
0268     std::string replacement;
0269     if (IsAngled) {
0270         replacement = "<";
0271         replacement += newFileName;
0272         replacement += ">";
0273     } else {
0274         replacement = "\"";
0275         replacement += newFileName;
0276         replacement += "\"";
0277     }
0278 
0279     std::vector<FixItHint> fixits;
0280     fixits.push_back(FixItHint::CreateReplacement(FilenameRange.getAsRange(), replacement));
0281     std::string message = "including ";
0282     message += FileName;
0283     emitWarning(FilenameRange.getAsRange().getBegin(), message, fixits);
0284     return;
0285 }