1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340
|
/*
Copyright 2007-2009 David Nolden <david.nolden.kdevelop@art-master.de>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef CODECOMPLETIONCONTEXT_H
#define CODECOMPLETIONCONTEXT_H
#include <ktexteditor/cursor.h>
#include <ksharedptr.h>
#include <language/duchain/duchainpointer.h>
#include "../cppduchain/typeconversion.h"
#include "../cppduchain/expressionparser.h"
#include "../cppduchain/viablefunctions.h"
#include "../cppduchain/overloadresolutionhelper.h"
#include "../cppduchain/expressionevaluationresult.h"
#include <language/util/includeitem.h>
#include "item.h"
#include <language/codecompletion/codecompletioncontext.h>
namespace KTextEditor {
class View;
class Cursor;
}
namespace KDevelop {
class DUContext;
class AbstractType;
class CompletionTreeItem;
typedef KSharedPtr<CompletionTreeItem> CompletionTreeItemPointer;
}
namespace Cpp {
class OverloadResolutionFunction;
class ImplementationHelperItem;
#ifdef TEST_COMPLETION
int expressionBefore( const QString& _text, int index );
#endif
/**
* This class is responsible for finding out what kind of completion is needed, what expression should be evaluated for the container-class of the completion, what conversion will be applied to the result of the completion, etc.
* */
class CodeCompletionContext : public KDevelop::CodeCompletionContext {
public:
///Computes the full set of completion items, using the information retrieved earlier.
///Should only be called on the first context, parent contexts are included in the computations.
///@param Abort is checked regularly, and if it is false, the computation is aborted.
virtual QList<CompletionTreeItemPointer> completionItems(bool& abort, bool fullCompletion = true);
virtual QList< KSharedPtr< KDevelop::CompletionTreeElement > > ungroupedElements();
typedef KSharedPtr<CodeCompletionContext> Ptr;
typedef OverloadResolutionFunction Function;
typedef QList<Function> FunctionList;
enum AccessType {
NoMemberAccess, /// With NoMemberAccess, a global completion should be done
MemberAccess, /// "Class."
ArrowMemberAccess, /// "Class->"
StaticMemberChoose, /// "Class::"
MemberChoose, /// "Class->ParentClass::"
SignalAccess, /// All signals from MemberAccessContainer should be listed
SlotAccess, /// All slots from MemberAccessContainer should be listed
IncludeListAccess, /// A list of include-files should be presented. Get the list through includeItems()
/// The following will never appear as initial accessType, but as a parentContext()
FunctionCallAccess, /// "function("
BinaryOpFunctionCallAccess, /// "var1 {somebinaryoperator} "
TemplateAccess, /// "bla<."
ReturnAccess, /// "return " -- Takes into account return type
CaseAccess, /// "case " -- Takes into account switch expression type
};
/**
* @param firstContext should be true for a context that has no parent. Such a context will never be a function-call context.
* @param text the text to analyze. It usually is the text in the range starting at the beginning of the context, and ending at the position where completion should start
* @warning The du-chain must be unlocked when this is called
* @param knownArgumentExpressions has no effect when firstContext is set
* @param line Optional line that will be used to filter the macros
* */
CodeCompletionContext(KDevelop::DUContextPointer context, const QString& text, const QString& followingText, const KDevelop::CursorInRevision& position, int depth = 0, const QStringList& knownArgumentExpressions = QStringList(), int line = -1 );
~CodeCompletionContext();
/**In the case of recursive argument-hints, there may be a chain of parent-contexts, each for the higher argument-matching
* The parentContext() should always have the access-operation FunctionCallAccess.
* When a completion-list is computed, the members of the list can be highlighted that match the corresponding parentContext()->functions() function-argument, or parentContext()->additionalMatchTypes()
* */
CodeCompletionContext* parentContext() const;
///@return the used access-operation
AccessType accessType() const;
/**
* When the access-operation is a MemberAccess or ArrowMemberAccess, this
* is the container that completion should happen in
* (the code-completion should list its non-static content).
*
* When memberAccessOperation is StaticMemberChoose, the code-completion
* should list all static members of this container.
*
* When memberAccessOperation is MemberChoose, it should be treated equivalently to MemberAccess.
*
* The type does not respect the member-access-operation, so
* the code-completion may check whether the arrow-access was used correctly
* and maybe do automatic correction.
* @return the type of the container that should be completed in.
* */
ExpressionEvaluationResult memberAccessContainer() const;
/**
* Returns the internal context of memberAccessContainer, if any.
*
* When memberAccessOperation is StaticMemberChoose, this returns all
* fitting namespace-contexts.
* *DUChain must be locked*
* */
QSet<DUContext*> memberAccessContainers() const;
/**
* When memberAccessOperation is FunctionCallAccess,
* this returns all functions available for matching, together with the argument-number that should be matched.
*
* Operators are treated as functions, but there is special-cases that need to be treated, especially operator=(..), because that operator competes with normal type-conversion.
*
* To also respect builtin operators, the types returned by additionalMatchTypes() must be respected.
* */
const FunctionList& functions() const;
/// @return of the function name for this context. Also works for operators.
QString functionName() const;
/**
* When memberAccessOperation is IncludeListAccess, then this contains all the files to be listed.
* */
QList<KDevelop::IncludeItem> includeItems() const;
///*DUChain must be locked*
KDevelop::IndexedType applyPointerConversionForMatching(KDevelop::IndexedType type, bool fromLValue) const;
QString followingText() const;
void setFollowingText(QString str);
bool isConstructorInitialization();
///If this is a function call context, this returns the arguments to the function that are already known
QList<ExpressionEvaluationResult> knownArgumentTypes() const;
///Returns position of the argument being matched
int matchPosition() const;
#ifndef TEST_COMPLETION
private:
#endif
enum OnlyShow {
ShowAll,
ShowTypes,
ShowSignals,
ShowSlots,
ShowVariables,
ShowImplementationHelpers
};
#ifdef TEST_COMPLETION
OnlyShow onlyShow() { return m_onlyShow; };
private:
#endif
///Preprocess m_text (replace macros with their body etc.)
void preprocessText(int line);
///looks at @param str to determine current context
///*DUChain must be locked*
AccessType findAccessType(const QString &str) const;
///Get local class from m_duContext, if available
///*DUChain must be locked*
DUContextPointer findLocalClass() const;
///Find if this context should limit completions to certain kinds
///*DUChain must be locked*
OnlyShow findOnlyShow(const QString &accessStr) const;
///Get the types for m_knownArgumentExpressions
///*DUChain must be locked*
QList<ExpressionEvaluationResult> getKnownArgumentTypes() const;
///Looks in m_text to find @param expression, @param expressionPrefix,
///and whether the expression @param istypeprefix
///*DUChain must be locked*
void findExpressionAndPrefix(QString &expression, QString &expressionPrefix, bool &isTypePrefix) const;
///Create and return a parent context for the given @param expressionPrefix
KSharedPtr<KDevelop::CodeCompletionContext> getParentContext(const QString &expressionPrefix) const;
///Evaluate m_expression
ExpressionEvaluationResult evaluateExpression() const;
///Remove unary operators from the end of m_text, setting m_pointerConversionsBeforeMatching accordingly
void skipUnaryOperators(QString &str, int &pointerConversions) const;
///test if the context is valid for its accessType
bool testContextValidity(const QString &expressionPrefix, const QString &accessStr) const;
/**
* Specialized processing for access types
* *DUChain must be locked for these functions*
**/
void processArrowMemberAccess();
void processFunctionCallAccess();
void processAllMemberAccesses();
///Whether or not this context should add parent items
bool shouldAddParentItems(bool fullCompletion);
/**
* Item creation functions for various completion types
**/
///*DUChain must be locked*
QList<CompletionTreeItemPointer> keywordCompletionItems();
QList<CompletionTreeItemPointer> memberAccessCompletionItems(const bool& shouldAbort);
QList<CompletionTreeItemPointer> returnAccessCompletionItems();
QList<CompletionTreeItemPointer> caseAccessCompletionItems();
QList<CompletionTreeItemPointer> templateAccessCompletionItems();
QList<CompletionTreeItemPointer> functionAccessCompletionItems(bool fullCompletion);
QList<CompletionTreeItemPointer> binaryFunctionAccessCompletionItems(bool fullCompletion);
///*DUChain must be locked*
QList<CompletionTreeItemPointer> commonFunctionAccessCompletionItems(bool fullCompletion);
QList<CompletionTreeItemPointer> includeListAccessCompletionItems(const bool& shouldAbort);
QList<CompletionTreeItemPointer> signalSlotAccessCompletionItems();
///Computes the completion-items for the case that no special kind of access is used(just a list of all suitable items is needed)
QList<CompletionTreeItemPointer> standardAccessCompletionItems();
QList<CompletionTreeItemPointer> getImplementationHelpers();
QList<CompletionTreeItemPointer> getImplementationHelpersInternal(const QualifiedIdentifier& minimumScope, DUContext* context);
///*DUChain must be locked*
bool filterDeclaration(Declaration* decl, DUContext* declarationContext = 0, bool dynamic = true);
///*DUChain must be locked*
bool filterDeclaration(ClassMemberDeclaration* decl, DUContext* declarationContext = 0);
///Replaces the member-access type at the current cursor position from "from" to "new", for example from "->" to "."
///*DUChain must be locked*
void replaceCurrentAccess(QString old, QString _new);
///Creates the group and adds it to m_storedUngroupedItems if items is not empty
void eventuallyAddGroup(QString name, int priority, QList< KSharedPtr< KDevelop::CompletionTreeItem > > items);
///Returns the required prefix that is needed in order to find the givne declaration from the current context.
///In worst case, it is the scope prefix of the declaration.
///*DUChain must be locked*
QualifiedIdentifier requiredPrefix(Declaration* decl) const;
///@param type The type of the argument the items are matched to.
///*DUChain must be locked*
QList<CompletionTreeItemPointer> specialItemsForArgumentType(AbstractType::Ptr type);
///Returns whether the declaration is directly visible from within the current context
bool visibleFromWithin(Declaration* decl, DUContext* currentContext);
///Returns whether the end of m_text is a valid completion-position
bool isValidPosition();
///Returns whether this is a valid context for implementation helpers
bool isImplementationHelperValid() const;
/**
* Group adding functions
* *DUChain must be locked for these functions*
**/
void addOverridableItems();
void addImplementationHelpers();
void addCPPBuiltin();
/**
* Specialized completion functions, if these completion types are
* valid, no need to continue searching for information about this context
* *DUChain must be locked for these functions*
**/
///Handle SIGNAL/SLOT in connect/disconnect, \returns true if valid
bool doSignalSlotCompletion();
///Handle include path completion, \returns true if valid
bool doIncludeCompletion();
///Handle code-completion for constructor-initializers, \returns true if valid
bool doConstructorCompletion();
AccessType m_accessType;
QString m_expression;
QString m_followingText;
QString m_operator; //If this completion-context ends with a binary operator, this is the operator
ExpressionEvaluationResult m_expressionResult;
//Here known argument-expressions and their types, that may have come from sub-contexts, are stored
QStringList m_knownArgumentExpressions;
QList<ExpressionEvaluationResult> m_knownArgumentTypes;
QString m_functionName;
QList<Function> m_matchingFunctionOverloads;
//If a signal/slot access is performed, and a slot is being connected to a signal, this contains the identifier and the signature
Identifier m_connectedSignalIdentifier;
QByteArray m_connectedSignalNormalizedSignature;
IndexedDeclaration m_connectedSignal;
//true if constructor completion is performed
bool m_isConstructorCompletion;
//include completion items for include completion
QList<KDevelop::IncludeItem> m_includeItems;
//0 = No conversion, +1, +2, .. = increase pointer level = &, -1, -2, .. = decrease pointer level = *
int m_pointerConversionsBeforeMatching;
QList<KDevelop::CompletionTreeElementPointer> m_storedUngroupedItems;
//A specific completion item type to show, or ShowAll, see enum OnlyShow
OnlyShow m_onlyShow;
//Expression is set to the type part in something like: {type}{varname}{initialization}
bool m_expressionIsTypePrefix;
bool m_doAccessFiltering;
DUContextPointer m_localClass;
friend class ImplementationHelperItem;
};
}
#endif
|