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
16 namespace Mono.CSharp {
18 using System.Collections.Generic;
19 using System.Reflection;
20 using System.Reflection.Emit;
24 // A common base class for Completing expressions, it
25 // is just a very simple ExpressionStatement
27 public abstract class CompletingExpression : ExpressionStatement {
28 public override void EmitStatement (EmitContext ec)
33 public override void Emit (EmitContext ec)
38 public override Expression CreateExpressionTree (ResolveContext ec)
44 public class CompletionSimpleName : CompletingExpression {
47 public CompletionSimpleName (string prefix, Location l)
53 public static void AppendResults (List<string> results, string prefix, IEnumerable<string> names)
55 foreach (string name in names){
56 if (name == null || prefix == null)
59 if (!name.StartsWith (prefix))
62 if (results.Contains (name))
66 results.Add (name.Substring (prefix.Length));
73 protected override Expression DoResolve (ResolveContext ec)
75 var results = new List<string> ();
77 AppendResults (results, Prefix, Evaluator.GetVarNames ());
78 AppendResults (results, Prefix, ec.CurrentTypeDefinition.NamespaceEntry.CompletionGetTypesStartingWith (Prefix));
79 AppendResults (results, Prefix, Evaluator.GetUsingList ());
81 throw new CompletionResult (Prefix, results.ToArray ());
84 protected override void CloneTo (CloneContext clonectx, Expression t)
90 public class CompletionMemberAccess : CompletingExpression {
95 internal static MemberFilter CollectingFilter = new MemberFilter (Match);
97 static bool Match (MemberInfo m, object filter_criteria)
100 if (((FieldInfo) m).IsSpecialName)
104 if (m is MethodInfo){
105 if (((MethodInfo) m).IsSpecialName)
109 if (filter_criteria == null)
112 string n = (string) filter_criteria;
113 if (m.Name.StartsWith (n))
119 public CompletionMemberAccess (Expression e, string partial_name, Location l)
123 this.partial_name = partial_name;
126 public CompletionMemberAccess (Expression e, string partial_name, TypeArguments targs, Location l)
130 this.partial_name = partial_name;
134 protected override Expression DoResolve (ResolveContext ec)
136 Expression expr_resolved = expr.Resolve (ec,
137 ResolveFlags.VariableOrValue | ResolveFlags.Type |
138 ResolveFlags.Intermediate);
140 if (expr_resolved == null)
143 Type expr_type = expr_resolved.Type;
144 if (expr_type.IsPointer || expr_type == TypeManager.void_type || expr_type == TypeManager.null_type || expr_type == InternalType.AnonymousMethod) {
145 Unary.Error_OperatorCannotBeApplied (ec, loc, ".", expr_type);
150 if (!targs.Resolve (ec))
154 var results = new List<string> ();
155 if (expr_resolved is Namespace){
156 Namespace nexpr = expr_resolved as Namespace;
157 string namespaced_partial;
159 if (partial_name == null)
160 namespaced_partial = nexpr.Name;
162 namespaced_partial = nexpr.Name + "." + partial_name;
165 Console.WriteLine ("Workign with: namespaced partial {0}", namespaced_partial);
166 foreach (var x in ec.TypeContainer.NamespaceEntry.CompletionGetTypesStartingWith (ec.TypeContainer, namespaced_partial)){
167 Console.WriteLine (" {0}", x);
171 CompletionSimpleName.AppendResults (
174 ec.CurrentTypeDefinition.NamespaceEntry.CompletionGetTypesStartingWith (namespaced_partial));
176 MemberInfo [] result = expr_type.FindMembers (
177 MemberTypes.All, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public,
178 CollectingFilter, partial_name);
180 foreach (MemberInfo r in result){
183 MethodBase rasb = r as MethodBase;
184 if (rasb != null && rasb.IsSpecialName)
187 if (partial_name == null)
190 name = r.Name.Substring (partial_name.Length);
192 if (results.Contains (name))
198 throw new CompletionResult (partial_name == null ? "" : partial_name, results.ToArray ());
201 protected override void CloneTo (CloneContext clonectx, Expression t)
203 CompletionMemberAccess target = (CompletionMemberAccess) t;
206 target.targs = targs.Clone ();
208 target.expr = expr.Clone (clonectx);
212 public class CompletionElementInitializer : CompletingExpression {
215 public CompletionElementInitializer (string partial_name, Location l)
217 this.partial_name = partial_name;
221 protected override Expression DoResolve (ResolveContext ec)
223 MemberList members = TypeManager.FindMembers (
224 ec.CurrentInitializerVariable.Type,
225 MemberTypes.Field | MemberTypes.Property,
226 BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public,
227 CompletionMemberAccess.CollectingFilter, partial_name);
229 string [] result = new string [members.Count];
231 foreach (MemberInfo mi in members){
234 if (partial_name == null)
237 name = mi.Name.Substring (partial_name.Length);
242 if (partial_name != null && i > 0 && result [0] == "")
243 throw new CompletionResult ("", new string [] { "=" });
245 throw new CompletionResult (partial_name == null ? "" : partial_name, result);
248 protected override void CloneTo (CloneContext clonectx, Expression t)