2 // namespace.cs: Tracks namespaces
5 // Miguel de Icaza (miguel@ximian.com)
6 // Marek Safar (marek.safar@seznam.cz)
8 // Copyright 2001 Ximian, Inc.
9 // Copyright 2003-2008 Novell, Inc.
10 // Copyright 2011 Xamarin Inc
13 using System.Collections.Generic;
16 namespace Mono.CSharp {
18 public class RootNamespace : Namespace {
20 readonly string alias_name;
21 readonly Dictionary<string, Namespace> all_namespaces;
23 public RootNamespace (string alias_name)
24 : base (null, String.Empty)
26 this.alias_name = alias_name;
28 all_namespaces = new Dictionary<string, Namespace> ();
29 all_namespaces.Add ("", this);
38 public static void Error_GlobalNamespaceRedefined (Report report, Location loc)
40 report.Error (1681, loc, "The global extern alias cannot be redefined");
43 public void RegisterNamespace (Namespace child)
46 all_namespaces.Add (child.Name, child);
49 public bool IsNamespace (string name)
51 return all_namespaces.ContainsKey (name);
54 protected void RegisterNamespace (string dotted_name)
56 if (dotted_name != null && dotted_name.Length != 0 && ! IsNamespace (dotted_name))
57 GetNamespace (dotted_name, true);
60 public override string GetSignatureForError ()
62 return alias_name + "::";
66 public class GlobalRootNamespace : RootNamespace
68 public GlobalRootNamespace ()
75 // Namespace cache for imported and compiled namespaces
77 // This is an Expression to allow it to be referenced in the
78 // compiler parse/intermediate tree during name resolution.
80 public class Namespace : FullNamedExpression
84 protected Dictionary<string, Namespace> namespaces;
85 protected Dictionary<string, IList<TypeSpec>> types;
86 Dictionary<string, TypeExpr> cached_types;
90 public readonly MemberName MemberName;
93 /// Constructor Takes the current namespace and the
94 /// name. This is bootstrapped with parent == null
97 public Namespace (Namespace parent, string name)
99 // Expression members.
100 this.eclass = ExprClass.Namespace;
101 this.Type = InternalType.Namespace;
102 this.loc = Location.Null;
104 this.parent = parent;
107 this.root = parent.root;
109 this.root = this as RootNamespace;
111 if (this.root == null)
112 throw new InternalErrorException ("Root namespaces must be created using RootNamespace");
114 string pname = parent != null ? parent.fullname : "";
119 fullname = parent.fullname + "." + name;
121 if (fullname == null)
122 throw new InternalErrorException ("Namespace has a null fullname");
124 if (parent != null && parent.MemberName != MemberName.Null)
125 MemberName = new MemberName (parent.MemberName, name, Location.Null);
126 else if (name.Length == 0)
127 MemberName = MemberName.Null;
129 MemberName = new MemberName (name, Location.Null);
131 namespaces = new Dictionary<string, Namespace> ();
132 cached_types = new Dictionary<string, TypeExpr> ();
134 root.RegisterNamespace (this);
140 /// The qualified name of the current namespace
143 get { return fullname; }
147 /// The parent of this namespace, used by the parser to "Pop"
148 /// the current namespace declaration
150 public Namespace Parent {
151 get { return parent; }
156 protected override Expression DoResolve (ResolveContext ec)
161 public void Error_NamespaceDoesNotExist (IMemberContext ctx, string name, int arity, Location loc)
163 var retval = LookupType (ctx, name, arity, LookupMode.IgnoreAccessibility, loc);
164 if (retval != null) {
165 ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (retval.Type);
166 ErrorIsInaccesible (ctx, retval.GetSignatureForError (), loc);
170 retval = LookupType (ctx, name, -System.Math.Max (1, arity), LookupMode.Probing, loc);
171 if (retval != null) {
172 Error_TypeArgumentsCannotBeUsed (ctx, retval.Type, arity, loc);
177 if (arity > 0 && namespaces.TryGetValue (name, out ns)) {
178 ns.Error_TypeArgumentsCannotBeUsed (ctx, null, arity, loc);
182 if (this is GlobalRootNamespace) {
183 ctx.Module.Compiler.Report.Error (400, loc,
184 "The type or namespace name `{0}' could not be found in the global namespace (are you missing an assembly reference?)",
187 ctx.Module.Compiler.Report.Error (234, loc,
188 "The type or namespace name `{0}' does not exist in the namespace `{1}'. Are you missing an assembly reference?",
189 name, GetSignatureForError ());
193 public override string GetSignatureForError ()
198 public Namespace AddNamespace (MemberName name)
201 if (name.Left != null) {
203 ns_parent = parent.AddNamespace (name.Left);
205 ns_parent = AddNamespace (name.Left);
211 if (!ns_parent.namespaces.TryGetValue (name.Basename, out ns)) {
212 ns = new Namespace (ns_parent, name.Basename);
213 ns_parent.namespaces.Add (name.Basename, ns);
219 // TODO: Replace with CreateNamespace where MemberName is created for the method call
220 public Namespace GetNamespace (string name, bool create)
222 int pos = name.IndexOf ('.');
227 first = name.Substring (0, pos);
231 if (!namespaces.TryGetValue (first, out ns)) {
235 ns = new Namespace (this, first);
236 namespaces.Add (first, ns);
240 ns = ns.GetNamespace (name.Substring (pos + 1), create);
245 public IList<TypeSpec> GetAllTypes (string name)
247 IList<TypeSpec> found;
248 if (types == null || !types.TryGetValue (name, out found))
254 public TypeExpr LookupType (IMemberContext ctx, string name, int arity, LookupMode mode, Location loc)
260 if (arity == 0 && cached_types.TryGetValue (name, out te))
263 IList<TypeSpec> found;
264 if (!types.TryGetValue (name, out found))
267 TypeSpec best = null;
268 foreach (var ts in found) {
269 if (ts.Arity == arity) {
271 if ((ts.Modifiers & Modifiers.INTERNAL) != 0 && !ts.MemberDefinition.IsInternalAsPublic (ctx.Module.DeclaringAssembly) && mode != LookupMode.IgnoreAccessibility)
278 if (best.MemberDefinition.IsImported && ts.MemberDefinition.IsImported) {
279 if (mode == LookupMode.Normal) {
280 ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (best);
281 ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ts);
282 ctx.Module.Compiler.Report.Error (433, loc, "The imported type `{0}' is defined multiple times", ts.GetSignatureForError ());
287 if (best.MemberDefinition.IsImported)
290 if ((best.Modifiers & Modifiers.INTERNAL) != 0 && !best.MemberDefinition.IsInternalAsPublic (ctx.Module.DeclaringAssembly))
293 if (mode != LookupMode.Normal)
296 if (ts.MemberDefinition.IsImported)
297 ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ts);
299 ctx.Module.Compiler.Report.Warning (436, 2, loc,
300 "The type `{0}' conflicts with the imported type of same name'. Ignoring the imported type definition",
301 best.GetSignatureForError ());
305 // Lookup for the best candidate with the closest arity match
310 } else if (System.Math.Abs (ts.Arity + arity) < System.Math.Abs (best.Arity + arity)) {
319 te = new TypeExpression (best, Location.Null);
321 // TODO MemberCache: Cache more
322 if (arity == 0 && mode == LookupMode.Normal)
323 cached_types.Add (name, te);
328 TypeSpec LookupType (string name, int arity)
333 IList<TypeSpec> found;
334 if (types.TryGetValue (name, out found)) {
335 TypeSpec best = null;
337 foreach (var ts in found) {
338 if (ts.Arity == arity)
342 // Lookup for the best candidate with closest arity match
347 } else if (System.Math.Abs (ts.Arity + arity) < System.Math.Abs (best.Arity + arity)) {
359 public FullNamedExpression LookupTypeOrNamespace (IMemberContext ctx, string name, int arity, LookupMode mode, Location loc)
361 var texpr = LookupType (ctx, name, arity, mode, loc);
364 if (arity == 0 && namespaces.TryGetValue (name, out ns)) {
368 if (mode != LookupMode.Probing) {
369 ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (texpr.Type);
370 // ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ns.loc, "");
371 ctx.Module.Compiler.Report.Warning (437, 2, loc,
372 "The type `{0}' conflicts with the imported namespace `{1}'. Using the definition found in the source file",
373 texpr.GetSignatureForError (), ns.GetSignatureForError ());
376 if (texpr.Type.MemberDefinition.IsImported)
384 // Completes types with the given `prefix'
386 public IEnumerable<string> CompletionGetTypesStartingWith (string prefix)
389 return Enumerable.Empty<string> ();
391 var res = from item in types
392 where item.Key.StartsWith (prefix) && item.Value.Any (l => (l.Modifiers & Modifiers.PUBLIC) != 0)
395 if (namespaces != null)
396 res = res.Concat (from item in namespaces where item.Key.StartsWith (prefix) select item.Key);
402 // Looks for extension method in this namespace
404 public List<MethodSpec> LookupExtensionMethod (IMemberContext invocationContext, TypeSpec extensionType, string name, int arity)
409 List<MethodSpec> found = null;
411 // TODO: Add per namespace flag when at least 1 type has extension
413 foreach (var tgroup in types.Values) {
414 foreach (var ts in tgroup) {
415 if ((ts.Modifiers & Modifiers.METHOD_EXTENSION) == 0)
418 var res = ts.MemberCache.FindExtensionMethods (invocationContext, extensionType, name, arity);
425 found.AddRange (res);
433 public void AddType (ModuleContainer module, TypeSpec ts)
436 types = new Dictionary<string, IList<TypeSpec>> (64);
440 IList<TypeSpec> existing;
441 if (types.TryGetValue (name, out existing)) {
442 TypeSpec better_type;
444 if (existing.Count == 1) {
446 if (ts.Arity == found.Arity) {
447 better_type = IsImportedTypeOverride (module, ts, found);
448 if (better_type == found)
451 if (better_type != null) {
452 existing [0] = better_type;
457 existing = new List<TypeSpec> ();
458 existing.Add (found);
459 types[name] = existing;
461 for (int i = 0; i < existing.Count; ++i) {
463 if (ts.Arity != found.Arity)
466 better_type = IsImportedTypeOverride (module, ts, found);
467 if (better_type == found)
470 if (better_type != null) {
471 existing.RemoveAt (i);
480 types.Add (name, new TypeSpec[] { ts });
485 // We import any types but in the situation there are same types
486 // but one has better visibility (either public or internal with friend)
487 // the less visible type is removed from the namespace cache
489 public static TypeSpec IsImportedTypeOverride (ModuleContainer module, TypeSpec ts, TypeSpec found)
491 var ts_accessible = (ts.Modifiers & Modifiers.PUBLIC) != 0 || ts.MemberDefinition.IsInternalAsPublic (module.DeclaringAssembly);
492 var found_accessible = (found.Modifiers & Modifiers.PUBLIC) != 0 || found.MemberDefinition.IsInternalAsPublic (module.DeclaringAssembly);
494 if (ts_accessible && !found_accessible)
497 // found is better always better for accessible or inaccessible ts
504 public void RemoveContainer (TypeContainer tc)
506 types.Remove (tc.Basename);
507 cached_types.Remove (tc.Basename);
510 public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc)
515 public void SetBuiltinType (BuiltinTypeSpec pts)
517 var found = types[pts.Name];
518 cached_types.Remove (pts.Name);
519 if (found.Count == 1) {
520 types[pts.Name][0] = pts;
522 throw new NotImplementedException ();
526 public void VerifyClsCompliance ()
528 if (types == null || cls_checked)
533 // TODO: This is quite ugly way to check for CLS compliance at namespace level
535 var locase_types = new Dictionary<string, List<TypeSpec>> (StringComparer.OrdinalIgnoreCase);
536 foreach (var tgroup in types.Values) {
537 foreach (var tm in tgroup) {
538 if ((tm.Modifiers & Modifiers.PUBLIC) == 0 || !tm.IsCLSCompliant ())
541 List<TypeSpec> found;
542 if (!locase_types.TryGetValue (tm.Name, out found)) {
543 found = new List<TypeSpec> ();
544 locase_types.Add (tm.Name, found);
551 foreach (var locase in locase_types.Values) {
552 if (locase.Count < 2)
555 bool all_same = true;
556 foreach (var notcompliant in locase) {
557 all_same = notcompliant.Name == locase[0].Name;
565 TypeContainer compiled = null;
566 foreach (var notcompliant in locase) {
567 if (!notcompliant.MemberDefinition.IsImported) {
568 if (compiled != null)
569 compiled.Compiler.Report.SymbolRelatedToPreviousError (compiled);
571 compiled = notcompliant.MemberDefinition as TypeContainer;
573 compiled.Compiler.Report.SymbolRelatedToPreviousError (notcompliant);
577 compiled.Compiler.Report.Warning (3005, 1, compiled.Location,
578 "Identifier `{0}' differing only in case is not CLS-compliant", compiled.GetSignatureForError ());
584 // Namespace block as created by the parser
586 public class NamespaceContainer : TypeContainer, IMemberContext
588 static readonly Namespace[] empty_namespaces = new Namespace[0];
589 static readonly string[] empty_using_list = new string[0];
593 readonly ModuleContainer module;
594 readonly CompilationSourceFile file;
596 public new readonly NamespaceContainer Parent;
600 List<UsingNamespace> clauses;
602 // Used by parsed to check for parser errors
603 public bool DeclarationFound;
605 Namespace[] namespace_using_table;
606 Dictionary<string, UsingAliasNamespace> aliases;
608 public NamespaceContainer (MemberName name, ModuleContainer module, NamespaceContainer parent, CompilationSourceFile sourceFile)
609 : base ((TypeContainer) parent ?? module, name, null, MemberKind.Namespace)
611 this.module = module;
612 this.Parent = parent;
613 this.file = sourceFile;
616 ns = parent.NS.AddNamespace (name);
617 else if (name != null)
618 ns = module.GlobalRootNamespace.AddNamespace (name);
620 ns = module.GlobalRootNamespace;
622 containers = new List<TypeContainer> ();
627 public override AttributeTargets AttributeTargets {
629 throw new NotSupportedException ();
633 public override string DocCommentHeader {
635 throw new NotSupportedException ();
639 public Namespace NS {
645 public override ModuleContainer Module {
651 public CompilationSourceFile SourceFile {
657 public List<UsingNamespace> Usings {
663 public override string[] ValidAttributeTargets {
665 throw new NotSupportedException ();
671 public void AddUsing (UsingNamespace un)
673 if (DeclarationFound){
674 Compiler.Report.Error (1529, un.Location, "A using clause must precede all other namespace elements except extern alias declarations");
678 clauses = new List<UsingNamespace> ();
683 public void AddUsing (UsingAliasNamespace un)
685 if (DeclarationFound){
686 Compiler.Report.Error (1529, un.Location, "A using clause must precede all other namespace elements except extern alias declarations");
692 void AddAlias (UsingAliasNamespace un)
694 if (clauses == null) {
695 clauses = new List<UsingNamespace> ();
697 foreach (var entry in clauses) {
698 var a = entry as UsingAliasNamespace;
699 if (a != null && a.Alias.Value == un.Alias.Value) {
700 Compiler.Report.SymbolRelatedToPreviousError (a.Location, "");
701 Compiler.Report.Error (1537, un.Location,
702 "The using alias `{0}' appeared previously in this namespace", un.Alias.Value);
710 public override void AddPartial (TypeDefinition next_part)
712 var existing = ns.LookupType (this, next_part.MemberName.Name, next_part.MemberName.Arity, LookupMode.Probing, Location.Null);
713 var td = existing != null ? existing.Type.MemberDefinition as TypeDefinition : null;
714 AddPartial (next_part, td);
717 public override void AddTypeContainer (TypeContainer tc)
719 string name = tc.Basename;
721 var mn = tc.MemberName;
722 while (mn.Left != null) {
728 if (defined_names.TryGetValue (name, out mc)) {
729 if (tc is NamespaceContainer && mc is NamespaceContainer) {
734 Report.SymbolRelatedToPreviousError (mc);
735 if ((mc.ModFlags & Modifiers.PARTIAL) != 0 && (tc is ClassOrStruct || tc is Interface)) {
736 Error_MissingPartialModifier (tc);
738 Report.Error (101, tc.Location, "The namespace `{0}' already contains a definition for `{1}'",
739 GetSignatureForError (), mn.GetSignatureForError ());
742 defined_names.Add (name, tc);
745 base.AddTypeContainer (tc);
747 var tdef = tc.PartialContainer;
749 ns.AddType (module, tdef.Definition);
752 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
754 throw new NotSupportedException ();
757 public override void EmitContainer ()
759 VerifyClsCompliance ();
761 base.EmitContainer ();
765 // Does extension methods look up to find a method which matches name and extensionType.
766 // Search starts from this namespace and continues hierarchically up to top level.
768 protected override ExtensionMethodCandidates LookupExtensionMethod (IMemberContext invocationContext, TypeSpec extensionType, string name, int arity)
770 return LookupExtensionMethod (invocationContext, extensionType, name, arity, this, 0);
773 public ExtensionMethodCandidates LookupExtensionMethod (IMemberContext invocationContext, TypeSpec extensionType, string name, int arity, NamespaceContainer container, int position)
776 // Here we try to resume the search for extension method at the point
777 // where the last bunch of candidates was found. It's more tricky than
778 // it seems as we have to check both namespace containers and namespace
786 // <our first search found candidates in A.B.C.D
790 // In the example above namespace A.B.C.D, A.B.C and A.B have to be
791 // checked before we hit A.N1 using
793 ExtensionMethodCandidates candidates;
794 for (; container != null; container = container.Parent) {
795 candidates = container.LookupExtensionMethodCandidates (invocationContext, extensionType, name, arity, ref position);
796 if (candidates != null || container.MemberName == null)
799 var container_ns = container.ns.Parent;
800 var mn = container.MemberName.Left;
801 int already_checked = position - 2;
802 while (already_checked-- > 0) {
804 container_ns = container_ns.Parent;
810 var methods = container_ns.LookupExtensionMethod (invocationContext, extensionType, name, arity);
811 if (methods != null) {
812 return new ExtensionMethodCandidates (invocationContext, methods, container, position);
816 container_ns = container_ns.Parent;
825 ExtensionMethodCandidates LookupExtensionMethodCandidates (IMemberContext invocationContext, TypeSpec extensionType, string name, int arity, ref int position)
827 List<MethodSpec> candidates = null;
832 candidates = ns.LookupExtensionMethod (invocationContext, extensionType, name, arity);
833 if (candidates != null) {
834 return new ExtensionMethodCandidates (invocationContext, candidates, this, position);
841 foreach (Namespace n in namespace_using_table) {
842 var a = n.LookupExtensionMethod (invocationContext, extensionType, name, arity);
846 if (candidates == null)
849 candidates.AddRange (a);
852 if (candidates != null)
853 return new ExtensionMethodCandidates (invocationContext, candidates, this, position);
859 public override FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
862 // Only simple names (no dots) will be looked up with this function
864 FullNamedExpression resolved;
865 for (NamespaceContainer container = this; container != null; container = container.Parent) {
866 resolved = container.Lookup (name, arity, mode, loc);
867 if (resolved != null || container.MemberName == null)
870 var container_ns = container.ns.Parent;
871 var mn = container.MemberName.Left;
873 resolved = container_ns.LookupTypeOrNamespace (this, name, arity, mode, loc);
874 if (resolved != null)
878 container_ns = container_ns.Parent;
885 public override void GetCompletionStartingWith (string prefix, List<string> results)
887 foreach (var un in Usings) {
888 if (un.Alias != null)
891 var name = un.NamespaceExpression.Name;
892 if (name.StartsWith (prefix))
897 IEnumerable<string> all = Enumerable.Empty<string> ();
899 foreach (Namespace using_ns in namespace_using_table) {
900 if (prefix.StartsWith (using_ns.Name)) {
901 int ld = prefix.LastIndexOf ('.');
903 string rest = prefix.Substring (ld + 1);
905 all = all.Concat (using_ns.CompletionGetTypesStartingWith (rest));
908 all = all.Concat (using_ns.CompletionGetTypesStartingWith (prefix));
911 results.AddRange (all);
913 base.GetCompletionStartingWith (prefix, results);
918 // Looks-up a alias named @name in this and surrounding namespace declarations
920 public FullNamedExpression LookupExternAlias (string name)
925 UsingAliasNamespace uan;
926 if (aliases.TryGetValue (name, out uan) && uan is UsingExternAlias)
927 return uan.ResolvedExpression;
933 // Looks-up a alias named @name in this and surrounding namespace declarations
935 public override FullNamedExpression LookupNamespaceAlias (string name)
937 for (NamespaceContainer n = this; n != null; n = n.Parent) {
938 if (n.aliases == null)
941 UsingAliasNamespace uan;
942 if (n.aliases.TryGetValue (name, out uan))
943 return uan.ResolvedExpression;
949 FullNamedExpression Lookup (string name, int arity, LookupMode mode, Location loc)
952 // Check whether it's in the namespace.
954 FullNamedExpression fne = ns.LookupTypeOrNamespace (this, name, arity, mode, loc);
959 if (aliases != null && arity == 0) {
960 UsingAliasNamespace uan;
961 if (aliases.TryGetValue (name, out uan)) {
963 // TODO: Namespace has broken location
964 //Report.SymbolRelatedToPreviousError (fne.Location, null);
965 Compiler.Report.SymbolRelatedToPreviousError (uan.Location, null);
966 Compiler.Report.Error (576, loc,
967 "Namespace `{0}' contains a definition with same name as alias `{1}'",
968 GetSignatureForError (), name);
971 return uan.ResolvedExpression;
979 // Lookup can be called before the namespace is defined from different namespace using alias clause
981 if (namespace_using_table == null) {
982 DoDefineNamespace ();
986 // Check using entries.
988 FullNamedExpression match = null;
989 foreach (Namespace using_ns in namespace_using_table) {
991 // A using directive imports only types contained in the namespace, it
992 // does not import any nested namespaces
994 fne = using_ns.LookupType (this, name, arity, mode, loc);
1003 // Prefer types over namespaces
1004 var texpr_fne = fne as TypeExpr;
1005 var texpr_match = match as TypeExpr;
1006 if (texpr_fne != null && texpr_match == null) {
1009 } else if (texpr_fne == null) {
1013 // It can be top level accessibility only
1014 var better = Namespace.IsImportedTypeOverride (module, texpr_match.Type, texpr_fne.Type);
1015 if (better == null) {
1016 if (mode == LookupMode.Normal) {
1017 Compiler.Report.SymbolRelatedToPreviousError (texpr_match.Type);
1018 Compiler.Report.SymbolRelatedToPreviousError (texpr_fne.Type);
1019 Compiler.Report.Error (104, loc, "`{0}' is an ambiguous reference between `{1}' and `{2}'",
1020 name, texpr_match.GetSignatureForError (), texpr_fne.GetSignatureForError ());
1026 if (better == texpr_fne.Type)
1033 public int SymbolFileID {
1035 if (symfile_id == 0 && file.SourceFileEntry != null) {
1036 int parent_id = Parent == null ? 0 : Parent.SymbolFileID;
1038 string [] using_list = empty_using_list;
1039 if (clauses != null) {
1040 // TODO: Why is it needed, what to do with aliases
1041 var ul = new List<string> ();
1042 foreach (var c in clauses) {
1043 ul.Add (c.ResolvedExpression.GetSignatureForError ());
1046 using_list = ul.ToArray ();
1049 symfile_id = SymbolWriter.DefineNamespace (ns.Name, file.CompileUnitEntry, using_list, parent_id);
1055 static void MsgtryRef (string s)
1057 Console.WriteLine (" Try using -r:" + s);
1060 static void MsgtryPkg (string s)
1062 Console.WriteLine (" Try using -pkg:" + s);
1065 public static void Error_NamespaceNotFound (Location loc, string name, Report Report)
1067 Report.Error (246, loc, "The type or namespace name `{0}' could not be found. Are you missing a using directive or an assembly reference?",
1071 case "Gtk": case "GtkSharp":
1072 MsgtryPkg ("gtk-sharp-2.0");
1075 case "Gdk": case "GdkSharp":
1076 MsgtryPkg ("gdk-sharp-2.0");
1079 case "Glade": case "GladeSharp":
1080 MsgtryPkg ("glade-sharp-2.0");
1083 case "System.Drawing":
1084 case "System.Web.Services":
1087 case "System.Windows.Forms":
1093 protected override void DefineNamespace ()
1095 if (namespace_using_table == null)
1096 DoDefineNamespace ();
1098 base.DefineNamespace ();
1101 void DoDefineNamespace ()
1103 namespace_using_table = empty_namespaces;
1105 if (clauses != null) {
1106 var list = new List<Namespace> (clauses.Count);
1107 bool post_process_using_aliases = false;
1109 for (int i = 0; i < clauses.Count; ++i) {
1110 var entry = clauses[i];
1112 if (entry.Alias != null) {
1113 if (aliases == null)
1114 aliases = new Dictionary<string, UsingAliasNamespace> ();
1117 // Aliases are not available when resolving using section
1118 // except extern aliases
1120 if (entry is UsingExternAlias) {
1121 entry.Define (this);
1122 if (entry.ResolvedExpression != null)
1123 aliases.Add (entry.Alias.Value, (UsingExternAlias) entry);
1125 clauses.RemoveAt (i--);
1127 post_process_using_aliases = true;
1133 entry.Define (this);
1135 Namespace using_ns = entry.ResolvedExpression as Namespace;
1136 if (using_ns == null)
1139 if (list.Contains (using_ns)) {
1140 Compiler.Report.Warning (105, 3, entry.Location,
1141 "The using directive for `{0}' appeared previously in this namespace", using_ns.GetSignatureForError ());
1143 list.Add (using_ns);
1147 namespace_using_table = list.ToArray ();
1149 if (post_process_using_aliases) {
1150 for (int i = 0; i < clauses.Count; ++i) {
1151 var entry = clauses[i];
1152 if (entry.Alias != null) {
1153 entry.Define (this);
1154 if (entry.ResolvedExpression != null) {
1155 aliases.Add (entry.Alias.Value, (UsingAliasNamespace) entry);
1158 clauses.RemoveAt (i--);
1165 public void EnableUsingClausesRedefinition ()
1167 namespace_using_table = null;
1170 internal override void GenerateDocComment (DocumentationBuilder builder)
1172 if (containers != null) {
1173 foreach (var tc in containers)
1174 tc.GenerateDocComment (builder);
1178 public override string GetSignatureForError ()
1180 return MemberName == null ? "global::" : base.GetSignatureForError ();
1183 public override void RemoveContainer (TypeContainer next_part)
1185 base.RemoveContainer (next_part);
1186 NS.RemoveContainer (next_part);
1189 protected override bool VerifyClsCompliance ()
1191 if (Module.IsClsComplianceRequired ()) {
1192 if (MemberName != null && MemberName.Name[0] == '_') {
1193 Warning_IdentifierNotCompliant ();
1196 ns.VerifyClsCompliance ();
1204 public class UsingNamespace
1206 readonly ATypeNameExpression expr;
1207 readonly Location loc;
1208 protected FullNamedExpression resolved;
1210 public UsingNamespace (ATypeNameExpression expr, Location loc)
1218 public virtual SimpleMemberName Alias {
1224 public Location Location {
1230 public ATypeNameExpression NamespaceExpression {
1236 public FullNamedExpression ResolvedExpression {
1244 public string GetSignatureForError ()
1246 return expr.GetSignatureForError ();
1249 public virtual void Define (NamespaceContainer ctx)
1251 resolved = expr.ResolveAsTypeOrNamespace (ctx);
1252 var ns = resolved as Namespace;
1254 if (resolved != null) {
1255 ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (resolved.Type);
1256 ctx.Module.Compiler.Report.Error (138, Location,
1257 "`{0}' is a type not a namespace. A using namespace directive can only be applied to namespaces",
1258 GetSignatureForError ());
1264 public class UsingExternAlias : UsingAliasNamespace
1266 public UsingExternAlias (SimpleMemberName alias, Location loc)
1267 : base (alias, null, loc)
1271 public override void Define (NamespaceContainer ctx)
1273 resolved = ctx.Module.GetRootNamespace (Alias.Value);
1274 if (resolved == null) {
1275 ctx.Module.Compiler.Report.Error (430, Location,
1276 "The extern alias `{0}' was not specified in -reference option",
1282 public class UsingAliasNamespace : UsingNamespace
1284 readonly SimpleMemberName alias;
1286 public struct AliasContext : IMemberContext
1288 readonly NamespaceContainer ns;
1290 public AliasContext (NamespaceContainer ns)
1295 public TypeSpec CurrentType {
1301 public TypeParameters CurrentTypeParameters {
1307 public MemberCore CurrentMemberDefinition {
1313 public bool IsObsolete {
1319 public bool IsUnsafe {
1321 throw new NotImplementedException ();
1325 public bool IsStatic {
1327 throw new NotImplementedException ();
1331 public ModuleContainer Module {
1337 public string GetSignatureForError ()
1339 throw new NotImplementedException ();
1342 public ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity)
1347 public FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
1349 var fne = ns.NS.LookupTypeOrNamespace (ns, name, arity, mode, loc);
1354 // Only extern aliases are allowed in this context
1356 fne = ns.LookupExternAlias (name);
1357 if (fne != null || ns.MemberName == null)
1360 var container_ns = ns.NS.Parent;
1361 var mn = ns.MemberName.Left;
1362 while (mn != null) {
1363 fne = container_ns.LookupTypeOrNamespace (this, name, arity, mode, loc);
1368 container_ns = container_ns.Parent;
1371 if (ns.Parent != null)
1372 return ns.Parent.LookupNamespaceOrType (name, arity, mode, loc);
1377 public FullNamedExpression LookupNamespaceAlias (string name)
1379 return ns.LookupNamespaceAlias (name);
1383 public UsingAliasNamespace (SimpleMemberName alias, ATypeNameExpression expr, Location loc)
1389 public override SimpleMemberName Alias {
1395 public override void Define (NamespaceContainer ctx)
1398 // The namespace-or-type-name of a using-alias-directive is resolved as if
1399 // the immediately containing compilation unit or namespace body had no
1400 // using-directives. A using-alias-directive may however be affected
1401 // by extern-alias-directives in the immediately containing compilation
1402 // unit or namespace body
1404 // We achieve that by introducing alias-context which redirect any local
1405 // namespace or type resolve calls to parent namespace
1407 resolved = NamespaceExpression.ResolveAsTypeOrNamespace (new AliasContext (ctx));