2 // complete.cs: Expression that are used for completion suggestions.
5 // Miguel de Icaza (miguel@ximian.com)
6 // Marek Safar (marek.safar@gmail.com)
8 // Copyright 2001, 2002, 2003 Ximian, Inc.
9 // Copyright 2003-2009 Novell, Inc.
11 // Completion* classes derive from ExpressionStatement as this allows
12 // them to pass through the parser in many conditions that require
13 // statements even when the expression is incomplete (for example
14 // completing inside a lambda
17 using System.Collections.Generic;
18 using System.Reflection;
19 using System.Reflection.Emit;
21 using Mono.CSharp.Linq;
23 namespace Mono.CSharp {
26 // A common base class for Completing expressions, it
27 // is just a very simple ExpressionStatement
29 public abstract class CompletingExpression : ExpressionStatement {
30 public override void EmitStatement (EmitContext ec)
35 public override void Emit (EmitContext ec)
40 public override Expression CreateExpressionTree (ResolveContext ec)
46 public class CompletionSimpleName : CompletingExpression {
49 public CompletionSimpleName (string prefix, Location l)
55 public static void AppendResults (List<string> results, string prefix, IEnumerable<string> names)
57 foreach (string name in names){
58 if (name == null || prefix == null)
61 if (!name.StartsWith (prefix))
64 if (results.Contains (name))
68 results.Add (name.Substring (prefix.Length));
75 protected override Expression DoResolve (ResolveContext ec)
77 var results = new List<string> ();
79 AppendResults (results, Prefix, Evaluator.GetVarNames ());
80 AppendResults (results, Prefix, ec.CurrentTypeDefinition.NamespaceEntry.CompletionGetTypesStartingWith (Prefix));
81 AppendResults (results, Prefix, Evaluator.GetUsingList ());
83 throw new CompletionResult (Prefix, results.ToArray ());
86 protected override void CloneTo (CloneContext clonectx, Expression t)
92 public class CompletionMemberAccess : CompletingExpression {
97 internal static MemberFilter CollectingFilter = new MemberFilter (Match);
99 static bool Match (MemberInfo m, object filter_criteria)
102 if (((FieldInfo) m).IsSpecialName)
106 if (m is MethodInfo){
107 if (((MethodInfo) m).IsSpecialName)
111 if (filter_criteria == null)
114 string n = (string) filter_criteria;
115 if (m.Name.StartsWith (n))
121 public CompletionMemberAccess (Expression e, string partial_name, Location l)
125 this.partial_name = partial_name;
128 public CompletionMemberAccess (Expression e, string partial_name, TypeArguments targs, Location l)
132 this.partial_name = partial_name;
136 protected override Expression DoResolve (ResolveContext ec)
138 Expression expr_resolved = expr.Resolve (ec,
139 ResolveFlags.VariableOrValue | ResolveFlags.Type |
140 ResolveFlags.Intermediate);
142 if (expr_resolved == null)
145 Type expr_type = expr_resolved.Type;
146 if (expr_type.IsPointer || expr_type == TypeManager.void_type || expr_type == TypeManager.null_type || expr_type == InternalType.AnonymousMethod) {
147 Unary.Error_OperatorCannotBeApplied (ec, loc, ".", expr_type);
152 if (!targs.Resolve (ec))
156 var results = new List<string> ();
157 if (expr_resolved is Namespace){
158 Namespace nexpr = expr_resolved as Namespace;
159 string namespaced_partial;
161 if (partial_name == null)
162 namespaced_partial = nexpr.Name;
164 namespaced_partial = nexpr.Name + "." + partial_name;
167 Console.WriteLine ("Workign with: namespaced partial {0}", namespaced_partial);
168 foreach (var x in ec.TypeContainer.NamespaceEntry.CompletionGetTypesStartingWith (ec.TypeContainer, namespaced_partial)){
169 Console.WriteLine (" {0}", x);
173 CompletionSimpleName.AppendResults (
176 ec.CurrentTypeDefinition.NamespaceEntry.CompletionGetTypesStartingWith (namespaced_partial));
178 MemberInfo [] result = expr_type.FindMembers (
179 MemberTypes.All, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public,
180 CollectingFilter, partial_name);
182 foreach (MemberInfo r in result){
185 MethodBase rasb = r as MethodBase;
186 if (rasb != null && rasb.IsSpecialName)
189 if (partial_name == null)
192 name = r.Name.Substring (partial_name.Length);
194 if (results.Contains (name))
200 throw new CompletionResult (partial_name == null ? "" : partial_name, results.ToArray ());
203 protected override void CloneTo (CloneContext clonectx, Expression t)
205 CompletionMemberAccess target = (CompletionMemberAccess) t;
208 target.targs = targs.Clone ();
210 target.expr = expr.Clone (clonectx);
214 public class CompletionElementInitializer : CompletingExpression {
217 public CompletionElementInitializer (string partial_name, Location l)
219 this.partial_name = partial_name;
223 protected override Expression DoResolve (ResolveContext ec)
225 MemberList members = TypeManager.FindMembers (
226 ec.CurrentInitializerVariable.Type,
227 MemberTypes.Field | MemberTypes.Property,
228 BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public,
229 CompletionMemberAccess.CollectingFilter, partial_name);
231 string [] result = new string [members.Count];
233 foreach (MemberInfo mi in members){
236 if (partial_name == null)
239 name = mi.Name.Substring (partial_name.Length);
244 if (partial_name != null && i > 0 && result [0] == "")
245 throw new CompletionResult ("", new string [] { "=" });
247 throw new CompletionResult (partial_name == null ? "" : partial_name, result);
250 protected override void CloneTo (CloneContext clonectx, Expression t)