X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fnamespace.cs;h=f5ca0a818a4480e5080a67945f414dca21fd4a2e;hb=31b2d605496b5018eb30835d468eacb6d87416e4;hp=6a6f17e8e9d7ceee288929f262704b4b5ad924f6;hpb=87f80d1139d559d7883da118f1ee2951b0e06856;p=mono.git diff --git a/mcs/mcs/namespace.cs b/mcs/mcs/namespace.cs index 6a6f17e8e9d..f5ca0a818a4 100644 --- a/mcs/mcs/namespace.cs +++ b/mcs/mcs/namespace.cs @@ -22,9 +22,10 @@ namespace Mono.CSharp { readonly Dictionary all_namespaces; public RootNamespace (string alias_name) - : base (null, String.Empty) + : base () { this.alias_name = alias_name; + RegisterNamespace (this); all_namespaces = new Dictionary (); all_namespaces.Add ("", this); @@ -87,24 +88,13 @@ namespace Mono.CSharp { all_namespaces.Add (child.Name, child); } - public bool IsNamespace (string name) - { - return all_namespaces.ContainsKey (name); - } - - protected void RegisterNamespace (string dotted_name) - { - if (dotted_name != null && dotted_name.Length != 0 && ! IsNamespace (dotted_name)) - GetNamespace (dotted_name, true); - } - public override string GetSignatureForError () { return alias_name + "::"; } } - public class GlobalRootNamespace : RootNamespace + public sealed class GlobalRootNamespace : RootNamespace { public GlobalRootNamespace () : base ("global") @@ -115,65 +105,50 @@ namespace Mono.CSharp { // // Namespace cache for imported and compiled namespaces // - // This is an Expression to allow it to be referenced in the - // compiler parse/intermediate tree during name resolution. - // - public class Namespace : FullNamedExpression + public class Namespace { - Namespace parent; + readonly Namespace parent; string fullname; protected Dictionary namespaces; protected Dictionary> types; List extension_method_types; Dictionary cached_types; - RootNamespace root; bool cls_checked; - public readonly MemberName MemberName; - /// /// Constructor Takes the current namespace and the /// name. This is bootstrapped with parent == null /// and name = "" /// public Namespace (Namespace parent, string name) + : this () { - // Expression members. - this.eclass = ExprClass.Namespace; - this.Type = InternalType.Namespace; - this.loc = Location.Null; + if (name == null) + throw new ArgumentNullException ("name"); this.parent = parent; - if (parent != null) - this.root = parent.root; - else - this.root = this as RootNamespace; - - if (this.root == null) - throw new InternalErrorException ("Root namespaces must be created using RootNamespace"); - - string pname = parent != null ? parent.fullname : ""; + string pname = parent != null ? parent.fullname : null; - if (pname == "") + if (pname == null) fullname = name; else - fullname = parent.fullname + "." + name; + fullname = pname + "." + name; - if (fullname == null) - throw new InternalErrorException ("Namespace has a null fullname"); + while (parent.parent != null) + parent = parent.parent; - if (parent != null && parent.MemberName != MemberName.Null) - MemberName = new MemberName (parent.MemberName, name, Location.Null); - else if (name.Length == 0) - MemberName = MemberName.Null; - else - MemberName = new MemberName (name, Location.Null); + var root = parent as RootNamespace; + if (root == null) + throw new InternalErrorException ("Root namespaces must be created using RootNamespace"); + + root.RegisterNamespace (this); + } + protected Namespace () + { namespaces = new Dictionary (); cached_types = new Dictionary (); - - root.RegisterNamespace (this); } #region Properties @@ -195,85 +170,6 @@ namespace Mono.CSharp { #endregion - protected override Expression DoResolve (ResolveContext ec) - { - return this; - } - - public void Error_NamespaceDoesNotExist (IMemberContext ctx, string name, int arity, Location loc) - { - var retval = LookupType (ctx, name, arity, LookupMode.IgnoreAccessibility, loc); - if (retval != null) { -// ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (retval.MemberDefinition); - ErrorIsInaccesible (ctx, retval.GetSignatureForError (), loc); - return; - } - - retval = LookupType (ctx, name, -System.Math.Max (1, arity), LookupMode.Probing, loc); - if (retval != null) { - Error_TypeArgumentsCannotBeUsed (ctx, retval, loc); - return; - } - - Namespace ns; - if (arity > 0 && namespaces.TryGetValue (name, out ns)) { - ns.Error_TypeArgumentsCannotBeUsed (ctx, null, loc); - return; - } - - string assembly = null; - string possible_name = fullname + "." + name; - - // Only assembly unique name should be added - switch (possible_name) { - case "System.Drawing": - case "System.Web.Services": - case "System.Web": - case "System.Data": - case "System.Configuration": - case "System.Data.Services": - case "System.DirectoryServices": - case "System.Json": - case "System.Net.Http": - case "System.Numerics": - case "System.Runtime.Caching": - case "System.ServiceModel": - case "System.Transactions": - case "System.Web.Routing": - case "System.Xml.Linq": - case "System.Xml": - assembly = possible_name; - break; - - case "System.Linq": - case "System.Linq.Expressions": - assembly = "System.Core"; - break; - - case "System.Windows.Forms": - case "System.Windows.Forms.Layout": - assembly = "System.Windows.Forms"; - break; - } - - assembly = assembly == null ? "an" : "`" + assembly + "'"; - - if (this is GlobalRootNamespace) { - ctx.Module.Compiler.Report.Error (400, loc, - "The type or namespace name `{0}' could not be found in the global namespace. Are you missing {1} assembly reference?", - name, assembly); - } else { - ctx.Module.Compiler.Report.Error (234, loc, - "The type or namespace name `{0}' does not exist in the namespace `{1}'. Are you missing {2} assembly reference?", - name, GetSignatureForError (), assembly); - } - } - - public override string GetSignatureForError () - { - return fullname; - } - public Namespace AddNamespace (MemberName name) { var ns_parent = name.Left == null ? this : AddNamespace (name.Left); @@ -292,6 +188,11 @@ namespace Mono.CSharp { return ns; } + public bool TryGetNamespace (string name, out Namespace ns) + { + return namespaces.TryGetValue (name, out ns); + } + // TODO: Replace with CreateNamespace where MemberName is created for the method call public Namespace GetNamespace (string name, bool create) { @@ -327,6 +228,11 @@ namespace Mono.CSharp { return found; } + public virtual string GetSignatureForError () + { + return fullname; + } + public TypeSpec LookupType (IMemberContext ctx, string name, int arity, LookupMode mode, Location loc) { if (types == null) @@ -343,7 +249,7 @@ namespace Mono.CSharp { return null; foreach (var ts in found) { - if (ts.Arity == arity) { + if (ts.Arity == arity || mode == LookupMode.NameOf) { if (best == null) { if ((ts.Modifiers & Modifiers.INTERNAL) != 0 && !ts.MemberDefinition.IsInternalAsPublic (ctx.Module.DeclaringAssembly) && mode != LookupMode.IgnoreAccessibility) continue; @@ -353,11 +259,20 @@ namespace Mono.CSharp { } if (best.MemberDefinition.IsImported && ts.MemberDefinition.IsImported) { + if (ts.Kind == MemberKind.MissingType) + continue; + + if (best.Kind == MemberKind.MissingType) { + best = ts; + continue; + } + if (mode == LookupMode.Normal) { ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (best); ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ts); ctx.Module.Compiler.Report.Error (433, loc, "The imported type `{0}' is defined multiple times", ts.GetSignatureForError ()); } + break; } @@ -396,6 +311,12 @@ namespace Mono.CSharp { if (arity == 0 && mode == LookupMode.Normal) cached_types.Add (name, best); + if (best != null) { + var dep = best.GetMissingDependencies (); + if (dep != null) + ImportedTypeDefinition.Error_MissingDependency (ctx, dep, loc); + } + return best; } @@ -406,7 +327,7 @@ namespace Mono.CSharp { Namespace ns; if (arity == 0 && namespaces.TryGetValue (name, out ns)) { if (texpr == null) - return ns; + return new NamespaceExpression (ns, loc); if (mode != LookupMode.Probing) { //ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (texpr.Type); @@ -417,7 +338,7 @@ namespace Mono.CSharp { } if (texpr.MemberDefinition.IsImported) - return ns; + return new NamespaceExpression (ns, loc); } if (texpr == null) @@ -567,13 +488,22 @@ namespace Mono.CSharp { public void RemoveContainer (TypeContainer tc) { - types.Remove (tc.Basename); - cached_types.Remove (tc.Basename); - } + IList found; + if (types.TryGetValue (tc.MemberName.Name, out found)) { + for (int i = 0; i < found.Count; ++i) { + if (tc.MemberName.Arity != found [i].Arity) + continue; - public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc) - { - return this; + if (found.Count == 1) + types.Remove (tc.MemberName.Name); + else + found.RemoveAt (i); + + break; + } + } + + cached_types.Remove (tc.MemberName.Basename); } public void SetBuiltinType (BuiltinTypeSpec pts) @@ -642,11 +572,6 @@ namespace Mono.CSharp { "Identifier `{0}' differing only in case is not CLS-compliant", compiled.GetSignatureForError ()); } } - - public override string ToString () - { - return Name; - } } public class CompilationSourceFile : NamespaceContainer @@ -778,6 +703,7 @@ namespace Mono.CSharp { public bool DeclarationFound; Namespace[] namespace_using_table; + TypeSpec[] types_using_table; Dictionary aliases; public NamespaceContainer (MemberName name, NamespaceContainer parent) @@ -878,9 +804,8 @@ namespace Mono.CSharp { public override void AddTypeContainer (TypeContainer tc) { - string name = tc.Basename; - var mn = tc.MemberName; + var name = mn.Basename; while (mn.Left != null) { mn = mn.Left; name = mn.Name; @@ -1026,6 +951,20 @@ namespace Mono.CSharp { candidates.AddRange (a); } + if (types_using_table != null) { + foreach (var t in types_using_table) { + + var res = t.MemberCache.FindExtensionMethods (invocationContext, name, arity); + if (res == null) + continue; + + if (candidates == null) + candidates = res; + else + candidates.AddRange (res); + } + } + if (candidates != null) return new ExtensionMethodCandidates (invocationContext, candidates, this, position); } @@ -1211,6 +1150,42 @@ namespace Mono.CSharp { return match; } + public static MethodGroupExpr LookupStaticUsings (IMemberContext mc, string name, int arity, Location loc) + { + for (var m = mc.CurrentMemberDefinition; m != null; m = m.Parent) { + + var nc = m as NamespaceContainer; + if (nc == null) + continue; + + List candidates = null; + if (nc.types_using_table != null) { + foreach (var using_type in nc.types_using_table) { + var members = MemberCache.FindMembers (using_type, name, true); + if (members != null) { + foreach (var member in members) { + if ((member.Modifiers & Modifiers.METHOD_EXTENSION) != 0) + continue; + + if (arity > 0 && member.Arity != arity) + continue; + + if (candidates == null) + candidates = new List (); + + candidates.Add (member); + } + } + } + } + + if (candidates != null) + return new MethodGroupExpr (candidates, null, loc); + } + + return null; + } + protected override void DefineNamespace () { if (namespace_using_table == null) @@ -1224,7 +1199,9 @@ namespace Mono.CSharp { namespace_using_table = empty_namespaces; if (clauses != null) { - var list = new List (clauses.Count); + List namespaces = null; + List types = null; + bool post_process_using_aliases = false; for (int i = 0; i < clauses.Count; ++i) { @@ -1262,22 +1239,37 @@ namespace Mono.CSharp { continue; } - Namespace using_ns = entry.ResolvedExpression as Namespace; - if (using_ns == null) - continue; + var using_ns = entry.ResolvedExpression as NamespaceExpression; + if (using_ns == null) { - if (list.Contains (using_ns)) { - // Ensure we don't report the warning multiple times in repl - clauses.RemoveAt (i--); + var type = ((TypeExpr)entry.ResolvedExpression).Type; - Compiler.Report.Warning (105, 3, entry.Location, - "The using directive for `{0}' appeared previously in this namespace", using_ns.GetSignatureForError ()); + if (types == null) + types = new List (); + + if (types.Contains (type)) { + Warning_DuplicateEntry (entry); + } else { + types.Add (type); + } } else { - list.Add (using_ns); + if (namespaces == null) + namespaces = new List (); + + if (namespaces.Contains (using_ns.Namespace)) { + // Ensure we don't report the warning multiple times in repl + clauses.RemoveAt (i--); + + Warning_DuplicateEntry (entry); + } else { + namespaces.Add (using_ns.Namespace); + } } } - namespace_using_table = list.ToArray (); + namespace_using_table = namespaces == null ? new Namespace [0] : namespaces.ToArray (); + if (types != null) + types_using_table = types.ToArray (); if (post_process_using_aliases) { for (int i = 0; i < clauses.Count; ++i) { @@ -1334,6 +1326,13 @@ namespace Mono.CSharp { return false; } + void Warning_DuplicateEntry (UsingNamespace entry) + { + Compiler.Report.Warning (105, 3, entry.Location, + "The using directive for `{0}' appeared previously in this namespace", + entry.ResolvedExpression.GetSignatureForError ()); + } + public override void Accept (StructuralVisitor visitor) { visitor.Visit (this); @@ -1387,15 +1386,29 @@ namespace Mono.CSharp { public virtual void Define (NamespaceContainer ctx) { - resolved = expr.ResolveAsTypeOrNamespace (ctx); - var ns = resolved as Namespace; - if (ns == null) { - if (resolved != null) { - ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (resolved.Type); - ctx.Module.Compiler.Report.Error (138, Location, - "`{0}' is a type not a namespace. A using namespace directive can only be applied to namespaces", - GetSignatureForError ()); + resolved = expr.ResolveAsTypeOrNamespace (ctx, false); + var ns = resolved as NamespaceExpression; + if (ns != null) + return; + + if (resolved != null) { + var compiler = ctx.Module.Compiler; + var type = resolved.Type; + if (compiler.Settings.Version >= LanguageVersion.V_6) { + if (!type.IsClass || !type.IsStatic) { + compiler.Report.SymbolRelatedToPreviousError (type); + compiler.Report.Error (7007, Location, + "`{0}' is not a static class. A using namespace directive can only be applied to static classes or namespace", + GetSignatureForError ()); + } + + return; } + + compiler.Report.SymbolRelatedToPreviousError (type); + compiler.Report.Error (138, Location, + "`{0}' is a type not a namespace. A using namespace directive can only be applied to namespaces", + GetSignatureForError ()); } } @@ -1414,12 +1427,15 @@ namespace Mono.CSharp { public override void Define (NamespaceContainer ctx) { - resolved = ctx.Module.GetRootNamespace (Alias.Value); - if (resolved == null) { + var ns = ctx.Module.GetRootNamespace (Alias.Value); + if (ns == null) { ctx.Module.Compiler.Report.Error (430, Location, "The extern alias `{0}' was not specified in -reference option", Alias.Value); + return; } + + resolved = new NamespaceExpression (ns, Location); } } @@ -1548,7 +1564,7 @@ namespace Mono.CSharp { // We achieve that by introducing alias-context which redirect any local // namespace or type resolve calls to parent namespace // - resolved = NamespaceExpression.ResolveAsTypeOrNamespace (new AliasContext (ctx)); + resolved = NamespaceExpression.ResolveAsTypeOrNamespace (new AliasContext (ctx), false); } } }