See More

/***************************************************************************** * Copyright (c) 2007 Piyush verma * * Copyright 2007 Andreas Pakulat * * * * Permission is hereby granted, free of charge, to any person obtaining * * a copy of this software and associated documentation files (the * * "Software"), to deal in the Software without restriction, including * * without limitation the rights to use, copy, modify, merge, publish, * * distribute, sublicense, and/or sell copies of the Software, and to * * permit persons to whom the Software is furnished to do so, subject to * * the following conditions: * * * * The above copyright notice and this permission notice shall be * * included in all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * *****************************************************************************/ #include "contextbuilder.h" // #include #include #include #include #include #include #include #include "pythoneditorintegrator.h" #include "dumpchain.h" #include #include using namespace KDevelop; using namespace KTextEditor; Python::PythonEditorIntegrator* Python::ContextBuilder::m_editor; namespace Python { PythonEditorIntegrator* ContextBuilder::editor() const { return ContextBuilder::m_editor; } TopDUContext* ContextBuilder::newTopContext(const RangeInRevision& range, ParsingEnvironmentFile* file) { IndexedString currentDocumentUrl = ContextBuilder::m_editor->parseSession()->currentDocument(); kDebug() << currentDocumentUrl.str(); if ( !file ) { file = new ParsingEnvironmentFile(currentDocumentUrl); file->setLanguage(IndexedString("python")); } TopDUContext* top = new TopDUContext(currentDocumentUrl, range, file); ReferencedTopDUContext ref(top); m_topContext = ref; return top; } void ContextBuilder::setEditor(PythonEditorIntegrator* editor) { //m_identifierCompiler = new IdentifierCompiler(editor->parseSession()); ContextBuilder::m_editor = editor; } void ContextBuilder::setEditor(ParseSession* session) { PythonEditorIntegrator* e = new PythonEditorIntegrator(/*session*/); //m_identifierCompiler = new IdentifierCompiler(e->parseSession()); setEditor(e); } void ContextBuilder::startVisiting( Ast* node ) { visitNode( node ); } void ContextBuilder::setContextOnNode( Ast* node, DUContext* context ) { node->context = context; } DUContext* ContextBuilder::contextFromNode( Ast* node ) { return node->context; } RangeInRevision ContextBuilder::editorFindRange( Ast* fromNode, Ast* toNode ) { return editor()->findRange(fromNode, toNode); } QualifiedIdentifier ContextBuilder::identifierForNode( Python::Identifier* node ) { return QualifiedIdentifier( node->value ); } void ContextBuilder::addImportedContexts() { if ( compilingContexts() && !m_importedParentContexts.isEmpty() ) { DUChainWriteLocker lock( DUChain::lock() ); foreach( DUContext* imported, m_importedParentContexts ) currentContext()->addImportedParentContext( imported ); m_importedParentContexts.clear(); } } void ContextBuilder::openContextForStatementList( const QList& l ) { if ( l.count() > 0 ) { Ast* first = l.first(); Ast* last = l.last(); openContext(first, RangeInRevision(first->startLine - 1, first->startCol, last->endLine + 1, 10000), DUContext::Other ); kDebug() << " +++ opening context: " << first->startLine - 1 << ":" << first->startCol << " -- " << last->endLine + 1 << "inf"; addImportedContexts(); visitNodeList( l ); closeContext(); } } void ContextBuilder::visitClassDefinition( ClassDefinitionAst* node ) { openContext( node, DUContext::Class, identifierForNode( node->name ) ); addImportedContexts(); visitNodeList( node->baseClasses ); visitNodeList( node->body ); closeContext(); } void ContextBuilder::visitArguments(ArgumentsAst* node) { AstDefaultVisitor::visitArguments(node); } void ContextBuilder::visitFunctionDefinition( FunctionDefinitionAst* node ) { kDebug() << " Building function definition context: " << node->name; ClassDefinitionAst* classast = dynamic_cast( node->parent ); if ( classast ) m_importedParentContexts.append( currentContext() ); visitNodeList( node->decorators ); if ( node->arguments ) { DUContext* funcctx = openContext( node->arguments, node->arguments, DUContext::Function, identifierForNode( node->name ) ); addImportedContexts(); visitNode( node->arguments ); closeContext(); m_importedParentContexts.append( funcctx ); } openContextForStatementList( node->body ); m_importedParentContexts.clear(); } void ContextBuilder::visitFor( ForAst* node ) { DUContext* forctx = openContext( node, KDevelop::DUContext::Other ); visitNode(node->target); closeContext(); visitNode(node->iterator); m_importedParentContexts = QList() << forctx; openContextForStatementList( node->body ); openContextForStatementList( node->orelse ); m_importedParentContexts.clear(); } void ContextBuilder::visitWhile( WhileAst* node ) { visitNode( node->condition ); openContextForStatementList( node->body ); openContextForStatementList( node->orelse ); } void ContextBuilder::visitWith( WithAst * node ) { m_importedParentContexts = QList() << openContext( node->contextExpression, DUContext::Other ); visitNode( node->contextExpression ); closeContext(); openContextForStatementList( node->body ); m_importedParentContexts.clear(); } // void ContextBuilder::visitTry( TryAst* node ) // { // kDebug() << "creating contexts for try"; // openContextForStatementList( node->tryBody ); // visitNodeList( node->exceptions ); // openContextForStatementList( node->elseBody ); // openContextForStatementList( node->finallyBody ); // } void ContextBuilder::visitIf( IfAst* node ) { visitNode( node->condition ); openContextForStatementList( node->body ); foreach ( StatementAst* current, node->body) { visitNode(current); } openContextForStatementList( node->orelse ); } }