[xbuild] Set ProjectFile and TargetName metadata on target outputs.
[mono.git] / mcs / mcs / complete.cs
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 //
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
15 //
16 using System.Collections.Generic;
17 using System.Linq;
18
19 namespace Mono.CSharp {
20
21         //
22         // A common base class for Completing expressions, it
23         // is just a very simple ExpressionStatement
24         //
25         public abstract class CompletingExpression : ExpressionStatement
26         {
27                 public static void AppendResults (List<string> results, string prefix, IEnumerable<string> names)
28                 {
29                         foreach (string name in names) {
30                                 if (name == null)
31                                         continue;
32
33                                 if (prefix != null && !name.StartsWith (prefix))
34                                         continue;
35
36                                 if (results.Contains (name))
37                                         continue;
38
39                                 if (prefix != null)
40                                         results.Add (name.Substring (prefix.Length));
41                                 else
42                                         results.Add (name);
43                         }
44                 }
45
46                 public override void EmitStatement (EmitContext ec)
47                 {
48                         // Do nothing
49                 }
50
51                 public override void Emit (EmitContext ec)
52                 {
53                         // Do nothing
54                 }
55
56                 public override Expression CreateExpressionTree (ResolveContext ec)
57                 {
58                         return null;
59                 }
60         }
61         
62         public class CompletionSimpleName : CompletingExpression {
63                 public string Prefix;
64                 
65                 public CompletionSimpleName (string prefix, Location l)
66                 {
67                         this.loc = l;
68                         this.Prefix = prefix;
69                 }
70                 
71                 protected override Expression DoResolve (ResolveContext ec)
72                 {
73                         var results = new List<string> ();
74
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 ());
78                         
79                         throw new CompletionResult (Prefix, results.ToArray ());
80                 }
81
82                 protected override void CloneTo (CloneContext clonectx, Expression t)
83                 {
84                         // Nothing
85                 }
86         }
87         
88         public class CompletionMemberAccess : CompletingExpression {
89                 Expression expr;
90                 string partial_name;
91                 TypeArguments targs;
92                 
93                 public CompletionMemberAccess (Expression e, string partial_name, Location l)
94                 {
95                         this.expr = e;
96                         this.loc = l;
97                         this.partial_name = partial_name;
98                 }
99
100                 public CompletionMemberAccess (Expression e, string partial_name, TypeArguments targs, Location l)
101                 {
102                         this.expr = e;
103                         this.loc = l;
104                         this.partial_name = partial_name;
105                         this.targs = targs;
106                 }
107                 
108                 protected override Expression DoResolve (ResolveContext ec)
109                 {
110                         Expression expr_resolved = expr.Resolve (ec,
111                                 ResolveFlags.VariableOrValue | ResolveFlags.Type);
112
113                         if (expr_resolved == null)
114                                 return null;
115
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);
119                                 return null;
120                         }
121
122                         if (targs != null) {
123                                 if (!targs.Resolve (ec))
124                                         return null;
125                         }
126
127                         var results = new List<string> ();
128                         if (expr_resolved is Namespace){
129                                 Namespace nexpr = expr_resolved as Namespace;
130                                 string namespaced_partial;
131
132                                 if (partial_name == null)
133                                         namespaced_partial = nexpr.Name;
134                                 else
135                                         namespaced_partial = nexpr.Name + "." + partial_name;
136
137 #if false
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);
141                                 }
142 #endif
143
144                                 CompletionSimpleName.AppendResults (
145                                         results,
146                                         partial_name, 
147                                         ec.CurrentMemberDefinition.Parent.NamespaceEntry.CompletionGetTypesStartingWith (namespaced_partial));
148                         } else {
149                                 var r = MemberCache.GetCompletitionMembers (ec, expr_type, partial_name).Select (l => l.Name);
150                                 AppendResults (results, partial_name, r);
151                         }
152
153                         throw new CompletionResult (partial_name == null ? "" : partial_name, results.Distinct ().ToArray ());
154                 }
155
156                 protected override void CloneTo (CloneContext clonectx, Expression t)
157                 {
158                         CompletionMemberAccess target = (CompletionMemberAccess) t;
159
160                         if (targs != null)
161                                 target.targs = targs.Clone ();
162
163                         target.expr = expr.Clone (clonectx);
164                 }
165         }
166
167         public class CompletionElementInitializer : CompletingExpression {
168                 string partial_name;
169                 
170                 public CompletionElementInitializer (string partial_name, Location l)
171                 {
172                         this.partial_name = partial_name;
173                         this.loc = l;
174                 }
175                 
176                 protected override Expression DoResolve (ResolveContext ec)
177                 {
178                         var members = MemberCache.GetCompletitionMembers (ec, ec.CurrentInitializerVariable.Type, partial_name);
179
180 // TODO: Does this mean exact match only ?
181 //                      if (partial_name != null && results.Count > 0 && result [0] == "")
182 //                              throw new CompletionResult ("", new string [] { "=" });
183
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);
188                                 results = temp;
189                         }
190
191                         throw new CompletionResult (partial_name == null ? "" : partial_name, results.Distinct ().ToArray ());
192                 }
193
194                 protected override void CloneTo (CloneContext clonectx, Expression t)
195                 {
196                         // Nothing
197                 }
198         }
199         
200 }