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

HandleCodeCompletion() public method

public HandleCodeCompletion ( MonoDevelop.Ide.CodeCompletion.CodeCompletionContext completionContext, char completionChar, int &triggerWordLength ) : ICompletionDataList
completionContext MonoDevelop.Ide.CodeCompletion.CodeCompletionContext
completionChar char
triggerWordLength int
return ICompletionDataList
		public override ICompletionDataList HandleCodeCompletion (CodeCompletionContext completionContext, char completionChar, ref int triggerWordLength)
		{
			if (textEditorData.CurrentMode is CompletionTextLinkMode) {
				if (!((CompletionTextLinkMode)textEditorData.CurrentMode).TriggerCodeCompletion)
					return null;
			} else if (textEditorData.CurrentMode is Mono.TextEditor.TextLinkEditMode) {
				return null;
			}

//		IDisposable timer = null;
			try {
				if (dom == null /*|| Document.CompilationUnit == null*/)
					return null;
				if (completionChar != '#' && stateTracker.Engine.IsInsidePreprocessorDirective)
					return null;
				//	timer = Counters.ResolveTime.BeginTiming ();
				DomLocation location = new DomLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset - 1);
				stateTracker.UpdateEngine ();
				ExpressionResult result;
				int cursor, newCursorOffset = 0, cpos;
				IType resolvedType;
				CodeCompletionContext ctx;
				NRefactoryParameterDataProvider provider;
				
				
				switch (completionChar) {
				case ':':
				case '.':
					if (stateTracker.Engine.IsInsideDocLineComment || stateTracker.Engine.IsInsideOrdinaryCommentOrString)
						return null;
					result = FindExpression (dom, completionContext);
					if (result == null || result.Expression == null)
						return null;
					int idx = result.Expression.LastIndexOf ('.');
					if (idx > 0)
						result.Expression = result.Expression.Substring (0, idx);
					// don't parse expressions that end with more than 1 dot - see #646820
					if (result.Expression.EndsWith ("."))
						return null;
					NRefactoryResolver resolver = CreateResolver ();
					ResolveResult resolveResult = resolver.Resolve (result, location);
					if (resolver.ResolvedExpression is ICSharpCode.NRefactory.Ast.PrimitiveExpression) {
						ICSharpCode.NRefactory.Ast.PrimitiveExpression pex = (ICSharpCode.NRefactory.Ast.PrimitiveExpression)resolver.ResolvedExpression;
						if (!tryToForceCompletion && !(pex.Value is string || pex.Value is char || pex.Value is bool))
							return null;
					}
					
					return CreateCompletionData (location, resolveResult, result, resolver);
				case '#':
					if (stateTracker.Engine.IsInsidePreprocessorDirective) 
						return GetDirectiveCompletionData ();
					return null;
				case '>':
					cursor = textEditorData.IsSomethingSelected ? textEditorData.SelectionRange.Offset : textEditorData.Caret.Offset;
				
					if (stateTracker.Engine.IsInsideDocLineComment) {
						string lineText = textEditorData.GetLineText (completionContext.TriggerLine);
						int startIndex = Math.Min (completionContext.TriggerLineOffset - 1, lineText.Length - 1);
					
						while (startIndex >= 0 && lineText [startIndex] != '<') {
							--startIndex;
							if (lineText [startIndex] == '/') { // already closed.
								startIndex = -1;
								break;
							}
						}
					
						if (startIndex >= 0) {
							int endIndex = startIndex;
							while (endIndex <= completionContext.TriggerLineOffset && endIndex < lineText.Length && !Char.IsWhiteSpace (lineText [endIndex])) {
								endIndex++;
							}
							string tag = endIndex - startIndex - 1 > 0 ? lineText.Substring (startIndex + 1, endIndex - startIndex - 2) : null;
							if (!String.IsNullOrEmpty (tag) && commentTags.IndexOf (tag) >= 0) {
								textEditorData.Insert (cursor, "</" + tag + ">");
								textEditorData.Caret.Offset = cursor; 
								return null;
							}
						}
					}
					return null;
/* Disabled because it gives problems when declaring arrays - for example string [] should not pop up code completion.
 			case '[':
				if (stateTracker.Engine.IsInsideDocLineComment || stateTracker.Engine.IsInsideOrdinaryCommentOrString)
					return null;
				result = FindExpression (dom, completionContext);
				if (result.ExpressionContext == ExpressionContext.Attribute)
					return CreateCtrlSpaceCompletionData (completionContext, result);
				return null;*/
				case '<':
					if (stateTracker.Engine.IsInsideDocLineComment) 
						return GetXmlDocumentationCompletionData ();
					return null;
				case '(':
					if (stateTracker.Engine.IsInsideDocLineComment || stateTracker.Engine.IsInsideOrdinaryCommentOrString)
						return null;
					result = FindExpression (dom, completionContext, -1);
					if (result == null || result.Expression == null)
						return null;
					resolver = CreateResolver ();
					resolveResult = resolver.Resolve (result, new DomLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset - 2));
					if (resolveResult == null)
						return null;
					
					if (resolver.ResolvedExpression is ICSharpCode.NRefactory.Ast.TypeOfExpression) {
						CompletionDataList completionList = new ProjectDomCompletionDataList ();
					
						CompletionDataCollector col = new CompletionDataCollector (dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
						AddPrimitiveTypes (col);
						foreach (object o in dom.GetNamespaceContents (GetUsedNamespaces (), true, true)) {
							col.Add (o);
						}
						if (resolver.CallingMember is IMethod) {
							foreach (ITypeParameter tp in ((IMethod)resolver.CallingMember).TypeParameters) {
								col.Add (tp.Name, "md-keyword");
							}
						}
						if (resolver.CallingType != null) {
							foreach (ITypeParameter tp in resolver.CallingType.TypeParameters) {
								col.Add (tp.Name, "md-keyword");
							}
						}
						return completionList;
					}
					if (resolveResult is MethodResolveResult) {
						var methodResolveResult = resolveResult as MethodResolveResult;
						return CreateParameterCompletion (resolver, location, result.ExpressionContext, methodResolveResult.Methods, 0);	
					}
					return null;
				case ',':
					if (!GetParameterCompletionCommandOffset (out cpos)) 
						return null;
					ctx = CompletionWidget.CreateCodeCompletionContext (cpos);
					provider = ParameterCompletionCommand (ctx) as NRefactoryParameterDataProvider;
					if (provider != null) {
						int currentParameter = provider.GetCurrentParameterIndex (CompletionWidget, ctx) - 1;
						return CreateParameterCompletion (CreateResolver (), location, ExpressionContext.MethodBody, provider.Methods, currentParameter);	
					}
					break;
				case '/':
					cursor = textEditorData.IsSomethingSelected ? textEditorData.SelectionRange.Offset : textEditorData.Caret.Offset;
					if (cursor < 2)
						break;
					
					if (stateTracker.Engine.IsInsideDocLineComment) {
						string lineText = textEditorData.GetLineText (completionContext.TriggerLine);
						bool startsDocComment = true;
						int slashes = 0;
						for (int i = 0; i < completionContext.TriggerLineOffset && i < lineText.Length; i++) {
							if (lineText [i] == '/') {
								slashes++;
								continue;
							}
							if (!Char.IsWhiteSpace (lineText [i])) {
								startsDocComment = false;
								break;
							}
						}
// check if lines above already start a doc comment
						for (int i = completionContext.TriggerLine - 2; i >= 1; i--) {
							string text = textEditorData.GetLineText (i);
							if (text.Length == 0)
								continue;
							if (text.StartsWith ("///")) {
								startsDocComment = false;
								break;
							}
							break;
						}
						
// check if following lines start a doc comment
						for (int i = completionContext.TriggerLine; i <= textEditorData.Document.LineCount; i++) {
							string text = textEditorData.GetLineText (i);
							if (text == null)
								break;
							text = text.Trim ();
							if (text.Length == 0)
								continue;
							if (text.StartsWith ("///")) {
								startsDocComment = false;
								break;
							}
							break;
						}
					
						if (!startsDocComment || slashes != 3)
							break;
						StringBuilder generatedComment = new StringBuilder ();
						bool generateStandardComment = true;
						ParsedDocument currentParsedDocument = Document.UpdateParseDocument ();
						IType insideClass = NRefactoryResolver.GetTypeAtCursor (currentParsedDocument.CompilationUnit, Document.FileName, location);
						if (insideClass != null) {
							string indent = textEditorData.Document.GetLineIndent (completionContext.TriggerLine);
							if (insideClass.ClassType == ClassType.Delegate) {
								AppendSummary (generatedComment, indent, out newCursorOffset);
								IMethod m = null;
								foreach (IMethod method in insideClass.Methods)
									m = method;
								AppendMethodComment (generatedComment, indent, m);
								generateStandardComment = false;
							} else {
								if (!IsInsideClassBody (insideClass, completionContext.TriggerLine, completionContext.TriggerLineOffset))
									break;
								string body = GenerateBody (insideClass, completionContext.TriggerLine, indent, out newCursorOffset);
								if (!String.IsNullOrEmpty (body)) {
									generatedComment.Append (body);
									generateStandardComment = false;
								}
							}
						}
						if (generateStandardComment) {
							string indent = textEditorData.Document.GetLineIndent (completionContext.TriggerLine);
							AppendSummary (generatedComment, indent, out newCursorOffset);
						}
						textEditorData.Document.EndAtomicUndo ();
						textEditorData.Document.BeginAtomicUndo ();
						textEditorData.Insert (cursor, generatedComment.ToString ());
						textEditorData.Caret.Offset = cursor + newCursorOffset;
						return null;
					}
					return null;
//			case '\n':
//			case '\r': {
//				if (stateTracker.Engine.IsInsideDocLineComment || stateTracker.Engine.IsInsideOrdinaryCommentOrString)
//					return null;
//				result = FindExpression (dom, completionContext);
//				if (result == null)
//					return null;
//					
//					
//				int tokenIndex = completionContext.TriggerOffset;
//				string token = GetPreviousToken (ref tokenIndex, false);
//				if (result.ExpressionContext == ExpressionContext.ObjectInitializer) {
//					if (token == "{" || token == ",")
//						return CreateCtrlSpaceCompletionData (completionContext, result); 
//				} 
//				return null;
//				}
				case ' ':
					if (stateTracker.Engine.IsInsideDocLineComment || stateTracker.Engine.IsInsideOrdinaryCommentOrString)
						return null;
					result = FindExpression (dom, completionContext);
					if (result == null)
						return null;
					
					int tokenIndex = completionContext.TriggerOffset;
					string token = GetPreviousToken (ref tokenIndex, false);
					if (result.ExpressionContext == ExpressionContext.ObjectInitializer) {
						resolver = CreateResolver ();
						ExpressionContext exactContext = new NewCSharpExpressionFinder (dom).FindExactContextForObjectInitializer (textEditorData, resolver.Unit, Document.FileName, resolver.CallingType);
						IReturnType objectInitializer = ((ExpressionContext.TypeExpressionContext)exactContext).UnresolvedType;
						if (objectInitializer != null && objectInitializer.ArrayDimensions == 0 && objectInitializer.PointerNestingLevel == 0 && (token == "{" || token == ","))
							return CreateCtrlSpaceCompletionData (completionContext, result); 
					}
					if (token == "=") {
						int j = tokenIndex;
						string prevToken = GetPreviousToken (ref j, false);
						if (prevToken == "=" || prevToken == "+" || prevToken == "-") {
							token = prevToken + token;
							tokenIndex = j;
						}
					}
					switch (token) {
					case "(":
					case ",":
						if (!GetParameterCompletionCommandOffset (out cpos)) 
							break;
						ctx = CompletionWidget.CreateCodeCompletionContext (cpos);
						provider = ParameterCompletionCommand (ctx) as NRefactoryParameterDataProvider;
						if (provider != null) {
							int currentParameter = provider.GetCurrentParameterIndex (CompletionWidget, ctx) - 1;
							return CreateParameterCompletion (CreateResolver (), location, ExpressionContext.IdentifierExpected, provider.Methods, currentParameter);	
						}
						break;
					case "=":
					case "==":
						result = FindExpression (dom, completionContext, tokenIndex - completionContext.TriggerOffset - 1);
						resolver = CreateResolver ();
						resolveResult = resolver.Resolve (result, location);
						if (resolveResult != null) {
							resolvedType = dom.GetType (resolveResult.ResolvedType);
							if (resolvedType == null) 
								return null;
							if (resolvedType.ClassType == ClassType.Enum) {
								CompletionDataList completionList = new ProjectDomCompletionDataList ();
								CompletionDataCollector cdc = new CompletionDataCollector (dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
								IReturnType returnType = new DomReturnType (resolvedType);
								bool added = false;
								foreach (IUsing u in Document.CompilationUnit.Usings) {
									foreach (KeyValuePair<string, IReturnType> alias in u.Aliases) {
										if (alias.Value.ToInvariantString () == returnType.ToInvariantString ()) {
											cdc.Add (alias.Key, "md-class");
											added = true;
										}
									}
								}
								if (!added && !string.IsNullOrEmpty (returnType.Namespace))
									cdc.Add (returnType);/*
							foreach (object o in CreateCtrlSpaceCompletionData (completionContext, result)) {
								MemberCompletionData memberData = o as MemberCompletionData;
								if (memberData == null || memberData.Member == null) {
									completionList.Add (o as CompletionData);
									continue;
								}
								if (memberData.Member is IMember) {
									returnType = ((IMember)memberData.Member).ReturnType;
								} else if (memberData.Member is IParameter) {
									returnType = ((IParameter)memberData.Member).ReturnType;
								} else {
									returnType = ((LocalVariable)memberData.Member).ReturnType;
								}
								// filter out void types
								if (returnType != null && returnType.FullName != DomReturnType.Void.FullName)
									completionList.Add (memberData);
							}*/
								completionList.AutoCompleteEmptyMatch = false;
								resolver.AddAccessibleCodeCompletionData (result.ExpressionContext, cdc);
								AddEnumMembers (completionList, resolvedType);
								return completionList;
							}
						
							if (resolvedType.FullName == DomReturnType.Bool.FullName) {
								CompletionDataList completionList = new ProjectDomCompletionDataList ();
								CompletionDataCollector cdc = new CompletionDataCollector (dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
								completionList.AutoCompleteEmptyMatch = false;
								cdc.Add ("true", "md-keyword");
								cdc.Add ("false", "md-keyword");
/*							foreach (object o in CreateCtrlSpaceCompletionData (completionContext, result)) {
								MemberCompletionData memberData = o as MemberCompletionData;
								if (memberData == null || memberData.Member == null) {
									completionList.Add (o as CompletionData);
									continue;
								}
								IReturnType returnType = null;
								if (memberData.Member is IMember) {
									returnType = ((IMember)memberData.Member).ReturnType;
								} else if (memberData.Member is IParameter) {
									returnType = ((IParameter)memberData.Member).ReturnType;
								} else {
									returnType = ((LocalVariable)memberData.Member).ReturnType;
								}
								// filter out void types
								if (returnType != null && returnType.FullName != DomReturnType.Void.FullName)
									completionList.Add (memberData);
							}*/
								resolver.AddAccessibleCodeCompletionData (result.ExpressionContext, cdc);
								return completionList;
							}
							if (resolvedType.ClassType == ClassType.Delegate && token == "=") {
								CompletionDataList completionList = new ProjectDomCompletionDataList ();
								string parameterDefinition = AddDelegateHandlers (completionList, resolvedType);
								string varName = GetPreviousMemberReferenceExpression (tokenIndex);
								completionList.Add (new EventCreationCompletionData (textEditorData, varName, resolvedType, null, parameterDefinition, resolver.CallingMember, resolvedType));
								return completionList;
							}
						}
						return null;
					case "+=":
					case "-=":
						if (stateTracker.Engine.IsInsideDocLineComment || stateTracker.Engine.IsInsideOrdinaryCommentOrString)
							return null;
						result = FindExpression (dom, completionContext, tokenIndex - completionContext.TriggerOffset);
						resolver = CreateResolver ();
						resolveResult = resolver.Resolve (result, location);
					
						if (resolveResult is MemberResolveResult) {
							MemberResolveResult mrr = resolveResult as MemberResolveResult;
							IEvent evt = mrr.ResolvedMember as IEvent;
							if (evt == null)
								return null;
							IType delegateType = resolver.SearchType (evt.ReturnType);
							if (delegateType == null || delegateType.ClassType != ClassType.Delegate)
								return null;
							CompletionDataList completionList = new ProjectDomCompletionDataList ();
							CompletionDataCollector cdc = new CompletionDataCollector (dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
						
							IType declaringType = resolver.CallingType;
							if (Document.LastErrorFreeParsedDocument != null) {
								declaringType = Document.LastErrorFreeParsedDocument.CompilationUnit.GetType (declaringType.FullName, declaringType.TypeParameters.Count);
							}
							IType typeFromDatabase = null;
							if (declaringType != null) {
								typeFromDatabase = dom.GetType (declaringType.FullName, new DomReturnType (declaringType).GenericArguments) ?? declaringType;
								bool includeProtected = DomType.IncludeProtected (dom, typeFromDatabase, resolver.CallingType);
								foreach (IType type in dom.GetInheritanceTree (typeFromDatabase)) {
									foreach (IMethod method in type.Methods) {
										if (method.IsAccessibleFrom (dom, resolver.CallingType, resolver.CallingMember, includeProtected) && MatchDelegate (delegateType, method)) {
											CompletionData data = cdc.Add (method);
											data.SetText (data.CompletionText + ";");
										}
									}
								}
							}
							if (token == "+=") {
								string parameterDefinition = AddDelegateHandlers (completionList, delegateType);
								string varName = GetPreviousMemberReferenceExpression (tokenIndex);
								completionList.Add (new EventCreationCompletionData (textEditorData, varName, delegateType, evt, parameterDefinition, resolver.CallingMember, typeFromDatabase));
							}
						
							return completionList;
						}
						return null;
					}
					return HandleKeywordCompletion (completionContext, result, tokenIndex, token);
				default:
					if ((Char.IsLetter (completionChar) || completionChar == '_') && TextEditorProperties.EnableAutoCodeCompletion && !stateTracker.Engine.IsInsideDocLineComment && !stateTracker.Engine.IsInsideOrdinaryCommentOrString) {
						char prevCh = completionContext.TriggerOffset > 2 ? textEditorData.GetCharAt (completionContext.TriggerOffset - 2) : '\0';
						char nextCh = completionContext.TriggerOffset < textEditorData.Length ? textEditorData.GetCharAt (completionContext.TriggerOffset) : ' ';
						const string allowedChars = ";,[(){}+-*/%^?:&|~!<>=";
						if (!Char.IsWhiteSpace (nextCh) && allowedChars.IndexOf (nextCh) < 0)
							return null;
						if (Char.IsWhiteSpace (prevCh) || allowedChars.IndexOf (prevCh) >= 0) {
							result = FindExpression (dom, completionContext, -1);
							if (result == null)
								return null;
							if (IsInLinqContext (result)) {
								tokenIndex = completionContext.TriggerOffset;
								token = GetPreviousToken (ref tokenIndex, false); // token last typed
								token = GetPreviousToken (ref tokenIndex, false); // possible linq keyword ?
								triggerWordLength = 1;
							
								if (linqKeywords.Contains (token)) {
									if (token == "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;
							} else if (result.ExpressionContext != ExpressionContext.IdentifierExpected) {
								triggerWordLength = 1;
								bool autoSelect = true;
								IType returnType = null;
								if ((prevCh == ',' || prevCh == '(') && GetParameterCompletionCommandOffset (out cpos)) {
									ctx = CompletionWidget.CreateCodeCompletionContext (cpos);
									NRefactoryParameterDataProvider dataProvider = ParameterCompletionCommand (ctx) as NRefactoryParameterDataProvider;
									if (dataProvider != null) {
										int i = dataProvider.GetCurrentParameterIndex (CompletionWidget, ctx) - 1;
										foreach (var method in dataProvider.Methods) {
											if (i < method.Parameters.Count) {
												returnType = dom.GetType (method.Parameters [i].ReturnType);
												autoSelect = returnType == null || returnType.ClassType != ClassType.Delegate;
												break;
											}
										}
									}
								}
								// Bug 677531 - Auto-complete doesn't always highlight generic parameter in method signature
								//if (result.ExpressionContext == ExpressionContext.TypeName)
								//	autoSelect = false;
								CompletionDataList dataList = CreateCtrlSpaceCompletionData (completionContext, result);
								AddEnumMembers (dataList, returnType);
								dataList.AutoSelect = autoSelect;
								return dataList;
							} else {
								result = FindExpression (dom, completionContext, 0);
								tokenIndex = completionContext.TriggerOffset;
								
								// check foreach case, unfortunately the expression finder is too dumb to handle full type names
								// should be overworked if the expression finder is replaced with a mcs ast based analyzer.
								var possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // starting letter
								possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // varname
							
								// read return types to '(' token
								possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // varType
								if (possibleForeachToken == ">") {
									while (possibleForeachToken != null && possibleForeachToken != "(") {
										possibleForeachToken = GetPreviousToken (ref tokenIndex, false);
									}
								} else {
									possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // (
									if (possibleForeachToken == ".")
										while (possibleForeachToken != null && possibleForeachToken != "(")
											possibleForeachToken = GetPreviousToken (ref tokenIndex, false);
								}
								possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // foreach
							
								if (possibleForeachToken == "foreach") {
									result.ExpressionContext = ExpressionContext.ForeachInToken;
								} else {
									return null;
									//								result.ExpressionContext = ExpressionContext.IdentifierExpected;
								}
								result.Expression = "";
								result.Region = DomRegion.Empty;
							
								// identifier has already started with the first letter
								completionContext.TriggerOffset--;
								completionContext.TriggerLineOffset--;
								completionContext.TriggerWordLength = 1;
								return CreateCtrlSpaceCompletionData (completionContext, result);
							}
						}
					}
					break;
				}
			} catch (Exception e) {
				LoggingService.LogError ("Unexpected code completion exception." + Environment.NewLine + 
					"FileName: " + Document.FileName + Environment.NewLine + 
					"Position: line=" + completionContext.TriggerLine + " col=" + completionContext.TriggerLineOffset + Environment.NewLine + 
					"Line text: " + Document.Editor.GetLineText (completionContext.TriggerLine), 
					e);
			} finally {
				//			if (timer != null)
				//				timer.Dispose ();
			}
			return null;
		}

Usage Example

		static CompletionDataList CreateProvider (string text, bool isCtrlSpace)
		{
			string parsedText;
			string editorText;
			int cursorPosition = text.IndexOf ('$');
			int endPos = text.IndexOf ('$', cursorPosition + 1);
			if (endPos == -1)
				parsedText = editorText = text.Substring (0, cursorPosition) + text.Substring (cursorPosition + 1);
			else {
				parsedText = text.Substring (0, cursorPosition) + new string (' ', endPos - cursorPosition) + text.Substring (endPos + 1);
				editorText = text.Substring (0, cursorPosition) + text.Substring (cursorPosition + 1, endPos - cursorPosition - 1) + text.Substring (endPos + 1);
				cursorPosition = endPos - 1; 
			}
			
			TestWorkbenchWindow tww = new TestWorkbenchWindow ();
			TestViewContent sev = new TestViewContent ();
			DotNetProject project = new DotNetAssemblyProject ("C#");
			project.FileName = GetTempFile (".csproj");
			
			string file = GetTempFile (".cs");
			project.AddFile (file);
			
			ProjectDomService.Load (project);
			ProjectDom dom = ProjectDomService.GetProjectDom (project);
			dom.ForceUpdate (true);
			ProjectDomService.Parse (project, file, delegate { return parsedText; });
			ProjectDomService.Parse (project, file, delegate { return parsedText; });
			
			sev.Project = project;
			sev.ContentName = file;
			sev.Text = editorText;
			sev.CursorPosition = cursorPosition;
			tww.ViewContent = sev;
			Document doc = new Document (tww);
			doc.ParsedDocument = new NRefactoryParser ().Parse (null, sev.ContentName, parsedText);
			foreach (var e in doc.ParsedDocument.Errors)
				Console.WriteLine (e);
			CSharpTextEditorCompletion textEditorCompletion = new CSharpTextEditorCompletion (doc);
			
			int triggerWordLength = 1;
			CodeCompletionContext ctx = new CodeCompletionContext ();
			ctx.TriggerOffset = sev.CursorPosition;
			int line, column;
			sev.GetLineColumnFromPosition (sev.CursorPosition, out line, out column);
			ctx.TriggerLine = line;
			ctx.TriggerLineOffset = column - 1;
			if (isCtrlSpace)
				return textEditorCompletion.CodeCompletionCommand (ctx) as CompletionDataList;
			return textEditorCompletion.HandleCodeCompletion (ctx, editorText[cursorPosition - 1] , ref triggerWordLength) as CompletionDataList;
		}