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