Merge pull request #818 from hanswolff/patch-1
[mono.git] / mcs / mcs / namespace.cs
1 //
2 // namespace.cs: Tracks namespaces
3 //
4 // Author:
5 //   Miguel de Icaza (miguel@ximian.com)
6 //   Marek Safar (marek.safar@seznam.cz)
7 //
8 // Copyright 2001 Ximian, Inc.
9 // Copyright 2003-2008 Novell, Inc.
10 // Copyright 2011 Xamarin Inc
11 //
12 using System;
13 using System.Collections.Generic;
14 using System.Linq;
15 using Mono.CompilerServices.SymbolWriter;
16
17 namespace Mono.CSharp {
18
19         public class RootNamespace : Namespace {
20
21                 readonly string alias_name;
22                 readonly Dictionary<string, Namespace> all_namespaces;
23
24                 public RootNamespace (string alias_name)
25                         : base (null, String.Empty)
26                 {
27                         this.alias_name = alias_name;
28
29                         all_namespaces = new Dictionary<string, Namespace> ();
30                         all_namespaces.Add ("", this);
31                 }
32
33                 public string Alias {
34                         get {
35                                 return alias_name;
36                         }
37                 }
38
39                 public static void Error_GlobalNamespaceRedefined (Report report, Location loc)
40                 {
41                         report.Error (1681, loc, "The global extern alias cannot be redefined");
42                 }
43
44                 //
45                 // For better error reporting where we try to guess missing using directive
46                 //
47                 public List<string> FindTypeNamespaces (IMemberContext ctx, string name, int arity)
48                 {
49                         List<string> res = null;
50
51                         foreach (var ns in all_namespaces) {
52                                 var type = ns.Value.LookupType (ctx, name, arity, LookupMode.Normal, Location.Null);
53                                 if (type != null) {
54                                         if (res == null)
55                                                 res = new List<string> ();
56
57                                         res.Add (ns.Key);
58                                 }
59                         }
60
61                         return res;
62                 }
63
64                 //
65                 // For better error reporting where compiler tries to guess missing using directive
66                 //
67                 public List<string> FindExtensionMethodNamespaces (IMemberContext ctx, string name, int arity)
68                 {
69                         List<string> res = null;
70
71                         foreach (var ns in all_namespaces) {
72                                 var methods = ns.Value.LookupExtensionMethod (ctx, name, arity);
73                                 if (methods != null) {
74                                         if (res == null)
75                                                 res = new List<string> ();
76
77                                         res.Add (ns.Key);
78                                 }
79                         }
80
81                         return res;
82                 }
83
84                 public void RegisterNamespace (Namespace child)
85                 {
86                         if (child != this)
87                                 all_namespaces.Add (child.Name, child);
88                 }
89
90                 public bool IsNamespace (string name)
91                 {
92                         return all_namespaces.ContainsKey (name);
93                 }
94
95                 protected void RegisterNamespace (string dotted_name)
96                 {
97                         if (dotted_name != null && dotted_name.Length != 0 && ! IsNamespace (dotted_name))
98                                 GetNamespace (dotted_name, true);
99                 }
100
101                 public override string GetSignatureForError ()
102                 {
103                         return alias_name + "::";
104                 }
105         }
106
107         public class GlobalRootNamespace : RootNamespace
108         {
109                 public GlobalRootNamespace ()
110                         : base ("global")
111                 {
112                 }
113         }
114
115         //
116         // Namespace cache for imported and compiled namespaces
117         //
118         // This is an Expression to allow it to be referenced in the
119         // compiler parse/intermediate tree during name resolution.
120         //
121         public class Namespace : FullNamedExpression
122         {
123                 Namespace parent;
124                 string fullname;
125                 protected Dictionary<string, Namespace> namespaces;
126                 protected Dictionary<string, IList<TypeSpec>> types;
127                 List<TypeSpec> extension_method_types;
128                 Dictionary<string, TypeSpec> cached_types;
129                 RootNamespace root;
130                 bool cls_checked;
131
132                 public readonly MemberName MemberName;
133
134                 /// <summary>
135                 ///   Constructor Takes the current namespace and the
136                 ///   name.  This is bootstrapped with parent == null
137                 ///   and name = ""
138                 /// </summary>
139                 public Namespace (Namespace parent, string name)
140                 {
141                         // Expression members.
142                         this.eclass = ExprClass.Namespace;
143                         this.Type = InternalType.Namespace;
144                         this.loc = Location.Null;
145
146                         this.parent = parent;
147
148                         if (parent != null)
149                                 this.root = parent.root;
150                         else
151                                 this.root = this as RootNamespace;
152
153                         if (this.root == null)
154                                 throw new InternalErrorException ("Root namespaces must be created using RootNamespace");
155                         
156                         string pname = parent != null ? parent.fullname : "";
157                                 
158                         if (pname == "")
159                                 fullname = name;
160                         else
161                                 fullname = parent.fullname + "." + name;
162
163                         if (fullname == null)
164                                 throw new InternalErrorException ("Namespace has a null fullname");
165
166                         if (parent != null && parent.MemberName != MemberName.Null)
167                                 MemberName = new MemberName (parent.MemberName, name, Location.Null);
168                         else if (name.Length == 0)
169                                 MemberName = MemberName.Null;
170                         else
171                                 MemberName = new MemberName (name, Location.Null);
172
173                         namespaces = new Dictionary<string, Namespace> ();
174                         cached_types = new Dictionary<string, TypeSpec> ();
175
176                         root.RegisterNamespace (this);
177                 }
178
179                 #region Properties
180
181                 /// <summary>
182                 ///   The qualified name of the current namespace
183                 /// </summary>
184                 public string Name {
185                         get { return fullname; }
186                 }
187
188                 /// <summary>
189                 ///   The parent of this namespace, used by the parser to "Pop"
190                 ///   the current namespace declaration
191                 /// </summary>
192                 public Namespace Parent {
193                         get { return parent; }
194                 }
195
196                 #endregion
197
198                 protected override Expression DoResolve (ResolveContext ec)
199                 {
200                         return this;
201                 }
202
203                 public void Error_NamespaceDoesNotExist (IMemberContext ctx, string name, int arity, Location loc)
204                 {
205                         var retval = LookupType (ctx, name, arity, LookupMode.IgnoreAccessibility, loc);
206                         if (retval != null) {
207 //                              ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (retval.MemberDefinition);
208                                 ErrorIsInaccesible (ctx, retval.GetSignatureForError (), loc);
209                                 return;
210                         }
211
212                         retval = LookupType (ctx, name, -System.Math.Max (1, arity), LookupMode.Probing, loc);
213                         if (retval != null) {
214                                 Error_TypeArgumentsCannotBeUsed (ctx, retval, loc);
215                                 return;
216                         }
217
218                         Namespace ns;
219                         if (arity > 0 && namespaces.TryGetValue (name, out ns)) {
220                                 ns.Error_TypeArgumentsCannotBeUsed (ctx, null, loc);
221                                 return;
222                         }
223
224                         string assembly = null;
225                         string possible_name = fullname + "." + name;
226
227                         // Only assembly unique name should be added
228                         switch (possible_name) {
229                         case "System.Drawing":
230                         case "System.Web.Services":
231                         case "System.Web":
232                         case "System.Data":
233                         case "System.Configuration":
234                         case "System.Data.Services":
235                         case "System.DirectoryServices":
236                         case "System.Json":
237                         case "System.Net.Http":
238                         case "System.Numerics":
239                         case "System.Runtime.Caching":
240                         case "System.ServiceModel":
241                         case "System.Transactions":
242                         case "System.Web.Routing":
243                         case "System.Xml.Linq":
244                         case "System.Xml":
245                                 assembly = possible_name;
246                                 break;
247
248                         case "System.Linq":
249                         case "System.Linq.Expressions":
250                                 assembly = "System.Core";
251                                 break;
252
253                         case "System.Windows.Forms":
254                         case "System.Windows.Forms.Layout":
255                                 assembly = "System.Windows.Forms";
256                                 break;
257                         }
258
259                         assembly = assembly == null ? "an" : "`" + assembly + "'";
260
261                         if (this is GlobalRootNamespace) {
262                                 ctx.Module.Compiler.Report.Error (400, loc,
263                                         "The type or namespace name `{0}' could not be found in the global namespace. Are you missing {1} assembly reference?",
264                                         name, assembly);
265                         } else {
266                                 ctx.Module.Compiler.Report.Error (234, loc,
267                                         "The type or namespace name `{0}' does not exist in the namespace `{1}'. Are you missing {2} assembly reference?",
268                                         name, GetSignatureForError (), assembly);
269                         }
270                 }
271
272                 public override string GetSignatureForError ()
273                 {
274                         return fullname;
275                 }
276
277                 public Namespace AddNamespace (MemberName name)
278                 {
279                         var ns_parent = name.Left == null ? this : AddNamespace (name.Left);
280                         return ns_parent.TryAddNamespace (name.Basename);
281                 }
282
283                 Namespace TryAddNamespace (string name)
284                 {
285                         Namespace ns;
286
287                         if (!namespaces.TryGetValue (name, out ns)) {
288                                 ns = new Namespace (this, name);
289                                 namespaces.Add (name, ns);
290                         }
291
292                         return ns;
293                 }
294
295                 // TODO: Replace with CreateNamespace where MemberName is created for the method call
296                 public Namespace GetNamespace (string name, bool create)
297                 {
298                         int pos = name.IndexOf ('.');
299
300                         Namespace ns;
301                         string first;
302                         if (pos >= 0)
303                                 first = name.Substring (0, pos);
304                         else
305                                 first = name;
306
307                         if (!namespaces.TryGetValue (first, out ns)) {
308                                 if (!create)
309                                         return null;
310
311                                 ns = new Namespace (this, first);
312                                 namespaces.Add (first, ns);
313                         }
314
315                         if (pos >= 0)
316                                 ns = ns.GetNamespace (name.Substring (pos + 1), create);
317
318                         return ns;
319                 }
320
321                 public IList<TypeSpec> GetAllTypes (string name)
322                 {
323                         IList<TypeSpec> found;
324                         if (types == null || !types.TryGetValue (name, out found))
325                                 return null;
326
327                         return found;
328                 }
329
330                 public TypeSpec LookupType (IMemberContext ctx, string name, int arity, LookupMode mode, Location loc)
331                 {
332                         if (types == null)
333                                 return null;
334
335                         TypeSpec best = null;
336                         if (arity == 0 && cached_types.TryGetValue (name, out best)) {
337                                 if (best != null || mode != LookupMode.IgnoreAccessibility)
338                                         return best;
339                         }
340
341                         IList<TypeSpec> found;
342                         if (!types.TryGetValue (name, out found))
343                                 return null;
344
345                         foreach (var ts in found) {
346                                 if (ts.Arity == arity) {
347                                         if (best == null) {
348                                                 if ((ts.Modifiers & Modifiers.INTERNAL) != 0 && !ts.MemberDefinition.IsInternalAsPublic (ctx.Module.DeclaringAssembly) && mode != LookupMode.IgnoreAccessibility)
349                                                         continue;
350
351                                                 best = ts;
352                                                 continue;
353                                         }
354
355                                         if (best.MemberDefinition.IsImported && ts.MemberDefinition.IsImported) {
356                                                 if (ts.Kind == MemberKind.MissingType)
357                                                         continue;
358
359                                                 if (best.Kind == MemberKind.MissingType) {
360                                                         best = ts;
361                                                         continue;
362                                                 }
363
364                                                 if (mode == LookupMode.Normal) {
365                                                         ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (best);
366                                                         ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ts);
367                                                         ctx.Module.Compiler.Report.Error (433, loc, "The imported type `{0}' is defined multiple times", ts.GetSignatureForError ());
368                                                 }
369
370                                                 break;
371                                         }
372
373                                         if (best.MemberDefinition.IsImported)
374                                                 best = ts;
375
376                                         if ((best.Modifiers & Modifiers.INTERNAL) != 0 && !best.MemberDefinition.IsInternalAsPublic (ctx.Module.DeclaringAssembly))
377                                                 continue;
378
379                                         if (mode != LookupMode.Normal)
380                                                 continue;
381
382                                         if (ts.MemberDefinition.IsImported) {
383                                                 ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (best);
384                                                 ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ts);
385                                         }
386
387                                         ctx.Module.Compiler.Report.Warning (436, 2, loc,
388                                                 "The type `{0}' conflicts with the imported type of same name'. Ignoring the imported type definition",
389                                                 best.GetSignatureForError ());
390                                 }
391
392                                 //
393                                 // Lookup for the best candidate with the closest arity match
394                                 //
395                                 if (arity < 0) {
396                                         if (best == null) {
397                                                 best = ts;
398                                         } else if (System.Math.Abs (ts.Arity + arity) < System.Math.Abs (best.Arity + arity)) {
399                                                 best = ts;
400                                         }
401                                 }
402                         }
403
404                         // TODO MemberCache: Cache more
405                         if (arity == 0 && mode == LookupMode.Normal)
406                                 cached_types.Add (name, best);
407
408                         return best;
409                 }
410
411                 public FullNamedExpression LookupTypeOrNamespace (IMemberContext ctx, string name, int arity, LookupMode mode, Location loc)
412                 {
413                         var texpr = LookupType (ctx, name, arity, mode, loc);
414
415                         Namespace ns;
416                         if (arity == 0 && namespaces.TryGetValue (name, out ns)) {
417                                 if (texpr == null)
418                                         return ns;
419
420                                 if (mode != LookupMode.Probing) {
421                                         //ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (texpr.Type);
422                                         // ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ns.loc, "");
423                                         ctx.Module.Compiler.Report.Warning (437, 2, loc,
424                                                 "The type `{0}' conflicts with the imported namespace `{1}'. Using the definition found in the source file",
425                                                 texpr.GetSignatureForError (), ns.GetSignatureForError ());
426                                 }
427
428                                 if (texpr.MemberDefinition.IsImported)
429                                         return ns;
430                         }
431
432                         if (texpr == null)
433                                 return null;
434
435                         return new TypeExpression (texpr, loc);
436                 }
437
438                 //
439                 // Completes types with the given `prefix'
440                 //
441                 public IEnumerable<string> CompletionGetTypesStartingWith (string prefix)
442                 {
443                         if (types == null)
444                                 return Enumerable.Empty<string> ();
445
446                         var res = from item in types
447                                           where item.Key.StartsWith (prefix) && item.Value.Any (l => (l.Modifiers & Modifiers.PUBLIC) != 0)
448                                           select item.Key;
449
450                         if (namespaces != null)
451                                 res = res.Concat (from item in namespaces where item.Key.StartsWith (prefix) select item.Key);
452
453                         return res;
454                 }
455
456                 // 
457                 // Looks for extension method in this namespace
458                 //
459                 public List<MethodSpec> LookupExtensionMethod (IMemberContext invocationContext, string name, int arity)
460                 {
461                         if (extension_method_types == null)
462                                 return null;
463
464                         List<MethodSpec> found = null;
465                         for (int i = 0; i < extension_method_types.Count; ++i) {
466                                 var ts = extension_method_types[i];
467
468                                 //
469                                 // When the list was built we didn't know what members the type
470                                 // contains
471                                 //
472                                 if ((ts.Modifiers & Modifiers.METHOD_EXTENSION) == 0) {
473                                         if (extension_method_types.Count == 1) {
474                                                 extension_method_types = null;
475                                                 return found;
476                                         }
477
478                                         extension_method_types.RemoveAt (i--);
479                                         continue;
480                                 }
481
482                                 var res = ts.MemberCache.FindExtensionMethods (invocationContext, name, arity);
483                                 if (res == null)
484                                         continue;
485
486                                 if (found == null) {
487                                         found = res;
488                                 } else {
489                                         found.AddRange (res);
490                                 }
491                         }
492
493                         return found;
494                 }
495
496                 public void AddType (ModuleContainer module, TypeSpec ts)
497                 {
498                         if (types == null) {
499                                 types = new Dictionary<string, IList<TypeSpec>> (64);
500                         }
501
502                         if (ts.IsClass && ts.Arity == 0) {
503                                 var extension_method_allowed = ts.MemberDefinition.IsImported ? (ts.Modifiers & Modifiers.METHOD_EXTENSION) != 0 : (ts.IsStatic || ts.MemberDefinition.IsPartial);
504                                 if (extension_method_allowed) {
505                                         if (extension_method_types == null)
506                                                 extension_method_types = new List<TypeSpec> ();
507
508                                         extension_method_types.Add (ts);
509                                 }
510                         }
511
512                         var name = ts.Name;
513                         IList<TypeSpec> existing;
514                         if (types.TryGetValue (name, out existing)) {
515                                 TypeSpec better_type;
516                                 TypeSpec found;
517                                 if (existing.Count == 1) {
518                                         found = existing[0];
519                                         if (ts.Arity == found.Arity) {
520                                                 better_type = IsImportedTypeOverride (module, ts, found);
521                                                 if (better_type == found)
522                                                         return;
523
524                                                 if (better_type != null) {
525                                                         existing [0] = better_type;
526                                                         return;
527                                                 }
528                                         }
529
530                                         existing = new List<TypeSpec> ();
531                                         existing.Add (found);
532                                         types[name] = existing;
533                                 } else {
534                                         for (int i = 0; i < existing.Count; ++i) {
535                                                 found = existing[i];
536                                                 if (ts.Arity != found.Arity)
537                                                         continue;
538
539                                                 better_type = IsImportedTypeOverride (module, ts, found);
540                                                 if (better_type == found)
541                                                         return;
542
543                                                 if (better_type != null) {
544                                                         existing.RemoveAt (i);
545                                                         --i;
546                                                         continue;
547                                                 }
548                                         }
549                                 }
550
551                                 existing.Add (ts);
552                         } else {
553                                 types.Add (name, new TypeSpec[] { ts });
554                         }
555                 }
556
557                 //
558                 // We import any types but in the situation there are same types
559                 // but one has better visibility (either public or internal with friend)
560                 // the less visible type is removed from the namespace cache
561                 //
562                 public static TypeSpec IsImportedTypeOverride (ModuleContainer module, TypeSpec ts, TypeSpec found)
563                 {
564                         var ts_accessible = (ts.Modifiers & Modifiers.PUBLIC) != 0 || ts.MemberDefinition.IsInternalAsPublic (module.DeclaringAssembly);
565                         var found_accessible = (found.Modifiers & Modifiers.PUBLIC) != 0 || found.MemberDefinition.IsInternalAsPublic (module.DeclaringAssembly);
566
567                         if (ts_accessible && !found_accessible)
568                                 return ts;
569
570                         // found is better always better for accessible or inaccessible ts
571                         if (!ts_accessible)
572                                 return found;
573
574                         return null;
575                 }
576
577                 public void RemoveContainer (TypeContainer tc)
578                 {
579                         types.Remove (tc.Basename);
580                         cached_types.Remove (tc.Basename);
581                 }
582
583                 public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc)
584                 {
585                         return this;
586                 }
587
588                 public void SetBuiltinType (BuiltinTypeSpec pts)
589                 {
590                         var found = types[pts.Name];
591                         cached_types.Remove (pts.Name);
592                         if (found.Count == 1) {
593                                 types[pts.Name][0] = pts;
594                         } else {
595                                 throw new NotImplementedException ();
596                         }
597                 }
598
599                 public void VerifyClsCompliance ()
600                 {
601                         if (types == null || cls_checked)
602                                 return;
603
604                         cls_checked = true;
605
606                         // TODO: This is quite ugly way to check for CLS compliance at namespace level
607
608                         var locase_types = new Dictionary<string, List<TypeSpec>> (StringComparer.OrdinalIgnoreCase);
609                         foreach (var tgroup in types.Values) {
610                                 foreach (var tm in tgroup) {
611                                         if ((tm.Modifiers & Modifiers.PUBLIC) == 0 || !tm.IsCLSCompliant ())
612                                                 continue;
613
614                                         List<TypeSpec> found;
615                                         if (!locase_types.TryGetValue (tm.Name, out found)) {
616                                                 found = new List<TypeSpec> ();
617                                                 locase_types.Add (tm.Name, found);
618                                         }
619
620                                         found.Add (tm);
621                                 }
622                         }
623
624                         foreach (var locase in locase_types.Values) {
625                                 if (locase.Count < 2)
626                                         continue;
627
628                                 bool all_same = true;
629                                 foreach (var notcompliant in locase) {
630                                         all_same = notcompliant.Name == locase[0].Name;
631                                         if (!all_same)
632                                                 break;
633                                 }
634
635                                 if (all_same)
636                                         continue;
637
638                                 TypeContainer compiled = null;
639                                 foreach (var notcompliant in locase) {
640                                         if (!notcompliant.MemberDefinition.IsImported) {
641                                                 if (compiled != null)
642                                                         compiled.Compiler.Report.SymbolRelatedToPreviousError (compiled);
643
644                                                 compiled = notcompliant.MemberDefinition as TypeContainer;
645                                         } else {
646                                                 compiled.Compiler.Report.SymbolRelatedToPreviousError (notcompliant);
647                                         }
648                                 }
649
650                                 compiled.Compiler.Report.Warning (3005, 1, compiled.Location,
651                                         "Identifier `{0}' differing only in case is not CLS-compliant", compiled.GetSignatureForError ());
652                         }
653                 }
654
655                 public override string ToString ()
656                 {
657                         return Name;
658                 }
659         }
660
661         public class CompilationSourceFile : NamespaceContainer
662         {
663                 readonly SourceFile file;
664                 CompileUnitEntry comp_unit;
665                 Dictionary<string, SourceFile> include_files;
666                 Dictionary<string, bool> conditionals;
667
668                 public CompilationSourceFile (ModuleContainer parent, SourceFile sourceFile)
669                         : this (parent)
670                 {
671                         this.file = sourceFile;
672                 }
673
674                 public CompilationSourceFile (ModuleContainer parent)
675                         : base (parent)
676                 {
677                 }
678
679                 public CompileUnitEntry SymbolUnitEntry {
680                         get {
681                                 return comp_unit;
682                         }
683                 }
684
685                 public string FileName {
686                         get {
687                                 return file.Name;
688                         }
689                 }
690
691                 public SourceFile SourceFile {
692                         get {
693                                 return file;
694                         }
695                 }
696
697                 public void AddIncludeFile (SourceFile file)
698                 {
699                         if (file == this.file)
700                                 return;
701
702                         if (include_files == null)
703                                 include_files = new Dictionary<string, SourceFile> ();
704
705                         if (!include_files.ContainsKey (file.FullPathName))
706                                 include_files.Add (file.FullPathName, file);
707                 }
708
709                 public void AddDefine (string value)
710                 {
711                         if (conditionals == null)
712                                 conditionals = new Dictionary<string, bool> (2);
713
714                         conditionals[value] = true;
715                 }
716
717                 public void AddUndefine (string value)
718                 {
719                         if (conditionals == null)
720                                 conditionals = new Dictionary<string, bool> (2);
721
722                         conditionals[value] = false;
723                 }
724
725                 public override void PrepareEmit ()
726                 {
727                         var sw = Module.DeclaringAssembly.SymbolWriter;
728                         if (sw != null) {
729                                 CreateUnitSymbolInfo (sw);
730                         }
731
732                         base.PrepareEmit ();
733                 }
734
735                 //
736                 // Creates symbol file index in debug symbol file
737                 //
738                 void CreateUnitSymbolInfo (MonoSymbolFile symwriter)
739                 {
740                         var si = file.CreateSymbolInfo (symwriter);
741                         comp_unit = new CompileUnitEntry (symwriter, si);
742
743                         if (include_files != null) {
744                                 foreach (SourceFile include in include_files.Values) {
745                                         si = include.CreateSymbolInfo (symwriter);
746                                         comp_unit.AddFile (si);
747                                 }
748                         }
749                 }
750
751                 public bool IsConditionalDefined (string value)
752                 {
753                         if (conditionals != null) {
754                                 bool res;
755                                 if (conditionals.TryGetValue (value, out res))
756                                         return res;
757
758                                 // When conditional was undefined
759                                 if (conditionals.ContainsKey (value))
760                                         return false;
761                         }
762
763                         return Compiler.Settings.IsConditionalSymbolDefined (value);
764                 }
765
766                 public override void Accept (StructuralVisitor visitor)
767                 {
768                         visitor.Visit (this);
769                 }
770         }
771
772
773         //
774         // Namespace block as created by the parser
775         //
776         public class NamespaceContainer : TypeContainer, IMemberContext
777         {
778                 static readonly Namespace[] empty_namespaces = new Namespace[0];
779
780                 readonly Namespace ns;
781
782                 public new readonly NamespaceContainer Parent;
783
784                 List<UsingNamespace> clauses;
785
786                 // Used by parsed to check for parser errors
787                 public bool DeclarationFound;
788
789                 Namespace[] namespace_using_table;
790                 Dictionary<string, UsingAliasNamespace> aliases;
791
792                 public NamespaceContainer (MemberName name, NamespaceContainer parent)
793                         : base (parent, name, null, MemberKind.Namespace)
794                 {
795                         this.Parent = parent;
796                         this.ns = parent.NS.AddNamespace (name);
797
798                         containers = new List<TypeContainer> ();
799                 }
800
801                 protected NamespaceContainer (ModuleContainer parent)
802                         : base (parent, null, null, MemberKind.Namespace)
803                 {
804                         ns = parent.GlobalRootNamespace;
805                         containers = new List<TypeContainer> (2);
806                 }
807
808                 #region Properties
809
810                 public override AttributeTargets AttributeTargets {
811                         get {
812                                 throw new NotSupportedException ();
813                         }
814                 }
815
816                 public override string DocCommentHeader {
817                         get {
818                                 throw new NotSupportedException ();
819                         }
820                 }
821
822                 public Namespace NS {
823                         get {
824                                 return ns;
825                         }
826                 }
827
828                 public List<UsingNamespace> Usings {
829                         get {
830                                 return clauses;
831                         }
832                 }
833
834                 public override string[] ValidAttributeTargets {
835                         get {
836                                 throw new NotSupportedException ();
837                         }
838                 }
839
840                 #endregion
841
842                 public void AddUsing (UsingNamespace un)
843                 {
844                         if (DeclarationFound){
845                                 Compiler.Report.Error (1529, un.Location, "A using clause must precede all other namespace elements except extern alias declarations");
846                         }
847
848                         if (clauses == null)
849                                 clauses = new List<UsingNamespace> ();
850
851                         clauses.Add (un);
852                 }
853
854                 public void AddUsing (UsingAliasNamespace un)
855                 {
856                         if (DeclarationFound){
857                                 Compiler.Report.Error (1529, un.Location, "A using clause must precede all other namespace elements except extern alias declarations");
858                         }
859
860                         AddAlias (un);
861                 }
862
863                 void AddAlias (UsingAliasNamespace un)
864                 {
865                         if (clauses == null) {
866                                 clauses = new List<UsingNamespace> ();
867                         } else {
868                                 foreach (var entry in clauses) {
869                                         var a = entry as UsingAliasNamespace;
870                                         if (a != null && a.Alias.Value == un.Alias.Value) {
871                                                 Compiler.Report.SymbolRelatedToPreviousError (a.Location, "");
872                                                 Compiler.Report.Error (1537, un.Location,
873                                                         "The using alias `{0}' appeared previously in this namespace", un.Alias.Value);
874                                         }
875                                 }
876                         }
877
878                         clauses.Add (un);
879                 }
880
881                 public override void AddPartial (TypeDefinition next_part)
882                 {
883                         var existing = ns.LookupType (this, next_part.MemberName.Name, next_part.MemberName.Arity, LookupMode.Probing, Location.Null);
884                         var td = existing != null ? existing.MemberDefinition as TypeDefinition : null;
885                         AddPartial (next_part, td);
886                 }
887
888                 public override void AddTypeContainer (TypeContainer tc)
889                 {
890                         string name = tc.Basename;
891
892                         var mn = tc.MemberName;
893                         while (mn.Left != null) {
894                                 mn = mn.Left;
895                                 name = mn.Name;
896                         }
897
898                         var names_container = Parent == null ? Module : (TypeContainer) this;
899
900                         MemberCore mc;
901                         if (names_container.DefinedNames.TryGetValue (name, out mc)) {
902                                 if (tc is NamespaceContainer && mc is NamespaceContainer) {
903                                         AddTypeContainerMember (tc);
904                                         return;
905                                 }
906
907                                 Report.SymbolRelatedToPreviousError (mc);
908                                 if ((mc.ModFlags & Modifiers.PARTIAL) != 0 && (tc is ClassOrStruct || tc is Interface)) {
909                                         Error_MissingPartialModifier (tc);
910                                 } else {
911                                         Report.Error (101, tc.Location, "The namespace `{0}' already contains a definition for `{1}'",
912                                                 GetSignatureForError (), mn.GetSignatureForError ());
913                                 }
914                         } else {
915                                 names_container.DefinedNames.Add (name, tc);
916
917                                 var tdef = tc.PartialContainer;
918                                 if (tdef != null) {
919                                         //
920                                         // Same name conflict in different namespace containers
921                                         //
922                                         var conflict = ns.GetAllTypes (name);
923                                         if (conflict != null) {
924                                                 foreach (var e in conflict) {
925                                                         if (e.Arity == mn.Arity) {
926                                                                 mc = (MemberCore) e.MemberDefinition;
927                                                                 break;
928                                                         }
929                                                 }
930                                         }
931
932                                         if (mc != null) {
933                                                 Report.SymbolRelatedToPreviousError (mc);
934                                                 Report.Error (101, tc.Location, "The namespace `{0}' already contains a definition for `{1}'",
935                                                         GetSignatureForError (), mn.GetSignatureForError ());
936                                         } else {
937                                                 ns.AddType (Module, tdef.Definition);
938                                         }
939                                 }
940                         }
941
942                         base.AddTypeContainer (tc);
943                 }
944
945                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
946                 {
947                         throw new NotSupportedException ();
948                 }
949
950                 public override void EmitContainer ()
951                 {
952                         VerifyClsCompliance ();
953
954                         base.EmitContainer ();
955                 }
956
957                 public ExtensionMethodCandidates LookupExtensionMethod (IMemberContext invocationContext, TypeSpec extensionType, string name, int arity, int position)
958                 {
959                         //
960                         // Here we try to resume the search for extension method at the point
961                         // where the last bunch of candidates was found. It's more tricky than
962                         // it seems as we have to check both namespace containers and namespace
963                         // in correct order.
964                         //
965                         // Consider:
966                         // 
967                         // namespace A {
968                         //      using N1;
969                         //  namespace B.C.D {
970                         //              <our first search found candidates in A.B.C.D
971                         //  }
972                         // }
973                         //
974                         // In the example above namespace A.B.C.D, A.B.C and A.B have to be
975                         // checked before we hit A.N1 using
976                         //
977                         ExtensionMethodCandidates candidates;
978                         var container = this;
979                         do {
980                                 candidates = container.LookupExtensionMethodCandidates (invocationContext, name, arity, ref position);
981                                 if (candidates != null || container.MemberName == null)
982                                         return candidates;
983
984                                 var container_ns = container.ns.Parent;
985                                 var mn = container.MemberName.Left;
986                                 int already_checked = position - 2;
987                                 while (already_checked-- > 0) {
988                                         mn = mn.Left;
989                                         container_ns = container_ns.Parent;
990                                 }
991
992                                 while (mn != null) {
993                                         ++position;
994
995                                         var methods = container_ns.LookupExtensionMethod (invocationContext, name, arity);
996                                         if (methods != null) {
997                                                 return new ExtensionMethodCandidates (invocationContext, methods, container, position);
998                                         }
999
1000                                         mn = mn.Left;
1001                                         container_ns = container_ns.Parent;
1002                                 }
1003
1004                                 position = 0;
1005                                 container = container.Parent;
1006                         } while (container != null);
1007
1008                         return null;
1009                 }
1010
1011                 ExtensionMethodCandidates LookupExtensionMethodCandidates (IMemberContext invocationContext, string name, int arity, ref int position)
1012                 {
1013                         List<MethodSpec> candidates = null;
1014
1015                         if (position == 0) {
1016                                 ++position;
1017
1018                                 candidates = ns.LookupExtensionMethod (invocationContext, name, arity);
1019                                 if (candidates != null) {
1020                                         return new ExtensionMethodCandidates (invocationContext, candidates, this, position);
1021                                 }
1022                         }
1023
1024                         if (position == 1) {
1025                                 ++position;
1026
1027                                 foreach (Namespace n in namespace_using_table) {
1028                                         var a = n.LookupExtensionMethod (invocationContext, name, arity);
1029                                         if (a == null)
1030                                                 continue;
1031
1032                                         if (candidates == null)
1033                                                 candidates = a;
1034                                         else
1035                                                 candidates.AddRange (a);
1036                                 }
1037
1038                                 if (candidates != null)
1039                                         return new ExtensionMethodCandidates (invocationContext, candidates, this, position);
1040                         }
1041
1042                         return null;
1043                 }
1044
1045                 public override FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
1046                 {
1047                         //
1048                         // Only simple names (no dots) will be looked up with this function
1049                         //
1050                         FullNamedExpression resolved;
1051                         for (NamespaceContainer container = this; container != null; container = container.Parent) {
1052                                 resolved = container.Lookup (name, arity, mode, loc);
1053                                 if (resolved != null || container.MemberName == null)
1054                                         return resolved;
1055
1056                                 var container_ns = container.ns.Parent;
1057                                 var mn = container.MemberName.Left;
1058                                 while (mn != null) {
1059                                         resolved = container_ns.LookupTypeOrNamespace (this, name, arity, mode, loc);
1060                                         if (resolved != null)
1061                                                 return resolved;
1062
1063                                         mn = mn.Left;
1064                                         container_ns = container_ns.Parent;
1065                                 }
1066                         }
1067
1068                         return null;
1069                 }
1070
1071                 public override void GetCompletionStartingWith (string prefix, List<string> results)
1072                 {
1073                         if (Usings == null)
1074                                 return;
1075
1076                         foreach (var un in Usings) {
1077                                 if (un.Alias != null)
1078                                         continue;
1079
1080                                 var name = un.NamespaceExpression.Name;
1081                                 if (name.StartsWith (prefix))
1082                                         results.Add (name);
1083                         }
1084
1085
1086                         IEnumerable<string> all = Enumerable.Empty<string> ();
1087
1088                         foreach (Namespace using_ns in namespace_using_table) {
1089                                 if (prefix.StartsWith (using_ns.Name)) {
1090                                         int ld = prefix.LastIndexOf ('.');
1091                                         if (ld != -1) {
1092                                                 string rest = prefix.Substring (ld + 1);
1093
1094                                                 all = all.Concat (using_ns.CompletionGetTypesStartingWith (rest));
1095                                         }
1096                                 }
1097                                 all = all.Concat (using_ns.CompletionGetTypesStartingWith (prefix));
1098                         }
1099
1100                         results.AddRange (all);
1101
1102                         base.GetCompletionStartingWith (prefix, results);
1103                 }
1104
1105                 
1106                 //
1107                 // Looks-up a alias named @name in this and surrounding namespace declarations
1108                 //
1109                 public FullNamedExpression LookupExternAlias (string name)
1110                 {
1111                         if (aliases == null)
1112                                 return null;
1113
1114                         UsingAliasNamespace uan;
1115                         if (aliases.TryGetValue (name, out uan) && uan is UsingExternAlias)
1116                                 return uan.ResolvedExpression;
1117
1118                         return null;
1119                 }
1120                 
1121                 //
1122                 // Looks-up a alias named @name in this and surrounding namespace declarations
1123                 //
1124                 public override FullNamedExpression LookupNamespaceAlias (string name)
1125                 {
1126                         for (NamespaceContainer n = this; n != null; n = n.Parent) {
1127                                 if (n.aliases == null)
1128                                         continue;
1129
1130                                 UsingAliasNamespace uan;
1131                                 if (n.aliases.TryGetValue (name, out uan))
1132                                         return uan.ResolvedExpression;
1133                         }
1134
1135                         return null;
1136                 }
1137
1138                 FullNamedExpression Lookup (string name, int arity, LookupMode mode, Location loc)
1139                 {
1140                         //
1141                         // Check whether it's in the namespace.
1142                         //
1143                         FullNamedExpression fne = ns.LookupTypeOrNamespace (this, name, arity, mode, loc);
1144
1145                         //
1146                         // Check aliases. 
1147                         //
1148                         if (aliases != null && arity == 0) {
1149                                 UsingAliasNamespace uan;
1150                                 if (aliases.TryGetValue (name, out uan)) {
1151                                         if (fne != null && mode != LookupMode.Probing) {
1152                                                 // TODO: Namespace has broken location
1153                                                 //Report.SymbolRelatedToPreviousError (fne.Location, null);
1154                                                 Compiler.Report.SymbolRelatedToPreviousError (uan.Location, null);
1155                                                 Compiler.Report.Error (576, loc,
1156                                                         "Namespace `{0}' contains a definition with same name as alias `{1}'",
1157                                                         GetSignatureForError (), name);
1158                                         }
1159
1160                                         return uan.ResolvedExpression;
1161                                 }
1162                         }
1163
1164                         if (fne != null)
1165                                 return fne;
1166
1167                         //
1168                         // Lookup can be called before the namespace is defined from different namespace using alias clause
1169                         //
1170                         if (namespace_using_table == null) {
1171                                 DoDefineNamespace ();
1172                         }
1173
1174                         //
1175                         // Check using entries.
1176                         //
1177                         FullNamedExpression match = null;
1178                         foreach (Namespace using_ns in namespace_using_table) {
1179                                 //
1180                                 // A using directive imports only types contained in the namespace, it
1181                                 // does not import any nested namespaces
1182                                 //
1183                                 var t = using_ns.LookupType (this, name, arity, mode, loc);
1184                                 if (t == null)
1185                                         continue;
1186
1187                                 fne = new TypeExpression (t, loc);
1188                                 if (match == null) {
1189                                         match = fne;
1190                                         continue;
1191                                 }
1192
1193                                 // Prefer types over namespaces
1194                                 var texpr_fne = fne as TypeExpr;
1195                                 var texpr_match = match as TypeExpr;
1196                                 if (texpr_fne != null && texpr_match == null) {
1197                                         match = fne;
1198                                         continue;
1199                                 } else if (texpr_fne == null) {
1200                                         continue;
1201                                 }
1202
1203                                 // It can be top level accessibility only
1204                                 var better = Namespace.IsImportedTypeOverride (Module, texpr_match.Type, texpr_fne.Type);
1205                                 if (better == null) {
1206                                         if (mode == LookupMode.Normal) {
1207                                                 Compiler.Report.SymbolRelatedToPreviousError (texpr_match.Type);
1208                                                 Compiler.Report.SymbolRelatedToPreviousError (texpr_fne.Type);
1209                                                 Compiler.Report.Error (104, loc, "`{0}' is an ambiguous reference between `{1}' and `{2}'",
1210                                                         name, texpr_match.GetSignatureForError (), texpr_fne.GetSignatureForError ());
1211                                         }
1212
1213                                         return match;
1214                                 }
1215
1216                                 if (better == texpr_fne.Type)
1217                                         match = texpr_fne;
1218                         }
1219
1220                         return match;
1221                 }
1222
1223                 protected override void DefineNamespace ()
1224                 {
1225                         if (namespace_using_table == null)
1226                                 DoDefineNamespace ();
1227
1228                         base.DefineNamespace ();
1229                 }
1230
1231                 void DoDefineNamespace ()
1232                 {
1233                         namespace_using_table = empty_namespaces;
1234
1235                         if (clauses != null) {
1236                                 var list = new List<Namespace> (clauses.Count);
1237                                 bool post_process_using_aliases = false;
1238
1239                                 for (int i = 0; i < clauses.Count; ++i) {
1240                                         var entry = clauses[i];
1241
1242                                         if (entry.Alias != null) {
1243                                                 if (aliases == null)
1244                                                         aliases = new Dictionary<string, UsingAliasNamespace> ();
1245
1246                                                 //
1247                                                 // Aliases are not available when resolving using section
1248                                                 // except extern aliases
1249                                                 //
1250                                                 if (entry is UsingExternAlias) {
1251                                                         entry.Define (this);
1252                                                         if (entry.ResolvedExpression != null)
1253                                                                 aliases.Add (entry.Alias.Value, (UsingExternAlias) entry);
1254
1255                                                         clauses.RemoveAt (i--);
1256                                                 } else {
1257                                                         post_process_using_aliases = true;
1258                                                 }
1259
1260                                                 continue;
1261                                         }
1262
1263                                         entry.Define (this);
1264
1265                                         //
1266                                         // It's needed for repl only, when using clause cannot be resolved don't hold it in
1267                                         // global list which is resolved for each evaluation
1268                                         //
1269                                         if (entry.ResolvedExpression == null) {
1270                                                 clauses.RemoveAt (i--);
1271                                                 continue;
1272                                         }
1273
1274                                         Namespace using_ns = entry.ResolvedExpression as Namespace;
1275                                         if (using_ns == null)
1276                                                 continue;
1277
1278                                         if (list.Contains (using_ns)) {
1279                                                 // Ensure we don't report the warning multiple times in repl
1280                                                 clauses.RemoveAt (i--);
1281
1282                                                 Compiler.Report.Warning (105, 3, entry.Location,
1283                                                         "The using directive for `{0}' appeared previously in this namespace", using_ns.GetSignatureForError ());
1284                                         } else {
1285                                                 list.Add (using_ns);
1286                                         }
1287                                 }
1288
1289                                 namespace_using_table = list.ToArray ();
1290
1291                                 if (post_process_using_aliases) {
1292                                         for (int i = 0; i < clauses.Count; ++i) {
1293                                                 var entry = clauses[i];
1294                                                 if (entry.Alias != null) {
1295                                                         entry.Define (this);
1296                                                         if (entry.ResolvedExpression != null) {
1297                                                                 aliases.Add (entry.Alias.Value, (UsingAliasNamespace) entry);
1298                                                         }
1299
1300                                                         clauses.RemoveAt (i--);
1301                                                 }
1302                                         }
1303                                 }
1304                         }
1305                 }
1306
1307                 public void EnableRedefinition ()
1308                 {
1309                         is_defined = false;
1310                         namespace_using_table = null;
1311                 }
1312
1313                 internal override void GenerateDocComment (DocumentationBuilder builder)
1314                 {
1315                         if (containers != null) {
1316                                 foreach (var tc in containers)
1317                                         tc.GenerateDocComment (builder);
1318                         }
1319                 }
1320
1321                 public override string GetSignatureForError ()
1322                 {
1323                         return MemberName == null ? "global::" : base.GetSignatureForError ();
1324                 }
1325
1326                 public override void RemoveContainer (TypeContainer cont)
1327                 {
1328                         base.RemoveContainer (cont);
1329                         NS.RemoveContainer (cont);
1330                 }
1331
1332                 protected override bool VerifyClsCompliance ()
1333                 {
1334                         if (Module.IsClsComplianceRequired ()) {
1335                                 if (MemberName != null && MemberName.Name[0] == '_') {
1336                                         Warning_IdentifierNotCompliant ();
1337                                 }
1338
1339                                 ns.VerifyClsCompliance ();
1340                                 return true;
1341                         }
1342
1343                         return false;
1344                 }
1345
1346                 public override void Accept (StructuralVisitor visitor)
1347                 {
1348                         visitor.Visit (this);
1349                 }
1350         }
1351
1352         public class UsingNamespace
1353         {
1354                 readonly ATypeNameExpression expr;
1355                 readonly Location loc;
1356                 protected FullNamedExpression resolved;
1357
1358                 public UsingNamespace (ATypeNameExpression expr, Location loc)
1359                 {
1360                         this.expr = expr;
1361                         this.loc = loc;
1362                 }
1363
1364                 #region Properties
1365
1366                 public virtual SimpleMemberName Alias {
1367                         get {
1368                                 return null;
1369                         }
1370                 }
1371
1372                 public Location Location {
1373                         get {
1374                                 return loc;
1375                         }
1376                 }
1377
1378                 public ATypeNameExpression NamespaceExpression  {
1379                         get {
1380                                 return expr;
1381                         }
1382                 }
1383
1384                 public FullNamedExpression ResolvedExpression {
1385                         get {
1386                                 return resolved;
1387                         }
1388                 }
1389
1390                 #endregion
1391
1392                 public string GetSignatureForError ()
1393                 {
1394                         return expr.GetSignatureForError ();
1395                 }
1396
1397                 public virtual void Define (NamespaceContainer ctx)
1398                 {
1399                         resolved = expr.ResolveAsTypeOrNamespace (ctx);
1400                         var ns = resolved as Namespace;
1401                         if (ns == null) {
1402                                 if (resolved != null) {
1403                                         ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (resolved.Type);
1404                                         ctx.Module.Compiler.Report.Error (138, Location,
1405                                                 "`{0}' is a type not a namespace. A using namespace directive can only be applied to namespaces",
1406                                                 GetSignatureForError ());
1407                                 }
1408                         }
1409                 }
1410
1411                 public override string ToString()
1412                 {
1413                         return resolved.ToString();
1414                 }
1415         }
1416
1417         public class UsingExternAlias : UsingAliasNamespace
1418         {
1419                 public UsingExternAlias (SimpleMemberName alias, Location loc)
1420                         : base (alias, null, loc)
1421                 {
1422                 }
1423
1424                 public override void Define (NamespaceContainer ctx)
1425                 {
1426                         resolved = ctx.Module.GetRootNamespace (Alias.Value);
1427                         if (resolved == null) {
1428                                 ctx.Module.Compiler.Report.Error (430, Location,
1429                                         "The extern alias `{0}' was not specified in -reference option",
1430                                         Alias.Value);
1431                         }
1432                 }
1433         }
1434
1435         public class UsingAliasNamespace : UsingNamespace
1436         {
1437                 readonly SimpleMemberName alias;
1438
1439                 public struct AliasContext : IMemberContext
1440                 {
1441                         readonly NamespaceContainer ns;
1442
1443                         public AliasContext (NamespaceContainer ns)
1444                         {
1445                                 this.ns = ns;
1446                         }
1447
1448                         public TypeSpec CurrentType {
1449                                 get {
1450                                         return null;
1451                                 }
1452                         }
1453
1454                         public TypeParameters CurrentTypeParameters {
1455                                 get {
1456                                         return null;
1457                                 }
1458                         }
1459
1460                         public MemberCore CurrentMemberDefinition {
1461                                 get {
1462                                         return null;
1463                                 }
1464                         }
1465
1466                         public bool IsObsolete {
1467                                 get {
1468                                         return false;
1469                                 }
1470                         }
1471
1472                         public bool IsUnsafe {
1473                                 get {
1474                                         throw new NotImplementedException ();
1475                                 }
1476                         }
1477
1478                         public bool IsStatic {
1479                                 get {
1480                                         throw new NotImplementedException ();
1481                                 }
1482                         }
1483
1484                         public ModuleContainer Module {
1485                                 get {
1486                                         return ns.Module;
1487                                 }
1488                         }
1489
1490                         public string GetSignatureForError ()
1491                         {
1492                                 throw new NotImplementedException ();
1493                         }
1494
1495                         public ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity)
1496                         {
1497                                 return null;
1498                         }
1499
1500                         public FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
1501                         {
1502                                 var fne = ns.NS.LookupTypeOrNamespace (ns, name, arity, mode, loc);
1503                                 if (fne != null)
1504                                         return fne;
1505
1506                                 //
1507                                 // Only extern aliases are allowed in this context
1508                                 //
1509                                 fne = ns.LookupExternAlias (name);
1510                                 if (fne != null || ns.MemberName == null)
1511                                         return fne;
1512
1513                                 var container_ns = ns.NS.Parent;
1514                                 var mn = ns.MemberName.Left;
1515                                 while (mn != null) {
1516                                         fne = container_ns.LookupTypeOrNamespace (this, name, arity, mode, loc);
1517                                         if (fne != null)
1518                                                 return fne;
1519
1520                                         mn = mn.Left;
1521                                         container_ns = container_ns.Parent;
1522                                 }
1523
1524                                 if (ns.Parent != null)
1525                                         return ns.Parent.LookupNamespaceOrType (name, arity, mode, loc);
1526
1527                                 return null;
1528                         }
1529
1530                         public FullNamedExpression LookupNamespaceAlias (string name)
1531                         {
1532                                 return ns.LookupNamespaceAlias (name);
1533                         }
1534                 }
1535
1536                 public UsingAliasNamespace (SimpleMemberName alias, ATypeNameExpression expr, Location loc)
1537                         : base (expr, loc)
1538                 {
1539                         this.alias = alias;
1540                 }
1541
1542                 public override SimpleMemberName Alias {
1543                         get {
1544                                 return alias;
1545                         }
1546                 }
1547
1548                 public override void Define (NamespaceContainer ctx)
1549                 {
1550                         //
1551                         // The namespace-or-type-name of a using-alias-directive is resolved as if
1552                         // the immediately containing compilation unit or namespace body had no
1553                         // using-directives. A using-alias-directive may however be affected
1554                         // by extern-alias-directives in the immediately containing compilation
1555                         // unit or namespace body
1556                         //
1557                         // We achieve that by introducing alias-context which redirect any local
1558                         // namespace or type resolve calls to parent namespace
1559                         //
1560                         resolved = NamespaceExpression.ResolveAsTypeOrNamespace (new AliasContext (ctx));
1561                 }
1562         }
1563 }