File indexing completed on 2024-04-28 12:21:52
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 }