public static ReachabilityAnalysis Create(Statement statement, CppAstResolver resolver = null, CancellationToken cancellationToken = default(CancellationToken))
		{
			var cfgBuilder = new ControlFlowGraphBuilder();
			var cfg = cfgBuilder.BuildControlFlowGraph(statement, resolver, cancellationToken);
			return Create(cfg, cancellationToken);
		}
		protected Tuple<ResolveResult, CppResolver> ResolveExpression (CppParsedFile file, AstNode expr, CompilationUnit unit)
		{
			if (expr == null)
				return null;
			AstNode resolveNode;
			if (expr is Expression || expr is AstType) {
				resolveNode = expr;
			} else if (expr is VariableDeclarationStatement) {
				resolveNode = ((VariableDeclarationStatement)expr).Type;
			} else {
				resolveNode = expr;
			}
			
//			var newContent = ProjectContent.UpdateProjectContent (CSharpParsedFile, file);
			
			var csResolver = new CppAstResolver(new CppResolver (ctx), unit, CSharpParsedFile);
			
			var result = csResolver.Resolve (resolveNode);
			var state = csResolver.GetResolverStateBefore (resolveNode);
			return Tuple.Create (result, state);
		}
		public static ResolveResult Resolve(ICompilation compilation, CppParsedFile parsedFile, CompilationUnit cu, TextLocation location, out AstNode node,
		                                    CancellationToken cancellationToken = default(CancellationToken))
		{
			node = cu.GetNodeAt(location);
			if (node == null)
				return null;
			if (CppAstResolver.IsUnresolvableNode(node)) {
				if (node is Identifier) {
					node = node.Parent;
				} else if (node.NodeType == NodeType.Token) {
					if (node.Parent is IndexerExpression || node.Parent is ConstructorInitializer) {
						// There's no other place where one could hover to see the indexer's tooltip,
						// so we need to resolve it when hovering over the '[' or ']'.
						// For constructor initializer, the same applies to the 'base'/'this' token.
						node = node.Parent;
					} else {
						return null;
					}
				} else {
					// don't resolve arbitrary nodes - we don't want to show tooltips for everything
					return null;
				}
			} else {
				// It's a resolvable node.
				// However, we usually don't want to show the tooltip everywhere
				// For example, hovering with the mouse over an empty line between two methods causes
				// node==TypeDeclaration, but we don't want to show any tooltip.
				
				if (!node.GetChildByRole(AstNode.Roles.Identifier).IsNull) {
					// We'll suppress the tooltip for resolvable nodes if there is an identifier that
					// could be hovered over instead:
					return null;
				}
			}
			if (node == null)
				return null;
			
			if (node.Parent is ObjectCreateExpression && node.Role == ObjectCreateExpression.Roles.Type) {
				node = node.Parent;
			}
			
			InvocationExpression parentInvocation = null;
			if (node is IdentifierExpression || node is MemberReferenceExpression || node is PointerReferenceExpression) {
				// we also need to resolve the invocation
				parentInvocation = node.Parent as InvocationExpression;
			}
			
			CppAstResolver resolver = new CppAstResolver(compilation, cu, parsedFile);
			ResolveResult rr = resolver.Resolve(node, cancellationToken);
			if (rr is MethodGroupResolveResult && parentInvocation != null)
				return resolver.Resolve(parentInvocation);
			else
				return rr;
		}
		IEnumerable<ICompletionData> MagicKeyCompletion (char completionChar, bool controlSpace)
		{
			switch (completionChar) {
			// Magic key completion
			case ':':
			case '.':
				if (IsInsideCommentOrString ())
					return Enumerable.Empty<ICompletionData> ();
				var expr = GetExpressionBeforeCursor ();
				if (expr == null)
					return null;
				// do not complete <number>. (but <number>.<number>.)
				if (expr.Item2 is PrimitiveExpression) {
					var pexpr = (PrimitiveExpression)expr.Item2;
					if (!(pexpr.Value is string || pexpr.Value is char) && !pexpr.LiteralValue.Contains ('.'))
						return null;
				}
				
				var resolveResult = ResolveExpression (expr.Item1, expr.Item2, expr.Item3);
				if (resolveResult == null)
					return null;
				if (expr.Item2 is AstType)
					return CreateTypeAndNamespaceCompletionData (location, resolveResult.Item1, expr.Item2, resolveResult.Item2);
				return CreateCompletionData (location, resolveResult.Item1, expr.Item2, resolveResult.Item2);
			case '#':
				if (IsInsideCommentOrString ())
					return null;
				return GetDirectiveCompletionData ();
			
// XML doc completion
			case '<':
				if (IsInsideDocComment ())
					return GetXmlDocumentationCompletionData ();
				if (controlSpace)
					return DefaultControlSpaceItems ();
				return null;
			case '>':
				if (!IsInsideDocComment ())
					return null;
				string lineText = document.GetText (document.GetLineByNumber (location.Line));
				int startIndex = Math.Min (location.Column - 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 <= location.Column && 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)
						document.Insert (offset, "</" + tag + ">");
				}
				return null;
			
			// Parameter completion
			case '(':
				if (IsInsideCommentOrString ())
					return null;
				var invoke = GetInvocationBeforeCursor (true);
				if (invoke == null)
					return null;
				if (invoke.Item2 is TypeOfExpression)
					return CreateTypeList ();
				var invocationResult = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3);
				if (invocationResult == null)
					return null;
				var methodGroup = invocationResult.Item1 as MethodGroupResolveResult;
				if (methodGroup != null)
					return CreateParameterCompletion (methodGroup, invocationResult.Item2, invoke.Item2, 0, controlSpace);
				
				if (controlSpace)
					return DefaultControlSpaceItems (invoke);
				
				return null;
			case '=':
				return controlSpace ? DefaultControlSpaceItems () : null;
			case ',':
				int cpos2;
				if (!GetParameterCompletionCommandOffset (out cpos2)) 
					return null;
			//	completionContext = CompletionWidget.CreateCodeCompletionContext (cpos2);
			//	int currentParameter2 = MethodParameterDataProvider.GetCurrentParameterIndex (CompletionWidget, completionContext) - 1;
//				return CreateParameterCompletion (CreateResolver (), location, ExpressionContext.MethodBody, provider.Methods, currentParameter);	
				break;
				
			// Completion on space:
			case ' ':
				if (IsInsideCommentOrString ())
					return null;
				
				int tokenIndex = offset;
				string token = GetPreviousToken (ref tokenIndex, false);
				// check propose name, for context <variable name> <ctrl+space> (but only in control space context)
				//IType isAsType = null;
				var isAsExpression = GetExpressionAt (offset);
				if (controlSpace && isAsExpression != null && isAsExpression.Item2 is VariableDeclarationStatement && token != "new") {
					var parent = isAsExpression.Item2 as VariableDeclarationStatement;
					var proposeNameList = new CompletionDataWrapper (this);
					
					foreach (var possibleName in GenerateNameProposals (parent.Type)) {
						if (possibleName.Length > 0)
							proposeNameList.Result.Add (factory.CreateLiteralCompletionData (possibleName.ToString ()));
					}
					
					AutoSelect = false;
					AutoCompleteEmptyMatch = false;
					return proposeNameList.Result;
				}
//				int tokenIndex = offset;
//				string token = GetPreviousToken (ref tokenIndex, false);
//				if (result.ExpressionContext == ExpressionContext.ObjectInitializer) {
//					resolver = CreateResolver ();
//					ExpressionContext exactContext = new NewCSharpExpressionFinder (dom).FindExactContextForObjectInitializer (document, 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 ",":
					int cpos;
					if (!GetParameterCompletionCommandOffset (out cpos)) 
						break;
					int currentParameter = GetCurrentParameterIndex (cpos, 0) - 1;
					if (currentParameter < 0)
						return null;
					invoke = GetInvocationBeforeCursor (token == "(");
					if (invoke == null)
						return null;
					invocationResult = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3);
					if (invocationResult == null)
						return null;
					methodGroup = invocationResult.Item1 as MethodGroupResolveResult;
					if (methodGroup != null)
						return CreateParameterCompletion (methodGroup, invocationResult.Item2, invoke.Item2, currentParameter, controlSpace);
					return null;
				case "=":
				case "==":
					GetPreviousToken (ref tokenIndex, false);
					var expressionOrVariableDeclaration = GetExpressionAt (tokenIndex);
					if (expressionOrVariableDeclaration == null)
						return null;
					
					resolveResult = ResolveExpression (expressionOrVariableDeclaration.Item1, expressionOrVariableDeclaration.Item2, expressionOrVariableDeclaration.Item3);
					
					if (resolveResult == null)
						return null;
					if (resolveResult.Item1.Type.Kind == TypeKind.Enum) {
						var wrapper = new CompletionDataWrapper (this);
						AddContextCompletion (wrapper, resolveResult.Item2, expressionOrVariableDeclaration.Item2);
						AddEnumMembers (wrapper, resolveResult.Item1.Type, resolveResult.Item2);
						AutoCompleteEmptyMatch = false;
						return wrapper.Result;
					}
//				
//					if (resolvedType.FullName == DomReturnType.Bool.FullName) {
//						CompletionDataList completionList = new ProjectDomCompletionDataList ();
//						CompletionDataCollector cdc = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
//						completionList.AutoCompleteEmptyMatch = false;
//						cdc.Add ("true", "md-keyword");
//						cdc.Add ("false", "md-keyword");
//						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 (document, varName, resolvedType, null, parameterDefinition, resolver.CallingMember, resolvedType));
//						
//						CompletionDataCollector cdc = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
//						resolver.AddAccessibleCodeCompletionData (result.ExpressionContext, cdc);
//						foreach (var data in completionList) {
//							if (data is MemberCompletionData) 
//								((MemberCompletionData)data).IsDelegateExpected = true;
//						}
//						return completionList;
//					}
					return null;
				case "+=":
				case "-=":
					GetPreviousToken (ref tokenIndex, false);
					
					expressionOrVariableDeclaration = GetExpressionAt (tokenIndex);
					if (expressionOrVariableDeclaration == null)
						return null;
				
					resolveResult = ResolveExpression (expressionOrVariableDeclaration.Item1, expressionOrVariableDeclaration.Item2, expressionOrVariableDeclaration.Item3);
					if (resolveResult == null)
						return null;
					
					
					var mrr = resolveResult.Item1 as MemberResolveResult;
					if (mrr != null) {
						var evt = mrr.Member as IEvent;
						if (evt == null)
							return null;
						var delegateType = evt.ReturnType;
						if (delegateType.Kind != TypeKind.Delegate)
							return null;
						
						var wrapper = new CompletionDataWrapper (this);
						if (currentType != null) {
//							bool includeProtected = DomType.IncludeProtected (dom, typeFromDatabase, resolver.CallingType);
							foreach (var method in currentType.Methods) {
								if (MatchDelegate (delegateType, method) /*&& method.IsAccessibleFrom (dom, resolver.CallingType, resolver.CallingMember, includeProtected) &&*/) {
									wrapper.AddMember (method);
//									data.SetText (data.CompletionText + ";");
								}
							}
						}
						if (token == "+=") {
							string parameterDefinition = AddDelegateHandlers (wrapper, delegateType);
							string varName = GetPreviousMemberReferenceExpression (tokenIndex);
							wrapper.Result.Add (factory.CreateEventCreationCompletionData (varName, delegateType, evt, parameterDefinition, currentMember, currentType));
						}
					
						return wrapper.Result;
					}
					return null;
				case ":":
					
/* Breaks constructor initializer case:
					 * if (currentMember == null) {
						var wrapper = new CompletionDataWrapper (this);
						AddTypesAndNamespaces (wrapper, GetState (), null, t => currentType != null ? !currentType.Equals (t) : true);
						return wrapper.Result;
					}*/
					return null;
				}
				
				var keywordCompletion = HandleKeywordCompletion (tokenIndex, token);
				if (keywordCompletion == null && controlSpace)
					goto default;
				return keywordCompletion;
			// Automatic completion
			default:
				if (IsInsideCommentOrString ())
					return null;
				if (IsInLinqContext (offset)) {
					if (!controlSpace && !(char.IsLetter (completionChar) || completionChar == '_'))
						return null;
					tokenIndex = offset;
					token = GetPreviousToken (ref tokenIndex, false); // token last typed
					if (!char.IsWhiteSpace (completionChar) && !linqKeywords.Contains (token))
						token = GetPreviousToken (ref tokenIndex, false); // token last typed
					
					if (linqKeywords.Contains (token)) {
						if (token == "from") // after from no auto code completion.
							return null;
						return DefaultControlSpaceItems ();
					}
					var dataList = new CompletionDataWrapper (this);
					AddKeywords (dataList, linqKeywords);
					return dataList.Result;
				}
				if (currentType != null && currentType.Kind == TypeKind.Enum)
					return HandleEnumContext ();
				
				var contextList = new CompletionDataWrapper (this);
				var identifierStart = GetExpressionAtCursor ();
				
				if (identifierStart != null && identifierStart.Item2 is TypeParameterDeclaration)
					return null;
				
				if (identifierStart != null && identifierStart.Item2 is VariableInitializer && location <= ((VariableInitializer)identifierStart.Item2).NameToken.EndLocation) {
					return controlSpace ? HandleAccessorContext () ?? DefaultControlSpaceItems (identifierStart) : null;
				}
				if (!(char.IsLetter (completionChar) || completionChar == '_') && (!controlSpace || identifierStart == null || !(identifierStart.Item2 is ArrayInitializerExpression))) {
					return controlSpace ? HandleAccessorContext () ?? DefaultControlSpaceItems (identifierStart) : null;
				}
				char prevCh = offset > 2 ? document.GetCharAt (offset - 2) : ';';
				char nextCh = offset < document.TextLength ? document.GetCharAt (offset) : ' ';
				const string allowedChars = ";,[](){}+-*/%^?:&|~!<>=";
				if (!Char.IsWhiteSpace (nextCh) && allowedChars.IndexOf (nextCh) < 0)
					return null;
				if (!(Char.IsWhiteSpace (prevCh) || allowedChars.IndexOf (prevCh) >= 0))
					return null;
				// Do not pop up completion on identifier identifier (should be handled by keyword completion).
				tokenIndex = offset - 1;
				token = GetPreviousToken (ref tokenIndex, false);
				if (token == "class" || token == "interface" || token == "struct" || token == "enum" || token == "namespace") // after these always follows a name
					return null;
				int prevTokenIndex = tokenIndex;
				var prevToken2 = GetPreviousToken (ref prevTokenIndex, false);
				if (prevToken2 == "delegate") // after these always follows a name
					return null;
				if (identifierStart == null && !string.IsNullOrEmpty (token) && !(IsInsideComment (tokenIndex) || IsInsideString (tokenIndex)) && (prevToken2 == ";" || prevToken2 == "{" || prevToken2 == "}")) {
					char last = token [token.Length - 1];
					if (char.IsLetterOrDigit (last) || last == '_' || token == ">") {
						return HandleKeywordCompletion (tokenIndex, token);
					}
				}
				if (identifierStart == null) {
					var accCtx = HandleAccessorContext ();
					if (accCtx != null)
						return accCtx;
					return DefaultControlSpaceItems (null, controlSpace);
				}
				CppResolver csResolver;
				AstNode n = identifierStart.Item2;
				
				if (n != null && n.Parent is AnonymousTypeCreateExpression) {
					AutoSelect = false;
				}
				
				// Handle foreach (type name _
				if (n is IdentifierExpression) {
					var prev = n.GetPrevNode () as ForeachStatement;
					if (prev != null && prev.InExpression.IsNull) {
						if (controlSpace) {
							contextList.AddCustom ("in");
							return contextList.Result;
						}
						return null;
					}
				}
				if (n != null && n.Parent is InvocationExpression) {
					var invokeParent = (InvocationExpression)n.Parent;
					var invokeResult = ResolveExpression (identifierStart.Item1, invokeParent.Target, identifierStart.Item3);
					var mgr = invokeResult != null ? invokeResult.Item1 as MethodGroupResolveResult : null;
					if (mgr != null) {
						int idx = 0;
						foreach (var arg in invokeParent.Arguments) {
							if (arg == n)
								break;
							idx++;
						}
						
						foreach (var method in mgr.Methods) {
							if (idx < method.Parameters.Count && method.Parameters[idx].Type.Kind == TypeKind.Delegate) {
								AutoSelect = false;
								AutoCompleteEmptyMatch = false;
							}
							foreach (var p in method.Parameters) {
								contextList.AddVariable (p);
							}
						}
						idx++;
						foreach (var list in mgr.GetExtensionMethods ()) {
							foreach (var method in list) {
								if (idx < method.Parameters.Count && method.Parameters[idx].Type.Kind == TypeKind.Delegate) {
									AutoSelect = false;
									AutoCompleteEmptyMatch = false;
								}
								
							}
						}
					}
				}
				
				if (n != null && n.Parent is ObjectCreateExpression) {
					var invokeResult = ResolveExpression (identifierStart.Item1, n.Parent, identifierStart.Item3);
					var mgr = invokeResult != null ? invokeResult.Item1 as ResolveResult : null;
					
					if (mgr != null) {
						foreach (var constructor in mgr.Type.GetConstructors ()) {
							foreach (var p in constructor.Parameters) {
								contextList.AddVariable (p);
							}
						}
					}
				}
				
				if (n is IdentifierExpression) {
					var bop = n.Parent as BinaryOperatorExpression;
					Expression evaluationExpr = null;
					
					if (bop != null && bop.Right == n && (bop.Operator == BinaryOperatorType.Equality || bop.Operator == BinaryOperatorType.InEquality)) {
						evaluationExpr = bop.Left;
					}
					// check for compare to enum case 
					if (evaluationExpr != null) {
						resolveResult = ResolveExpression (identifierStart.Item1, evaluationExpr, identifierStart.Item3);
						if (resolveResult != null && resolveResult.Item1.Type.Kind == TypeKind.Enum) {
							var wrapper = new CompletionDataWrapper (this);
							AddContextCompletion (wrapper, resolveResult.Item2, evaluationExpr);
							AddEnumMembers (wrapper, resolveResult.Item1.Type, resolveResult.Item2);
							AutoCompleteEmptyMatch = false;
							return wrapper.Result;
						}
					}
				}
				
				
				if (n is Identifier && n.Parent is ForeachStatement) {
					if (controlSpace)
						return DefaultControlSpaceItems ();
					return null;
				}
				if (n is ArrayInitializerExpression) {
					// check for new [] {...} expression -> no need to resolve the type there
					var parent = n.Parent as ArrayCreateExpression;
					if (parent != null && parent.Type.IsNull)
						return DefaultControlSpaceItems ();
					
					var initalizerResult = ResolveExpression (identifierStart.Item1, n.Parent, identifierStart.Item3);
					
					var concreteNode = identifierStart.Item3.GetNodeAt<IdentifierExpression> (location);
					// check if we're on the right side of an initializer expression
					if (concreteNode != null && concreteNode.Parent != null && concreteNode.Parent.Parent != null && concreteNode.Identifier != "a" && concreteNode.Parent.Parent is NamedExpression) {
						return DefaultControlSpaceItems ();
					}
					
					if (initalizerResult != null && initalizerResult.Item1.Type.Kind != TypeKind.Unknown) { 
						
						foreach (var property in initalizerResult.Item1.Type.GetProperties ()) {
							if (!property.IsPublic)
								continue;
							contextList.AddMember (property);
						}
						foreach (var field in initalizerResult.Item1.Type.GetFields ()) {       
							if (!field.IsPublic)
								continue;
							contextList.AddMember (field);
						}
						return contextList.Result;
					}
					return DefaultControlSpaceItems ();
				}
				if (n != null/* && !(identifierStart.Item2 is TypeDeclaration)*/) {
					csResolver = new CppResolver (ctx);
					var nodes = new List<AstNode> ();
					nodes.Add (n);
					if (n.Parent is ICSharpCode.NRefactory.Cpp.Attribute)
						nodes.Add (n.Parent);
					var astResolver = new CppAstResolver (csResolver, identifierStart.Item3, identifierStart.Item1);
					astResolver.ApplyNavigator (new NodeListResolveVisitorNavigator (nodes));
					try {
						csResolver = astResolver.GetResolverStateBefore (n);
					} catch (Exception) {
						csResolver = GetState ();
					}
					// add attribute properties.
					if (n.Parent is ICSharpCode.NRefactory.Cpp.Attribute) {
						var resolved = astResolver.Resolve (n.Parent);
						if (resolved != null && resolved.Type != null) {
							foreach (var property in resolved.Type.GetProperties (p => p.Accessibility == Accessibility.Public)) {
								contextList.AddMember (property);
							}
							foreach (var field in resolved.Type.GetFields (p => p.Accessibility == Accessibility.Public)) {
								contextList.AddMember (field);
							}
						}
					}
				} else {
					csResolver = GetState ();
				}
				// identifier has already started with the first letter
				offset--;
				AddContextCompletion (contextList, csResolver, identifierStart.Item2);
				return contextList.Result;
//				if (stub.Parent is BlockStatement)
				
//				result = FindExpression (dom, completionContext, -1);
//				if (result == null)
//					return null;
//				 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 = offset;
//					
//					// 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;
//				
//					return CreateCtrlSpaceCompletionData (completionContext, result);
//				}
//				break;
			}
			return null;
		}
Exemple #5
0
			internal override void NavigatorDone(CppAstResolver resolver, CancellationToken cancellationToken)
			{
				foreach (var expr in potentialMethodGroupConversions) {
					var conversion = resolver.GetConversion(expr, cancellationToken);
					if (conversion.IsMethodGroupConversion && conversion.Method.MemberDefinition == method) {
						IType targetType = resolver.GetExpectedType(expr, cancellationToken);
						ResolveResult result = resolver.Resolve(expr, cancellationToken);
						ReportMatch(expr, new ConversionResolveResult(targetType, result, conversion));
					}
				}
				base.NavigatorDone(resolver, cancellationToken);
			}
Exemple #6
0
		/// <summary>
		/// Finds all references in the given file.
		/// </summary>
		/// <param name="searchScopes">The search scopes for which to look.</param>
		/// <param name="parsedFile">The type system representation of the file being searched.</param>
		/// <param name="compilationUnit">The compilation unit of the file being searched.</param>
		/// <param name="compilation">The compilation for the project that contains the file.</param>
		/// <param name="callback">Callback used to report the references that were found.</param>
		/// <param name="cancellationToken">CancellationToken that may be used to cancel the operation.</param>
		public void FindReferencesInFile(IList<IFindReferenceSearchScope> searchScopes, CppParsedFile parsedFile, CompilationUnit compilationUnit,
		                                 ICompilation compilation, FoundReferenceCallback callback, CancellationToken cancellationToken)
		{
			if (searchScopes == null)
				throw new ArgumentNullException("searchScopes");
			if (parsedFile == null)
				throw new ArgumentNullException("parsedFile");
			if (compilationUnit == null)
				throw new ArgumentNullException("compilationUnit");
			if (compilation == null)
				throw new ArgumentNullException("compilation");
			if (callback == null)
				throw new ArgumentNullException("callback");
			
			if (searchScopes.Count == 0)
				return;
			var navigators = new IResolveVisitorNavigator[searchScopes.Count];
			for (int i = 0; i < navigators.Length; i++) {
				navigators[i] = searchScopes[i].GetNavigator(compilation, callback);
			}
			IResolveVisitorNavigator combinedNavigator;
			if (searchScopes.Count == 1) {
				combinedNavigator = navigators[0];
			} else {
				combinedNavigator = new CompositeResolveVisitorNavigator(navigators);
			}
			
			cancellationToken.ThrowIfCancellationRequested();
			combinedNavigator = new DetectSkippableNodesNavigator(combinedNavigator, compilationUnit);
			cancellationToken.ThrowIfCancellationRequested();
			CppAstResolver resolver = new CppAstResolver(compilation, compilationUnit, parsedFile);
			resolver.ApplyNavigator(combinedNavigator, cancellationToken);
			foreach (var n in navigators) {
				var frn = n as FindReferenceNavigator;
				if (frn != null)
					frn.NavigatorDone(resolver, cancellationToken);
			}
		}
Exemple #7
0
			internal virtual void NavigatorDone(CppAstResolver resolver, CancellationToken cancellationToken)
			{
			}