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 using System.Collections.Generic;
19 namespace Mono.CSharp {
22 // A common base class for Completing expressions, it
23 // is just a very simple ExpressionStatement
25 public abstract class CompletingExpression : ExpressionStatement
27 public static void AppendResults (List<string> results, string prefix, IEnumerable<string> names)
29 foreach (string name in names) {
33 if (prefix != null && !name.StartsWith (prefix))
36 if (results.Contains (name))
40 results.Add (name.Substring (prefix.Length));
46 public override void EmitStatement (EmitContext ec)
51 public override void Emit (EmitContext ec)
56 public override Expression CreateExpressionTree (ResolveContext ec)
62 public class CompletionSimpleName : CompletingExpression {
65 public CompletionSimpleName (string prefix, Location l)
71 protected override Expression DoResolve (ResolveContext ec)
73 var results = new List<string> ();
75 AppendResults (results, Prefix, ec.Module.Evaluator.GetVarNames ());
76 AppendResults (results, Prefix, ec.CurrentMemberDefinition.Parent.NamespaceEntry.CompletionGetTypesStartingWith (Prefix));
77 AppendResults (results, Prefix, ec.Module.Evaluator.GetUsingList ());
79 throw new CompletionResult (Prefix, results.ToArray ());
82 protected override void CloneTo (CloneContext clonectx, Expression t)
88 public class CompletionMemberAccess : CompletingExpression {
93 public CompletionMemberAccess (Expression e, string partial_name, Location l)
97 this.partial_name = partial_name;
100 public CompletionMemberAccess (Expression e, string partial_name, TypeArguments targs, Location l)
104 this.partial_name = partial_name;
108 protected override Expression DoResolve (ResolveContext ec)
110 Expression expr_resolved = expr.Resolve (ec,
111 ResolveFlags.VariableOrValue | ResolveFlags.Type);
113 if (expr_resolved == null)
116 TypeSpec expr_type = expr_resolved.Type;
117 if (expr_type.IsPointer || expr_type.Kind == MemberKind.Void || expr_type == InternalType.NullLiteral || expr_type == InternalType.AnonymousMethod) {
118 Unary.Error_OperatorCannotBeApplied (ec, loc, ".", expr_type);
123 if (!targs.Resolve (ec))
127 var results = new List<string> ();
128 if (expr_resolved is Namespace){
129 Namespace nexpr = expr_resolved as Namespace;
130 string namespaced_partial;
132 if (partial_name == null)
133 namespaced_partial = nexpr.Name;
135 namespaced_partial = nexpr.Name + "." + partial_name;
138 Console.WriteLine ("Workign with: namespaced partial {0}", namespaced_partial);
139 foreach (var x in ec.TypeContainer.NamespaceEntry.CompletionGetTypesStartingWith (ec.TypeContainer, namespaced_partial)){
140 Console.WriteLine (" {0}", x);
144 CompletionSimpleName.AppendResults (
147 ec.CurrentMemberDefinition.Parent.NamespaceEntry.CompletionGetTypesStartingWith (namespaced_partial));
149 var r = MemberCache.GetCompletitionMembers (ec, expr_type, partial_name).Select (l => l.Name);
150 AppendResults (results, partial_name, r);
153 throw new CompletionResult (partial_name == null ? "" : partial_name, results.Distinct ().ToArray ());
156 protected override void CloneTo (CloneContext clonectx, Expression t)
158 CompletionMemberAccess target = (CompletionMemberAccess) t;
161 target.targs = targs.Clone ();
163 target.expr = expr.Clone (clonectx);
167 public class CompletionElementInitializer : CompletingExpression {
170 public CompletionElementInitializer (string partial_name, Location l)
172 this.partial_name = partial_name;
176 protected override Expression DoResolve (ResolveContext ec)
178 var members = MemberCache.GetCompletitionMembers (ec, ec.CurrentInitializerVariable.Type, partial_name);
180 // TODO: Does this mean exact match only ?
181 // if (partial_name != null && results.Count > 0 && result [0] == "")
182 // throw new CompletionResult ("", new string [] { "=" });
184 var results = members.Where (l => (l.Kind & (MemberKind.Field | MemberKind.Property)) != 0).Select (l => l.Name).ToList ();
185 if (partial_name != null) {
186 var temp = new List<string> ();
187 AppendResults (temp, partial_name, results);
191 throw new CompletionResult (partial_name == null ? "" : partial_name, results.Distinct ().ToArray ());
194 protected override void CloneTo (CloneContext clonectx, Expression t)