Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/HeuristicLab.ExtLibs/HeuristicLab.NRefactory/5.5.0/NRefactory.CSharp-5.5.0/Parser/mcs/complete.cs @ 15682

Last change on this file since 15682 was 11700, checked in by jkarder, 10 years ago

#2077: created branch and added first version

File size: 6.0 KB
Line 
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// Copyright 2011 Xamarin Inc
11//
12// Completion* classes derive from ExpressionStatement as this allows
13// them to pass through the parser in many conditions that require
14// statements even when the expression is incomplete (for example
15// completing inside a lambda
16//
17using System.Collections.Generic;
18using System.Linq;
19
20namespace Mono.CSharp {
21
22  //
23  // A common base class for Completing expressions, it
24  // is just a very simple ExpressionStatement
25  //
26  public abstract class CompletingExpression : ExpressionStatement
27  {
28    public static void AppendResults (List<string> results, string prefix, IEnumerable<string> names)
29    {
30      foreach (string name in names) {
31        if (name == null)
32          continue;
33
34        if (prefix != null && !name.StartsWith (prefix))
35          continue;
36
37        if (results.Contains (name))
38          continue;
39
40        if (prefix != null)
41          results.Add (name.Substring (prefix.Length));
42        else
43          results.Add (name);
44      }
45    }
46
47    public override bool ContainsEmitWithAwait ()
48    {
49      return false;
50    }
51
52    public override Expression CreateExpressionTree (ResolveContext ec)
53    {
54      return null;
55    }
56
57    public override void EmitStatement (EmitContext ec)
58    {
59      // Do nothing
60    }
61
62    public override void Emit (EmitContext ec)
63    {
64      // Do nothing
65    }
66  }
67 
68  public class CompletionSimpleName : CompletingExpression {
69    public string Prefix;
70   
71    public CompletionSimpleName (string prefix, Location l)
72    {
73      this.loc = l;
74      this.Prefix = prefix;
75    }
76   
77    protected override Expression DoResolve (ResolveContext ec)
78    {
79      var results = new List<string> ();
80
81      ec.CurrentMemberDefinition.GetCompletionStartingWith (Prefix, results);
82
83      throw new CompletionResult (Prefix, results.Distinct ().Select (l => l.Substring (Prefix.Length)).ToArray ());
84    }
85
86    protected override void CloneTo (CloneContext clonectx, Expression t)
87    {
88      // Nothing
89    }
90  }
91 
92  public class CompletionMemberAccess : CompletingExpression {
93    Expression expr;
94    string partial_name;
95    TypeArguments targs;
96   
97    public CompletionMemberAccess (Expression e, string partial_name, Location l)
98    {
99      this.expr = e;
100      this.loc = l;
101      this.partial_name = partial_name;
102    }
103
104    public CompletionMemberAccess (Expression e, string partial_name, TypeArguments targs, Location l)
105    {
106      this.expr = e;
107      this.loc = l;
108      this.partial_name = partial_name;
109      this.targs = targs;
110    }
111   
112    protected override Expression DoResolve (ResolveContext rc)
113    {
114      var sn = expr as SimpleName;
115      const ResolveFlags flags = ResolveFlags.VariableOrValue | ResolveFlags.Type;
116
117      if (sn != null) {
118        expr = sn.LookupNameExpression (rc, MemberLookupRestrictions.ReadAccess | MemberLookupRestrictions.ExactArity);
119
120        //
121        // Resolve expression which does have type set as we need expression type
122        // with disable flow analysis as we don't know whether left side expression
123        // is used as variable or type
124        //
125        if (expr is VariableReference || expr is ConstantExpr || expr is Linq.TransparentMemberAccess) {
126          expr = expr.Resolve (rc);
127        } else if (expr is TypeParameterExpr) {
128          expr.Error_UnexpectedKind (rc, flags, sn.Location);
129          expr = null;
130        }
131      } else {
132        expr = expr.Resolve (rc, flags);
133      }
134
135      if (expr == null)
136        return null;
137
138      TypeSpec expr_type = expr.Type;
139      if (expr_type.IsPointer || expr_type.Kind == MemberKind.Void || expr_type == InternalType.NullLiteral || expr_type == InternalType.AnonymousMethod) {
140        expr.Error_OperatorCannotBeApplied (rc, loc, ".", expr_type);
141        return null;
142      }
143
144      if (targs != null) {
145        if (!targs.Resolve (rc))
146          return null;
147      }
148
149      var results = new List<string> ();
150      var nexpr = expr as NamespaceExpression;
151      if (nexpr != null) {
152        string namespaced_partial;
153
154        if (partial_name == null)
155          namespaced_partial = nexpr.Namespace.Name;
156        else
157          namespaced_partial = nexpr.Namespace.Name + "." + partial_name;
158
159        rc.CurrentMemberDefinition.GetCompletionStartingWith (namespaced_partial, results);
160        if (partial_name != null)
161          results = results.Select (l => l.Substring (partial_name.Length)).ToList ();
162      } else {
163        var r = MemberCache.GetCompletitionMembers (rc, expr_type, partial_name).Select (l => l.Name);
164        AppendResults (results, partial_name, r);
165      }
166
167      throw new CompletionResult (partial_name == null ? "" : partial_name, results.Distinct ().ToArray ());
168    }
169
170    protected override void CloneTo (CloneContext clonectx, Expression t)
171    {
172      CompletionMemberAccess target = (CompletionMemberAccess) t;
173
174      if (targs != null)
175        target.targs = targs.Clone ();
176
177      target.expr = expr.Clone (clonectx);
178    }
179  }
180
181  public class CompletionElementInitializer : CompletingExpression {
182    string partial_name;
183   
184    public CompletionElementInitializer (string partial_name, Location l)
185    {
186      this.partial_name = partial_name;
187      this.loc = l;
188    }
189   
190    protected override Expression DoResolve (ResolveContext ec)
191    {
192      var members = MemberCache.GetCompletitionMembers (ec, ec.CurrentInitializerVariable.Type, partial_name);
193
194// TODO: Does this mean exact match only ?
195//      if (partial_name != null && results.Count > 0 && result [0] == "")
196//        throw new CompletionResult ("", new string [] { "=" });
197
198      var results = members.Where (l => (l.Kind & (MemberKind.Field | MemberKind.Property)) != 0).Select (l => l.Name).ToList ();
199      if (partial_name != null) {
200        var temp = new List<string> ();
201        AppendResults (temp, partial_name, results);
202        results = temp;
203      }
204
205      throw new CompletionResult (partial_name == null ? "" : partial_name, results.Distinct ().ToArray ());
206    }
207
208    protected override void CloneTo (CloneContext clonectx, Expression t)
209    {
210      // Nothing
211    }
212  }
213
214  public class EmptyCompletion : CompletingExpression
215  {
216    protected override void CloneTo (CloneContext clonectx, Expression target)
217    {
218    }
219
220    protected override Expression DoResolve (ResolveContext rc)
221    {
222      throw new CompletionResult ("", new string [0]);
223    }
224  }
225 
226}
Note: See TracBrowser for help on using the repository browser.