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
17 using System
.Collections
.Generic
;
18 using System
.Reflection
;
19 using System
.Reflection
.Emit
;
21 using Mono
.CSharp
.Linq
;
23 namespace Mono
.CSharp
{
26 // A common base class for Completing expressions, it
27 // is just a very simple ExpressionStatement
29 public abstract class CompletingExpression
: ExpressionStatement
{
30 public override void EmitStatement (EmitContext ec
)
35 public override void Emit (EmitContext ec
)
40 public override Expression
CreateExpressionTree (ResolveContext ec
)
46 public class CompletionSimpleName
: CompletingExpression
{
49 public CompletionSimpleName (string prefix
, Location l
)
55 public static void AppendResults (List
<string> results
, string prefix
, IEnumerable
<string> names
)
57 foreach (string name
in names
){
58 if (name
== null || prefix
== null)
61 if (!name
.StartsWith (prefix
))
64 if (results
.Contains (name
))
68 results
.Add (name
.Substring (prefix
.Length
));
75 protected override Expression
DoResolve (ResolveContext ec
)
77 var results
= new List
<string> ();
79 AppendResults (results
, Prefix
, Evaluator
.GetVarNames ());
80 AppendResults (results
, Prefix
, ec
.CurrentTypeDefinition
.NamespaceEntry
.CompletionGetTypesStartingWith (Prefix
));
81 AppendResults (results
, Prefix
, Evaluator
.GetUsingList ());
83 throw new CompletionResult (Prefix
, results
.ToArray ());
86 protected override void CloneTo (CloneContext clonectx
, Expression t
)
92 public class CompletionMemberAccess
: CompletingExpression
{
97 internal static MemberFilter CollectingFilter
= new MemberFilter (Match
);
99 static bool Match (MemberInfo m
, object filter_criteria
)
102 if (((FieldInfo
) m
).IsSpecialName
)
106 if (m
is MethodInfo
){
107 if (((MethodInfo
) m
).IsSpecialName
)
111 if (filter_criteria
== null)
114 string n
= (string) filter_criteria
;
115 if (m
.Name
.StartsWith (n
))
121 public CompletionMemberAccess (Expression e
, string partial_name
, Location l
)
125 this.partial_name
= partial_name
;
128 public CompletionMemberAccess (Expression e
, string partial_name
, TypeArguments targs
, Location l
)
132 this.partial_name
= partial_name
;
136 protected override Expression
DoResolve (ResolveContext ec
)
138 Expression expr_resolved
= expr
.Resolve (ec
,
139 ResolveFlags
.VariableOrValue
| ResolveFlags
.Type
|
140 ResolveFlags
.Intermediate
);
142 if (expr_resolved
== null)
145 Type expr_type
= expr_resolved
.Type
;
146 if (expr_type
.IsPointer
|| expr_type
== TypeManager
.void_type
|| expr_type
== TypeManager
.null_type
|| expr_type
== InternalType
.AnonymousMethod
) {
147 Unary
.Error_OperatorCannotBeApplied (ec
, loc
, ".", expr_type
);
152 if (!targs
.Resolve (ec
))
156 var results
= new List
<string> ();
157 if (expr_resolved
is Namespace
){
158 Namespace nexpr
= expr_resolved
as Namespace
;
159 string namespaced_partial
;
161 if (partial_name
== null)
162 namespaced_partial
= nexpr
.Name
;
164 namespaced_partial
= nexpr
.Name
+ "." + partial_name
;
167 Console
.WriteLine ("Workign with: namespaced partial {0}", namespaced_partial
);
168 foreach (var x
in ec
.TypeContainer
.NamespaceEntry
.CompletionGetTypesStartingWith (ec
.TypeContainer
, namespaced_partial
)){
169 Console
.WriteLine (" {0}", x
);
173 CompletionSimpleName
.AppendResults (
176 ec
.CurrentTypeDefinition
.NamespaceEntry
.CompletionGetTypesStartingWith (namespaced_partial
));
178 MemberInfo
[] result
= expr_type
.FindMembers (
179 MemberTypes
.All
, BindingFlags
.Instance
| BindingFlags
.Static
| BindingFlags
.Public
,
180 CollectingFilter
, partial_name
);
182 foreach (MemberInfo r
in result
){
185 MethodBase rasb
= r
as MethodBase
;
186 if (rasb
!= null && rasb
.IsSpecialName
)
189 if (partial_name
== null)
192 name
= r
.Name
.Substring (partial_name
.Length
);
194 if (results
.Contains (name
))
200 throw new CompletionResult (partial_name
== null ? "" : partial_name
, results
.ToArray ());
203 protected override void CloneTo (CloneContext clonectx
, Expression t
)
205 CompletionMemberAccess target
= (CompletionMemberAccess
) t
;
208 target
.targs
= targs
.Clone ();
210 target
.expr
= expr
.Clone (clonectx
);
214 public class CompletionElementInitializer
: CompletingExpression
{
217 public CompletionElementInitializer (string partial_name
, Location l
)
219 this.partial_name
= partial_name
;
223 protected override Expression
DoResolve (ResolveContext ec
)
225 MemberList members
= TypeManager
.FindMembers (
226 ec
.CurrentInitializerVariable
.Type
,
227 MemberTypes
.Field
| MemberTypes
.Property
,
228 BindingFlags
.Instance
| BindingFlags
.Static
| BindingFlags
.Public
,
229 CompletionMemberAccess
.CollectingFilter
, partial_name
);
231 string [] result
= new string [members
.Count
];
233 foreach (MemberInfo mi
in members
){
236 if (partial_name
== null)
239 name
= mi
.Name
.Substring (partial_name
.Length
);
244 if (partial_name
!= null && i
> 0 && result
[0] == "")
245 throw new CompletionResult ("", new string [] { "=" }
);
247 throw new CompletionResult (partial_name
== null ? "" : partial_name
, result
);
250 protected override void CloneTo (CloneContext clonectx
, Expression t
)