[mono/tests] Fix out of tree build.
[mono-project.git] / mcs / mcs / complete.cs
blobb1d2993256a517fc96483d5be1af20d2b09f332c
1 //
2 // complete.cs: Expression that are used for completion suggestions.
3 //
4 // Author:
5 // Miguel de Icaza (miguel@ximian.com)
6 // Marek Safar (marek.safar@gmail.com)
7 //
8 // Copyright 2001, 2002, 2003 Ximian, Inc.
9 // Copyright 2003-2009 Novell, Inc.
10 // Copyright 2011 Xamarin Inc
12 // Completion* classes derive from ExpressionStatement as this allows
13 // them to pass through the parser in many conditions that require
14 // statements even when the expression is incomplete (for example
15 // completing inside a lambda
17 using System.Collections.Generic;
18 using System.Linq;
20 namespace Mono.CSharp {
23 // A common base class for Completing expressions, it
24 // is just a very simple ExpressionStatement
26 public abstract class CompletingExpression : ExpressionStatement
28 public static void AppendResults (List<string> results, string prefix, IEnumerable<string> names)
30 foreach (string name in names) {
31 if (name == null)
32 continue;
34 if (prefix != null && !name.StartsWith (prefix))
35 continue;
37 if (results.Contains (name))
38 continue;
40 if (prefix != null)
41 results.Add (name.Substring (prefix.Length));
42 else
43 results.Add (name);
47 public override bool ContainsEmitWithAwait ()
49 return false;
52 public override Expression CreateExpressionTree (ResolveContext ec)
54 return null;
57 public override void EmitStatement (EmitContext ec)
59 // Do nothing
62 public override void Emit (EmitContext ec)
64 // Do nothing
68 public class CompletionSimpleName : CompletingExpression {
69 public string Prefix;
71 public CompletionSimpleName (string prefix, Location l)
73 this.loc = l;
74 this.Prefix = prefix;
77 protected override Expression DoResolve (ResolveContext ec)
79 var results = new List<string> ();
81 ec.CurrentMemberDefinition.GetCompletionStartingWith (Prefix, results);
83 throw new CompletionResult (Prefix, results.Distinct ().Select (l => l.Substring (Prefix.Length)).ToArray ());
86 protected override void CloneTo (CloneContext clonectx, Expression t)
88 // Nothing
92 public class CompletionMemberAccess : CompletingExpression {
93 Expression expr;
94 string partial_name;
95 TypeArguments targs;
97 public CompletionMemberAccess (Expression e, string partial_name, Location l)
99 this.expr = e;
100 this.loc = l;
101 this.partial_name = partial_name;
104 public CompletionMemberAccess (Expression e, string partial_name, TypeArguments targs, Location l)
106 this.expr = e;
107 this.loc = l;
108 this.partial_name = partial_name;
109 this.targs = targs;
112 protected override Expression DoResolve (ResolveContext rc)
114 var sn = expr as SimpleName;
115 const ResolveFlags flags = ResolveFlags.VariableOrValue | ResolveFlags.Type;
117 if (sn != null) {
118 var errors_printer = new SessionReportPrinter ();
119 var old = rc.Report.SetPrinter (errors_printer);
120 try {
121 expr = sn.LookupNameExpression (rc, MemberLookupRestrictions.ReadAccess | MemberLookupRestrictions.ExactArity);
122 } finally {
123 rc.Report.SetPrinter (old);
126 if (errors_printer.ErrorsCount != 0)
127 return null;
130 // Resolve expression which does have type set as we need expression type
131 // with disable flow analysis as we don't know whether left side expression
132 // is used as variable or type
134 if (expr is VariableReference || expr is ConstantExpr || expr is Linq.TransparentMemberAccess) {
135 expr = expr.Resolve (rc);
136 } else if (expr is TypeParameterExpr) {
137 expr.Error_UnexpectedKind (rc, flags, sn.Location);
138 expr = null;
140 } else {
141 expr = expr.Resolve (rc, flags);
144 if (expr == null)
145 return null;
147 TypeSpec expr_type = expr.Type;
148 if (expr_type.IsPointer || expr_type.Kind == MemberKind.Void || expr_type == InternalType.NullLiteral || expr_type == InternalType.AnonymousMethod) {
149 expr.Error_OperatorCannotBeApplied (rc, loc, ".", expr_type);
150 return null;
153 if (targs != null) {
154 if (!targs.Resolve (rc, true))
155 return null;
158 var results = new List<string> ();
159 var nexpr = expr as NamespaceExpression;
160 if (nexpr != null) {
161 string namespaced_partial;
163 if (partial_name == null)
164 namespaced_partial = nexpr.Namespace.Name;
165 else
166 namespaced_partial = nexpr.Namespace.Name + "." + partial_name;
168 rc.CurrentMemberDefinition.GetCompletionStartingWith (namespaced_partial, results);
169 if (partial_name != null)
170 results = results.Select (l => l.Substring (partial_name.Length)).ToList ();
171 } else {
172 var r = MemberCache.GetCompletitionMembers (rc, expr_type, partial_name).Select (l => l.Name);
173 AppendResults (results, partial_name, r);
176 throw new CompletionResult (partial_name == null ? "" : partial_name, results.Distinct ().ToArray ());
179 protected override void CloneTo (CloneContext clonectx, Expression t)
181 CompletionMemberAccess target = (CompletionMemberAccess) t;
183 if (targs != null)
184 target.targs = targs.Clone ();
186 target.expr = expr.Clone (clonectx);
190 public class CompletionElementInitializer : CompletingExpression {
191 string partial_name;
193 public CompletionElementInitializer (string partial_name, Location l)
195 this.partial_name = partial_name;
196 this.loc = l;
199 protected override Expression DoResolve (ResolveContext ec)
201 var members = MemberCache.GetCompletitionMembers (ec, ec.CurrentInitializerVariable.Type, partial_name);
203 // TODO: Does this mean exact match only ?
204 // if (partial_name != null && results.Count > 0 && result [0] == "")
205 // throw new CompletionResult ("", new string [] { "=" });
207 var results = members.Where (l => (l.Kind & (MemberKind.Field | MemberKind.Property)) != 0).Select (l => l.Name).ToList ();
208 if (partial_name != null) {
209 var temp = new List<string> ();
210 AppendResults (temp, partial_name, results);
211 results = temp;
214 throw new CompletionResult (partial_name == null ? "" : partial_name, results.Distinct ().ToArray ());
217 protected override void CloneTo (CloneContext clonectx, Expression t)
219 // Nothing
223 public class EmptyCompletion : CompletingExpression
225 protected override void CloneTo (CloneContext clonectx, Expression target)
229 protected override Expression DoResolve (ResolveContext rc)
231 throw new CompletionResult ("", new string [0]);