IEnumerable<CodeAction> GetActionsForType(RefactoringContext context, AstNode node)
		{
			var rr = context.Resolve(node) as UnknownIdentifierResolveResult;
			if (rr == null)
				return EmptyList<CodeAction>.Instance;
			
			string identifier = rr.Identifier;
			int tc = rr.TypeArgumentCount;
			string attributeIdentifier = null;
			if (node.Parent is Attribute)
				attributeIdentifier = identifier + "Attribute";
			
			var lookup = new MemberLookup(null, context.Compilation.MainAssembly);
			List<CodeAction> actions = new List<CodeAction>();
			foreach (var typeDefinition in context.Compilation.GetAllTypeDefinitions()) {
				if ((typeDefinition.Name == identifier || typeDefinition.Name == attributeIdentifier)
				    && typeDefinition.TypeParameterCount == tc
				    && lookup.IsAccessible(typeDefinition, false))
				{
					if (typeDefinition.DeclaringTypeDefinition == null) {
						actions.Add(NewUsingAction(context, node, typeDefinition.Namespace));
					}
					actions.Add(ReplaceWithFullTypeNameAction(context, node, typeDefinition));
				}
			}
			return actions;
		}
		bool IsAccessible(MemberLookup lookup, INamespace ns)
		{
			if (ns.Types.Any (t => lookup.IsAccessible (t, false)))
				return true;
			foreach (var child in ns.ChildNamespaces)
				if (IsAccessible (lookup, child))
					return true;
			return false;
		}
		CSharpUnresolvedFile Parse(string program)
		{
			SyntaxTree syntaxTree = SyntaxTree.Parse(program, "test.cs");
			CSharpUnresolvedFile unresolvedFile = syntaxTree.ToTypeSystem();
			project = project.AddOrUpdateFiles(unresolvedFile);
			compilation = project.CreateCompilation();
			lookup = new MemberLookup(null, compilation.MainAssembly);
			return unresolvedFile;
		}
        CSharpUnresolvedFile Parse(string program)
        {
            SyntaxTree           syntaxTree     = SyntaxTree.Parse(program, "test.cs");
            CSharpUnresolvedFile unresolvedFile = syntaxTree.ToTypeSystem();

            project     = project.AddOrUpdateFiles(unresolvedFile);
            compilation = project.CreateCompilation();
            lookup      = new MemberLookup(null, compilation.MainAssembly);
            return(unresolvedFile);
        }
		public void AddNamespace (MemberLookup lookup, INamespace ns)
		{
			if (usedNamespaces.Contains (ns.Name))
				return;
			if (!IsAccessible (lookup, ns)) {
				usedNamespaces.Add (ns.Name);
				return;
			}
			usedNamespaces.Add (ns.Name);
			result.Add (Factory.CreateNamespaceCompletionData (ns));
		}
		public ConstructorParameterDataProvider (int startOffset, CSharpCompletionTextEditorExtension ext, IType type) : base (startOffset, ext)
		{
			this.type = type;
			
			var ctx = ext.CSharpParsedFile.GetTypeResolveContext (ext.Compilation, ext.Document.Editor.Caret.Location) as CSharpTypeResolveContext;

			var lookup = new MemberLookup (ctx.CurrentTypeDefinition, ext.Compilation.MainAssembly);
			bool isProtectedAllowed = ctx.CurrentTypeDefinition != null && type.GetDefinition () != null ? ctx.CurrentTypeDefinition.IsDerivedFrom (type.GetDefinition ()) : false;
						
			foreach (var method in type.GetConstructors ()) {
				Console.WriteLine ("constructor:" + method);
				if (!lookup.IsAccessible (method, isProtectedAllowed)) {
					Console.WriteLine ("skip !!!");
					continue;
				}
				methods.Add (method);
			}
		}
		public ConstructorParameterDataProvider (int startOffset, CSharpCompletionTextEditorExtension ext, IType type) : base (startOffset, ext)
		{
			this.type = type;
			
			var ctx = ext.CSharpParsedFile.GetTypeResolveContext (ext.Compilation, ext.Document.Editor.Caret.Location) as CSharpTypeResolveContext;

			var lookup = new MemberLookup (ctx.CurrentTypeDefinition, ext.Compilation.MainAssembly);
			bool isProtectedAllowed = false;
			var typeDefinition = type.GetDefinition ();
			if (ctx.CurrentTypeDefinition != null && typeDefinition != null) {
				isProtectedAllowed = ctx.CurrentTypeDefinition.IsDerivedFrom (ctx.CurrentTypeDefinition.Compilation.Import (typeDefinition));
			}
						
			foreach (var method in type.GetConstructors ()) {
				if (!lookup.IsAccessible (method, isProtectedAllowed)) {
					continue;
				}
				if (!method.IsBrowsable ())
					continue;
				methods.Add (method);
			}
			methods.Sort ((l, r) => l.GetEditorBrowsableState ().CompareTo (r.GetEditorBrowsableState ()));
		}
		public ConstructorParameterDataProvider (int startOffset, CSharpCompletionTextEditorExtension ext, IType type, AstNode skipInitializer = null) : base (startOffset, ext)
		{
			this.type = type;
			
			var ctx = ext.CSharpUnresolvedFile.GetTypeResolveContext (ext.UnresolvedFileCompilation, ext.Editor.CaretLocation) as CSharpTypeResolveContext;

			var lookup = new MemberLookup (ctx.CurrentTypeDefinition, ext.Compilation.MainAssembly);
			bool isProtectedAllowed = false;
			var typeDefinition = type.GetDefinition ();
			if (ctx.CurrentTypeDefinition != null && typeDefinition != null) {
				isProtectedAllowed = ctx.CurrentTypeDefinition.IsDerivedFrom (ctx.CurrentTypeDefinition.Compilation.Import (typeDefinition));
			}
			foreach (var method in type.GetConstructors ()) {
				if (!lookup.IsAccessible (method, isProtectedAllowed)) {
					continue;
				}
				if (!method.IsBrowsable ())
					continue;
				if (skipInitializer != null && skipInitializer.Parent.StartLocation == method.Region.Begin)
					continue;
				methods.Add (method);
			}
			methods.Sort (MethodComparer);
		}
		public IList<ICompletionItem> CreateElementList(XamlCompletionContext context, bool includeAbstract)
		{
			if (context.ParseInformation == null)
				return EmptyList<ICompletionItem>.Instance;
			
			List<ICompletionItem> result = new List<ICompletionItem>();
			AXmlElement last = context.ParentElement;
			ITextEditor editor = context.Editor;
			compilation = SD.ParserService.GetCompilationForFile(editor.FileName);
			IUnresolvedFile file = context.ParseInformation.UnresolvedFile;
			
			foreach (string item in XamlConst.GetAllowedItems(context)) {
				result.Add(new XamlCompletionItem(item));
			}
			
			IType rt = null;

			if (last != null) {
				if (string.Equals(last.Prefix, context.XamlNamespacePrefix, StringComparison.OrdinalIgnoreCase)) {
					if (string.Equals(last.LocalName, "Members", StringComparison.OrdinalIgnoreCase))
						return result;
					if (string.Equals(last.LocalName, "Code", StringComparison.OrdinalIgnoreCase))
						return result;
				}
				// If we have an element that is not a property or an incomplete
				// definition => interpret element as a type.
				XamlResolver resolver = new XamlResolver(compilation);
				int dotIndex = last.LocalName.IndexOf(".", StringComparison.Ordinal) + 1;
				if (dotIndex < 1 || dotIndex == last.LocalName.Length) {
					rt = resolver.ResolveType(last.Namespace, last.LocalName.Trim('.'));
					string contentPropertyName = GetContentPropertyName(rt.GetDefinition());
					// If the type has a content property specified, use its type for completion.
					if (!string.IsNullOrEmpty(contentPropertyName)) {
						IProperty p = rt.GetProperties(m => m.Name == contentPropertyName).FirstOrDefault();
						if (p != null) {
							rt = p.ReturnType;
						}
					}
				} else {
					string typeName = last.LocalName.Substring(0, dotIndex - 1);
					string memberName = last.LocalName.Substring(dotIndex);
					rt = resolver.ResolveType(last.Namespace, typeName);
					IMember member = rt.GetMembers(m => m.Name == memberName).FirstOrDefault();
					if (member != null) {
						rt = member.ReturnType;
					}
				}
			}
			
			bool parentAdded = false;
			var utd = file.GetInnermostTypeDefinition(editor.Caret.Location);
			ITypeDefinition currentTypeDef = null;
			if (utd != null) {
				currentTypeDef = utd.Resolve(new SimpleTypeResolveContext(compilation.MainAssembly)).GetDefinition();
			}
			MemberLookup memberLookup = new MemberLookup(currentTypeDef, compilation.MainAssembly);
			
			IList<ITypeDefinition> possibleTypesInCollection = EmptyList<ITypeDefinition>.Instance;
			if (rt != null && Extensions.IsListType(rt)) {
				possibleTypesInCollection = rt.GetMethods(m => m.Parameters.Count == 1 && "Add".Equals(m.Name, StringComparison.Ordinal))
					.Select(m => m.Parameters[0].Type.GetDefinition())
					.Where(t => t != null)
					.ToList();
			}
			
			var items = GetClassesFromContext(context);
			
			foreach (var ns in items) {
				foreach (ITypeDefinition td in ns.Value) {
					if (td.Kind != TypeKind.Class && (!includeAbstract || td.Kind != TypeKind.Interface))
						continue;
					if (td.IsStatic || (!includeAbstract && td.IsAbstract) || td.IsDerivedFrom(KnownTypeCode.Attribute))
						continue;
					if (td.Kind == TypeKind.Class && !td.GetConstructors().Any(m => memberLookup.IsAccessible(m, false)))
						continue;
					if (possibleTypesInCollection.Count > 0 && !possibleTypesInCollection.Any(td.IsDerivedFrom))
						continue;
					string fullName = td.Name;
					if (!string.IsNullOrEmpty(ns.Key))
						fullName = ns.Key + ":" + fullName;
					XamlCompletionItem item = new XamlCompletionItem(fullName, td);
					parentAdded = parentAdded || (last != null && item.Text == last.Name);
					result.Add(item);
				}
			}
			
			// TODO reimplement this if it is really necessary.
//			if (!parentAdded && last != null && !last.Name.Contains(".")) {
//				IClass itemClass = cu.CreateType(last.Namespace, last.LocalName.Trim('.')).GetUnderlyingClass();
//				if (itemClass != null)
//					result.Add(new XamlCodeCompletionItem(itemClass, last.Prefix));
//			}
			
			return result;
		}
		protected override void Run ()
		{
			var doc = IdeApp.Workbench.ActiveDocument;
			if (doc == null || doc.FileName == FilePath.Null || doc.ParsedDocument == null)
				return;
			ITextEditorExtension ext = doc.EditorExtension;
			while (ext != null && !(ext is CompletionTextEditorExtension))
				ext = ext.Next;
			if (ext == null)
				return;
		
			var dom = doc.Compilation;
			ImportSymbolCache cache = new ImportSymbolCache ();
			var lookup = new MemberLookup (null, doc.Compilation.MainAssembly);

			List<ImportSymbolCompletionData> typeList = new List<ImportSymbolCompletionData> ();
			foreach (var type in dom.GetAllTypeDefinitions ()) {
				if (!lookup.IsAccessible (type, false))
					continue;
				typeList.Add (new ImportSymbolCompletionData (doc, cache, type));
			}
			
			typeList.Sort (delegate (ImportSymbolCompletionData left, ImportSymbolCompletionData right) {
				return left.Type.Name.CompareTo (right.Type.Name);
			});
			
			
			CompletionDataList completionList = new CompletionDataList ();
			completionList.IsSorted = true;
			typeList.ForEach (cd => completionList.Add (cd));
			
			((CompletionTextEditorExtension)ext).ShowCompletion (completionList);
		}
 public override void SetUp()
 {
     base.SetUp();
     lookup = new MemberLookup(null, compilation.MainAssembly);
 }
		bool IsAccessibleOrHasSourceCode (IEntity entity)
		{
			if (!entity.Region.Begin.IsEmpty)
				return true;
			var lookup = new MemberLookup (resolver.CurrentTypeDefinition, resolver.Compilation.MainAssembly);
			return lookup.IsAccessible (entity, false);
		}
		static IEnumerable<PossibleNamespace> GetPossibleNamespaces (Document doc, AstNode node, ResolveResult resolveResult, DocumentLocation location)
		{
			var unit = doc.ParsedDocument.GetAst<SyntaxTree> ();
			if (unit == null)
				yield break;

			int tc = GetTypeParameterCount (node);
			var attribute = unit.GetNodeAt<ICSharpCode.NRefactory.CSharp.Attribute> (location);
			bool isInsideAttributeType = attribute != null && attribute.Type.Contains (location);

			var compilations = new List<Tuple<ICompilation, MonoDevelop.Projects.ProjectReference>> ();
			compilations.Add (Tuple.Create (doc.Compilation, (MonoDevelop.Projects.ProjectReference)null));
			var referencedItems = doc.Project.GetReferencedItems (IdeApp.Workspace.ActiveConfiguration).ToList ();
			foreach (var project in doc.Project.ParentSolution.GetAllProjects ()) {
				if (project == doc.Project || referencedItems.Contains (project))
					continue;
				var comp = TypeSystemService.GetCompilation (project);
				if (comp == null)
					continue;
				compilations.Add (Tuple.Create (comp, new MonoDevelop.Projects.ProjectReference (project)));
			}

			var netProject = doc.Project as DotNetProject;
			if (netProject == null) 
				yield break;
			var frameworkLookup = TypeSystemService.GetFrameworkLookup (netProject);

			if (resolveResult is UnknownMemberResolveResult) {
				var umResult = (UnknownMemberResolveResult)resolveResult;
				foreach (var r in frameworkLookup.LookupExtensionMethod (umResult.MemberName)) {
					var systemAssembly = netProject.AssemblyContext.GetAssemblyFromFullName (r.FullName, r.Package, netProject.TargetFramework);
					if (systemAssembly == null)
						continue;
					compilations.Add (Tuple.Create (TypeSystemService.GetCompilation (systemAssembly, doc.Compilation), new MonoDevelop.Projects.ProjectReference (systemAssembly)));
				}
			}

			var lookup = new MemberLookup (null, doc.Compilation.MainAssembly);
			foreach (var comp in compilations) {
				var compilation = comp.Item1;
				var requiredReference = comp.Item2;
				if (resolveResult is AmbiguousTypeResolveResult) {
					var aResult = resolveResult as AmbiguousTypeResolveResult;
					var file = doc.ParsedDocument.ParsedFile as CSharpUnresolvedFile;
					var scope = file.GetUsingScope (location).Resolve (compilation);
					while (scope != null) {
						foreach (var u in scope.Usings) {
							foreach (var typeDefinition in u.Types) {
								if (typeDefinition.Name == aResult.Type.Name && 
									typeDefinition.TypeParameterCount == tc &&
									lookup.IsAccessible (typeDefinition, false)) {
									yield return new PossibleNamespace (typeDefinition.Namespace, true, requiredReference);
								}
							}
						}
						scope = scope.Parent;
					}
				}

				if (resolveResult is UnknownIdentifierResolveResult) {
					var uiResult = resolveResult as UnknownIdentifierResolveResult;
					string possibleAttributeName = isInsideAttributeType ? uiResult.Identifier + "Attribute" : null;
					foreach (var typeDefinition in compilation.GetAllTypeDefinitions ()) {
						if ((typeDefinition.Name == uiResult.Identifier || typeDefinition.Name == possibleAttributeName) && typeDefinition.TypeParameterCount == tc && 
							lookup.IsAccessible (typeDefinition, false)) {
							if (typeDefinition.DeclaringTypeDefinition != null) {
								var builder = new TypeSystemAstBuilder (new CSharpResolver (doc.Compilation));
								yield return new PossibleNamespace (builder.ConvertType (typeDefinition.DeclaringTypeDefinition).ToString (), false, requiredReference);
							} else {
								yield return new PossibleNamespace (typeDefinition.Namespace, true, requiredReference);
							}
						}
					}
				}

				if (resolveResult is UnknownMemberResolveResult) {
					var umResult = (UnknownMemberResolveResult)resolveResult;
					string possibleAttributeName = isInsideAttributeType ? umResult.MemberName + "Attribute" : null;
					foreach (var typeDefinition in compilation.GetAllTypeDefinitions ().Where (t => t.HasExtensionMethods)) {
						foreach (var method in typeDefinition.Methods.Where (m => m.IsExtensionMethod && (m.Name == umResult.MemberName || m.Name == possibleAttributeName))) {
							IType[] inferredTypes;
							if (CSharpResolver.IsEligibleExtensionMethod (
								compilation.Import (umResult.TargetType),
								method,
								true,
								out inferredTypes
							)) {
								yield return new PossibleNamespace (typeDefinition.Namespace, true, requiredReference);
								goto skipType;
							}
						}
						skipType:
						;
					}
				}
				
				if (resolveResult is ErrorResolveResult) {
					var identifier = unit != null ? unit.GetNodeAt<Identifier> (location) : null;
					if (identifier != null) {
						var uiResult = resolveResult as UnknownIdentifierResolveResult;
						if (uiResult != null) {
							string possibleAttributeName = isInsideAttributeType ? uiResult.Identifier + "Attribute" : null;
							foreach (var typeDefinition in compilation.GetAllTypeDefinitions ()) {
								if ((identifier.Name == uiResult.Identifier || identifier.Name == possibleAttributeName) && 
								    typeDefinition.TypeParameterCount == tc && 
								    lookup.IsAccessible (typeDefinition, false))
									yield return new PossibleNamespace (typeDefinition.Namespace, true, requiredReference);
							}
						}
					}
				}
			}
		

			if (resolveResult is UnknownIdentifierResolveResult) {
				var uiResult = resolveResult as UnknownIdentifierResolveResult;

				foreach (var r in frameworkLookup.LookupIdentifier (uiResult.Identifier, tc)) {
					var systemAssembly = netProject.AssemblyContext.GetAssemblyFromFullName (r.FullName, r.Package, netProject.TargetFramework);
					if (systemAssembly == null)
						continue;
					yield return new PossibleNamespace (r.Namespace, true, new MonoDevelop.Projects.ProjectReference (systemAssembly));
				}
			}

		}
		void AddTypesAndNamespaces(CompletionDataWrapper wrapper, CSharpResolver state, AstNode node, Func<IType, IType> typePred = null, Predicate<IMember> memberPred = null, Action<ICompletionData, IType> callback = null)
		{
			var lookup = new MemberLookup(
				ctx.CurrentTypeDefinition,
				Compilation.MainAssembly
			);
			if (currentType != null) {
				for (var ct = currentType; ct != null; ct = ct.DeclaringTypeDefinition) {
					foreach (var nestedType in ct.NestedTypes) {
						string name = nestedType.Name;
						if (IsAttributeContext(node) && name.EndsWith("Attribute") && name.Length > "Attribute".Length) {
							name = name.Substring(0, name.Length - "Attribute".Length);
						}

						if (typePred == null) {
							wrapper.AddType(nestedType, name);
							continue;
						}

						var type = typePred(nestedType.Resolve(ctx));
						if (type != null) {
							var a2 = wrapper.AddType(type, name);
							if (a2 != null && callback != null) {
								callback(a2, type);
							}
						}
						continue;
					}
				}
				if (this.currentMember != null && !(node is AstType)) {
					var def = ctx.CurrentTypeDefinition ?? Compilation.MainAssembly.GetTypeDefinition(currentType);
					if (def != null) {
						bool isProtectedAllowed = true;
						foreach (var member in def.GetMembers ()) {
							if (member is IMethod && ((IMethod)member).FullName == "System.Object.Finalize") {
								continue;
							}
							if (member.EntityType == EntityType.Operator) {
								continue;
							}
							if (member.IsExplicitInterfaceImplementation) {
								continue;
							}
							if (!lookup.IsAccessible(member, isProtectedAllowed)) {
								continue;
							}

							if (memberPred == null || memberPred(member)) {
								wrapper.AddMember(member);
							}
						}
						var declaring = def.DeclaringTypeDefinition;
						while (declaring != null) {
							foreach (var member in declaring.GetMembers (m => m.IsStatic)) {
								if (memberPred == null || memberPred(member)) {
									wrapper.AddMember(member);
								}
							}
							declaring = declaring.DeclaringTypeDefinition;
						}
					}
				}
				foreach (var p in currentType.TypeParameters) {
					wrapper.AddTypeParameter(p);
				}
			}
			var scope = CSharpParsedFile.GetUsingScope(location).Resolve(Compilation);
			
			for (var n = scope; n != null; n = n.Parent) {
				foreach (var pair in n.UsingAliases) {
					wrapper.AddNamespace(pair.Key);
				}
				foreach (var u in n.Usings) {
					foreach (var type in u.Types) {
						if (!lookup.IsAccessible(type, false))
							continue;

						IType addType = typePred != null ? typePred(type) : type;
						if (addType != null) {
							string name = type.Name;
							if (IsAttributeContext(node) && name.EndsWith("Attribute") && name.Length > "Attribute".Length) {
								name = name.Substring(0, name.Length - "Attribute".Length);
							}
							var a = wrapper.AddType(addType, name);
							if (a != null && callback != null) {
								callback(a, type);
							}
						}
					}
				}
				
				foreach (var type in n.Namespace.Types) {
					if (!lookup.IsAccessible(type, false))
						continue;
					IType addType = typePred != null ? typePred(type) : type;
					if (addType != null) {
						var a2 = wrapper.AddType(addType, addType.Name);
						if (a2 != null && callback != null) {
							callback(a2, type);
						}
					}
				}
				
				foreach (var curNs in n.Namespace.ChildNamespaces) {
					wrapper.AddNamespace(curNs.Name);
				}
			}
		}
		IEnumerable<ICompletionData> CreateConstructorCompletionData(IType hintType)
		{
			var wrapper = new CompletionDataWrapper(this);
			var state = GetState();
			Func<IType, IType> pred = null;
			Action<ICompletionData, IType> typeCallback = null;
			var inferredTypesCategory = new Category("Inferred Types", null);
			var derivedTypesCategory = new Category("Derived Types", null);
			if (hintType != null) {
				if (hintType.Kind != TypeKind.Unknown) {
					var lookup = new MemberLookup(
						ctx.CurrentTypeDefinition,
						Compilation.MainAssembly
					);
					typeCallback = (data, t) => {
						//check if type is in inheritance tree.
						if (hintType.GetDefinition() != null &&
							t.GetDefinition() != null &&
							t.GetDefinition().IsDerivedFrom(hintType.GetDefinition())) {
							data.CompletionCategory = derivedTypesCategory;
						}
					};
					pred = t => {
						if (t.Kind == TypeKind.Interface && hintType.Kind != TypeKind.Array) {
							return null;
						}
						// check for valid constructors
						if (t.GetConstructors().Count() > 0) {
							bool isProtectedAllowed = currentType != null ? 
							                          currentType.Resolve(ctx).GetDefinition().IsDerivedFrom(t.GetDefinition()) : false;
							if (!t.GetConstructors().Any(m => lookup.IsAccessible(m, isProtectedAllowed))) {
								return null;
							}
						}

						// check derived types
						var typeDef = t.GetDefinition();
						var hintDef = hintType.GetDefinition();
						if (typeDef != null && hintDef != null && typeDef.IsDerivedFrom(hintDef)) {
							var newType = wrapper.AddType(t, true);
							if (newType != null) {
								newType.CompletionCategory = inferredTypesCategory;
							}
						}

						// check type inference
						var typeInference = new TypeInference(Compilation);
						typeInference.Algorithm = TypeInferenceAlgorithm.ImprovedReturnAllResults;

						var inferedType = typeInference.FindTypeInBounds(new [] { t }, new [] { hintType });
						if (inferedType != SpecialType.UnknownType) {
							var newType = wrapper.AddType(inferedType, true);
							if (newType != null) {
								newType.CompletionCategory = inferredTypesCategory;
							}
							return null;
						}
						return t;
					};
					if (!(hintType.Kind == TypeKind.Interface && hintType.Kind != TypeKind.Array)) {
						var hint = wrapper.AddType(hintType, true);
						if (hint != null) {
							DefaultCompletionString = hint.DisplayText;
							hint.CompletionCategory = derivedTypesCategory;
						}
					}
					if (hintType is ParameterizedType && hintType.TypeParameterCount == 1 && hintType.FullName == "System.Collections.Generic.IEnumerable") {
						var arg = ((ParameterizedType)hintType).TypeArguments.FirstOrDefault();
						if (arg.Kind != TypeKind.TypeParameter) {
							var array = new ArrayType(ctx.Compilation, arg, 1);
							wrapper.AddType(array, true);
						}
					}
				} else {
					var hint = wrapper.AddType(hintType, true);
					if (hint != null) {
						DefaultCompletionString = hint.DisplayText;
						hint.CompletionCategory = derivedTypesCategory;
					}
				}
			} 
			AddTypesAndNamespaces(wrapper, state, null, pred, m => false, typeCallback, true);
			if (hintType == null || hintType == SpecialType.UnknownType) {
				AddKeywords(wrapper, primitiveTypesKeywords.Where(k => k != "void"));
			}

			CloseOnSquareBrackets = true;
			AutoCompleteEmptyMatch = true;
			AutoCompleteEmptyMatchOnCurlyBracket = false;
			return wrapper.Result;
		}
		/// <summary>
		/// Gets the types that needs to be imported via using or full type name.
		/// </summary>
		public IEnumerable<ICompletionData> GetImportCompletionData(int offset)
		{
			var generalLookup = new MemberLookup(null, Compilation.MainAssembly);
			SetOffset(offset);

			// flatten usings
			var namespaces = new List<INamespace>();
			for (var n = ctx.CurrentUsingScope; n != null; n = n.Parent) {
				namespaces.Add(n.Namespace);
				foreach (var u in n.Usings)
					namespaces.Add(u);
			}

			foreach (var type in Compilation.GetAllTypeDefinitions ()) {
				if (!generalLookup.IsAccessible(type, false))
					continue;	
				if (namespaces.Any(n => n.FullName == type.Namespace))
					continue;
				bool useFullName = false;
				foreach (var ns in namespaces) {
					if (ns.GetTypeDefinition(type.Name, type.TypeParameterCount) != null) {
						useFullName = true;
						break;
					}
				}
				yield return factory.CreateImportCompletionData(type, useFullName, false);
			}
		}
		IEnumerable<IProperty> GetAccessibleIndexers(IType type)
		{
			var lookup = new MemberLookup(ctx.CurrentTypeDefinition, Compilation.MainAssembly);
			var properties = new List<IProperty>();
			foreach (var property in type.GetProperties ()) {
				if (!property.IsIndexer)
					continue;
				if (!lookup.IsAccessible (property, true))
					continue;
				if (property.IsShadowing) {
					for (int j = 0; j < properties.Count; j++) {
						if (ParameterListComparer.Instance.Equals(properties[j].Parameters, property.Parameters)) {
							properties.RemoveAt (j);
							j--;
						}
					}
				}

				properties.Add (property);
			}
			return properties;
		}
		IEnumerable<IMethod> CollectMethods(AstNode resolvedNode, MethodGroupResolveResult resolveResult)
		{
			var lookup = new MemberLookup(ctx.CurrentTypeDefinition, Compilation.MainAssembly);
			bool onlyStatic = false;
			if (resolvedNode is IdentifierExpression && currentMember != null && currentMember.IsStatic || resolveResult.TargetResult is TypeResolveResult) {
				onlyStatic = true;
			}
			var methods = new List<IMethod>();
			foreach (var method in resolveResult.Methods) {
				if (method.IsConstructor) {
					continue;
				}
				if (!lookup.IsAccessible (method, true))
					continue;
				if (onlyStatic && !method.IsStatic) {
					continue;
				}
				if (method.IsShadowing) {
					for (int j = 0; j < methods.Count; j++) {
						if (ParameterListComparer.Instance.Equals(methods[j].Parameters, method.Parameters)) {
							methods.RemoveAt (j);
							j--;
						}
					}
				}
				methods.Add (method);
			}
			foreach (var m in methods) {
				yield return m;
			}
			foreach (var extMethods in resolveResult.GetEligibleExtensionMethods (true)) {
				foreach (var method in extMethods) {
					if (methods.Contains (method))
						continue;
					yield return new ReducedExtensionMethod (method);
				}
			}
		}
Exemple #19
0
        IEnumerable<ICompletionData> CreateTypeCompletionData(IType hintType, AstType hintTypeAst)
        {
            var wrapper = new CompletionDataWrapper (this);
            var state = GetState ();
            Predicate<IType> pred = null;
            if (hintType != null) {

                if (hintType.Kind != TypeKind.Unknown) {
                    var lookup = new MemberLookup (ctx.CurrentTypeDefinition, Compilation.MainAssembly);
                    pred = t => {
                        // check if type is in inheritance tree.
                        if (hintType.GetDefinition () != null && !t.GetDefinition ().IsDerivedFrom (hintType.GetDefinition ()))
                            return false;

                        // check for valid constructors
                        if (t.GetConstructors ().Count () == 0)
                            return true;
                        bool isProtectedAllowed = currentType != null ? currentType.Resolve (ctx).GetDefinition ().IsDerivedFrom (t.GetDefinition ()) : false;
                        return t.GetConstructors ().Any (m => lookup.IsAccessible (m, isProtectedAllowed));
                    };
                    DefaultCompletionString = GetShortType (hintType, GetState ());
                    wrapper.AddType (hintType, DefaultCompletionString);
                } else {
                    DefaultCompletionString = hintTypeAst.ToString ();
                    wrapper.AddType (hintType, DefaultCompletionString);
                }
            }
            AddTypesAndNamespaces (wrapper, state, null, pred, m => false);
            AddKeywords (wrapper, primitiveTypesKeywords.Where (k => k != "void"));
            CloseOnSquareBrackets = true;
            AutoCompleteEmptyMatch = true;
            return wrapper.Result;
        }
Exemple #20
0
        IEnumerable<ICompletionData> CreateCompletionData(TextLocation location, ResolveResult resolveResult, AstNode resolvedNode, CSharpResolver state)
        {
            if (resolveResult == null /*|| resolveResult.IsError*/)
                return null;

            if (resolveResult is NamespaceResolveResult) {
                var nr = (NamespaceResolveResult)resolveResult;
                var namespaceContents = new CompletionDataWrapper (this);

                foreach (var cl in nr.Namespace.Types) {
                    namespaceContents.AddType (cl, cl.Name);
                }

                foreach (var ns in nr.Namespace.ChildNamespaces) {
                    namespaceContents.AddNamespace (ns.Name);
                }
                return namespaceContents.Result;
            }

            IType type = resolveResult.Type;
            var typeDef = resolveResult.Type.GetDefinition ();
            var lookup = new MemberLookup (ctx.CurrentTypeDefinition, Compilation.MainAssembly);
            var result = new CompletionDataWrapper (this);
            bool isProtectedAllowed = false;
            bool includeStaticMembers = false;

            if (resolveResult is LocalResolveResult) {
                isProtectedAllowed = currentType != null && typeDef != null ? typeDef.GetAllBaseTypeDefinitions ().Any (bt => bt.Equals (currentType)) : false;
                if (resolvedNode is IdentifierExpression) {
                    var mrr = (LocalResolveResult)resolveResult;
                    includeStaticMembers = mrr.Variable.Name == mrr.Type.Name;
                }
            } else {
                isProtectedAllowed = currentType != null && typeDef != null ? currentType.Resolve (ctx).GetDefinition ().GetAllBaseTypeDefinitions ().Any (bt => bt.Equals (typeDef)) : false;
            }
            if (resolveResult is TypeResolveResult && type.Kind == TypeKind.Enum) {
                foreach (var field in type.GetFields ()) {
                    result.AddMember (field);
                }
                foreach (var m in type.GetMethods ()) {
                    if (m.Name == "TryParse")
                        result.AddMember (m);
                }
                return result.Result;
            }

            if (resolveResult is MemberResolveResult && resolvedNode is IdentifierExpression) {
                var mrr = (MemberResolveResult)resolveResult;
                includeStaticMembers = mrr.Member.Name == mrr.Type.Name;
            }

            //			Console.WriteLine ("type:" + type +"/"+type.GetType ());
            //			Console.WriteLine ("IS PROT ALLOWED:" + isProtectedAllowed);
            //			Console.WriteLine (resolveResult);
            //			Console.WriteLine (currentMember !=  null ? currentMember.IsStatic : "currentMember == null");

            if (resolvedNode.Annotation<ObjectCreateExpression> () == null) { //tags the created expression as part of an object create expression.
                foreach (var member in type.GetMembers ()) {
                    if (!lookup.IsAccessible (member, isProtectedAllowed)) {
                        //					Console.WriteLine ("skip access: " + member.FullName);
                        continue;
                    }
                    if (resolvedNode is BaseReferenceExpression && member.IsAbstract)
                        continue;

                    if (!includeStaticMembers && member.IsStatic && !(resolveResult is TypeResolveResult)) {
                        //					Console.WriteLine ("skip static member: " + member.FullName);
                        continue;
                    }
                    if (!member.IsStatic && (resolveResult is TypeResolveResult)) {
                        //					Console.WriteLine ("skip non static member: " + member.FullName);
                        continue;
                    }
                    //				Console.WriteLine ("add : "+ member.FullName + " --- " + member.IsStatic);
                    result.AddMember (member);
                }
            }

            if (resolveResult is TypeResolveResult || includeStaticMembers) {
                foreach (var nested in type.GetNestedTypes ()) {
                    result.AddType (nested, nested.Name);
                }

            } else {
                foreach (var meths in state.GetAllExtensionMethods (type)) {
                    foreach (var m in meths) {
                        result.AddMember (m);
                    }
                }
            }

            //			IEnumerable<object> objects = resolveResult.CreateResolveResult (dom, resolver != null ? resolver.CallingMember : null);
            //			CompletionDataCollector col = new CompletionDataCollector (this, dom, result, Document.CompilationUnit, resolver != null ? resolver.CallingType : null, location);
            //			col.HideExtensionParameter = !resolveResult.StaticResolve;
            //			col.NamePrefix = expressionResult.Expression;
            //			bool showOnlyTypes = expressionResult.Contexts.Any (ctx => ctx == ExpressionContext.InheritableType || ctx == ExpressionContext.Constraints);
            //			if (objects != null) {
            //				foreach (object obj in objects) {
            //					if (expressionResult.ExpressionContext != null && expressionResult.ExpressionContext.FilterEntry (obj))
            //						continue;
            //					if (expressionResult.ExpressionContext == ExpressionContext.NamespaceNameExcepted && !(obj is Namespace))
            //						continue;
            //					if (showOnlyTypes && !(obj is IType))
            //						continue;
            //					CompletionData data = col.Add (obj);
            //					if (data != null && expressionResult.ExpressionContext == ExpressionContext.Attribute && data.CompletionText != null && data.CompletionText.EndsWith ("Attribute")) {
            //						string newText = data.CompletionText.Substring (0, data.CompletionText.Length - "Attribute".Length);
            //						data.SetText (newText);
            //					}
            //				}
            //			}

            return result.Result;
        }
		static IEnumerable<string> GetPossibleNamespaces (Document doc, AstNode node, ResolveResult resolveResult, DocumentLocation location)
		{
			var unit = doc.ParsedDocument.GetAst<CompilationUnit> ();
			if (unit == null)
				yield break;

			int tc = GetTypeParameterCount (node);
			var attribute = unit.GetNodeAt<ICSharpCode.NRefactory.CSharp.Attribute> (location);
			bool isInsideAttributeType = attribute != null && attribute.Type.Contains (location);
			var lookup = new MemberLookup (null, doc.Compilation.MainAssembly);

			if (resolveResult is AmbiguousTypeResolveResult) {
				var aResult = resolveResult as AmbiguousTypeResolveResult;
				var file = doc.ParsedDocument.ParsedFile as CSharpParsedFile;
				var scope = file.GetUsingScope (location).Resolve (doc.Compilation);
				while (scope != null) {
					foreach (var u in scope.Usings) {
						foreach (var typeDefinition in u.Types) {
							if (typeDefinition.Name == aResult.Type.Name && 
								typeDefinition.TypeParameterCount == tc &&
								lookup.IsAccessible (typeDefinition, false)) {
								yield return typeDefinition.Namespace;
							}
						}
					}
					scope = scope.Parent;
				}
				yield break;
			}

			if (resolveResult is UnknownIdentifierResolveResult) {
				var uiResult = resolveResult as UnknownIdentifierResolveResult;
				string possibleAttributeName = isInsideAttributeType ? uiResult.Identifier + "Attribute" : null;
				foreach (var typeDefinition in doc.Compilation.GetAllTypeDefinitions ()) {
					if ((typeDefinition.Name == uiResult.Identifier || typeDefinition.Name == possibleAttributeName) && typeDefinition.TypeParameterCount == tc && 
						lookup.IsAccessible (typeDefinition, false)) {
						yield return typeDefinition.Namespace;
					}
				}
				yield break;
			}

			if (resolveResult is UnknownMemberResolveResult) {
				var umResult = (UnknownMemberResolveResult)resolveResult;
				string possibleAttributeName = isInsideAttributeType ? umResult.MemberName + "Attribute" : null;
				var compilation = doc.Compilation;
				foreach (var typeDefinition in compilation.GetAllTypeDefinitions ().Where (t => t.HasExtensionMethods)) {
					foreach (var method in typeDefinition.Methods.Where (m => m.IsExtensionMethod && (m.Name == umResult.MemberName || m.Name == possibleAttributeName))) {
						IType[] inferredTypes;
						if (CSharpResolver.IsEligibleExtensionMethod (
							compilation.Import (umResult.TargetType),
							method,
							true,
							out inferredTypes
						)) {
							yield return typeDefinition.Namespace;
							goto skipType;
						}
					}
					skipType:
					;
				}
				yield break;
			}
			
			if (resolveResult is ErrorResolveResult) {
				var identifier = unit != null ? unit.GetNodeAt<ICSharpCode.NRefactory.CSharp.Identifier> (location) : null;
				if (identifier != null) {
					var uiResult = resolveResult as UnknownIdentifierResolveResult;
					if (uiResult != null) {
						string possibleAttributeName = isInsideAttributeType ? uiResult.Identifier + "Attribute" : null;
						foreach (var typeDefinition in doc.Compilation.GetAllTypeDefinitions ()) {
							if ((identifier.Name == uiResult.Identifier || identifier.Name == possibleAttributeName) && 
							    typeDefinition.TypeParameterCount == tc && 
							    lookup.IsAccessible (typeDefinition, false))
								yield return typeDefinition.Namespace;
						}
					}
				}
				yield break;
			}
		}
		IEnumerable<ICompletionData> CreateCompletionData(TextLocation location, ResolveResult resolveResult, AstNode resolvedNode, CSharpResolver state, Func<IType, IType> typePred = null)
		{
			if (resolveResult == null /*			|| resolveResult.IsError*/) {
				return null;
			}

			var lookup = new MemberLookup(
				ctx.CurrentTypeDefinition,
				Compilation.MainAssembly
			);

			if (resolveResult is NamespaceResolveResult) {
				var nr = (NamespaceResolveResult)resolveResult;
				var namespaceContents = new CompletionDataWrapper(this);

				foreach (var cl in nr.Namespace.Types) {
					if (!lookup.IsAccessible(cl, false))
						continue;
					IType addType = typePred != null ? typePred(cl) : cl;
					if (addType != null)
						namespaceContents.AddType(addType, false);
				}

				foreach (var ns in nr.Namespace.ChildNamespaces) {
					namespaceContents.AddNamespace(lookup, ns);
				}
				return namespaceContents.Result;
			}
			IType type = resolveResult.Type;

			if (type.Namespace == "System" && type.Name == "Void")
				return null;

			if (resolvedNode.Parent is PointerReferenceExpression && (type is PointerType)) {
				resolveResult = new OperatorResolveResult(((PointerType)type).ElementType, System.Linq.Expressions.ExpressionType.Extension, resolveResult);
			}

			//var typeDef = resolveResult.Type.GetDefinition();
			var result = new CompletionDataWrapper(this);
			bool includeStaticMembers = false;

			if (resolveResult is LocalResolveResult) {
				if (resolvedNode is IdentifierExpression) {
					var mrr = (LocalResolveResult)resolveResult;
					includeStaticMembers = mrr.Variable.Name == mrr.Type.Name;
				}
			}
			if (resolveResult is TypeResolveResult && type.Kind == TypeKind.Enum) {
				foreach (var field in type.GetFields ()) {
					if (!lookup.IsAccessible(field, false))
						continue;
					result.AddMember(field);
				}
				return result.Result;
			}

			bool isProtectedAllowed = resolveResult is ThisResolveResult ? true : lookup.IsProtectedAccessAllowed(type);
			bool skipNonStaticMembers = (resolveResult is TypeResolveResult);

			if (resolveResult is MemberResolveResult && resolvedNode is IdentifierExpression) {
				var mrr = (MemberResolveResult)resolveResult;
				includeStaticMembers = mrr.Member.Name == mrr.Type.Name;

				TypeResolveResult trr;
				if (state.IsVariableReferenceWithSameType(
					resolveResult,
					((IdentifierExpression)resolvedNode).Identifier,
					out trr
				)) {
					if (currentMember != null && mrr.Member.IsStatic ^ currentMember.IsStatic) {
						skipNonStaticMembers = true;

						if (trr.Type.Kind == TypeKind.Enum) {
							foreach (var field in trr.Type.GetFields ()) {
								if (lookup.IsAccessible(field, false))
									result.AddMember(field);
							}
							return result.Result;
						}
					}
				}
				// ADD Aliases
				var scope = ctx.CurrentUsingScope;

				for (var n = scope; n != null; n = n.Parent) {
					foreach (var pair in n.UsingAliases) {
						if (pair.Key == mrr.Member.Name) {
							foreach (var r in CreateCompletionData (location, pair.Value, resolvedNode, state)) {
								if (r is IEntityCompletionData && ((IEntityCompletionData)r).Entity is IMember) {
									result.AddMember((IMember)((IEntityCompletionData)r).Entity);
								} else {
									result.Add(r);
								}
							}
						}
					}
				}				


			}
			if (resolveResult is TypeResolveResult && (resolvedNode is IdentifierExpression || resolvedNode is MemberReferenceExpression)) {
				includeStaticMembers = true;
			}

			//			Console.WriteLine ("type:" + type +"/"+type.GetType ());
			//			Console.WriteLine ("current:" + ctx.CurrentTypeDefinition);
			//			Console.WriteLine ("IS PROT ALLOWED:" + isProtectedAllowed + " static: "+ includeStaticMembers);
			//			Console.WriteLine (resolveResult);
			//			Console.WriteLine ("node:" + resolvedNode);
			//			Console.WriteLine (currentMember !=  null ? currentMember.IsStatic : "currentMember == null");

			if (resolvedNode.Annotation<ObjectCreateExpression>() == null) {
				//tags the created expression as part of an object create expression.
				/*				
				var filteredList = new List<IMember>();
				foreach (var member in type.GetMembers ()) {
					filteredList.Add(member);
				}
				
				foreach (var member in filteredList) {
					//					Console.WriteLine ("add:" + member + "/" + member.IsStatic);
					result.AddMember(member);
				}*/
				foreach (var member in lookup.GetAccessibleMembers (resolveResult)) {
					if (member.SymbolKind == SymbolKind.Indexer || member.SymbolKind == SymbolKind.Operator || member.SymbolKind == SymbolKind.Constructor || member.SymbolKind == SymbolKind.Destructor) {
						continue;
					}
					if (resolvedNode is BaseReferenceExpression && member.IsAbstract) {
						continue;
					}
					if (member is IType) {
						if (resolveResult is TypeResolveResult || includeStaticMembers) {
							if (!lookup.IsAccessible(member, isProtectedAllowed))
								continue;
							result.AddType((IType)member, false);
							continue;
						}
					}
					bool memberIsStatic = member.IsStatic;
					if (!includeStaticMembers && memberIsStatic && !(resolveResult is TypeResolveResult)) {
						//						Console.WriteLine ("skip static member: " + member.FullName);
						continue;
					}

					var field = member as IField;
					if (field != null) {
						memberIsStatic |= field.IsConst;
					}
					if (!memberIsStatic && skipNonStaticMembers) {
						continue;
					}

					if (member is IMethod && ((IMethod)member).FullName == "System.Object.Finalize") {
						continue;
					}
					if (member.SymbolKind == SymbolKind.Operator) {
						continue;
					}

					if (member is IMember) {
						result.AddMember((IMember)member);
					}
				}
			}

			if (!(resolveResult is TypeResolveResult || includeStaticMembers)) {
				foreach (var meths in state.GetExtensionMethods (type)) {
					foreach (var m in meths) {
						if (!lookup.IsAccessible(m, isProtectedAllowed))
							continue;
						result.AddMember(new ReducedExtensionMethod(m));
					}
				}
			}

			//			IEnumerable<object> objects = resolveResult.CreateResolveResult (dom, resolver != null ? resolver.CallingMember : null);
			//			CompletionDataCollector col = new CompletionDataCollector (this, dom, result, Document.CompilationUnit, resolver != null ? resolver.CallingType : null, location);
			//			col.HideExtensionParameter = !resolveResult.StaticResolve;
			//			col.NamePrefix = expressionResult.Expression;
			//			bool showOnlyTypes = expressionResult.Contexts.Any (ctx => ctx == ExpressionContext.InheritableType || ctx == ExpressionContext.Constraints);
			//			if (objects != null) {
			//				foreach (object obj in objects) {
			//					if (expressionResult.ExpressionContext != null && expressionResult.ExpressionContext.FilterEntry (obj))
			//						continue;
			//					if (expressionResult.ExpressionContext == ExpressionContext.NamespaceNameExcepted && !(obj is Namespace))
			//						continue;
			//					if (showOnlyTypes && !(obj is IType))
			//						continue;
			//					CompletionData data = col.Add (obj);
			//					if (data != null && expressionResult.ExpressionContext == ExpressionContext.Attribute && data.CompletionText != null && data.CompletionText.EndsWith ("Attribute")) {
			//						string newText = data.CompletionText.Substring (0, data.CompletionText.Length - "Attribute".Length);
			//						data.SetText (newText);
			//					}
			//				}
			//			}

			return result.Result;
		}
        IEnumerable<ICompletionData> HandleObjectInitializer(SyntaxTree unit, AstNode n)
        {
            var p = n.Parent;
            while (p != null && !(p is ObjectCreateExpression)) {
                p = p.Parent;
            }
            var parent = n.Parent as ArrayInitializerExpression;
            if (parent == null)
                return null;
            if (parent.IsSingleElement)
                parent = (ArrayInitializerExpression)parent.Parent;
            if (p != null) {
                var contextList = new CompletionDataWrapper(this);
                var initializerResult = ResolveExpression(p);
                if (initializerResult != null && initializerResult.Item1.Type.Kind != TypeKind.Unknown) {
                    // check 3 cases:
                    // 1) New initalizer { xpr
                    // 2) Object initializer { prop = val1, field = val2, xpr
                    // 3) Array initializer { new Foo (), a, xpr
                    // in case 1 all object/array initializer options should be given - in the others not.

                    AstNode prev = null;
                    if (parent.Elements.Count > 1) {
                        prev = parent.Elements.First();
                        if (prev is ArrayInitializerExpression && ((ArrayInitializerExpression)prev).IsSingleElement)
                            prev = ((ArrayInitializerExpression)prev).Elements.FirstOrDefault();
                    }

                    if (prev != null && !(prev is NamedExpression)) {
                        AddContextCompletion(contextList, GetState(), n);
                        // case 3)
                        return contextList.Result;
                    }

                    var lookup = new MemberLookup(ctx.CurrentTypeDefinition, Compilation.MainAssembly);
                    bool isProtectedAllowed = ctx.CurrentTypeDefinition != null ?
                        ctx.CurrentTypeDefinition.IsDerivedFrom(initializerResult.Item1.Type.GetDefinition()) :
                            false;

                    foreach (var m in initializerResult.Item1.Type.GetMembers (m => m.EntityType == EntityType.Field)) {
                        if (lookup.IsAccessible (m, isProtectedAllowed))
                            contextList.AddMember(m);
                    }
                    foreach (IProperty m in initializerResult.Item1.Type.GetMembers (m => m.EntityType == EntityType.Property)) {
                        if (m.CanSet && lookup.IsAccessible (m.Setter, isProtectedAllowed))
                            contextList.AddMember(m);
                    }

                    if (prev != null && (prev is NamedExpression)) {
                        // case 2)
                        return contextList.Result;
                    }

                    // case 1)

                    // check if the object is a list, if not only provide object initalizers
                    var list = typeof(System.Collections.IList).ToTypeReference().Resolve(Compilation);
                    if (initializerResult.Item1.Type.Kind != TypeKind.Array && list != null) {
                        var def = initializerResult.Item1.Type.GetDefinition();
                        if (def != null && !def.IsDerivedFrom(list.GetDefinition()))
                            return contextList.Result;
                    }

                    AddContextCompletion(contextList, GetState(), n);
                    return contextList.Result;
                }
            }
            return null;
        }
 public override void SetUp()
 {
     base.SetUp();
     lookup = new MemberLookup(null, compilation.MainAssembly);
 }
		static IEnumerable<PossibleNamespace> GetPossibleNamespaces (Document doc, AstNode node, ResolveResult resolveResult, DocumentLocation location)
		{
			var unit = doc.ParsedDocument.GetAst<SyntaxTree> ();
			if (unit == null)
				yield break;
			var project = doc.Project;
			if (project == null)
				yield break;
			int tc = GetTypeParameterCount (node);
			var attribute = unit.GetNodeAt<ICSharpCode.NRefactory.CSharp.Attribute> (location);
			bool isInsideAttributeType = attribute != null && attribute.Type.Contains (location);

			var compilations = new List<Tuple<ICompilation, MonoDevelop.Projects.ProjectReference>> ();
			compilations.Add (Tuple.Create (doc.Compilation, (MonoDevelop.Projects.ProjectReference)null));
			var referencedItems = IdeApp.Workspace != null ? project.GetReferencedItems (IdeApp.Workspace.ActiveConfiguration).ToList () : (IEnumerable<SolutionItem>) new SolutionItem[0];
			var solution = project != null ? project.ParentSolution : null;
			if (solution != null) {
				foreach (var curProject in solution.GetAllProjects ()) {
					if (curProject == project || referencedItems.Contains (curProject))
						continue;

					var otherRefes = IdeApp.Workspace != null ? curProject.GetReferencedItems (IdeApp.Workspace.ActiveConfiguration).ToList () : (IEnumerable<SolutionItem>) new SolutionItem[0];
					if (otherRefes.Contains (project))
						continue;

					var comp = TypeSystemService.GetCompilation (curProject);
					if (comp == null)
						continue;
					compilations.Add (Tuple.Create (comp, new MonoDevelop.Projects.ProjectReference (curProject)));
				}
			}

			var netProject = project as DotNetProject;
			if (netProject == null) 
				yield break;
			FrameworkLookup frameworkLookup;
			if (!TypeSystemService.TryGetFrameworkLookup (netProject, out frameworkLookup))
				frameworkLookup = null;
			if (frameworkLookup != null && resolveResult is UnknownMemberResolveResult) {
				var umResult = (UnknownMemberResolveResult)resolveResult;
				try {
					foreach (var r in frameworkLookup.GetExtensionMethodLookups (umResult)) {
						var systemAssembly = netProject.AssemblyContext.GetAssemblyFromFullName (r.FullName, r.Package, netProject.TargetFramework);
						if (systemAssembly == null)
							continue;
						if (CanBeReferenced (doc.Project, systemAssembly))
							compilations.Add (Tuple.Create (TypeSystemService.GetCompilation (systemAssembly, doc.Compilation), new MonoDevelop.Projects.ProjectReference (systemAssembly)));
					}
				} catch (Exception e) {
					if (!TypeSystemService.RecreateFrameworkLookup (netProject))
						LoggingService.LogError (string.Format ("Error while looking up extension method {0}", umResult.MemberName), e);
				}
			}
			bool foundIdentifier = false;
			var lookup = new MemberLookup (null, doc.Compilation.MainAssembly);
			foreach (var comp in compilations) {
				var compilation = comp.Item1;
				var requiredReference = comp.Item2;
				if (resolveResult is AmbiguousTypeResolveResult) {
					if (compilation != doc.Compilation)
						continue;
					var aResult = resolveResult as AmbiguousTypeResolveResult;
					var file = doc.ParsedDocument.ParsedFile as CSharpUnresolvedFile;
					var scope = file.GetUsingScope (location).Resolve (compilation);
					while (scope != null) {
						foreach (var u in scope.Usings) {
							foreach (var typeDefinition in u.Types) {
								if (typeDefinition.Name == aResult.Type.Name && 
								    typeDefinition.TypeParameterCount == tc &&
								    lookup.IsAccessible (typeDefinition, false)) {
									yield return new PossibleNamespace (typeDefinition.Namespace, true, requiredReference);
								}
							}
						}
						scope = scope.Parent;
					}
				}
				var allTypes =  compilation == doc.Compilation ? compilation.GetAllTypeDefinitions () : compilation.MainAssembly.GetAllTypeDefinitions ();
				if (resolveResult is UnknownIdentifierResolveResult) {
					var uiResult = resolveResult as UnknownIdentifierResolveResult;
					string possibleAttributeName = isInsideAttributeType ? uiResult.Identifier + "Attribute" : uiResult.Identifier;
					foreach (var typeDefinition in allTypes) {
						if ((typeDefinition.Name == possibleAttributeName || typeDefinition.Name == uiResult.Identifier) && typeDefinition.TypeParameterCount == tc &&
						    lookup.IsAccessible (typeDefinition, false)) {
							if (typeDefinition.DeclaringTypeDefinition != null) {
								var builder = new TypeSystemAstBuilder (new CSharpResolver (doc.Compilation));
								foundIdentifier = true;
								yield return new PossibleNamespace (builder.ConvertType (typeDefinition.DeclaringTypeDefinition).ToString (), false, requiredReference);
							} else {
								foundIdentifier = true;
								yield return new PossibleNamespace (typeDefinition.Namespace, true, requiredReference);
							}
						}
					}
				}

				if (resolveResult is UnknownMemberResolveResult) {
					var umResult = (UnknownMemberResolveResult)resolveResult;
					string possibleAttributeName = isInsideAttributeType ? umResult.MemberName + "Attribute" : umResult.MemberName;
					foreach (var typeDefinition in allTypes.Where (t => t.HasExtensionMethods)) {
						if (!lookup.IsAccessible (typeDefinition, false))
							continue;
						foreach (var method in typeDefinition.Methods.Where (m => m.IsExtensionMethod && (m.Name == possibleAttributeName || m.Name == umResult.MemberName))) {
							if (!lookup.IsAccessible (method, false))
								continue;
							IType[] inferredTypes;
							if (CSharpResolver.IsEligibleExtensionMethod (
								compilation.Import (umResult.TargetType),
								method,
								true,
								out inferredTypes
							)) {
								yield return new PossibleNamespace (typeDefinition.Namespace, true, requiredReference);
								goto skipType;
							}
						}
						skipType:
						;
					}
				}
				
				if (resolveResult is ErrorResolveResult) {
					var identifier = unit != null ? unit.GetNodeAt<Identifier> (location) : null;
					if (identifier != null) {
						var uiResult = resolveResult as UnknownIdentifierResolveResult;
						if (uiResult != null) {
							string possibleAttributeName = isInsideAttributeType ? uiResult.Identifier + "Attribute" : uiResult.Identifier;
							foreach (var typeDefinition in allTypes) {
								if ((identifier.Name == possibleAttributeName || identifier.Name == uiResult.Identifier) && 
									typeDefinition.TypeParameterCount == tc && 
									lookup.IsAccessible (typeDefinition, false))
									yield return new PossibleNamespace (typeDefinition.Namespace, true, requiredReference);
							}
						}
					}
				}
			}

			// Try to search framework types
			if (!foundIdentifier && frameworkLookup != null && resolveResult is UnknownIdentifierResolveResult && node is AstType) {
				var uiResult = resolveResult as UnknownIdentifierResolveResult;
				if (uiResult != null) {
					var lookups = new List<Tuple<FrameworkLookup.AssemblyLookup, SystemAssembly>> ();
					try {
						foreach (var r in frameworkLookup.GetLookups (uiResult, tc, isInsideAttributeType)) {
							var systemAssembly = netProject.AssemblyContext.GetAssemblyFromFullName (r.FullName, r.Package, netProject.TargetFramework);
							if (systemAssembly == null)
								continue;
							if (CanBeReferenced (doc.Project, systemAssembly))
								lookups.Add (Tuple.Create (r, systemAssembly));
						}
					} catch (Exception e) {
						if (!TypeSystemService.RecreateFrameworkLookup (netProject))
							LoggingService.LogError (string.Format ("Error while looking up identifier {0}", uiResult.Identifier), e);
					}
					foreach(var kv in lookups)
						yield return new PossibleNamespace (kv.Item1.Namespace, true, new MonoDevelop.Projects.ProjectReference (kv.Item2));

				}
			}
			if (!foundIdentifier && frameworkLookup != null && resolveResult is UnknownMemberResolveResult) {
				var uiResult = resolveResult as UnknownMemberResolveResult;
				if (uiResult != null) {
					var lookups = new List<Tuple<FrameworkLookup.AssemblyLookup, SystemAssembly>> ();
					try {
						foreach (var r in frameworkLookup.GetLookups (uiResult, node.ToString (), tc, isInsideAttributeType)) {
							var systemAssembly = netProject.AssemblyContext.GetAssemblyFromFullName (r.FullName, r.Package, netProject.TargetFramework);
							if (systemAssembly == null)
								continue;
							if (CanBeReferenced (doc.Project, systemAssembly))
								lookups.Add (Tuple.Create (r, systemAssembly));
						}
					} catch (Exception e) {
						if (!TypeSystemService.RecreateFrameworkLookup (netProject))
							LoggingService.LogError (string.Format ("Error while looking up member resolve result {0}", node), e);
					}
					foreach(var kv in lookups)
						yield return new PossibleNamespace (kv.Item1.Namespace, true, new MonoDevelop.Projects.ProjectReference (kv.Item2));
				}
			}

		}
		ResolveResult ResolveAttributeValue(IMember propertyOrEvent, AXmlAttribute attribute, CancellationToken cancellationToken)
		{
			IUnresolvedTypeDefinition typeDefinition = parseInfo.UnresolvedFile.TypeDefinition;
			if (typeDefinition != null) {
				IType type = typeDefinition.Resolve(new SimpleTypeResolveContext(compilation.MainAssembly));
				if (propertyOrEvent is IEvent) {
					var memberLookup = new MemberLookup(type.GetDefinition(), compilation.MainAssembly);
					var rr = memberLookup.Lookup(new ThisResolveResult(type), attribute.Value, EmptyList<IType>.Instance, false);
					if (rr is MethodGroupResolveResult) {
						Conversion conversion = CSharpConversions.Get(compilation).ImplicitConversion(rr, propertyOrEvent.ReturnType);
						IMethod method = conversion.Method;
						if (method == null)
							method = ((MethodGroupResolveResult)rr).Methods.FirstOrDefault();
						if (method != null)
							return new MemberResolveResult(null, method);
					}
					return rr;
				}
				if (propertyOrEvent.Name == "Name") {
					IField field = type.GetFields(f => f.Name == attribute.Value).FirstOrDefault();
					if (field != null)
						return new MemberResolveResult(null, field);
				}
				if (propertyOrEvent.ReturnType.Kind == TypeKind.Enum) {
					IField field = propertyOrEvent.ReturnType.GetFields(f => f.Name == attribute.Value).FirstOrDefault();
					if (field != null)
						return new MemberResolveResult(null, field);
				}
				// TODO might be a markup extension
				return new UnknownMemberResolveResult(type, attribute.Value, EmptyList<IType>.Instance);
			}
			return ErrorResolveResult.UnknownError;
		}
		void AddTypesAndNamespaces(CompletionDataWrapper wrapper, CSharpResolver state, AstNode node, Func<IType, IType> typePred = null, Predicate<IMember> memberPred = null, Action<ICompletionData, IType> callback = null, bool onlyAddConstructors = false)
		{
			var lookup = new MemberLookup(ctx.CurrentTypeDefinition, Compilation.MainAssembly);

			if (currentType != null) {
				for (var ct = ctx.CurrentTypeDefinition; ct != null; ct = ct.DeclaringTypeDefinition) {
					foreach (var nestedType in ct.GetNestedTypes ()) {
						if (!lookup.IsAccessible(nestedType.GetDefinition(), true))
							continue;
						if (onlyAddConstructors) {
							if (!nestedType.GetConstructors().Any(c => lookup.IsAccessible(c, true)))
								continue;
						}

						if (typePred == null) {
							if (onlyAddConstructors)
								wrapper.AddConstructors(nestedType, false, IsAttributeContext(node));
							else
								wrapper.AddType(nestedType, false, IsAttributeContext(node));
							continue;
						}

						var type = typePred(nestedType);
						if (type != null) {
							var a2 = onlyAddConstructors ? wrapper.AddConstructors(type, false, IsAttributeContext(node)) : wrapper.AddType(type, false, IsAttributeContext(node));
							if (a2 != null && callback != null) {
								callback(a2, type);
							}
						}
						continue;
					}
				}

				if (this.currentMember != null && !(node is AstType)) {
					var def = ctx.CurrentTypeDefinition;
					if (def == null && currentType != null)
						def = Compilation.MainAssembly.GetTypeDefinition(currentType.FullTypeName);
					if (def != null) {
						bool isProtectedAllowed = true;

						foreach (var member in def.GetMembers (m => currentMember.IsStatic ? m.IsStatic : true)) {
							if (member is IMethod && ((IMethod)member).FullName == "System.Object.Finalize") {
								continue;
							}
							if (member.SymbolKind == SymbolKind.Operator) {
								continue;
							}
							if (member.IsExplicitInterfaceImplementation) {
								continue;
							}
							if (!lookup.IsAccessible(member, isProtectedAllowed)) {
								continue;
							}
							if (memberPred == null || memberPred(member)) {
								wrapper.AddMember(member);
							}
						}
						var declaring = def.DeclaringTypeDefinition;
						while (declaring != null) {
							foreach (var member in declaring.GetMembers (m => m.IsStatic)) {
								if (memberPred == null || memberPred(member)) {
									wrapper.AddMember(member);
								}
							}
							declaring = declaring.DeclaringTypeDefinition;
						}
					}
				}
				if (ctx.CurrentTypeDefinition != null) {
					foreach (var p in ctx.CurrentTypeDefinition.TypeParameters) {
						wrapper.AddTypeParameter(p);
					}
				}
			}
			var scope = ctx.CurrentUsingScope;

			for (var n = scope; n != null; n = n.Parent) {
				foreach (var pair in n.UsingAliases) {
					wrapper.AddAlias(pair.Key);
				}
				foreach (var alias in n.ExternAliases) {
					wrapper.AddAlias(alias);
				}
				foreach (var u in n.Usings) {
					foreach (var type in u.Types) {
						if (!lookup.IsAccessible(type, false))
							continue;

						IType addType = typePred != null ? typePred(type) : type;

						if (onlyAddConstructors && addType != null) {
							if (!addType.GetConstructors().Any(c => lookup.IsAccessible(c, true)))
								continue;
						}

						if (addType != null) {
							var a = onlyAddConstructors ? wrapper.AddConstructors(addType, false, IsAttributeContext(node)) : wrapper.AddType(addType, false, IsAttributeContext(node));
							if (a != null && callback != null) {
								callback(a, type);
							}
						}
					}
				}

				foreach (var type in n.Namespace.Types) {
					if (!lookup.IsAccessible(type, false))
						continue;
					IType addType = typePred != null ? typePred(type) : type;

					if (onlyAddConstructors && addType != null) {
						if (!addType.GetConstructors().Any(c => lookup.IsAccessible(c, true)))
							continue;
					}

					if (addType != null) {
						var a2 = onlyAddConstructors ? wrapper.AddConstructors(addType, false, IsAttributeContext(node)) : wrapper.AddType(addType, false);
						if (a2 != null && callback != null) {
							callback(a2, type);
						}
					}
				}
			}

			for (var n = scope; n != null; n = n.Parent) {
				foreach (var curNs in n.Namespace.ChildNamespaces) {
					wrapper.AddNamespace(lookup, curNs);
				}
			}

			if (node is AstType && node.Parent is Constraint && IncludeKeywordsInCompletionList) {
				wrapper.AddCustom("new()");
			}

			if (AutomaticallyAddImports) {
				state = GetState();
				ICompletionData[] importData;

				var namespaces = new List<INamespace>();
				for (var n = ctx.CurrentUsingScope; n != null; n = n.Parent) {
					namespaces.Add(n.Namespace);
					foreach (var u in n.Usings)
						namespaces.Add(u);
				}

				if (this.CompletionEngineCache != null && ListEquals(namespaces, CompletionEngineCache.namespaces)) {
					importData = CompletionEngineCache.importCompletion;
				} else {
					// flatten usings
					var importList = new List<ICompletionData>();
					var dict = new Dictionary<string, Dictionary<string, ICompletionData>>();
					foreach (var type in Compilation.GetAllTypeDefinitions ()) {
						if (!lookup.IsAccessible(type, false))
							continue;
						if (namespaces.Any(n => n.FullName == type.Namespace))
							continue;
						bool useFullName = false;
						foreach (var ns in namespaces) {
							if (ns.GetTypeDefinition(type.Name, type.TypeParameterCount) != null) {
								useFullName = true;
								break;
							}
						}

						if (onlyAddConstructors) {
							if (!type.GetConstructors().Any(c => lookup.IsAccessible(c, true)))
								continue;
						}
						var data = factory.CreateImportCompletionData(type, useFullName, onlyAddConstructors);
						Dictionary<string, ICompletionData> createdDict;
						if (!dict.TryGetValue(type.Name, out createdDict)) {
							createdDict = new Dictionary<string, ICompletionData>();
							dict.Add(type.Name, createdDict);
						}
						ICompletionData oldData;
						if (!createdDict.TryGetValue(type.Namespace, out oldData)) {
							importList.Add(data);
							createdDict.Add(type.Namespace, data);
						} else {
							oldData.AddOverload(data); 
						}
					}

					importData = importList.ToArray();
					if (CompletionEngineCache != null) {
						CompletionEngineCache.namespaces = namespaces;
						CompletionEngineCache.importCompletion = importData;
					}
				}
				foreach (var data in importData) {
					wrapper.Result.Add(data);
				}


			}

		}
 private IEnumerable<IMethod> FilterMethodsForAccessibility(IType type, IEnumerable<IMethod> methods) {
   var typeResolveContext = context.TypeResolveContextAtCaret;
   var lookup = new MemberLookup(typeResolveContext.CurrentTypeDefinition, typeResolveContext.Compilation.MainAssembly);
   bool protectedAccessAllowed = lookup.IsProtectedAccessAllowed(type);
   return protectedAccessAllowed ? methods : methods.Where(x => !x.IsProtected);
 }
		IEnumerable<ICompletionData> CreateTypeAndNamespaceCompletionData(TextLocation location, ResolveResult resolveResult, AstNode resolvedNode, CSharpResolver state)
		{
			if (resolveResult == null || resolveResult.IsError) {
				return null;
			}
			var exprParent = resolvedNode.GetParent<Expression>();
			var unit = exprParent != null ? exprParent.GetParent<SyntaxTree>() : null;

			var astResolver = unit != null ? CompletionContextProvider.GetResolver(state, unit) : null;
			IType hintType = exprParent != null && astResolver != null ? 
			                 TypeGuessing.GetValidTypes(astResolver, exprParent).FirstOrDefault() :
			                 null;
			var result = new CompletionDataWrapper(this);
			var lookup = new MemberLookup(
				ctx.CurrentTypeDefinition,
				Compilation.MainAssembly
			);
			if (resolveResult is NamespaceResolveResult) {
				var nr = (NamespaceResolveResult)resolveResult;
				if (!(resolvedNode.Parent is UsingDeclaration || resolvedNode.Parent != null && resolvedNode.Parent.Parent is UsingDeclaration)) {
					foreach (var cl in nr.Namespace.Types) {
						if (hintType != null && hintType.Kind != TypeKind.Array && cl.Kind == TypeKind.Interface) {
							continue;
						}
						if (!lookup.IsAccessible(cl, false))
							continue;
						result.AddType(cl, false, IsAttributeContext(resolvedNode));
					}
				}
				foreach (var ns in nr.Namespace.ChildNamespaces) {
					result.AddNamespace(lookup, ns);
				}
			} else if (resolveResult is TypeResolveResult) {
				var type = resolveResult.Type;
				foreach (var nested in type.GetNestedTypes ()) {
					if (hintType != null && hintType.Kind != TypeKind.Array && nested.Kind == TypeKind.Interface) {
						continue;
					}
					var def = nested.GetDefinition();
					if (def != null && !lookup.IsAccessible(def, false))
						continue;
					result.AddType(nested, false);
				}
			}
			return result.Result;
		}
Exemple #30
0
        IEnumerable<CodeAction> GetActionsForExtensionMethodInvocation(RefactoringContext context, InvocationExpression invocation)
        {
            var rr = context.Resolve(invocation) as UnknownMethodResolveResult;
            if (rr == null)
                return EmptyList<CodeAction>.Instance;

            var lookup = new MemberLookup(null, context.Compilation.MainAssembly);
            HashSet<string> namespaces = new HashSet<string>();
            List<CodeAction> result = new List<CodeAction>();
            foreach (var typeDefinition in context.Compilation.GetAllTypeDefinitions()) {
                if (!(typeDefinition.HasExtensionMethods && lookup.IsAccessible(typeDefinition, false))) {
                    continue;
                }
                foreach (var method in typeDefinition.Methods.Where(m => m.IsExtensionMethod && m.Name == rr.MemberName)) {
                    IType[] inferredTypes;
                    if (CSharpResolver.IsEligibleExtensionMethod(rr.TargetType, method, true, out inferredTypes)) {
                        // avoid offering the same namespace twice
                        if (namespaces.Add(typeDefinition.Namespace)) {
                            result.Add(NewUsingAction(context, invocation, typeDefinition.Namespace));
                        }
                        break; // continue with the next type
                    }
                }
            }
            return result;
        }
		IEnumerable<ICompletionData> HandleObjectInitializer(SyntaxTree unit, AstNode n)
		{
			var p = n.Parent;
			while (p != null && !(p is ObjectCreateExpression)) {
				p = p.Parent;
			}
			var parent = n.Parent as ArrayInitializerExpression;
			if (parent == null)
				return null;
			if (parent.IsSingleElement)
				parent = (ArrayInitializerExpression)parent.Parent;
			if (p != null) {
				var contextList = new CompletionDataWrapper(this);
				var initializerResult = ResolveExpression(p);
				IType initializerType = null;

				if (initializerResult.Result is DynamicInvocationResolveResult) {
					var dr = (DynamicInvocationResolveResult)initializerResult.Result;
					var constructor = (dr.Target as MethodGroupResolveResult).Methods.FirstOrDefault();
					if (constructor != null)
						initializerType = constructor.DeclaringType;
				} else {
					initializerType = initializerResult != null ? initializerResult.Result.Type : null;
				}


				if (initializerType != null && initializerType.Kind != TypeKind.Unknown) {
					// check 3 cases:
					// 1) New initalizer { xpr
					// 2) Object initializer { prop = val1, field = val2, xpr
					// 3) Array initializer { new Foo (), a, xpr
					// in case 1 all object/array initializer options should be given - in the others not.

					AstNode prev = null;
					if (parent.Elements.Count > 1) {
						prev = parent.Elements.First();
						if (prev is ArrayInitializerExpression && ((ArrayInitializerExpression)prev).IsSingleElement)
							prev = ((ArrayInitializerExpression)prev).Elements.FirstOrDefault();
					}

					if (prev != null && !(prev is NamedExpression)) {
						AddContextCompletion(contextList, GetState(), n);
						// case 3)
						return contextList.Result;
					}
					var lookup = new MemberLookup(ctx.CurrentTypeDefinition, Compilation.MainAssembly);
					bool isProtectedAllowed = ctx.CurrentTypeDefinition != null && initializerType.GetDefinition() != null ? 
					                          ctx.CurrentTypeDefinition.IsDerivedFrom(initializerType.GetDefinition()) : 
					                          false;
					foreach (var m in initializerType.GetMembers (m => m.SymbolKind == SymbolKind.Field)) {
						var f = m as IField;
						if (f != null && (f.IsReadOnly || f.IsConst))
							continue;
						if (lookup.IsAccessible(m, isProtectedAllowed)) {
							var data = contextList.AddMember(m);
							if (data != null)
								data.DisplayFlags |= DisplayFlags.NamedArgument;
						}
					}

					foreach (IProperty m in initializerType.GetMembers (m => m.SymbolKind == SymbolKind.Property)) {
						if (m.CanSet && lookup.IsAccessible(m.Setter, isProtectedAllowed)) {
							var data = contextList.AddMember(m);
							if (data != null)
								data.DisplayFlags |= DisplayFlags.NamedArgument;
						}
					}

					if (prev != null && (prev is NamedExpression)) {
						// case 2)
						return contextList.Result;
					}

					// case 1)

					// check if the object is a list, if not only provide object initalizers
					var list = typeof(System.Collections.IList).ToTypeReference().Resolve(Compilation);
					if (initializerType.Kind != TypeKind.Array && list != null) {
						var def = initializerType.GetDefinition(); 
						if (def != null && !def.IsDerivedFrom(list.GetDefinition()))
							return contextList.Result;
					}

					AddContextCompletion(contextList, GetState(), n);
					return contextList.Result;
				}
			}
			return null;
		}
        void AddTypesAndNamespaces(CompletionDataWrapper wrapper, CSharpResolver state, AstNode node, Func<IType, IType> typePred = null, Predicate<IMember> memberPred = null, Action<ICompletionData, IType> callback = null, bool onlyAddConstructors = false)
        {
            var lookup = new MemberLookup(ctx.CurrentTypeDefinition, Compilation.MainAssembly);

            if (currentType != null) {
                for (var ct = ctx.CurrentTypeDefinition; ct != null; ct = ct.DeclaringTypeDefinition) {
                    foreach (var nestedType in ct.GetNestedTypes ()) {
                        if (!lookup.IsAccessible (nestedType.GetDefinition (), true))
                            continue;
                        if (onlyAddConstructors) {
                            if (!nestedType.GetConstructors().Any(c => lookup.IsAccessible(c, true)))
                                continue;
                        }

                        if (typePred == null) {
                            if (onlyAddConstructors)
                                wrapper.AddConstructors (nestedType, false, IsAttributeContext(node));
                            else
                                wrapper.AddType(nestedType, false, IsAttributeContext(node));
                            continue;
                        }

                        var type = typePred(nestedType);
                        if (type != null) {
                            var a2 = onlyAddConstructors ? wrapper.AddConstructors(type, false, IsAttributeContext(node)) : wrapper.AddType(type, false, IsAttributeContext(node));
                            if (a2 != null && callback != null) {
                                callback(a2, type);
                            }
                        }
                        continue;
                    }
                }

                if (this.currentMember != null && !(node is AstType)) {
                    var def = ctx.CurrentTypeDefinition;
                    if (def == null && currentType != null)
                        def = Compilation.MainAssembly.GetTypeDefinition(currentType.FullTypeName);
                    if (def != null) {
                        bool isProtectedAllowed = true;

                        foreach (var member in def.GetMembers (m => currentMember.IsStatic ? m.IsStatic : true)) {
                            if (member is IMethod && ((IMethod)member).FullName == "System.Object.Finalize") {
                                continue;
                            }
                            if (member.SymbolKind == SymbolKind.Operator) {
                                continue;
                            }
                            if (member.IsExplicitInterfaceImplementation) {
                                continue;
                            }
                            if (!lookup.IsAccessible(member, isProtectedAllowed)) {
                                continue;
                            }
                            if (memberPred == null || memberPred(member)) {
                                wrapper.AddMember(member);
                            }
                        }
                        var declaring = def.DeclaringTypeDefinition;
                        while (declaring != null) {
                            foreach (var member in declaring.GetMembers (m => m.IsStatic)) {
                                if (memberPred == null || memberPred(member)) {
                                    wrapper.AddMember(member);
                                }
                            }
                            declaring = declaring.DeclaringTypeDefinition;
                        }
                    }
                }
                if (ctx.CurrentTypeDefinition != null) {
                    foreach (var p in ctx.CurrentTypeDefinition.TypeParameters) {
                        wrapper.AddTypeParameter(p);
                    }
                }
            }
            var scope = ctx.CurrentUsingScope;

            for (var n = scope; n != null; n = n.Parent) {
                foreach (var pair in n.UsingAliases) {
                    wrapper.AddAlias(pair.Key);
                }
                foreach (var alias in n.ExternAliases) {
                    wrapper.AddAlias(alias);
                }
                foreach (var u in n.Usings) {
                    foreach (var type in u.Types) {
                        if (!lookup.IsAccessible(type, false))
                            continue;

                        IType addType = typePred != null ? typePred(type) : type;

                        if (onlyAddConstructors && addType != null) {
                            if (!addType.GetConstructors().Any(c => lookup.IsAccessible(c, true)))
                                continue;
                        }

                        if (addType != null) {
                            var a = onlyAddConstructors ? wrapper.AddConstructors(addType, false, IsAttributeContext(node)) : wrapper.AddType(addType, false, IsAttributeContext(node));
                            if (a != null && callback != null) {
                                callback(a, type);
                            }
                        }
                    }
                }

                foreach (var type in n.Namespace.Types) {
                    if (!lookup.IsAccessible(type, false))
                        continue;
                    IType addType = typePred != null ? typePred(type) : type;

                    if (onlyAddConstructors && addType != null) {
                        if (!addType.GetConstructors().Any(c => lookup.IsAccessible(c, true)))
                            continue;
                    }

                    if (addType != null) {
                        var a2 = onlyAddConstructors ? wrapper.AddConstructors(addType, false, IsAttributeContext(node)) : wrapper.AddType(addType, false);
                        if (a2 != null && callback != null) {
                            callback(a2, type);
                        }
                    }
                }

                foreach (var curNs in n.Namespace.ChildNamespaces) {
                    wrapper.AddNamespace(lookup, curNs);
                }
            }

            if (node is AstType && node.Parent is Constraint && IncludeKeywordsInCompletionList) {
                wrapper.AddCustom ("new()");
            }

            if (AutomaticallyAddImports) {
                state = GetState();
                foreach (var type in Compilation.GetAllTypeDefinitions ()) {
                    if (!lookup.IsAccessible (type, false))
                        continue;
                    var resolveResult = state.LookupSimpleNameOrTypeName(type.Name, type.TypeArguments, NameLookupMode.Expression);
                    if (resolveResult.Type.GetDefinition () == type)
                        continue;

                    if (onlyAddConstructors) {
                        if (!type.GetConstructors().Any(c => lookup.IsAccessible(c, true)))
                            continue;
                    }

                    wrapper.AddTypeImport(type, !resolveResult.IsError, onlyAddConstructors);
                }
            }
        }