X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=mcs%2Fmcs%2Fcomplete.cs;h=6eb42cddada0a51de2f96f54fe9c35b0b6cd294e;hb=009d937c1df7d8949b7671c89426e33a11c6d284;hp=d3eb5a99b2a77aac67dfe592bd81744b89142692;hpb=bbcf0ee13c6cfea51c358fb6875d594901012fb2;p=mono.git diff --git a/mcs/mcs/complete.cs b/mcs/mcs/complete.cs index d3eb5a99b2a..6eb42cddada 100644 --- a/mcs/mcs/complete.cs +++ b/mcs/mcs/complete.cs @@ -7,38 +7,62 @@ // // Copyright 2001, 2002, 2003 Ximian, Inc. // Copyright 2003-2009 Novell, Inc. +// Copyright 2011 Xamarin Inc // // Completion* classes derive from ExpressionStatement as this allows // them to pass through the parser in many conditions that require // statements even when the expression is incomplete (for example // completing inside a lambda // +using System.Collections.Generic; +using System.Linq; + namespace Mono.CSharp { - using System; - using System.Collections; - using System.Reflection; - using System.Reflection.Emit; - using System.Text; // // A common base class for Completing expressions, it // is just a very simple ExpressionStatement // - public abstract class CompletingExpression : ExpressionStatement { - public override void EmitStatement (EmitContext ec) + public abstract class CompletingExpression : ExpressionStatement + { + public static void AppendResults (List results, string prefix, IEnumerable names) { - // Do nothing + foreach (string name in names) { + if (name == null) + continue; + + if (prefix != null && !name.StartsWith (prefix)) + continue; + + if (results.Contains (name)) + continue; + + if (prefix != null) + results.Add (name.Substring (prefix.Length)); + else + results.Add (name); + } } - public override void Emit (EmitContext ec) + public override bool ContainsEmitWithAwait () { - // Do nothing + return false; } - public override Expression CreateExpressionTree (EmitContext ec) + public override Expression CreateExpressionTree (ResolveContext ec) { return null; } + + public override void EmitStatement (EmitContext ec) + { + // Do nothing + } + + public override void Emit (EmitContext ec) + { + // Do nothing + } } public class CompletionSimpleName : CompletingExpression { @@ -49,33 +73,14 @@ namespace Mono.CSharp { this.loc = l; this.Prefix = prefix; } - - public static void AppendResults (ArrayList results, string prefix, IEnumerable names) - { - foreach (string name in names){ - if (!name.StartsWith (prefix)) - continue; - - if (results.Contains (name)) - continue; - - if (prefix != null) - results.Add (name.Substring (prefix.Length)); - else - results.Add (name); - } - - } - public override Expression DoResolve (EmitContext ec) + protected override Expression DoResolve (ResolveContext ec) { - ArrayList results = new ArrayList (); + var results = new List (); - AppendResults (results, Prefix, Evaluator.GetVarNames ()); - AppendResults (results, Prefix, ec.TypeContainer.NamespaceEntry.CompletionGetTypesStartingWith (ec.TypeContainer, Prefix)); - AppendResults (results, Prefix, Evaluator.GetUsingList ()); - - throw new CompletionResult (Prefix, (string []) results.ToArray (typeof (string))); + ec.CurrentMemberDefinition.GetCompletionStartingWith (Prefix, results); + + throw new CompletionResult (Prefix, results.Distinct ().Select (l => l.Substring (Prefix.Length)).ToArray ()); } protected override void CloneTo (CloneContext clonectx, Expression t) @@ -88,30 +93,6 @@ namespace Mono.CSharp { Expression expr; string partial_name; TypeArguments targs; - - internal static MemberFilter CollectingFilter = new MemberFilter (Match); - - static bool Match (MemberInfo m, object filter_criteria) - { - if (m is FieldInfo){ - if (((FieldInfo) m).IsSpecialName) - return false; - - } - if (m is MethodInfo){ - if (((MethodInfo) m).IsSpecialName) - return false; - } - - if (filter_criteria == null) - return true; - - string n = (string) filter_criteria; - if (m.Name.StartsWith (n)) - return true; - - return false; - } public CompletionMemberAccess (Expression e, string partial_name, Location l) { @@ -128,30 +109,56 @@ namespace Mono.CSharp { this.targs = targs; } - public override Expression DoResolve (EmitContext ec) - { - SimpleName original = expr as SimpleName; - Expression expr_resolved = expr.Resolve (ec, - ResolveFlags.VariableOrValue | ResolveFlags.Type | - ResolveFlags.Intermediate | ResolveFlags.DisableStructFlowAnalysis); + protected override Expression DoResolve (ResolveContext rc) + { + var sn = expr as SimpleName; + const ResolveFlags flags = ResolveFlags.VariableOrValue | ResolveFlags.Type; + + // + // Resolve the expression with flow analysis turned off, we'll do the definite + // assignment checks later. This is because we don't know yet what the expression + // will resolve to - it may resolve to a FieldExpr and in this case we must do the + // definite assignment check on the actual field and not on the whole struct. + // + using (rc.Set (ResolveContext.Options.OmitStructFlowAnalysis)) { + if (sn != null) { + expr = sn.LookupNameExpression (rc, MemberLookupRestrictions.ReadAccess | MemberLookupRestrictions.ExactArity); + + // + // Resolve expression which does have type set as we need expression type + // with disable flow analysis as we don't know whether left side expression + // is used as variable or type + // + if (expr is VariableReference || expr is ConstantExpr || expr is Linq.TransparentMemberAccess) { + using (rc.With (ResolveContext.Options.DoFlowAnalysis, false)) { + expr = expr.Resolve (rc); + } + } else if (expr is TypeParameterExpr) { + expr.Error_UnexpectedKind (rc, flags, sn.Location); + expr = null; + } + } else { + expr = expr.Resolve (rc, flags); + } + } - if (expr_resolved == null) + if (expr == null) return null; - Type expr_type = expr_resolved.Type; - if (expr_type.IsPointer || expr_type == TypeManager.void_type || expr_type == TypeManager.null_type || expr_type == TypeManager.anonymous_method_type) { - Unary.Error_OperatorCannotBeApplied (loc, ".", expr_type); + TypeSpec expr_type = expr.Type; + if (expr_type.IsPointer || expr_type.Kind == MemberKind.Void || expr_type == InternalType.NullLiteral || expr_type == InternalType.AnonymousMethod) { + expr.Error_OperatorCannotBeApplied (rc, loc, ".", expr_type); return null; } if (targs != null) { - if (!targs.Resolve (ec)) + if (!targs.Resolve (rc)) return null; } - ArrayList results = new ArrayList (); - if (expr_resolved is Namespace){ - Namespace nexpr = expr_resolved as Namespace; + var results = new List (); + if (expr is Namespace) { + Namespace nexpr = expr as Namespace; string namespaced_partial; if (partial_name == null) @@ -159,41 +166,15 @@ namespace Mono.CSharp { else namespaced_partial = nexpr.Name + "." + partial_name; -#if false - Console.WriteLine ("Workign with: namespaced partial {0}", namespaced_partial); - foreach (var x in ec.TypeContainer.NamespaceEntry.CompletionGetTypesStartingWith (ec.TypeContainer, namespaced_partial)){ - Console.WriteLine (" {0}", x); - } -#endif - - CompletionSimpleName.AppendResults ( - results, - partial_name, - ec.TypeContainer.NamespaceEntry.CompletionGetTypesStartingWith (ec.TypeContainer, namespaced_partial)); + rc.CurrentMemberDefinition.GetCompletionStartingWith (namespaced_partial, results); + if (partial_name != null) + results = results.Select (l => l.Substring (partial_name.Length)).ToList (); } else { - MemberInfo [] result = expr_type.FindMembers ( - MemberTypes.All, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, - CollectingFilter, partial_name); - - foreach (MemberInfo r in result){ - string name; - - MethodBase rasb = r as MethodBase; - if (rasb != null && rasb.IsSpecialName) - continue; - - if (partial_name == null) - name = r.Name; - else - name = r.Name.Substring (partial_name.Length); - - if (results.Contains (name)) - continue; - results.Add (name); - } + var r = MemberCache.GetCompletitionMembers (rc, expr_type, partial_name).Select (l => l.Name); + AppendResults (results, partial_name, r); } - throw new CompletionResult (partial_name == null ? "" : partial_name, (string []) results.ToArray (typeof (string))); + throw new CompletionResult (partial_name == null ? "" : partial_name, results.Distinct ().ToArray ()); } protected override void CloneTo (CloneContext clonectx, Expression t) @@ -216,41 +197,28 @@ namespace Mono.CSharp { this.loc = l; } - public override Expression DoResolve (EmitContext ec) + protected override Expression DoResolve (ResolveContext ec) { - MemberList members = TypeManager.FindMembers ( - ec.CurrentInitializerVariable.Type, - MemberTypes.Field | MemberTypes.Property, - BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, - CompletionMemberAccess.CollectingFilter, partial_name); + var members = MemberCache.GetCompletitionMembers (ec, ec.CurrentInitializerVariable.Type, partial_name); - string [] result = new string [members.Count]; - int i = 0; - foreach (MemberInfo mi in members){ - string name; - - if (partial_name == null) - name = mi.Name; - else - name = mi.Name.Substring (partial_name.Length); - - result [i++] = name; +// TODO: Does this mean exact match only ? +// if (partial_name != null && results.Count > 0 && result [0] == "") +// throw new CompletionResult ("", new string [] { "=" }); + + var results = members.Where (l => (l.Kind & (MemberKind.Field | MemberKind.Property)) != 0).Select (l => l.Name).ToList (); + if (partial_name != null) { + var temp = new List (); + AppendResults (temp, partial_name, results); + results = temp; } - if (partial_name != null && i > 0 && result [0] == "") - throw new CompletionResult ("", new string [] { "=" }); - - throw new CompletionResult (partial_name == null ? "" : partial_name, result); + throw new CompletionResult (partial_name == null ? "" : partial_name, results.Distinct ().ToArray ()); } protected override void CloneTo (CloneContext clonectx, Expression t) { // Nothing } - - public override string ToString () - { - return "CompletionElementInitializer (" + (partial_name ?? "") + ")"; - } } + }