| 
									
										
										
										
											2017-05-24 13:23:01 +02:00
										 |  |  | /****************************************************************************
 | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** Copyright (C) 2017 The Qt Company Ltd. | 
					
						
							|  |  |  | ** Contact: https://www.qt.io/licensing/
 | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** This file is part of Qt Creator. | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** Commercial License Usage | 
					
						
							|  |  |  | ** Licensees holding valid commercial Qt licenses may use this file in | 
					
						
							|  |  |  | ** accordance with the commercial license agreement provided with the | 
					
						
							|  |  |  | ** Software or, alternatively, in accordance with the terms contained in | 
					
						
							|  |  |  | ** a written agreement between you and The Qt Company. For licensing terms | 
					
						
							|  |  |  | ** and conditions see https://www.qt.io/terms-conditions. For further
 | 
					
						
							|  |  |  | ** information use the contact form at https://www.qt.io/contact-us.
 | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** GNU General Public License Usage | 
					
						
							|  |  |  | ** Alternatively, this file may be used under the terms of the GNU | 
					
						
							|  |  |  | ** General Public License version 3 as published by the Free Software | 
					
						
							|  |  |  | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT | 
					
						
							|  |  |  | ** included in the packaging of this file. Please review the following | 
					
						
							|  |  |  | ** information to ensure the GNU General Public License requirements will | 
					
						
							|  |  |  | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
 | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ****************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "builtincursorinfo.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "cppcanonicalsymbol.h"
 | 
					
						
							|  |  |  | #include "cppcursorinfo.h"
 | 
					
						
							|  |  |  | #include "cpplocalsymbols.h"
 | 
					
						
							|  |  |  | #include "cppmodelmanager.h"
 | 
					
						
							|  |  |  | #include "cppsemanticinfo.h"
 | 
					
						
							|  |  |  | #include "cpptoolsreuse.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <texteditor/convenience.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <cplusplus/CppDocument.h>
 | 
					
						
							|  |  |  | #include <cplusplus/Macro.h>
 | 
					
						
							|  |  |  | #include <cplusplus/TranslationUnit.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <utils/qtcassert.h>
 | 
					
						
							|  |  |  | #include <utils/runextensions.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <QTextBlock>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using namespace CPlusPlus; | 
					
						
							|  |  |  | using SemanticUses = QList<CppTools::SemanticInfo::Use>; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace CppTools { | 
					
						
							|  |  |  | namespace { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CursorInfo::Range toRange(const SemanticInfo::Use &use) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return CursorInfo::Range(use.line, use.column, use.length); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CursorInfo::Range toRange(int tokenIndex, TranslationUnit *translationUnit) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     unsigned line, column; | 
					
						
							|  |  |  |     translationUnit->getTokenPosition(static_cast<unsigned>(tokenIndex), &line, &column); | 
					
						
							|  |  |  |     if (column) | 
					
						
							|  |  |  |         --column;  // adjust the column position.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return CursorInfo::Range( | 
					
						
							|  |  |  |                 line, | 
					
						
							|  |  |  |                 column +1, | 
					
						
							|  |  |  |                 translationUnit->tokenAt(static_cast<unsigned>(tokenIndex)).utf16chars()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CursorInfo::Range toRange(const QTextCursor &textCursor, | 
					
						
							|  |  |  |                                 unsigned utf16offset, | 
					
						
							|  |  |  |                                 unsigned length) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QTextCursor cursor(textCursor.document()); | 
					
						
							|  |  |  |     cursor.setPosition(static_cast<int>(utf16offset)); | 
					
						
							|  |  |  |     const QTextBlock textBlock = cursor.block(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return CursorInfo::Range( | 
					
						
							|  |  |  |                 static_cast<unsigned>(textBlock.blockNumber() + 1), | 
					
						
							|  |  |  |                 static_cast<unsigned>(cursor.position() - textBlock.position() + 1), | 
					
						
							|  |  |  |                 length); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CursorInfo::Ranges toRanges(const SemanticUses &uses) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     CursorInfo::Ranges ranges; | 
					
						
							|  |  |  |     ranges.reserve(uses.size()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (const SemanticInfo::Use &use : uses) | 
					
						
							|  |  |  |         ranges.append(toRange(use)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return ranges; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CursorInfo::Ranges toRanges(const QList<int> tokenIndices, TranslationUnit *translationUnit) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     CursorInfo::Ranges ranges; | 
					
						
							|  |  |  |     ranges.reserve(tokenIndices.size()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (int reference : tokenIndices) | 
					
						
							|  |  |  |         ranges.append(toRange(reference, translationUnit)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return ranges; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class FunctionDefinitionUnderCursor: protected ASTVisitor | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-06-12 10:31:29 +02:00
										 |  |  |     unsigned m_line = 0; | 
					
						
							|  |  |  |     unsigned m_column = 0; | 
					
						
							|  |  |  |     DeclarationAST *m_functionDefinition = nullptr; | 
					
						
							| 
									
										
										
										
											2017-05-24 13:23:01 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     FunctionDefinitionUnderCursor(TranslationUnit *translationUnit) | 
					
						
							|  |  |  |         : ASTVisitor(translationUnit) | 
					
						
							|  |  |  |     { } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     DeclarationAST *operator()(AST *ast, unsigned line, unsigned column) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-12 10:31:29 +02:00
										 |  |  |         m_functionDefinition = nullptr; | 
					
						
							|  |  |  |         m_line = line; | 
					
						
							|  |  |  |         m_column = column; | 
					
						
							| 
									
										
										
										
											2017-05-24 13:23:01 +02:00
										 |  |  |         accept(ast); | 
					
						
							| 
									
										
										
										
											2017-06-12 10:31:29 +02:00
										 |  |  |         return m_functionDefinition; | 
					
						
							| 
									
										
										
										
											2017-05-24 13:23:01 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | protected: | 
					
						
							|  |  |  |     virtual bool preVisit(AST *ast) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-12 10:31:29 +02:00
										 |  |  |         if (m_functionDefinition) | 
					
						
							| 
									
										
										
										
											2017-05-24 13:23:01 +02:00
										 |  |  |             return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (FunctionDefinitionAST *def = ast->asFunctionDefinition()) | 
					
						
							|  |  |  |             return checkDeclaration(def); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (ObjCMethodDeclarationAST *method = ast->asObjCMethodDeclaration()) { | 
					
						
							|  |  |  |             if (method->function_body) | 
					
						
							|  |  |  |                 return checkDeclaration(method); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     bool checkDeclaration(DeclarationAST *ast) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         unsigned startLine, startColumn; | 
					
						
							|  |  |  |         unsigned endLine, endColumn; | 
					
						
							|  |  |  |         getTokenStartPosition(ast->firstToken(), &startLine, &startColumn); | 
					
						
							|  |  |  |         getTokenEndPosition(ast->lastToken() - 1, &endLine, &endColumn); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-12 10:31:29 +02:00
										 |  |  |         if (m_line > startLine || (m_line == startLine && m_column >= startColumn)) { | 
					
						
							|  |  |  |             if (m_line < endLine || (m_line == endLine && m_column < endColumn)) { | 
					
						
							|  |  |  |                 m_functionDefinition = ast; | 
					
						
							| 
									
										
										
										
											2017-05-24 13:23:01 +02:00
										 |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class FindUses | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2017-06-16 14:15:02 +02:00
										 |  |  |     static CursorInfo find(const Document::Ptr document, const Snapshot &snapshot, | 
					
						
							|  |  |  |                            int line, int column, Scope *scope, const QString &expression) | 
					
						
							| 
									
										
										
										
											2017-05-24 13:23:01 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-16 14:15:02 +02:00
										 |  |  |         FindUses findUses(document, snapshot, line, column, scope, expression); | 
					
						
							| 
									
										
										
										
											2017-05-24 13:23:01 +02:00
										 |  |  |         return findUses.doFind(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							| 
									
										
										
										
											2017-06-16 14:15:02 +02:00
										 |  |  |     FindUses(const Document::Ptr document, const Snapshot &snapshot, int line, int column, | 
					
						
							|  |  |  |              Scope *scope, const QString &expression) | 
					
						
							|  |  |  |         : m_document(document) | 
					
						
							|  |  |  |         , m_line(line) | 
					
						
							|  |  |  |         , m_column(column) | 
					
						
							|  |  |  |         , m_scope(scope) | 
					
						
							|  |  |  |         , m_expression(expression) | 
					
						
							|  |  |  |         , m_snapshot(snapshot) | 
					
						
							| 
									
										
										
										
											2017-05-24 13:23:01 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     CursorInfo doFind() const | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         CursorInfo result; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-18 14:51:32 +02:00
										 |  |  |         const CppTools::SemanticInfo::LocalUseMap localUses | 
					
						
							|  |  |  |                 = BuiltinCursorInfo::findLocalUses(m_document, m_line, m_column); | 
					
						
							| 
									
										
										
										
											2017-05-24 13:23:01 +02:00
										 |  |  |         result.localUses = localUses; | 
					
						
							|  |  |  |         splitLocalUses(localUses, &result.useRanges, &result.unusedVariablesRanges); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!result.useRanges.isEmpty()) { | 
					
						
							|  |  |  |             result.areUseRangesForLocalVariable = true; | 
					
						
							|  |  |  |             return result; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         result.useRanges = findReferences(); | 
					
						
							|  |  |  |         result.areUseRangesForLocalVariable = false; | 
					
						
							|  |  |  |         return result; // OK, result.unusedVariablesRanges will be passed on
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void splitLocalUses(const CppTools::SemanticInfo::LocalUseMap &uses, | 
					
						
							|  |  |  |                         CursorInfo::Ranges *rangesForLocalVariableUnderCursor, | 
					
						
							|  |  |  |                         CursorInfo::Ranges *rangesForLocalUnusedVariables) const | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         QTC_ASSERT(rangesForLocalVariableUnderCursor, return); | 
					
						
							|  |  |  |         QTC_ASSERT(rangesForLocalUnusedVariables, return); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-12 10:31:29 +02:00
										 |  |  |         LookupContext context(m_document, m_snapshot); | 
					
						
							| 
									
										
										
										
											2017-05-24 13:23:01 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         CppTools::SemanticInfo::LocalUseIterator it(uses); | 
					
						
							|  |  |  |         while (it.hasNext()) { | 
					
						
							|  |  |  |             it.next(); | 
					
						
							|  |  |  |             const SemanticUses &uses = it.value(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             bool good = false; | 
					
						
							|  |  |  |             foreach (const CppTools::SemanticInfo::Use &use, uses) { | 
					
						
							| 
									
										
										
										
											2017-06-12 10:31:29 +02:00
										 |  |  |                 unsigned l = static_cast<unsigned>(m_line); | 
					
						
							| 
									
										
										
										
											2017-05-24 13:23:01 +02:00
										 |  |  |                 // convertCursorPosition() returns a 0-based column number.
 | 
					
						
							| 
									
										
										
										
											2017-06-12 10:31:29 +02:00
										 |  |  |                 unsigned c = static_cast<unsigned>(m_column + 1); | 
					
						
							| 
									
										
										
										
											2017-05-24 13:23:01 +02:00
										 |  |  |                 if (l == use.line && c >= use.column && c <= (use.column + use.length)) { | 
					
						
							|  |  |  |                     good = true; | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (uses.size() == 1) { | 
					
						
							|  |  |  |                 if (!CppTools::isOwnershipRAIIType(it.key(), context)) | 
					
						
							|  |  |  |                     rangesForLocalUnusedVariables->append(toRanges(uses)); // unused declaration
 | 
					
						
							|  |  |  |             } else if (good && rangesForLocalVariableUnderCursor->isEmpty()) { | 
					
						
							|  |  |  |                 rangesForLocalVariableUnderCursor->append(toRanges(uses)); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     CursorInfo::Ranges findReferences() const | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         CursorInfo::Ranges result; | 
					
						
							| 
									
										
										
										
											2017-06-12 10:31:29 +02:00
										 |  |  |         if (!m_scope || m_expression.isEmpty()) | 
					
						
							| 
									
										
										
										
											2017-05-24 13:23:01 +02:00
										 |  |  |             return result; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         TypeOfExpression typeOfExpression; | 
					
						
							| 
									
										
										
										
											2017-06-12 10:31:29 +02:00
										 |  |  |         Snapshot theSnapshot = m_snapshot; | 
					
						
							|  |  |  |         theSnapshot.insert(m_document); | 
					
						
							|  |  |  |         typeOfExpression.init(m_document, theSnapshot); | 
					
						
							| 
									
										
										
										
											2017-05-24 13:23:01 +02:00
										 |  |  |         typeOfExpression.setExpandTemplates(true); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-12 10:31:29 +02:00
										 |  |  |         if (Symbol *s = CanonicalSymbol::canonicalSymbol(m_scope, m_expression, typeOfExpression)) { | 
					
						
							| 
									
										
										
										
											2017-05-24 13:23:01 +02:00
										 |  |  |             CppTools::CppModelManager *mmi = CppTools::CppModelManager::instance(); | 
					
						
							|  |  |  |             const QList<int> tokenIndices = mmi->references(s, typeOfExpression.context()); | 
					
						
							| 
									
										
										
										
											2017-06-12 10:31:29 +02:00
										 |  |  |             result = toRanges(tokenIndices, m_document->translationUnit()); | 
					
						
							| 
									
										
										
										
											2017-05-24 13:23:01 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return result; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     // Shared
 | 
					
						
							| 
									
										
										
										
											2017-06-12 10:31:29 +02:00
										 |  |  |     Document::Ptr m_document; | 
					
						
							| 
									
										
										
										
											2017-05-24 13:23:01 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // For local use calculation
 | 
					
						
							| 
									
										
										
										
											2017-06-12 10:31:29 +02:00
										 |  |  |     int m_line; | 
					
						
							|  |  |  |     int m_column; | 
					
						
							| 
									
										
										
										
											2017-05-24 13:23:01 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // For references calculation
 | 
					
						
							| 
									
										
										
										
											2017-06-12 10:31:29 +02:00
										 |  |  |     Scope *m_scope; | 
					
						
							|  |  |  |     QString m_expression; | 
					
						
							|  |  |  |     Snapshot m_snapshot; | 
					
						
							| 
									
										
										
										
											2017-05-24 13:23:01 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool isSemanticInfoValidExceptLocalUses(const SemanticInfo &semanticInfo, int revision) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return semanticInfo.doc | 
					
						
							|  |  |  |         && semanticInfo.revision == static_cast<unsigned>(revision) | 
					
						
							|  |  |  |         && !semanticInfo.snapshot.isEmpty(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool isMacroUseOf(const Document::MacroUse &marcoUse, const Macro ¯o) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const Macro &candidate = marcoUse.macro(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return candidate.line() == macro.line() | 
					
						
							|  |  |  |         && candidate.utf16CharOffset() == macro.utf16CharOffset() | 
					
						
							|  |  |  |         && candidate.length() == macro.length() | 
					
						
							|  |  |  |         && candidate.fileName() == macro.fileName(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool handleMacroCase(const Document::Ptr document, | 
					
						
							|  |  |  |                      const QTextCursor &textCursor, | 
					
						
							|  |  |  |                      CursorInfo::Ranges *ranges) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QTC_ASSERT(ranges, return false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const Macro *macro = CppTools::findCanonicalMacro(textCursor, document); | 
					
						
							|  |  |  |     if (!macro) | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const unsigned length = static_cast<unsigned>(macro->nameToQString().size()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Macro definition
 | 
					
						
							|  |  |  |     if (macro->fileName() == document->fileName()) | 
					
						
							|  |  |  |         ranges->append(toRange(textCursor, macro->utf16CharOffset(), length)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Other macro uses
 | 
					
						
							|  |  |  |     foreach (const Document::MacroUse &use, document->macroUses()) { | 
					
						
							|  |  |  |         if (isMacroUseOf(use, *macro)) | 
					
						
							|  |  |  |             ranges->append(toRange(textCursor, use.utf16charsBegin(), length)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // anonymous namespace
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QFuture<CursorInfo> BuiltinCursorInfo::run(const CursorInfoParams &cursorInfoParams) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QFuture<CursorInfo> nothing; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const SemanticInfo semanticInfo = cursorInfoParams.semanticInfo; | 
					
						
							|  |  |  |     const int currentDocumentRevision = cursorInfoParams.textCursor.document()->revision(); | 
					
						
							|  |  |  |     if (!isSemanticInfoValidExceptLocalUses(semanticInfo, currentDocumentRevision)) | 
					
						
							|  |  |  |         return nothing; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const Document::Ptr document = semanticInfo.doc; | 
					
						
							|  |  |  |     const Snapshot snapshot = semanticInfo.snapshot; | 
					
						
							|  |  |  |     if (!document) | 
					
						
							|  |  |  |         return nothing; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QTC_ASSERT(document->translationUnit(), return nothing); | 
					
						
							|  |  |  |     QTC_ASSERT(document->translationUnit()->ast(), return nothing); | 
					
						
							|  |  |  |     QTC_ASSERT(!snapshot.isEmpty(), return nothing); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     CursorInfo::Ranges ranges; | 
					
						
							|  |  |  |     if (handleMacroCase(document, cursorInfoParams.textCursor, &ranges)) { | 
					
						
							|  |  |  |         CursorInfo result; | 
					
						
							|  |  |  |         result.useRanges = ranges; | 
					
						
							|  |  |  |         result.areUseRangesForLocalVariable = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         QFutureInterface<CursorInfo> fi; | 
					
						
							|  |  |  |         fi.reportResult(result); | 
					
						
							|  |  |  |         fi.reportFinished(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return fi.future(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-16 14:15:02 +02:00
										 |  |  |     const QTextCursor &textCursor = cursorInfoParams.textCursor; | 
					
						
							|  |  |  |     int line, column; | 
					
						
							|  |  |  |     TextEditor::Convenience::convertPosition(textCursor.document(), textCursor.position(), | 
					
						
							|  |  |  |                                              &line, &column); | 
					
						
							|  |  |  |     CanonicalSymbol canonicalSymbol(document, snapshot); | 
					
						
							|  |  |  |     QString expression; | 
					
						
							|  |  |  |     Scope *scope = canonicalSymbol.getScopeAndExpression(textCursor, &expression); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return Utils::runAsync(&FindUses::find, document, snapshot, line, column, scope, expression); | 
					
						
							| 
									
										
										
										
											2017-05-24 13:23:01 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-18 14:51:32 +02:00
										 |  |  | CppTools::SemanticInfo::LocalUseMap | 
					
						
							|  |  |  | BuiltinCursorInfo::findLocalUses(const Document::Ptr &document, int line, int column) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-08-24 08:31:27 +02:00
										 |  |  |     if (!document || !document->translationUnit() || !document->translationUnit()->ast()) | 
					
						
							|  |  |  |         return SemanticInfo::LocalUseMap(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-18 14:51:32 +02:00
										 |  |  |     AST *ast = document->translationUnit()->ast(); | 
					
						
							|  |  |  |     FunctionDefinitionUnderCursor functionDefinitionUnderCursor(document->translationUnit()); | 
					
						
							|  |  |  |     DeclarationAST *declaration = functionDefinitionUnderCursor(ast, | 
					
						
							|  |  |  |                                                                 static_cast<unsigned>(line), | 
					
						
							|  |  |  |                                                                 static_cast<unsigned>(column)); | 
					
						
							|  |  |  |     return CppTools::LocalSymbols(document, declaration).uses; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-24 13:23:01 +02:00
										 |  |  | } // namespace CppTools
 |