File indexing completed on 2024-04-28 15:52:42

0001 /*
0002     SPDX-FileCopyrightText: 2009 Milian Wolff <mail@milianw.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #include "magicconstantnavigationcontext.h"
0008 
0009 #include <QTextDocument>
0010 #include <KLocalizedString>
0011 #include <language/duchain/topducontext.h>
0012 #include <language/duchain/declaration.h>
0013 #include <language/duchain/types/functiontype.h>
0014 #include <serialization/indexedstring.h>
0015 
0016 using namespace KDevelop;
0017 
0018 namespace Php {
0019 
0020 MagicConstantNavigationContext::MagicConstantNavigationContext(TopDUContextPointer topContext,
0021                                                                 const KTextEditor::Cursor& position,
0022                                                                 const QString& constant)
0023     : AbstractNavigationContext(topContext, nullptr), m_position(position.line(), position.column()), m_constant(constant)
0024 {
0025 }
0026 
0027 
0028 QString MagicConstantNavigationContext::name() const
0029 {
0030     return m_constant;
0031 }
0032 
0033 DUContext* findContext(TopDUContextPointer topCtx, const CursorInRevision& pos, DUContext::ContextType type) {
0034     DUContext* ctx = topCtx->findContextAt(pos);
0035     while ( ctx && ctx->type() != type ) {
0036         ctx = ctx->parentContext();
0037     }
0038     if ( !ctx || ctx->type() != type ) {
0039         return nullptr;
0040     } else {
0041         return ctx;
0042     }
0043 }
0044 
0045 QString MagicConstantNavigationContext::html(bool /*shorten*/)
0046 {
0047     QString html = QStringLiteral("<html><body><p><small><small>");
0048     html += typeHighlight(i18n("magic constant"));
0049     html += ' ';
0050     html += nameHighlight(m_constant.toHtmlEscaped());
0051     html += QLatin1String("<br/>\n");
0052 
0053     QString value;
0054 
0055     if ( m_constant == QLatin1String("__FILE__") ) {
0056         value = topContext()->url().str().toHtmlEscaped();
0057     } else if ( m_constant == QLatin1String("__DIR__") ) {
0058         value = QFileInfo(topContext()->url().str()).absoluteDir().path().toHtmlEscaped();
0059     } else if ( m_constant == QLatin1String("__LINE__") ) {
0060         value.setNum(m_position.line + 1);
0061     } else if ( m_constant == QLatin1String("__CLASS__") ) {
0062         if ( DUContext* ctx = findContext(topContext(), m_position, DUContext::Class) ) {
0063             value = codeHighlight(ctx->localScopeIdentifier().toString().toHtmlEscaped());
0064         } else {
0065             value = commentHighlight(i18n("empty (not inside a class)"));
0066         }
0067     } else if ( m_constant == QLatin1String("__TRAIT__") ) {
0068         if ( DUContext* ctx = findContext(topContext(), m_position, DUContext::Class) ) {
0069             value = codeHighlight(ctx->localScopeIdentifier().toString().toHtmlEscaped());
0070         } else {
0071             value = commentHighlight(i18n("empty (not inside a trait)"));
0072         }
0073     } else if ( m_constant == QLatin1String("__METHOD__") ) {
0074         CursorInRevision pos = m_position;
0075         while ( DUContext* ctx = findContext(topContext(), pos, DUContext::Other) ) {
0076             if ( !ctx->parentContext() ) {
0077                 break;
0078             }
0079             if ( ctx->parentContext()->type() == DUContext::Class ) {
0080                 value = codeHighlight(QString(
0081                             ctx->parentContext()->localScopeIdentifier().toString() + "::"
0082                             + ctx->localScopeIdentifier().toString()
0083                         ).toHtmlEscaped());
0084                 break;
0085             }
0086             // might be a "normal" function inside a method...
0087             pos = ctx->range().start;
0088         }
0089         if ( value.isEmpty() ) {
0090             value = commentHighlight(i18n("empty (not inside a method)"));
0091         }
0092     } else if ( m_constant == QLatin1String("__FUNCTION__") ) {
0093         CursorInRevision pos = m_position;
0094         if ( DUContext* ctx = findContext(topContext(), pos, DUContext::Other) ) {
0095             if ( ctx->owner() && ctx->owner()->type<FunctionType>() ) {
0096                 value = codeHighlight(ctx->localScopeIdentifier().toString().toHtmlEscaped());
0097             }
0098         }
0099         if ( value.isEmpty() ) {
0100             value = commentHighlight(i18n("empty (not inside a function)"));
0101         }
0102     } else if ( m_constant == QLatin1String("__NAMESPACE__") ) {
0103         if ( DUContext* ctx = findContext(topContext(), m_position, DUContext::Namespace) ) {
0104             if ( ctx->owner() && ctx->owner()->kind() == Declaration::Namespace ) {
0105                 value = codeHighlight(ctx->localScopeIdentifier().toString().toHtmlEscaped());
0106             }
0107         }
0108         if ( value.isEmpty() ) {
0109             value = commentHighlight(i18n("empty (not inside a namespace)"));
0110         }
0111     }
0112 
0113     html += i18n("current value: %1", value);
0114 
0115     html += QLatin1String("</small></small></p></body></html>");
0116 
0117     return html;
0118 }
0119 
0120 
0121 }