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 public static void AppendResults (ArrayList results
, string prefix
, IEnumerable names
)
55 foreach (string name
in names
){
59 if (!name
.StartsWith (prefix
))
62 if (results
.Contains (name
))
66 results
.Add (name
.Substring (prefix
.Length
));
73 public override Expression
DoResolve (EmitContext ec
)
75 ArrayList results
= new ArrayList ();
77 AppendResults (results
, Prefix
, Evaluator
.GetVarNames ());
78 AppendResults (results
, Prefix
, ec
.TypeContainer
.NamespaceEntry
.CompletionGetTypesStartingWith (ec
.TypeContainer
, Prefix
));
79 AppendResults (results
, Prefix
, Evaluator
.GetUsingList ());
81 throw new CompletionResult (Prefix
, (string []) results
.ToArray (typeof (string)));
84 protected override void CloneTo (CloneContext clonectx
, Expression t
)
90 public class CompletionMemberAccess
: CompletingExpression
{
95 internal static MemberFilter CollectingFilter
= new MemberFilter (Match
);
97 static bool Match (MemberInfo m
, object filter_criteria
)
100 if (((FieldInfo
) m
).IsSpecialName
)
104 if (m
is MethodInfo
){
105 if (((MethodInfo
) m
).IsSpecialName
)
109 if (filter_criteria
== null)
112 string n
= (string) filter_criteria
;
113 if (m
.Name
.StartsWith (n
))
119 public CompletionMemberAccess (Expression e
, string partial_name
, Location l
)
123 this.partial_name
= partial_name
;
126 public CompletionMemberAccess (Expression e
, string partial_name
, TypeArguments targs
, Location l
)
130 this.partial_name
= partial_name
;
134 public override Expression
DoResolve (EmitContext ec
)
136 SimpleName original
= expr
as SimpleName
;
137 Expression expr_resolved
= expr
.Resolve (ec
,
138 ResolveFlags
.VariableOrValue
| ResolveFlags
.Type
|
139 ResolveFlags
.Intermediate
| ResolveFlags
.DisableStructFlowAnalysis
);
141 if (expr_resolved
== null)
144 Type expr_type
= expr_resolved
.Type
;
145 if (expr_type
.IsPointer
|| expr_type
== TypeManager
.void_type
|| expr_type
== TypeManager
.null_type
|| expr_type
== InternalType
.AnonymousMethod
) {
146 Unary
.Error_OperatorCannotBeApplied (loc
, ".", expr_type
);
151 if (!targs
.Resolve (ec
))
155 ArrayList results
= new ArrayList ();
156 if (expr_resolved
is Namespace
){
157 Namespace nexpr
= expr_resolved
as Namespace
;
158 string namespaced_partial
;
160 if (partial_name
== null)
161 namespaced_partial
= nexpr
.Name
;
163 namespaced_partial
= nexpr
.Name
+ "." + partial_name
;
166 Console
.WriteLine ("Workign with: namespaced partial {0}", namespaced_partial
);
167 foreach (var x
in ec
.TypeContainer
.NamespaceEntry
.CompletionGetTypesStartingWith (ec
.TypeContainer
, namespaced_partial
)){
168 Console
.WriteLine (" {0}", x
);
172 CompletionSimpleName
.AppendResults (
175 ec
.TypeContainer
.NamespaceEntry
.CompletionGetTypesStartingWith (ec
.TypeContainer
, namespaced_partial
));
177 MemberInfo
[] result
= expr_type
.FindMembers (
178 MemberTypes
.All
, BindingFlags
.Instance
| BindingFlags
.Static
| BindingFlags
.Public
,
179 CollectingFilter
, partial_name
);
181 foreach (MemberInfo r
in result
){
184 MethodBase rasb
= r
as MethodBase
;
185 if (rasb
!= null && rasb
.IsSpecialName
)
188 if (partial_name
== null)
191 name
= r
.Name
.Substring (partial_name
.Length
);
193 if (results
.Contains (name
))
199 throw new CompletionResult (partial_name
== null ? "" : partial_name
, (string []) results
.ToArray (typeof (string)));
202 protected override void CloneTo (CloneContext clonectx
, Expression t
)
204 CompletionMemberAccess target
= (CompletionMemberAccess
) t
;
207 target
.targs
= targs
.Clone ();
209 target
.expr
= expr
.Clone (clonectx
);
213 public class CompletionElementInitializer
: CompletingExpression
{
216 public CompletionElementInitializer (string partial_name
, Location l
)
218 this.partial_name
= partial_name
;
222 public override Expression
DoResolve (EmitContext ec
)
224 MemberList members
= TypeManager
.FindMembers (
225 ec
.CurrentInitializerVariable
.Type
,
226 MemberTypes
.Field
| MemberTypes
.Property
,
227 BindingFlags
.Instance
| BindingFlags
.Static
| BindingFlags
.Public
,
228 CompletionMemberAccess
.CollectingFilter
, partial_name
);
230 string [] result
= new string [members
.Count
];
232 foreach (MemberInfo mi
in members
){
235 if (partial_name
== null)
238 name
= mi
.Name
.Substring (partial_name
.Length
);
243 if (partial_name
!= null && i
> 0 && result
[0] == "")
244 throw new CompletionResult ("", new string [] { "=" }
);
246 throw new CompletionResult (partial_name
== null ? "" : partial_name
, result
);
249 protected override void CloneTo (CloneContext clonectx
, Expression t
)