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 (ResolveContext 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 protected override Expression
DoResolve (ResolveContext ec
)
75 ArrayList results
= new ArrayList ();
77 AppendResults (results
, Prefix
, Evaluator
.GetVarNames ());
78 AppendResults (results
, Prefix
, ec
.CurrentTypeDefinition
.NamespaceEntry
.CompletionGetTypesStartingWith (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 protected override Expression
DoResolve (ResolveContext ec
)
136 Expression expr_resolved
= expr
.Resolve (ec
,
137 ResolveFlags
.VariableOrValue
| ResolveFlags
.Type
|
138 ResolveFlags
.Intermediate
);
140 if (expr_resolved
== null)
143 Type expr_type
= expr_resolved
.Type
;
144 if (expr_type
.IsPointer
|| expr_type
== TypeManager
.void_type
|| expr_type
== TypeManager
.null_type
|| expr_type
== InternalType
.AnonymousMethod
) {
145 Unary
.Error_OperatorCannotBeApplied (ec
, loc
, ".", expr_type
);
150 if (!targs
.Resolve (ec
))
154 ArrayList results
= new ArrayList ();
155 if (expr_resolved
is Namespace
){
156 Namespace nexpr
= expr_resolved
as Namespace
;
157 string namespaced_partial
;
159 if (partial_name
== null)
160 namespaced_partial
= nexpr
.Name
;
162 namespaced_partial
= nexpr
.Name
+ "." + partial_name
;
165 Console
.WriteLine ("Workign with: namespaced partial {0}", namespaced_partial
);
166 foreach (var x
in ec
.TypeContainer
.NamespaceEntry
.CompletionGetTypesStartingWith (ec
.TypeContainer
, namespaced_partial
)){
167 Console
.WriteLine (" {0}", x
);
171 CompletionSimpleName
.AppendResults (
174 ec
.CurrentTypeDefinition
.NamespaceEntry
.CompletionGetTypesStartingWith (namespaced_partial
));
176 MemberInfo
[] result
= expr_type
.FindMembers (
177 MemberTypes
.All
, BindingFlags
.Instance
| BindingFlags
.Static
| BindingFlags
.Public
,
178 CollectingFilter
, partial_name
);
180 foreach (MemberInfo r
in result
){
183 MethodBase rasb
= r
as MethodBase
;
184 if (rasb
!= null && rasb
.IsSpecialName
)
187 if (partial_name
== null)
190 name
= r
.Name
.Substring (partial_name
.Length
);
192 if (results
.Contains (name
))
198 throw new CompletionResult (partial_name
== null ? "" : partial_name
, (string []) results
.ToArray (typeof (string)));
201 protected override void CloneTo (CloneContext clonectx
, Expression t
)
203 CompletionMemberAccess target
= (CompletionMemberAccess
) t
;
206 target
.targs
= targs
.Clone ();
208 target
.expr
= expr
.Clone (clonectx
);
212 public class CompletionElementInitializer
: CompletingExpression
{
215 public CompletionElementInitializer (string partial_name
, Location l
)
217 this.partial_name
= partial_name
;
221 protected override Expression
DoResolve (ResolveContext ec
)
223 MemberList members
= TypeManager
.FindMembers (
224 ec
.CurrentInitializerVariable
.Type
,
225 MemberTypes
.Field
| MemberTypes
.Property
,
226 BindingFlags
.Instance
| BindingFlags
.Static
| BindingFlags
.Public
,
227 CompletionMemberAccess
.CollectingFilter
, partial_name
);
229 string [] result
= new string [members
.Count
];
231 foreach (MemberInfo mi
in members
){
234 if (partial_name
== null)
237 name
= mi
.Name
.Substring (partial_name
.Length
);
242 if (partial_name
!= null && i
> 0 && result
[0] == "")
243 throw new CompletionResult ("", new string [] { "=" }
);
245 throw new CompletionResult (partial_name
== null ? "" : partial_name
, result
);
248 protected override void CloneTo (CloneContext clonectx
, Expression t
)