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);
}
}
}