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