MonoDevelop.CSharp.Completion.CSharpTextEditorCompletion.HandleKeywordCompletion C# (CSharp) Method

HandleKeywordCompletion() public method

public HandleKeywordCompletion ( MonoDevelop.Ide.CodeCompletion.CodeCompletionContext completionContext, MonoDevelop.Projects.Dom.ExpressionResult result, int wordStart, string word ) : ICompletionDataList
completionContext MonoDevelop.Ide.CodeCompletion.CodeCompletionContext
result MonoDevelop.Projects.Dom.ExpressionResult
wordStart int
word string
return ICompletionDataList
		public ICompletionDataList HandleKeywordCompletion (CodeCompletionContext completionContext, ExpressionResult result, int wordStart, string word)
		{
			if (stateTracker.Engine.IsInsideDocLineComment || stateTracker.Engine.IsInsideOrdinaryCommentOrString)
				return null;
			DomLocation location = new DomLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset);
			switch (word) {
			case "using":
				if (result.ExpressionContext != ExpressionContext.NamespaceNameExcepted)
					return null;
				return CreateCompletionData (location, new NamespaceResolveResult (""), result, null);
			case "namespace":
				result.ExpressionContext = ExpressionContext.NamespaceNameExcepted;
				return CreateCompletionData (location, new NamespaceResolveResult (""), result, null);
			case "case":
				return CreateCaseCompletionData (location, result);
			case ",":
			case ":":
				if (result.ExpressionContext == ExpressionContext.InheritableType) {
					IType cls = NRefactoryResolver.GetTypeAtCursor (Document.CompilationUnit, Document.FileName, new DomLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
					CompletionDataList completionList = new ProjectDomCompletionDataList ();
					List<string> namespaceList = GetUsedNamespaces ();
					CSharpTextEditorCompletion.CompletionDataCollector col = new CSharpTextEditorCompletion.CompletionDataCollector (dom, completionList, Document.CompilationUnit, null, location);
					bool isInterface = false;
					HashSet<string> baseTypeNames = new HashSet<string> ();
					if (cls != null) {
						baseTypeNames.Add (cls.Name);
						if (cls.ClassType == ClassType.Struct)
							isInterface = true;
					}
					int tokenIndex = completionContext.TriggerOffset;

										// Search base types " : [Type1, ... ,TypeN,] <Caret>"
					string token = null;
					do {
						token = GetPreviousToken (ref tokenIndex, false);
						if (string.IsNullOrEmpty (token))
							break;
						token = token.Trim ();
						if (Char.IsLetterOrDigit (token[0]) || token[0] == '_') {
							IType baseType = dom.SearchType (Document.CompilationUnit, cls, result.Region.Start, token);
							if (baseType != null) {
								if (baseType.ClassType != ClassType.Interface)
									isInterface = true;
								baseTypeNames.Add (baseType.Name);
							}
						}
					} while (token != ":");
					foreach (object o in dom.GetNamespaceContents (namespaceList, true, true)) {
						IType type = o as IType;
						if (type != null && (type.IsStatic || type.IsSealed || baseTypeNames.Contains (type.Name) || isInterface && type.ClassType != ClassType.Interface)) {
							continue;
						}
						if (o is Namespace && !namespaceList.Any (ns => ns.StartsWith (((Namespace)o).FullName)))
							continue;
						col.Add (o);
					}
					// Add inner classes
					Stack<IType> innerStack = new Stack<IType> ();
					innerStack.Push (cls);
					while (innerStack.Count > 0) {
						IType curType = innerStack.Pop ();
						if (curType == null)
							continue;
						foreach (IType innerType in curType.InnerTypes) {
							if (innerType != cls)
								// don't add the calling class as possible base type
								col.Add (innerType);
						}
						if (curType.DeclaringType != null)
							innerStack.Push (curType.DeclaringType);
					}
					return completionList;
				}
				break;
			case "is":
			case "as":
				
				{
					CompletionDataList completionList = new ProjectDomCompletionDataList ();
					ExpressionResult expressionResult = FindExpression (dom, completionContext, wordStart - textEditorData.Caret.Offset);
					NRefactoryResolver resolver = CreateResolver ();
					ResolveResult resolveResult = resolver.Resolve (expressionResult, new DomLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
					if (resolveResult != null && resolveResult.ResolvedType != null) {
						CompletionDataCollector col = new CompletionDataCollector (dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
						IType foundType = null;
						if (word == "as") {
							ExpressionContext exactContext = new NewCSharpExpressionFinder (dom).FindExactContextForAsCompletion (textEditorData, Document.CompilationUnit, Document.FileName, resolver.CallingType);
							if (exactContext is ExpressionContext.TypeExpressionContext) {
								foundType = resolver.SearchType (((ExpressionContext.TypeExpressionContext)exactContext).Type);
								AddAsCompletionData (col, foundType);
							}
						}
					
						if (foundType == null)
							foundType = resolver.SearchType (resolveResult.ResolvedType);
					
						if (foundType != null) {
							if (foundType.ClassType == ClassType.Interface)
								foundType = resolver.SearchType (DomReturnType.Object);
						
							foreach (IType type in dom.GetSubclasses (foundType)) {
								if (type.IsSpecialName || type.Name.StartsWith ("<"))
									continue;
								AddAsCompletionData (col, type);
							}
						}
						List<string> namespaceList = GetUsedNamespaces ();
						foreach (object o in dom.GetNamespaceContents (namespaceList, true, true)) {
							if (o is IType) {
								IType type = (IType)o;
								if (type.ClassType != ClassType.Interface || type.IsSpecialName || type.Name.StartsWith ("<"))
									continue;
//								if (foundType != null && !dom.GetInheritanceTree (foundType).Any (x => x.FullName == type.FullName))
//									continue;
								AddAsCompletionData (col, type);
								continue;
							}
							if (o is Namespace)
								continue;
							col.Add (o);
						}
						return completionList;
					}
					result.ExpressionContext = ExpressionContext.TypeName;
					return CreateCtrlSpaceCompletionData (completionContext, result);
				}
			case "override":
				// Look for modifiers, in order to find the beginning of the declaration
				int firstMod = wordStart;
				int i = wordStart;
				for (int n = 0; n < 3; n++) {
					string mod = GetPreviousToken (ref i, true);
					if (mod == "public" || mod == "protected" || mod == "private" || mod == "internal" || mod == "sealed") {
						firstMod = i;
					} else if (mod == "static") {
						// static methods are not overridable
						return null;
					} else
						break;
				}
				IType overrideCls = NRefactoryResolver.GetTypeAtCursor (Document.CompilationUnit, Document.FileName, new DomLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
				if (overrideCls == null)
					overrideCls = NRefactoryResolver.GetTypeAtCursor (Document.CompilationUnit, Document.FileName, new DomLocation (completionContext.TriggerLine - 1, 1));
				if (overrideCls != null && (overrideCls.ClassType == ClassType.Class || overrideCls.ClassType == ClassType.Struct)) {
					string modifiers = textEditorData.GetTextBetween (firstMod, wordStart);
					return GetOverrideCompletionData (completionContext, overrideCls, modifiers);
				}
				return null;
			case "partial":
				// Look for modifiers, in order to find the beginning of the declaration
				firstMod = wordStart;
				i = wordStart;
				for (int n = 0; n < 3; n++) {
					string mod = GetPreviousToken (ref i, true);
					if (mod == "public" || mod == "protected" || mod == "private" || mod == "internal" || mod == "sealed") {
						firstMod = i;
					} else if (mod == "static") {
						// static methods are not overridable
						return null;
					} else
						break;
				}
				overrideCls = NRefactoryResolver.GetTypeAtCursor (Document.CompilationUnit, Document.FileName, new DomLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
				if (overrideCls != null && (overrideCls.ClassType == ClassType.Class || overrideCls.ClassType == ClassType.Struct)) {
					string modifiers = textEditorData.GetTextBetween (firstMod, wordStart);
					return GetPartialCompletionData (completionContext, overrideCls, modifiers);
				}
				return null;
				
			case "new":
				IType callingType = NRefactoryResolver.GetTypeAtCursor (Document.CompilationUnit, Document.FileName, new DomLocation (textEditorData.Caret.Line, textEditorData.Caret.Column));
				ExpressionContext newExactContext = new NewCSharpExpressionFinder (dom).FindExactContextForNewCompletion (textEditorData, Document.CompilationUnit, Document.FileName, callingType);
				if (newExactContext is ExpressionContext.TypeExpressionContext)
					return CreateTypeCompletionData (location, callingType, newExactContext, ((ExpressionContext.TypeExpressionContext)newExactContext).Type, ((ExpressionContext.TypeExpressionContext)newExactContext).UnresolvedType);
				if (newExactContext == null) {
					int j = completionContext.TriggerOffset - 4;
					string token = GetPreviousToken (ref j, true);
					string yieldToken = GetPreviousToken (ref j, true);
					if (token == "return") {
						NRefactoryResolver resolver = CreateResolver ();
						resolver.SetupResolver (new DomLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
						IReturnType returnType = resolver.CallingMember.ReturnType;
						if (yieldToken == "yield" && returnType.GenericArguments.Count > 0)
							returnType = returnType.GenericArguments[0];
						if (resolver.CallingMember != null)
							return CreateTypeCompletionData (location, callingType, newExactContext, null, returnType);
					}
				}
				return CreateCtrlSpaceCompletionData (completionContext, null);
			case "if":
			case "elif":
				if (stateTracker.Engine.IsInsidePreprocessorDirective) 
					return GetDefineCompletionData ();
				return null;
			case "yield":
				CompletionDataList yieldDataList = new CompletionDataList ();
				yieldDataList.DefaultCompletionString = "return";
				yieldDataList.Add ("break", "md-keyword");
				yieldDataList.Add ("return", "md-keyword");
				return yieldDataList;
			case "where":
				CompletionDataList whereDataList = new CompletionDataList ();
				NRefactoryResolver constraintResolver = CreateResolver ();
				constraintResolver.SetupResolver (new DomLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
				if (constraintResolver.CallingMember is IMethod) {
					foreach (ITypeParameter tp in ((IMethod)constraintResolver.CallingMember).TypeParameters) {
						whereDataList.Add (tp.Name, "md-keyword");
					}
				} else {
					if (constraintResolver.CallingType != null) {
						foreach (ITypeParameter tp in constraintResolver.CallingType.TypeParameters) {
							whereDataList.Add (tp.Name, "md-keyword");
						}
					}
				}

				return whereDataList;
			}
			if (IsInLinqContext (result)) {
				if (linqKeywords.Contains (word)) {
					if (word == "from") // after from no auto code completion.
						return null;
					result.Expression = "";
					return CreateCtrlSpaceCompletionData (completionContext, result);
				}
				CompletionDataList dataList = new ProjectDomCompletionDataList ();
				CompletionDataCollector col = new CompletionDataCollector (dom, dataList, Document.CompilationUnit, null, new DomLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
				foreach (string kw in linqKeywords) {
					col.Add (kw, "md-keyword");
				}
				return dataList;
			}
			return null;
		}