File indexing completed on 2024-03-24 04:36:55
0001 /***************************************************************************** 0002 * Copyright (c) 2007 Andreas Pakulat <apaku@gmx.de> * 0003 * Copyright (c) 2007 Piyush verma <piyush.verma@gmail.com> * 0004 * Copyright (c) 2008 Niko Sams <niko.sams@gmail.com> * 0005 * * 0006 * Permission is hereby granted, free of charge, to any person obtaining * 0007 * a copy of this software and associated documentation files (the * 0008 * "Software"), to deal in the Software without restriction, including * 0009 * without limitation the rights to use, copy, modify, merge, publish, * 0010 * distribute, sublicense, and/or sell copies of the Software, and to * 0011 * permit persons to whom the Software is furnished to do so, subject to * 0012 * the following conditions: * 0013 * * 0014 * The above copyright notice and this permission notice shall be * 0015 * included in all copies or substantial portions of the Software. * 0016 * * 0017 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * 0018 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 0019 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * 0020 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * 0021 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * 0022 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * 0023 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 0024 *****************************************************************************/ 0025 #include "parsesession.h" 0026 0027 #include "cssast.h" 0028 #include "debug.h" 0029 0030 #include "kdev-pg-memory-pool.h" 0031 #include "kdev-pg-token-stream.h" 0032 0033 #include <QFile> 0034 #include <QTextCodec> 0035 #include <KLocalizedString> 0036 0037 namespace Css 0038 { 0039 0040 ParseSession::ParseSession() 0041 : m_debug(false), 0042 m_pool(new KDevPG::MemoryPool()), 0043 m_tokenStream(new KDevPG::TokenStream()) 0044 { 0045 } 0046 ParseSession::~ParseSession() 0047 { 0048 delete m_pool; 0049 delete m_tokenStream; 0050 } 0051 0052 QString ParseSession::contents() const 0053 { 0054 return m_contents; 0055 } 0056 0057 KDevelop::IndexedString ParseSession::currentDocument() const 0058 { 0059 return m_currentDocument; 0060 } 0061 0062 void ParseSession::setContents(const QString& contents) 0063 { 0064 m_contents = contents; 0065 } 0066 0067 void ParseSession::setCurrentDocument(const KDevelop::IndexedString& filename) 0068 { 0069 m_currentDocument = filename; 0070 } 0071 0072 bool ParseSession::readFile(const QString& filename, const char* codec) 0073 { 0074 m_currentDocument = KDevelop::IndexedString(filename); 0075 0076 QFile f(filename); 0077 if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) { 0078 qCDebug(KDEV_CSS) << "Couldn't open project file:" << filename; 0079 return false; 0080 } 0081 QTextStream s(&f); 0082 if (codec) 0083 s.setCodec(QTextCodec::codecForName(codec)); 0084 m_contents = s.readAll(); 0085 return true; 0086 } 0087 0088 void ParseSession::setDebug(bool debug) 0089 { 0090 m_debug = debug; 0091 } 0092 0093 void ParseSession::setOffset(const KDevelop::CursorInRevision& offset) 0094 { 0095 m_offset = offset; 0096 } 0097 0098 KDevPG::TokenStream* ParseSession::tokenStream() const 0099 { 0100 return m_tokenStream; 0101 } 0102 0103 Parser* ParseSession::createParser() 0104 { 0105 Parser* parser = new Parser; 0106 parser->setTokenStream(m_tokenStream); 0107 parser->setMemoryPool(m_pool); 0108 parser->setDebug(m_debug); 0109 parser->setCurrentDocument(m_currentDocument); 0110 0111 parser->tokenize(m_contents); 0112 return parser; 0113 } 0114 0115 bool ParseSession::parse(Css::StartAst** ast) 0116 { 0117 Parser* parser = createParser(); 0118 StartAst* cssAst; 0119 bool matched = parser->parseStart(&cssAst); 0120 *ast = cssAst; 0121 if (matched) { 0122 qCDebug(KDEV_CSS) << "Successfully parsed"; 0123 } else { 0124 parser->expectedSymbol(AstNode::StartKind, "start"); 0125 qCDebug(KDEV_CSS) << "Couldn't parse content"; 0126 } 0127 m_problems << parser->problems(); 0128 delete parser; 0129 return matched; 0130 } 0131 0132 bool ParseSession::parse(DeclarationListAst** ast) 0133 { 0134 Parser* parser = createParser(); 0135 DeclarationListAst* cssAst; 0136 bool matched = parser->parseDeclarationList(&cssAst); 0137 *ast = cssAst; 0138 if (matched) { 0139 qCDebug(KDEV_CSS) << "Successfully parsed"; 0140 } else { 0141 parser->expectedSymbol(AstNode::DeclarationListKind, "declarationList"); 0142 qCDebug(KDEV_CSS) << "Couldn't parse content"; 0143 } 0144 m_problems << parser->problems(); 0145 delete parser; 0146 return matched; 0147 } 0148 0149 KDevelop::CursorInRevision ParseSession::positionAt(qint64 offset) const 0150 { 0151 qint64 line, column; 0152 m_tokenStream->locationTable()->positionAt(offset, &line, &column); 0153 if (m_offset.isValid()) { 0154 if (line == 0) column += m_offset.column; 0155 line += m_offset.line; 0156 } 0157 return KDevelop::CursorInRevision(line, column); 0158 } 0159 0160 QString ParseSession::symbol(qint64 token) const 0161 { 0162 const KDevPG::TokenStream::Token& tok = m_tokenStream->at(token); 0163 return m_contents.mid(tok.begin, tok.end - tok.begin + 1); 0164 } 0165 0166 QString ParseSession::symbol(AstNode* node) const 0167 { 0168 const KDevPG::TokenStream::Token& startTok = m_tokenStream->at(node->startToken); 0169 const KDevPG::TokenStream::Token& endTok = m_tokenStream->at(node->endToken); 0170 return m_contents.mid(startTok.begin, endTok.end - startTok.begin + 1); 0171 } 0172 0173 QList<KDevelop::ProblemPointer> ParseSession::problems() 0174 { 0175 return m_problems; 0176 } 0177 0178 }