File indexing completed on 2024-04-28 04:34:23

0001 /***************************************************************************
0002  *   This file is part of KDevelop                                         *
0003  *   Copyright 2010 Niko Sams <niko.sams@gmail.com>                        *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU Library General Public License as       *
0007  *   published by the Free Software Foundation; either version 2 of the    *
0008  *   License, or (at your option) any later version.                       *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU Library General Public     *
0016  *   License along with this program; if not, write to the                 *
0017  *   Free Software Foundation, Inc.,                                       *
0018  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
0019  ***************************************************************************/
0020 
0021 #include "contextbuilder.h"
0022 
0023 #include <language/duchain/duchain.h>
0024 #include <language/duchain/topducontext.h>
0025 #include <language/duchain/duchainlock.h>
0026 #include <language/duchain/declaration.h>
0027 #include <language/duchain/classdeclaration.h>
0028 
0029 #include <interfaces/icore.h>
0030 #include <interfaces/ilanguagecontroller.h>
0031 #include <interfaces/icompletionsettings.h>
0032 
0033 #include <KLocalizedString>
0034 
0035 #include "../../parser/parsesession.h"
0036 #include "../../parser/editorintegrator.h"
0037 // #include "../helper.h"
0038 #include "cssast.h"
0039 
0040 namespace Css
0041 {
0042 
0043 ContextBuilder::ContextBuilder()
0044     : m_reportErrors(true)
0045     , m_editor(nullptr)
0046 {
0047 }
0048 
0049 ContextBuilder::~ContextBuilder()
0050 {
0051 }
0052 
0053 KDevelop::ReferencedTopDUContext ContextBuilder::build(const KDevelop::IndexedString& url, AstNode* node,
0054         const KDevelop::ReferencedTopDUContext& updateContext)
0055 {
0056     if ( KDevelop::ICore::self() ) {
0057         m_reportErrors = KDevelop::ICore::self()->languageController()->completionSettings()->highlightSemanticProblems();
0058     }
0059     return ContextBuilderBase::build(url, node, updateContext);
0060 }
0061 
0062 void ContextBuilder::startVisiting(AstNode* node)
0063 {
0064     if (node->kind == HtmlAst::KIND) {
0065         foreach (AstNode *el, static_cast<HtmlAst*>(node)->elements) {
0066             qCDebug(KDEV_CSS) << el->kind;
0067             if (el->kind == StyleElementAst::KIND) {
0068                 editor()->setParseSession(static_cast<StyleElementAst*>(el)->session);
0069                 visitNode(static_cast<StyleElementAst*>(el)->start);
0070             } else if (el->kind == InlineStyleAst::KIND) {
0071                 editor()->setParseSession(static_cast<InlineStyleAst*>(el)->session);
0072                 InlineStyleAst* n = static_cast<InlineStyleAst*>(el);
0073 
0074                 KDevelop::RangeInRevision range = editor()->findRange(n->declarationList);
0075                 qCDebug(KDEV_CSS) << range;
0076                 openContext(n, range,
0077                             KDevelop::DUContext::Class,
0078                             KDevelop::QualifiedIdentifier("TODO"));
0079                 visitNode(n->declarationList);
0080                 closeContext();
0081             } else {
0082                 Q_ASSERT(0);
0083             }
0084         }
0085     } else {
0086         qCDebug(KDEV_CSS)  << node->kind;
0087         Q_ASSERT(node->kind == StartAst::KIND);
0088         visitNode(node);
0089     }
0090 }
0091 
0092 KDevelop::TopDUContext* ContextBuilder::newTopContext(const KDevelop::RangeInRevision& range,
0093                                                       KDevelop::ParsingEnvironmentFile* file)
0094 {
0095     if (!file) {
0096         file = new KDevelop::ParsingEnvironmentFile(document());
0097         file->setLanguage(KDevelop::IndexedString("Css"));
0098     }
0099     return new KDevelop::TopDUContext(document(), range, file);
0100 }
0101 
0102 void ContextBuilder::setContextOnNode(AstNode* /*node*/, KDevelop::DUContext* /*ctx*/)
0103 {
0104     //node->ducontext = ctx;
0105 }
0106 
0107 KDevelop::DUContext* ContextBuilder::contextFromNode(AstNode* /*node*/)
0108 {
0109     //return node->ducontext;
0110     return nullptr;
0111 }
0112 
0113 void ContextBuilder::setEditor( EditorIntegrator* editor )
0114 {
0115     m_editor = editor;
0116 }
0117 
0118 EditorIntegrator* ContextBuilder::editor() const
0119 {
0120     Q_ASSERT(m_editor);
0121     return m_editor;
0122 }
0123 
0124 KDevelop::CursorInRevision ContextBuilder::startPos(AstNode* node)
0125 {
0126     return editor()->findPosition(node->startToken, EditorIntegrator::FrontEdge);
0127 }
0128 KDevelop::QualifiedIdentifier ContextBuilder::identifierForNode(SpecifierAst* id)
0129 {
0130     if (!id)
0131         return KDevelop::QualifiedIdentifier();
0132     if (id->className != -1) {
0133         return KDevelop::QualifiedIdentifier(editor()->parseSession()->symbol(id->className));
0134     }
0135     return KDevelop::QualifiedIdentifier();
0136 }
0137 
0138 KDevelop::RangeInRevision ContextBuilder::editorFindRange( AstNode* fromRange, AstNode* toRange )
0139 {
0140     return m_editor->findRange(fromRange, toRange);
0141 }
0142 
0143 void ContextBuilder::visitRuleset(RulesetAst* node)
0144 {
0145     qCDebug(KDEV_CSS) << node << node->declarations;
0146     Q_ASSERT(node->declarations);
0147     KDevelop::RangeInRevision range;
0148     if (node->lbrace != -1) {
0149         range.start = editor()->findPosition(node->lbrace, EditorIntegrator::BackEdge);
0150     } else {
0151         range.start = editor()->findPosition(node->declarations->startToken, EditorIntegrator::FrontEdge);
0152     }
0153     range.end = editor()->findPosition(node->declarations->endToken, EditorIntegrator::BackEdge);
0154     openContext(node, range,
0155                 KDevelop::DUContext::Class,
0156                 KDevelop::QualifiedIdentifier("TODO"));
0157     DefaultVisitor::visitRuleset(node);
0158     closeContext();
0159 }
0160 
0161 }