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;
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 (EmitContext ec)
44 public class CompletionSimpleName : CompletingExpression {
47 public CompletionSimpleName (string prefix, Location l)
53 void AppendResults (ArrayList results, string prefix, IEnumerable names)
55 foreach (string name in names){
56 if (!name.StartsWith (prefix))
59 if (results.Contains (name))
63 results.Add (name.Substring (prefix.Length));
70 public override Expression DoResolve (EmitContext ec)
72 ArrayList results = new ArrayList ();
74 AppendResults (results, prefix, Evaluator.GetVarNames ());
75 AppendResults (results, prefix, ec.TypeContainer.NamespaceEntry.CompletionGetTypesStartingWith (ec.TypeContainer, prefix));
76 AppendResults (results, prefix, Evaluator.GetUsingList ());
78 throw new CompletionResult (prefix, (string []) results.ToArray (typeof (string)));
81 protected override void CloneTo (CloneContext clonectx, Expression t)
87 public class CompletionMemberAccess : CompletingExpression {
92 static MemberFilter CollectingFilter = new MemberFilter (Match);
94 static bool Match (MemberInfo m, object filter_criteria)
97 if (((FieldInfo) m).IsSpecialName)
101 if (m is MethodInfo){
102 if (((MethodInfo) m).IsSpecialName)
106 if (filter_criteria == null)
109 string n = (string) filter_criteria;
110 if (m.Name.StartsWith (n))
116 public CompletionMemberAccess (Expression e, string partial_name, Location l)
120 this.partial_name = partial_name;
123 public CompletionMemberAccess (Expression e, string partial_name, TypeArguments targs, Location l)
127 this.partial_name = partial_name;
131 public override Expression DoResolve (EmitContext ec)
133 SimpleName original = expr as SimpleName;
134 Expression expr_resolved = expr.Resolve (ec,
135 ResolveFlags.VariableOrValue | ResolveFlags.Type |
136 ResolveFlags.Intermediate | ResolveFlags.DisableStructFlowAnalysis);
138 if (expr_resolved == null)
141 Type expr_type = expr_resolved.Type;
142 if (expr_type.IsPointer || expr_type == TypeManager.void_type || expr_type == TypeManager.null_type || expr_type == TypeManager.anonymous_method_type) {
143 Unary.Error_OperatorCannotBeApplied (loc, ".", expr_type);
148 if (!targs.Resolve (ec))
152 ArrayList results = new ArrayList ();
153 MemberInfo [] result = expr_type.FindMembers (MemberTypes.All, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, CollectingFilter, partial_name);
154 foreach (MemberInfo r in result){
157 MethodBase rasb = r as MethodBase;
158 if (rasb != null && rasb.IsSpecialName)
161 if (partial_name == null)
164 name = r.Name.Substring (partial_name.Length);
167 if (results.Contains (name))
172 throw new CompletionResult (partial_name == null ? "" : partial_name, (string []) results.ToArray (typeof (string)));
175 protected override void CloneTo (CloneContext clonectx, Expression t)
177 CompletionMemberAccess target = (CompletionMemberAccess) t;
180 target.targs = targs.Clone ();
182 target.expr = expr.Clone (clonectx);