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