Implement MachineKey.Protect and MachineKey.Unprotect
[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.MemberName.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                         var mn = tc.MemberName;
808                         var name = mn.Basename;
809                         while (mn.Left != null) {
810                                 mn = mn.Left;
811                                 name = mn.Name;
812                         }
813
814                         var names_container = Parent == null ? Module : (TypeContainer) this;
815
816                         MemberCore mc;
817                         if (names_container.DefinedNames.TryGetValue (name, out mc)) {
818                                 if (tc is NamespaceContainer && mc is NamespaceContainer) {
819                                         AddTypeContainerMember (tc);
820                                         return;
821                                 }
822
823                                 Report.SymbolRelatedToPreviousError (mc);
824                                 if ((mc.ModFlags & Modifiers.PARTIAL) != 0 && (tc is ClassOrStruct || tc is Interface)) {
825                                         Error_MissingPartialModifier (tc);
826                                 } else {
827                                         Report.Error (101, tc.Location, "The namespace `{0}' already contains a definition for `{1}'",
828                                                 GetSignatureForError (), mn.GetSignatureForError ());
829                                 }
830                         } else {
831                                 names_container.DefinedNames.Add (name, tc);
832
833                                 var tdef = tc.PartialContainer;
834                                 if (tdef != null) {
835                                         //
836                                         // Same name conflict in different namespace containers
837                                         //
838                                         var conflict = ns.GetAllTypes (name);
839                                         if (conflict != null) {
840                                                 foreach (var e in conflict) {
841                                                         if (e.Arity == mn.Arity) {
842                                                                 mc = (MemberCore) e.MemberDefinition;
843                                                                 break;
844                                                         }
845                                                 }
846                                         }
847
848                                         if (mc != null) {
849                                                 Report.SymbolRelatedToPreviousError (mc);
850                                                 Report.Error (101, tc.Location, "The namespace `{0}' already contains a definition for `{1}'",
851                                                         GetSignatureForError (), mn.GetSignatureForError ());
852                                         } else {
853                                                 ns.AddType (Module, tdef.Definition);
854                                         }
855                                 }
856                         }
857
858                         base.AddTypeContainer (tc);
859                 }
860
861                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
862                 {
863                         throw new NotSupportedException ();
864                 }
865
866                 public override void EmitContainer ()
867                 {
868                         VerifyClsCompliance ();
869
870                         base.EmitContainer ();
871                 }
872
873                 public ExtensionMethodCandidates LookupExtensionMethod (IMemberContext invocationContext, TypeSpec extensionType, string name, int arity, int position)
874                 {
875                         //
876                         // Here we try to resume the search for extension method at the point
877                         // where the last bunch of candidates was found. It's more tricky than
878                         // it seems as we have to check both namespace containers and namespace
879                         // in correct order.
880                         //
881                         // Consider:
882                         // 
883                         // namespace A {
884                         //      using N1;
885                         //  namespace B.C.D {
886                         //              <our first search found candidates in A.B.C.D
887                         //  }
888                         // }
889                         //
890                         // In the example above namespace A.B.C.D, A.B.C and A.B have to be
891                         // checked before we hit A.N1 using
892                         //
893                         ExtensionMethodCandidates candidates;
894                         var container = this;
895                         do {
896                                 candidates = container.LookupExtensionMethodCandidates (invocationContext, name, arity, ref position);
897                                 if (candidates != null || container.MemberName == null)
898                                         return candidates;
899
900                                 var container_ns = container.ns.Parent;
901                                 var mn = container.MemberName.Left;
902                                 int already_checked = position - 2;
903                                 while (already_checked-- > 0) {
904                                         mn = mn.Left;
905                                         container_ns = container_ns.Parent;
906                                 }
907
908                                 while (mn != null) {
909                                         ++position;
910
911                                         var methods = container_ns.LookupExtensionMethod (invocationContext, name, arity);
912                                         if (methods != null) {
913                                                 return new ExtensionMethodCandidates (invocationContext, methods, container, position);
914                                         }
915
916                                         mn = mn.Left;
917                                         container_ns = container_ns.Parent;
918                                 }
919
920                                 position = 0;
921                                 container = container.Parent;
922                         } while (container != null);
923
924                         return null;
925                 }
926
927                 ExtensionMethodCandidates LookupExtensionMethodCandidates (IMemberContext invocationContext, string name, int arity, ref int position)
928                 {
929                         List<MethodSpec> candidates = null;
930
931                         if (position == 0) {
932                                 ++position;
933
934                                 candidates = ns.LookupExtensionMethod (invocationContext, name, arity);
935                                 if (candidates != null) {
936                                         return new ExtensionMethodCandidates (invocationContext, candidates, this, position);
937                                 }
938                         }
939
940                         if (position == 1) {
941                                 ++position;
942
943                                 foreach (Namespace n in namespace_using_table) {
944                                         var a = n.LookupExtensionMethod (invocationContext, name, arity);
945                                         if (a == null)
946                                                 continue;
947
948                                         if (candidates == null)
949                                                 candidates = a;
950                                         else
951                                                 candidates.AddRange (a);
952                                 }
953
954                                 if (candidates != null)
955                                         return new ExtensionMethodCandidates (invocationContext, candidates, this, position);
956                         }
957
958                         // LAMESPEC: TODO no spec about priority over normal extension methods yet
959                         if (types_using_table != null) {
960                                 foreach (var t in types_using_table) {
961
962                                         var res = t.MemberCache.FindExtensionMethods (invocationContext, name, arity);
963                                         if (res == null)
964                                                 continue;
965
966                                         if (candidates == null)
967                                                 candidates = res;
968                                         else
969                                                 candidates.AddRange (res);
970                                 }
971
972                                 if (candidates != null)
973                                         return new ExtensionMethodCandidates (invocationContext, candidates, this, position);
974                         }
975
976                         return null;
977                 }
978
979                 public override FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
980                 {
981                         //
982                         // Only simple names (no dots) will be looked up with this function
983                         //
984                         FullNamedExpression resolved;
985                         for (NamespaceContainer container = this; container != null; container = container.Parent) {
986                                 resolved = container.Lookup (name, arity, mode, loc);
987                                 if (resolved != null || container.MemberName == null)
988                                         return resolved;
989
990                                 var container_ns = container.ns.Parent;
991                                 var mn = container.MemberName.Left;
992                                 while (mn != null) {
993                                         resolved = container_ns.LookupTypeOrNamespace (this, name, arity, mode, loc);
994                                         if (resolved != null)
995                                                 return resolved;
996
997                                         mn = mn.Left;
998                                         container_ns = container_ns.Parent;
999                                 }
1000                         }
1001
1002                         return null;
1003                 }
1004
1005                 public override void GetCompletionStartingWith (string prefix, List<string> results)
1006                 {
1007                         if (Usings == null)
1008                                 return;
1009
1010                         foreach (var un in Usings) {
1011                                 if (un.Alias != null)
1012                                         continue;
1013
1014                                 var name = un.NamespaceExpression.Name;
1015                                 if (name.StartsWith (prefix))
1016                                         results.Add (name);
1017                         }
1018
1019
1020                         IEnumerable<string> all = Enumerable.Empty<string> ();
1021
1022                         foreach (Namespace using_ns in namespace_using_table) {
1023                                 if (prefix.StartsWith (using_ns.Name)) {
1024                                         int ld = prefix.LastIndexOf ('.');
1025                                         if (ld != -1) {
1026                                                 string rest = prefix.Substring (ld + 1);
1027
1028                                                 all = all.Concat (using_ns.CompletionGetTypesStartingWith (rest));
1029                                         }
1030                                 }
1031                                 all = all.Concat (using_ns.CompletionGetTypesStartingWith (prefix));
1032                         }
1033
1034                         results.AddRange (all);
1035
1036                         base.GetCompletionStartingWith (prefix, results);
1037                 }
1038
1039                 
1040                 //
1041                 // Looks-up a alias named @name in this and surrounding namespace declarations
1042                 //
1043                 public FullNamedExpression LookupExternAlias (string name)
1044                 {
1045                         if (aliases == null)
1046                                 return null;
1047
1048                         UsingAliasNamespace uan;
1049                         if (aliases.TryGetValue (name, out uan) && uan is UsingExternAlias)
1050                                 return uan.ResolvedExpression;
1051
1052                         return null;
1053                 }
1054                 
1055                 //
1056                 // Looks-up a alias named @name in this and surrounding namespace declarations
1057                 //
1058                 public override FullNamedExpression LookupNamespaceAlias (string name)
1059                 {
1060                         for (NamespaceContainer n = this; n != null; n = n.Parent) {
1061                                 if (n.aliases == null)
1062                                         continue;
1063
1064                                 UsingAliasNamespace uan;
1065                                 if (n.aliases.TryGetValue (name, out uan))
1066                                         return uan.ResolvedExpression;
1067                         }
1068
1069                         return null;
1070                 }
1071
1072                 FullNamedExpression Lookup (string name, int arity, LookupMode mode, Location loc)
1073                 {
1074                         //
1075                         // Check whether it's in the namespace.
1076                         //
1077                         FullNamedExpression fne = ns.LookupTypeOrNamespace (this, name, arity, mode, loc);
1078
1079                         //
1080                         // Check aliases. 
1081                         //
1082                         if (aliases != null && arity == 0) {
1083                                 UsingAliasNamespace uan;
1084                                 if (aliases.TryGetValue (name, out uan)) {
1085                                         if (fne != null && mode != LookupMode.Probing) {
1086                                                 // TODO: Namespace has broken location
1087                                                 //Report.SymbolRelatedToPreviousError (fne.Location, null);
1088                                                 Compiler.Report.SymbolRelatedToPreviousError (uan.Location, null);
1089                                                 Compiler.Report.Error (576, loc,
1090                                                         "Namespace `{0}' contains a definition with same name as alias `{1}'",
1091                                                         GetSignatureForError (), name);
1092                                         }
1093
1094                                         return uan.ResolvedExpression;
1095                                 }
1096                         }
1097
1098                         if (fne != null)
1099                                 return fne;
1100
1101                         //
1102                         // Lookup can be called before the namespace is defined from different namespace using alias clause
1103                         //
1104                         if (namespace_using_table == null) {
1105                                 DoDefineNamespace ();
1106                         }
1107
1108                         //
1109                         // Check using entries.
1110                         //
1111                         FullNamedExpression match = null;
1112                         foreach (Namespace using_ns in namespace_using_table) {
1113                                 //
1114                                 // A using directive imports only types contained in the namespace, it
1115                                 // does not import any nested namespaces
1116                                 //
1117                                 var t = using_ns.LookupType (this, name, arity, mode, loc);
1118                                 if (t == null)
1119                                         continue;
1120
1121                                 fne = new TypeExpression (t, loc);
1122                                 if (match == null) {
1123                                         match = fne;
1124                                         continue;
1125                                 }
1126
1127                                 // Prefer types over namespaces
1128                                 var texpr_fne = fne as TypeExpr;
1129                                 var texpr_match = match as TypeExpr;
1130                                 if (texpr_fne != null && texpr_match == null) {
1131                                         match = fne;
1132                                         continue;
1133                                 } else if (texpr_fne == null) {
1134                                         continue;
1135                                 }
1136
1137                                 // It can be top level accessibility only
1138                                 var better = Namespace.IsImportedTypeOverride (Module, texpr_match.Type, texpr_fne.Type);
1139                                 if (better == null) {
1140                                         if (mode == LookupMode.Normal) {
1141                                                 Compiler.Report.SymbolRelatedToPreviousError (texpr_match.Type);
1142                                                 Compiler.Report.SymbolRelatedToPreviousError (texpr_fne.Type);
1143                                                 Compiler.Report.Error (104, loc, "`{0}' is an ambiguous reference between `{1}' and `{2}'",
1144                                                         name, texpr_match.GetSignatureForError (), texpr_fne.GetSignatureForError ());
1145                                         }
1146
1147                                         return match;
1148                                 }
1149
1150                                 if (better == texpr_fne.Type)
1151                                         match = texpr_fne;
1152                         }
1153
1154                         return match;
1155                 }
1156
1157                 public static MethodGroupExpr LookupStaticUsings (IMemberContext mc, string name, int arity, Location loc)
1158                 {
1159                         for (var m = mc.CurrentMemberDefinition; m != null; m = m.Parent) {
1160
1161                                 var nc = m as NamespaceContainer;
1162                                 if (nc == null)
1163                                         continue;
1164
1165                                 List<MemberSpec> candidates = null;
1166                                 if (nc.types_using_table != null) {
1167                                         foreach (var using_type in nc.types_using_table) {
1168                                                 var members = MemberCache.FindMembers (using_type, name, true);
1169                                                 if (members != null) {
1170                                                         foreach (var member in members) {
1171                                                                 if ((member.Modifiers & Modifiers.METHOD_EXTENSION) != 0)
1172                                                                         continue;
1173
1174                                                                 if (arity > 0 && member.Arity != arity)
1175                                                                         continue;
1176
1177                                                                 if (candidates == null)
1178                                                                         candidates = new List<MemberSpec> ();
1179
1180                                                                 candidates.Add (member);
1181                                                         }
1182                                                 }
1183                                         }
1184                                 }
1185
1186                                 if (candidates != null)
1187                                         return new MethodGroupExpr (candidates, null, loc);
1188                         }
1189
1190                         return null;
1191                 }
1192
1193                 protected override void DefineNamespace ()
1194                 {
1195                         if (namespace_using_table == null)
1196                                 DoDefineNamespace ();
1197
1198                         base.DefineNamespace ();
1199                 }
1200
1201                 void DoDefineNamespace ()
1202                 {
1203                         namespace_using_table = empty_namespaces;
1204
1205                         if (clauses != null) {
1206                                 List<Namespace> namespaces = null;
1207                                 List<TypeSpec> types = null;
1208
1209                                 bool post_process_using_aliases = false;
1210
1211                                 for (int i = 0; i < clauses.Count; ++i) {
1212                                         var entry = clauses[i];
1213
1214                                         if (entry.Alias != null) {
1215                                                 if (aliases == null)
1216                                                         aliases = new Dictionary<string, UsingAliasNamespace> ();
1217
1218                                                 //
1219                                                 // Aliases are not available when resolving using section
1220                                                 // except extern aliases
1221                                                 //
1222                                                 if (entry is UsingExternAlias) {
1223                                                         entry.Define (this);
1224                                                         if (entry.ResolvedExpression != null)
1225                                                                 aliases.Add (entry.Alias.Value, (UsingExternAlias) entry);
1226
1227                                                         clauses.RemoveAt (i--);
1228                                                 } else {
1229                                                         post_process_using_aliases = true;
1230                                                 }
1231
1232                                                 continue;
1233                                         }
1234
1235                                         entry.Define (this);
1236
1237                                         //
1238                                         // It's needed for repl only, when using clause cannot be resolved don't hold it in
1239                                         // global list which is resolved for each evaluation
1240                                         //
1241                                         if (entry.ResolvedExpression == null) {
1242                                                 clauses.RemoveAt (i--);
1243                                                 continue;
1244                                         }
1245
1246                                         var using_ns = entry.ResolvedExpression as NamespaceExpression;
1247                                         if (using_ns == null) {
1248
1249                                                 var type = ((TypeExpr)entry.ResolvedExpression).Type;
1250
1251                                                 if (types == null)
1252                                                         types = new List<TypeSpec> ();
1253
1254                                                 if (types.Contains (type)) {
1255                                                         Warning_DuplicateEntry (entry);
1256                                                 } else {
1257                                                         types.Add (type);
1258                                                 }
1259                                         } else {
1260                                                 if (namespaces == null)
1261                                                         namespaces = new List<Namespace> ();
1262
1263                                                 if (namespaces.Contains (using_ns.Namespace)) {
1264                                                         // Ensure we don't report the warning multiple times in repl
1265                                                         clauses.RemoveAt (i--);
1266
1267                                                         Warning_DuplicateEntry (entry);
1268                                                 } else {
1269                                                         namespaces.Add (using_ns.Namespace);
1270                                                 }
1271                                         }
1272                                 }
1273
1274                                 namespace_using_table = namespaces == null ? new Namespace [0] : namespaces.ToArray ();
1275                                 if (types != null)
1276                                         types_using_table = types.ToArray ();
1277
1278                                 if (post_process_using_aliases) {
1279                                         for (int i = 0; i < clauses.Count; ++i) {
1280                                                 var entry = clauses[i];
1281                                                 if (entry.Alias != null) {
1282                                                         entry.Define (this);
1283                                                         if (entry.ResolvedExpression != null) {
1284                                                                 aliases.Add (entry.Alias.Value, (UsingAliasNamespace) entry);
1285                                                         }
1286
1287                                                         clauses.RemoveAt (i--);
1288                                                 }
1289                                         }
1290                                 }
1291                         }
1292                 }
1293
1294                 public void EnableRedefinition ()
1295                 {
1296                         is_defined = false;
1297                         namespace_using_table = null;
1298                 }
1299
1300                 internal override void GenerateDocComment (DocumentationBuilder builder)
1301                 {
1302                         if (containers != null) {
1303                                 foreach (var tc in containers)
1304                                         tc.GenerateDocComment (builder);
1305                         }
1306                 }
1307
1308                 public override string GetSignatureForError ()
1309                 {
1310                         return MemberName == null ? "global::" : base.GetSignatureForError ();
1311                 }
1312
1313                 public override void RemoveContainer (TypeContainer cont)
1314                 {
1315                         base.RemoveContainer (cont);
1316                         NS.RemoveContainer (cont);
1317                 }
1318
1319                 protected override bool VerifyClsCompliance ()
1320                 {
1321                         if (Module.IsClsComplianceRequired ()) {
1322                                 if (MemberName != null && MemberName.Name[0] == '_') {
1323                                         Warning_IdentifierNotCompliant ();
1324                                 }
1325
1326                                 ns.VerifyClsCompliance ();
1327                                 return true;
1328                         }
1329
1330                         return false;
1331                 }
1332
1333                 void Warning_DuplicateEntry (UsingNamespace entry)
1334                 {
1335                         Compiler.Report.Warning (105, 3, entry.Location,
1336                                 "The using directive for `{0}' appeared previously in this namespace",
1337                                 entry.ResolvedExpression.GetSignatureForError ());
1338                 }
1339
1340                 public override void Accept (StructuralVisitor visitor)
1341                 {
1342                         visitor.Visit (this);
1343                 }
1344         }
1345
1346         public class UsingNamespace
1347         {
1348                 readonly ATypeNameExpression expr;
1349                 readonly Location loc;
1350                 protected FullNamedExpression resolved;
1351
1352                 public UsingNamespace (ATypeNameExpression expr, Location loc)
1353                 {
1354                         this.expr = expr;
1355                         this.loc = loc;
1356                 }
1357
1358                 #region Properties
1359
1360                 public virtual SimpleMemberName Alias {
1361                         get {
1362                                 return null;
1363                         }
1364                 }
1365
1366                 public Location Location {
1367                         get {
1368                                 return loc;
1369                         }
1370                 }
1371
1372                 public ATypeNameExpression NamespaceExpression  {
1373                         get {
1374                                 return expr;
1375                         }
1376                 }
1377
1378                 public FullNamedExpression ResolvedExpression {
1379                         get {
1380                                 return resolved;
1381                         }
1382                 }
1383
1384                 #endregion
1385
1386                 public string GetSignatureForError ()
1387                 {
1388                         return expr.GetSignatureForError ();
1389                 }
1390
1391                 public virtual void Define (NamespaceContainer ctx)
1392                 {
1393                         resolved = expr.ResolveAsTypeOrNamespace (ctx, false);
1394                         var ns = resolved as NamespaceExpression;
1395                         if (ns != null)
1396                                 return;
1397
1398                         if (resolved != null) {
1399                                 var compiler = ctx.Module.Compiler;
1400                                 var type = resolved.Type;
1401                                 if (compiler.Settings.Version >= LanguageVersion.V_6) {
1402                                         if (!type.IsClass || !type.IsStatic) {
1403                                                 compiler.Report.SymbolRelatedToPreviousError (type);
1404                                                 compiler.Report.Error (7007, Location,
1405                                                         "`{0}' is not a static class. A using namespace directive can only be applied to static classes or namespace",
1406                                                         GetSignatureForError ());
1407                                         }
1408
1409                                         return;
1410                                 }
1411
1412                                 compiler.Report.SymbolRelatedToPreviousError (type);
1413                                 compiler.Report.Error (138, Location,
1414                                         "`{0}' is a type not a namespace. A using namespace directive can only be applied to namespaces",
1415                                         GetSignatureForError ());
1416                         }
1417                 }
1418
1419                 public override string ToString()
1420                 {
1421                         return resolved.ToString();
1422                 }
1423         }
1424
1425         public class UsingExternAlias : UsingAliasNamespace
1426         {
1427                 public UsingExternAlias (SimpleMemberName alias, Location loc)
1428                         : base (alias, null, loc)
1429                 {
1430                 }
1431
1432                 public override void Define (NamespaceContainer ctx)
1433                 {
1434                         var ns = ctx.Module.GetRootNamespace (Alias.Value);
1435                         if (ns == null) {
1436                                 ctx.Module.Compiler.Report.Error (430, Location,
1437                                         "The extern alias `{0}' was not specified in -reference option",
1438                                         Alias.Value);
1439                                 return;
1440                         }
1441
1442                         resolved = new NamespaceExpression (ns, Location);
1443                 }
1444         }
1445
1446         public class UsingAliasNamespace : UsingNamespace
1447         {
1448                 readonly SimpleMemberName alias;
1449
1450                 public struct AliasContext : IMemberContext
1451                 {
1452                         readonly NamespaceContainer ns;
1453
1454                         public AliasContext (NamespaceContainer ns)
1455                         {
1456                                 this.ns = ns;
1457                         }
1458
1459                         public TypeSpec CurrentType {
1460                                 get {
1461                                         return null;
1462                                 }
1463                         }
1464
1465                         public TypeParameters CurrentTypeParameters {
1466                                 get {
1467                                         return null;
1468                                 }
1469                         }
1470
1471                         public MemberCore CurrentMemberDefinition {
1472                                 get {
1473                                         return null;
1474                                 }
1475                         }
1476
1477                         public bool IsObsolete {
1478                                 get {
1479                                         return false;
1480                                 }
1481                         }
1482
1483                         public bool IsUnsafe {
1484                                 get {
1485                                         throw new NotImplementedException ();
1486                                 }
1487                         }
1488
1489                         public bool IsStatic {
1490                                 get {
1491                                         throw new NotImplementedException ();
1492                                 }
1493                         }
1494
1495                         public ModuleContainer Module {
1496                                 get {
1497                                         return ns.Module;
1498                                 }
1499                         }
1500
1501                         public string GetSignatureForError ()
1502                         {
1503                                 throw new NotImplementedException ();
1504                         }
1505
1506                         public ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity)
1507                         {
1508                                 return null;
1509                         }
1510
1511                         public FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
1512                         {
1513                                 var fne = ns.NS.LookupTypeOrNamespace (ns, name, arity, mode, loc);
1514                                 if (fne != null)
1515                                         return fne;
1516
1517                                 //
1518                                 // Only extern aliases are allowed in this context
1519                                 //
1520                                 fne = ns.LookupExternAlias (name);
1521                                 if (fne != null || ns.MemberName == null)
1522                                         return fne;
1523
1524                                 var container_ns = ns.NS.Parent;
1525                                 var mn = ns.MemberName.Left;
1526                                 while (mn != null) {
1527                                         fne = container_ns.LookupTypeOrNamespace (this, name, arity, mode, loc);
1528                                         if (fne != null)
1529                                                 return fne;
1530
1531                                         mn = mn.Left;
1532                                         container_ns = container_ns.Parent;
1533                                 }
1534
1535                                 if (ns.Parent != null)
1536                                         return ns.Parent.LookupNamespaceOrType (name, arity, mode, loc);
1537
1538                                 return null;
1539                         }
1540
1541                         public FullNamedExpression LookupNamespaceAlias (string name)
1542                         {
1543                                 return ns.LookupNamespaceAlias (name);
1544                         }
1545                 }
1546
1547                 public UsingAliasNamespace (SimpleMemberName alias, ATypeNameExpression expr, Location loc)
1548                         : base (expr, loc)
1549                 {
1550                         this.alias = alias;
1551                 }
1552
1553                 public override SimpleMemberName Alias {
1554                         get {
1555                                 return alias;
1556                         }
1557                 }
1558
1559                 public override void Define (NamespaceContainer ctx)
1560                 {
1561                         //
1562                         // The namespace-or-type-name of a using-alias-directive is resolved as if
1563                         // the immediately containing compilation unit or namespace body had no
1564                         // using-directives. A using-alias-directive may however be affected
1565                         // by extern-alias-directives in the immediately containing compilation
1566                         // unit or namespace body
1567                         //
1568                         // We achieve that by introducing alias-context which redirect any local
1569                         // namespace or type resolve calls to parent namespace
1570                         //
1571                         resolved = NamespaceExpression.ResolveAsTypeOrNamespace (new AliasContext (ctx), false);
1572                 }
1573         }
1574 }