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
;
24 namespace Mono
.CSharp
{
27 // A common base class for Completing expressions, it
28 // is just a very simple ExpressionStatement
30 public abstract class CompletingExpression
: ExpressionStatement
32 public static void AppendResults (List
<string> results
, string prefix
, IEnumerable
<string> names
)
34 foreach (string name
in names
) {
35 if (name
== null || prefix
== null)
38 if (!name
.StartsWith (prefix
))
41 if (results
.Contains (name
))
45 results
.Add (name
.Substring (prefix
.Length
));
51 public override void EmitStatement (EmitContext ec
)
56 public override void Emit (EmitContext ec
)
61 public override Expression
CreateExpressionTree (ResolveContext ec
)
67 public class CompletionSimpleName
: CompletingExpression
{
70 public CompletionSimpleName (string prefix
, Location l
)
76 protected override Expression
DoResolve (ResolveContext ec
)
78 var results
= new List
<string> ();
80 AppendResults (results
, Prefix
, Evaluator
.GetVarNames ());
81 AppendResults (results
, Prefix
, ec
.CurrentMemberDefinition
.Parent
.NamespaceEntry
.CompletionGetTypesStartingWith (Prefix
));
82 AppendResults (results
, Prefix
, Evaluator
.GetUsingList ());
84 throw new CompletionResult (Prefix
, results
.ToArray ());
87 protected override void CloneTo (CloneContext clonectx
, Expression t
)
93 public class CompletionMemberAccess
: CompletingExpression
{
98 public CompletionMemberAccess (Expression e
, string partial_name
, Location l
)
102 this.partial_name
= partial_name
;
105 public CompletionMemberAccess (Expression e
, string partial_name
, TypeArguments targs
, Location l
)
109 this.partial_name
= partial_name
;
113 protected override Expression
DoResolve (ResolveContext ec
)
115 Expression expr_resolved
= expr
.Resolve (ec
,
116 ResolveFlags
.VariableOrValue
| ResolveFlags
.Type
);
118 if (expr_resolved
== null)
121 TypeSpec expr_type
= expr_resolved
.Type
;
122 if (expr_type
.IsPointer
|| expr_type
== TypeManager
.void_type
|| expr_type
== TypeManager
.null_type
|| expr_type
== InternalType
.AnonymousMethod
) {
123 Unary
.Error_OperatorCannotBeApplied (ec
, loc
, ".", expr_type
);
128 if (!targs
.Resolve (ec
))
132 var results
= new List
<string> ();
133 if (expr_resolved
is Namespace
){
134 Namespace nexpr
= expr_resolved
as Namespace
;
135 string namespaced_partial
;
137 if (partial_name
== null)
138 namespaced_partial
= nexpr
.Name
;
140 namespaced_partial
= nexpr
.Name
+ "." + partial_name
;
143 Console
.WriteLine ("Workign with: namespaced partial {0}", namespaced_partial
);
144 foreach (var x
in ec
.TypeContainer
.NamespaceEntry
.CompletionGetTypesStartingWith (ec
.TypeContainer
, namespaced_partial
)){
145 Console
.WriteLine (" {0}", x
);
149 CompletionSimpleName
.AppendResults (
152 ec
.CurrentMemberDefinition
.Parent
.NamespaceEntry
.CompletionGetTypesStartingWith (namespaced_partial
));
154 var r
= MemberCache
.GetCompletitionMembers (expr_type
, partial_name
).Select (l
=> l
.Name
);
155 AppendResults (results
, partial_name
, r
);
158 throw new CompletionResult (partial_name
== null ? "" : partial_name
, results
.Distinct ().ToArray ());
161 protected override void CloneTo (CloneContext clonectx
, Expression t
)
163 CompletionMemberAccess target
= (CompletionMemberAccess
) t
;
166 target
.targs
= targs
.Clone ();
168 target
.expr
= expr
.Clone (clonectx
);
172 public class CompletionElementInitializer
: CompletingExpression
{
175 public CompletionElementInitializer (string partial_name
, Location l
)
177 this.partial_name
= partial_name
;
181 protected override Expression
DoResolve (ResolveContext ec
)
183 var members
= MemberCache
.GetCompletitionMembers (ec
.CurrentInitializerVariable
.Type
, partial_name
);
185 // TODO: Does this mean exact match only ?
186 // if (partial_name != null && results.Count > 0 && result [0] == "")
187 // throw new CompletionResult ("", new string [] { "=" });
189 var results
= members
.Where (l
=> (l
.Kind
& (MemberKind
.Field
| MemberKind
.Property
)) != 0).Select (l
=> l
.Name
).ToList ();
190 if (partial_name
!= null) {
191 var temp
= new List
<string> ();
192 AppendResults (temp
, partial_name
, results
);
196 throw new CompletionResult (partial_name
== null ? "" : partial_name
, results
.Distinct ().ToArray ());
199 protected override void CloneTo (CloneContext clonectx
, Expression t
)