File indexing completed on 2024-04-21 15:24:19

0001 /*
0002     SPDX-FileCopyrightText: 2007 Piyush verma <piyush.verma@gmail.com>
0003     SPDX-FileCopyrightText: 2008 Niko Sams <niko.sams@gmail.com>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "parsesession.h"
0009 
0010 #include "phpast.h"
0011 
0012 #include "kdev-pg-memory-pool.h"
0013 #include "kdev-pg-token-stream.h"
0014 #include "parserdebug.h"
0015 
0016 #include <QFile>
0017 #include <QTextCodec>
0018 
0019 #include <KLocalizedString>
0020 
0021 #include <interfaces/icore.h>
0022 #include <interfaces/ilanguagecontroller.h>
0023 #include <interfaces/icompletionsettings.h>
0024 #include <language/editor/documentrange.h>
0025 
0026 namespace Php
0027 {
0028 
0029 ParseSession::ParseSession()
0030         :   m_debug(false),
0031         m_pool(new KDevPG::MemoryPool()),
0032         m_tokenStream(new TokenStream())
0033 {
0034 }
0035 ParseSession::~ParseSession()
0036 {
0037     delete m_pool;
0038     delete m_tokenStream;
0039 }
0040 
0041 QString ParseSession::contents() const
0042 {
0043     return m_contents;
0044 }
0045 
0046 void ParseSession::setContents(const QString& contents)
0047 {
0048     m_contents = contents;
0049 }
0050 
0051 void ParseSession::setCurrentDocument(const KDevelop::IndexedString& filename)
0052 {
0053     m_currentDocument = filename;
0054 }
0055 
0056 KDevelop::IndexedString ParseSession::currentDocument() const
0057 {
0058     return m_currentDocument;
0059 }
0060 
0061 bool ParseSession::readFile(const QString& filename, const char* codec)
0062 {
0063     m_currentDocument = KDevelop::IndexedString(filename);
0064 
0065     QFile f(filename);
0066     if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
0067         KDevelop::ProblemPointer p(new KDevelop::Problem());
0068         p->setSource(KDevelop::IProblem::Disk);
0069         p->setDescription(i18n("Could not open file '%1'", filename));
0070         switch (f.error()) {
0071         case QFile::ReadError:
0072             p->setExplanation(i18n("File could not be read from."));
0073             break;
0074         case QFile::OpenError:
0075             p->setExplanation(i18n("File could not be opened."));
0076             break;
0077         case QFile::PermissionsError:
0078             p->setExplanation(i18n("File permissions prevent opening for read."));
0079             break;
0080         default:
0081             break;
0082         }
0083         p->setFinalLocation(KDevelop::DocumentRange(m_currentDocument, KTextEditor::Range()));
0084         m_problems << p;
0085         qCWarning(PARSER) << "Could not open file" << filename;
0086         return false;
0087     }
0088     QTextStream s(&f);
0089     if (codec)
0090         s.setCodec(QTextCodec::codecForName(codec));
0091     m_contents = s.readAll();
0092     return true;
0093 }
0094 
0095 void ParseSession::setDebug(bool debug)
0096 {
0097     m_debug = debug;
0098 }
0099 
0100 TokenStream* ParseSession::tokenStream() const
0101 {
0102     return m_tokenStream;
0103 }
0104 
0105 Parser* ParseSession::createParser(int initialState)
0106 {
0107     auto* parser = new Parser;
0108     parser->setTokenStream(m_tokenStream);
0109     parser->setMemoryPool(m_pool);
0110     parser->setDebug(m_debug);
0111     parser->setCurrentDocument(m_currentDocument);
0112     parser->setTodoMarkers(KDevelop::ICore::self()->languageController()->completionSettings()->todoMarkerWords());
0113 
0114     parser->tokenize(m_contents, initialState);
0115     return parser;
0116 }
0117 
0118 bool ParseSession::parse(Php::StartAst** ast)
0119 {
0120     Parser* parser = createParser();
0121     StartAst* phpAst;
0122     bool matched = parser->parseStart(&phpAst);
0123     if (matched) {
0124         qCDebug(PARSER) << "Successfully parsed";
0125         *ast = phpAst;
0126     } else {
0127         *ast = nullptr;
0128         parser->expectedSymbol(AstNode::StartKind, QStringLiteral("start"));
0129         qCDebug(PARSER) << "Couldn't parse content";
0130     }
0131     m_problems << parser->problems();
0132     delete parser;
0133     return matched;
0134 }
0135 
0136 KDevelop::CursorInRevision ParseSession::positionAt(qint64 offset) const
0137 {
0138     qint64 line, column;
0139     m_tokenStream->locationTable()->positionAt(offset, &line, &column);
0140     return KDevelop::CursorInRevision(line, column);
0141 }
0142 
0143 QString ParseSession::symbol(qint64 token) const
0144 {
0145     const TokenStream::Token& tok = m_tokenStream->at(token);
0146     return m_contents.mid(tok.begin, tok.end - tok.begin + 1);
0147 }
0148 
0149 QString ParseSession::symbol(AstNode* node) const
0150 {
0151     const TokenStream::Token& startTok = m_tokenStream->at(node->startToken);
0152     const TokenStream::Token& endTok = m_tokenStream->at(node->endToken);
0153     return m_contents.mid(startTok.begin, endTok.end - startTok.begin + 1);
0154 }
0155 
0156 QString ParseSession::docComment(qint64 token) const
0157 {
0158     const TokenStream::Token& tok = m_tokenStream->at(token);
0159     if (!tok.docCommentEnd) return QString();
0160     return m_contents.mid(tok.docCommentBegin, tok.docCommentEnd - tok.docCommentBegin + 1);
0161 }
0162 
0163 QList<KDevelop::ProblemPointer> ParseSession::problems()
0164 {
0165     return m_problems;
0166 }
0167 
0168 }