[mcs] Add NamespaceExpression to avoid problems with error location for misused names...
authorMarek Safar <marek.safar@gmail.com>
Mon, 17 Feb 2014 15:36:55 +0000 (16:36 +0100)
committerMarek Safar <marek.safar@gmail.com>
Mon, 17 Feb 2014 15:37:30 +0000 (16:37 +0100)
mcs/errors/cs0119-10.cs [new file with mode: 0644]
mcs/mcs/complete.cs
mcs/mcs/doc.cs
mcs/mcs/ecore.cs
mcs/mcs/expression.cs
mcs/mcs/namespace.cs

diff --git a/mcs/errors/cs0119-10.cs b/mcs/errors/cs0119-10.cs
new file mode 100644 (file)
index 0000000..7d57947
--- /dev/null
@@ -0,0 +1,10 @@
+// CS0119: Expression denotes a `namespace', where a `variable', `value' or `method group' was expected
+// Line: 8
+
+class X
+{
+       public static void Main ()
+       {
+               System.Collections.Generic ("");
+       }
+}
\ No newline at end of file
index 2931d137f737917aa2fab3e74fe0c6ac1c44b5c2..f66a7bd9fba44bed618ed76e01838f45c1967ee8 100644 (file)
@@ -147,14 +147,14 @@ namespace Mono.CSharp {
                        }
 
                        var results = new List<string> ();
-                       if (expr is Namespace) {
-                               Namespace nexpr = expr as Namespace;
+                       var nexpr = expr as NamespaceExpression;
+                       if (nexpr != null) {
                                string namespaced_partial;
 
                                if (partial_name == null)
-                                       namespaced_partial = nexpr.Name;
+                                       namespaced_partial = nexpr.Namespace.Name;
                                else
-                                       namespaced_partial = nexpr.Name + "." + partial_name;
+                                       namespaced_partial = nexpr.Namespace.Name + "." + partial_name;
 
                                rc.CurrentMemberDefinition.GetCompletionStartingWith (namespaced_partial, results);
                                if (partial_name != null)
index 4abcf6a0ef40a10f85aa879270c0495c22b161f6..34faed55948ff9ed62c7cbf033e06aa6c0653fd8 100644 (file)
@@ -297,7 +297,7 @@ namespace Mono.CSharp
                                return context.LookupNamespaceOrType (mn.Name, mn.Arity, LookupMode.Probing, Location.Null);
 
                        var left = ResolveMemberName (context, mn.Left);
-                       var ns = left as Namespace;
+                       var ns = left as NamespaceExpression;
                        if (ns != null)
                                return ns.LookupTypeOrNamespace (context, mn.Name, mn.Arity, LookupMode.Probing, Location.Null);
 
@@ -383,7 +383,7 @@ namespace Mono.CSharp
                                        } else if (ParsedName.Left != null) {
                                                fne = ResolveMemberName (mc, ParsedName.Left);
                                                if (fne != null) {
-                                                       var ns = fne as Namespace;
+                                                       var ns = fne as NamespaceExpression;
                                                        if (ns != null) {
                                                                fne = ns.LookupTypeOrNamespace (mc, ParsedName.Name, ParsedName.Arity, LookupMode.Probing, Location.Null);
                                                                if (fne != null) {
index 266eeed31c9647bca6726c227d4532041f4663ac..2c7c29db30b698884926887cc7699df7f6aee83c 100644 (file)
@@ -2606,7 +2606,7 @@ namespace Mono.CSharp {
                                //
                                // dynamic namespace is ignored when dynamic is allowed (does not apply to types)
                                //
-                               if (!(fne is Namespace))
+                               if (!(fne is NamespaceExpression))
                                        return fne;
                        }
 
@@ -2984,6 +2984,114 @@ namespace Mono.CSharp {
                }
        }
 
+       public class NamespaceExpression : FullNamedExpression
+       {
+               readonly Namespace ns;
+
+               public NamespaceExpression (Namespace ns, Location loc)
+               {
+                       this.ns = ns;
+                       this.Type = InternalType.Namespace;
+                       this.eclass = ExprClass.Namespace;
+                       this.loc = loc;
+               }
+
+               public Namespace Namespace {
+                       get {
+                               return ns;
+                       }
+               }
+
+               protected override Expression DoResolve (ResolveContext rc)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc)
+               {
+                       return this;
+               }
+
+               public void Error_NamespaceDoesNotExist (IMemberContext ctx, string name, int arity)
+               {
+                       var retval = Namespace.LookupType (ctx, name, arity, LookupMode.IgnoreAccessibility, loc);
+                       if (retval != null) {
+//                             ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (retval.MemberDefinition);
+                               ErrorIsInaccesible (ctx, retval.GetSignatureForError (), loc);
+                               return;
+                       }
+
+                       retval = Namespace.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 && Namespace.TryGetNamespace (name, out ns)) {
+                               Error_TypeArgumentsCannotBeUsed (ctx, ExprClassName, ns.GetSignatureForError (), loc);
+                               return;
+                       }
+
+                       string assembly = null;
+                       string possible_name = Namespace.GetSignatureForError () + "." + 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 (Namespace 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 ns.GetSignatureForError ();
+               }
+
+               public FullNamedExpression LookupTypeOrNamespace (IMemberContext ctx, string name, int arity, LookupMode mode, Location loc)
+               {
+                       return ns.LookupTypeOrNamespace (ctx, name, arity, mode, loc);
+               }
+    }
+
        /// <summary>
        ///   This class denotes an expression which evaluates to a member
        ///   of a struct or a class.
index b8c16a8e4c21b09a0fd0afd2cfc04b9a8d8fa8fa..9b8240d0e82776ca85961ee854536de1d6a05d9e 100644 (file)
@@ -8645,7 +8645,7 @@ namespace Mono.CSharp
                public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext ec)
                {
                        if (alias == GlobalAlias) {
-                               expr = ec.Module.GlobalRootNamespace;
+                               expr = new NamespaceExpression (ec.Module.GlobalRootNamespace, loc);
                                return base.ResolveAsTypeOrNamespace (ec);
                        }
 
@@ -8808,12 +8808,12 @@ namespace Mono.CSharp
                        if (expr == null)
                                return null;
 
-                       Namespace ns = expr as Namespace;
+                       var ns = expr as NamespaceExpression;
                        if (ns != null) {
                                var retval = ns.LookupTypeOrNamespace (rc, Name, Arity, LookupMode.Normal, loc);
 
                                if (retval == null) {
-                                       ns.Error_NamespaceDoesNotExist (rc, Name, Arity, loc);
+                                       ns.Error_NamespaceDoesNotExist (rc, Name, Arity);
                                        return null;
                                }
 
@@ -8948,12 +8948,12 @@ namespace Mono.CSharp
                        if (expr_resolved == null)
                                return null;
 
-                       Namespace ns = expr_resolved as Namespace;
+                       var ns = expr_resolved as NamespaceExpression;
                        if (ns != null) {
                                FullNamedExpression retval = ns.LookupTypeOrNamespace (rc, Name, Arity, LookupMode.Normal, loc);
 
                                if (retval == null) {
-                                       ns.Error_NamespaceDoesNotExist (rc, Name, Arity, loc);
+                                       ns.Error_NamespaceDoesNotExist (rc, Name, Arity);
                                } else if (HasTypeArguments) {
                                        retval = new GenericTypeExpr (retval.Type, targs, loc);
                                        if (retval.ResolveAsType (rc) == null)
index 26db3a4d93d1aab7fb88e2b0d39e353304ff6377..f6031a534d39c5b1a48b228a1b71ca625ce5c881 100644 (file)
@@ -22,9 +22,10 @@ namespace Mono.CSharp {
                readonly Dictionary<string, Namespace> all_namespaces;
 
                public RootNamespace (string alias_name)
-                       : base (null, String.Empty)
+                       : base ()
                {
                        this.alias_name = alias_name;
+                       RegisterNamespace (this);
 
                        all_namespaces = new Dictionary<string, Namespace> ();
                        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<string, Namespace> namespaces;
                protected Dictionary<string, IList<TypeSpec>> types;
                List<TypeSpec> extension_method_types;
                Dictionary<string, TypeSpec> cached_types;
-               RootNamespace root;
                bool cls_checked;
 
-               public readonly MemberName MemberName;
-
                /// <summary>
                ///   Constructor Takes the current namespace and the
                ///   name.  This is bootstrapped with parent == null
                ///   and name = ""
                /// </summary>
                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<string, Namespace> ();
                        cached_types = new Dictionary<string, TypeSpec> ();
-
-                       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)
@@ -415,7 +321,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);
@@ -426,7 +332,7 @@ namespace Mono.CSharp {
                                }
 
                                if (texpr.MemberDefinition.IsImported)
-                                       return ns;
+                                       return new NamespaceExpression (ns, loc);
                        }
 
                        if (texpr == null)
@@ -580,11 +486,6 @@ namespace Mono.CSharp {
                        cached_types.Remove (tc.Basename);
                }
 
-               public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc)
-               {
-                       return this;
-               }
-
                public void SetBuiltinType (BuiltinTypeSpec pts)
                {
                        var found = types[pts.Name];
@@ -651,11 +552,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
@@ -1271,18 +1167,18 @@ namespace Mono.CSharp {
                                                continue;
                                        }
 
-                                       Namespace using_ns = entry.ResolvedExpression as Namespace;
+                                       var using_ns = entry.ResolvedExpression as NamespaceExpression;
                                        if (using_ns == null)
                                                continue;
 
-                                       if (list.Contains (using_ns)) {
+                                       if (list.Contains (using_ns.Namespace)) {
                                                // Ensure we don't report the warning multiple times in repl
                                                clauses.RemoveAt (i--);
 
                                                Compiler.Report.Warning (105, 3, entry.Location,
                                                        "The using directive for `{0}' appeared previously in this namespace", using_ns.GetSignatureForError ());
                                        } else {
-                                               list.Add (using_ns);
+                                               list.Add (using_ns.Namespace);
                                        }
                                }
 
@@ -1397,7 +1293,7 @@ namespace Mono.CSharp {
                public virtual void Define (NamespaceContainer ctx)
                {
                        resolved = expr.ResolveAsTypeOrNamespace (ctx);
-                       var ns = resolved as Namespace;
+                       var ns = resolved as NamespaceExpression;
                        if (ns == null) {
                                if (resolved != null) {
                                        ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (resolved.Type);
@@ -1423,12 +1319,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);
                }
        }