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;
15
using Mono.CompilerServices.SymbolWriter;
17
namespace Mono.CSharp {
19
public class RootNamespace : Namespace {
21
readonly string alias_name;
22
readonly Dictionary<string, Namespace> all_namespaces;
24
public RootNamespace (string alias_name)
25
: base (null, String.Empty)
27
this.alias_name = alias_name;
29
all_namespaces = new Dictionary<string, Namespace> ();
30
all_namespaces.Add ("", this);
39
public static void Error_GlobalNamespaceRedefined (Report report, Location loc)
41
report.Error (1681, loc, "The global extern alias cannot be redefined");
44
public void RegisterNamespace (Namespace child)
47
all_namespaces.Add (child.Name, child);
50
public bool IsNamespace (string name)
52
return all_namespaces.ContainsKey (name);
55
protected void RegisterNamespace (string dotted_name)
57
if (dotted_name != null && dotted_name.Length != 0 && ! IsNamespace (dotted_name))
58
GetNamespace (dotted_name, true);
61
public override string GetSignatureForError ()
63
return alias_name + "::";
67
public class GlobalRootNamespace : RootNamespace
69
public GlobalRootNamespace ()
76
// Namespace cache for imported and compiled namespaces
78
// This is an Expression to allow it to be referenced in the
79
// compiler parse/intermediate tree during name resolution.
81
public class Namespace : FullNamedExpression
85
protected Dictionary<string, Namespace> namespaces;
86
protected Dictionary<string, IList<TypeSpec>> types;
87
List<TypeSpec> extension_method_types;
88
Dictionary<string, TypeExpr> cached_types;
92
public readonly MemberName MemberName;
95
/// Constructor Takes the current namespace and the
96
/// name. This is bootstrapped with parent == null
99
public Namespace (Namespace parent, string name)
101
// Expression members.
102
this.eclass = ExprClass.Namespace;
103
this.Type = InternalType.Namespace;
104
this.loc = Location.Null;
106
this.parent = parent;
109
this.root = parent.root;
111
this.root = this as RootNamespace;
113
if (this.root == null)
114
throw new InternalErrorException ("Root namespaces must be created using RootNamespace");
116
string pname = parent != null ? parent.fullname : "";
121
fullname = parent.fullname + "." + name;
123
if (fullname == null)
124
throw new InternalErrorException ("Namespace has a null fullname");
126
if (parent != null && parent.MemberName != MemberName.Null)
127
MemberName = new MemberName (parent.MemberName, name, Location.Null);
128
else if (name.Length == 0)
129
MemberName = MemberName.Null;
131
MemberName = new MemberName (name, Location.Null);
133
namespaces = new Dictionary<string, Namespace> ();
134
cached_types = new Dictionary<string, TypeExpr> ();
136
root.RegisterNamespace (this);
142
/// The qualified name of the current namespace
145
get { return fullname; }
149
/// The parent of this namespace, used by the parser to "Pop"
150
/// the current namespace declaration
152
public Namespace Parent {
153
get { return parent; }
158
protected override Expression DoResolve (ResolveContext ec)
163
public void Error_NamespaceDoesNotExist (IMemberContext ctx, string name, int arity, Location loc)
165
var retval = LookupType (ctx, name, arity, LookupMode.IgnoreAccessibility, loc);
166
if (retval != null) {
167
ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (retval.Type);
168
ErrorIsInaccesible (ctx, retval.GetSignatureForError (), loc);
172
retval = LookupType (ctx, name, -System.Math.Max (1, arity), LookupMode.Probing, loc);
173
if (retval != null) {
174
Error_TypeArgumentsCannotBeUsed (ctx, retval.Type, arity, loc);
179
if (arity > 0 && namespaces.TryGetValue (name, out ns)) {
180
ns.Error_TypeArgumentsCannotBeUsed (ctx, null, arity, loc);
184
if (this is GlobalRootNamespace) {
185
ctx.Module.Compiler.Report.Error (400, loc,
186
"The type or namespace name `{0}' could not be found in the global namespace (are you missing an assembly reference?)",
189
ctx.Module.Compiler.Report.Error (234, loc,
190
"The type or namespace name `{0}' does not exist in the namespace `{1}'. Are you missing an assembly reference?",
191
name, GetSignatureForError ());
195
public override string GetSignatureForError ()
200
public Namespace AddNamespace (MemberName name)
203
if (name.Left != null) {
205
ns_parent = parent.AddNamespace (name.Left);
207
ns_parent = AddNamespace (name.Left);
213
if (!ns_parent.namespaces.TryGetValue (name.Basename, out ns)) {
214
ns = new Namespace (ns_parent, name.Basename);
215
ns_parent.namespaces.Add (name.Basename, ns);
221
// TODO: Replace with CreateNamespace where MemberName is created for the method call
222
public Namespace GetNamespace (string name, bool create)
224
int pos = name.IndexOf ('.');
229
first = name.Substring (0, pos);
233
if (!namespaces.TryGetValue (first, out ns)) {
237
ns = new Namespace (this, first);
238
namespaces.Add (first, ns);
242
ns = ns.GetNamespace (name.Substring (pos + 1), create);
247
public IList<TypeSpec> GetAllTypes (string name)
249
IList<TypeSpec> found;
250
if (types == null || !types.TryGetValue (name, out found))
256
public TypeExpr LookupType (IMemberContext ctx, string name, int arity, LookupMode mode, Location loc)
262
if (arity == 0 && cached_types.TryGetValue (name, out te))
265
IList<TypeSpec> found;
266
if (!types.TryGetValue (name, out found))
269
TypeSpec best = null;
270
foreach (var ts in found) {
271
if (ts.Arity == arity) {
273
if ((ts.Modifiers & Modifiers.INTERNAL) != 0 && !ts.MemberDefinition.IsInternalAsPublic (ctx.Module.DeclaringAssembly) && mode != LookupMode.IgnoreAccessibility)
280
if (best.MemberDefinition.IsImported && ts.MemberDefinition.IsImported) {
281
if (mode == LookupMode.Normal) {
282
ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (best);
283
ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ts);
284
ctx.Module.Compiler.Report.Error (433, loc, "The imported type `{0}' is defined multiple times", ts.GetSignatureForError ());
289
if (best.MemberDefinition.IsImported)
292
if ((best.Modifiers & Modifiers.INTERNAL) != 0 && !best.MemberDefinition.IsInternalAsPublic (ctx.Module.DeclaringAssembly))
295
if (mode != LookupMode.Normal)
298
if (ts.MemberDefinition.IsImported)
299
ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ts);
301
ctx.Module.Compiler.Report.Warning (436, 2, loc,
302
"The type `{0}' conflicts with the imported type of same name'. Ignoring the imported type definition",
303
best.GetSignatureForError ());
307
// Lookup for the best candidate with the closest arity match
312
} else if (System.Math.Abs (ts.Arity + arity) < System.Math.Abs (best.Arity + arity)) {
321
te = new TypeExpression (best, Location.Null);
323
// TODO MemberCache: Cache more
324
if (arity == 0 && mode == LookupMode.Normal)
325
cached_types.Add (name, te);
330
public FullNamedExpression LookupTypeOrNamespace (IMemberContext ctx, string name, int arity, LookupMode mode, Location loc)
332
var texpr = LookupType (ctx, name, arity, mode, loc);
335
if (arity == 0 && namespaces.TryGetValue (name, out ns)) {
339
if (mode != LookupMode.Probing) {
340
ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (texpr.Type);
341
// ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ns.loc, "");
342
ctx.Module.Compiler.Report.Warning (437, 2, loc,
343
"The type `{0}' conflicts with the imported namespace `{1}'. Using the definition found in the source file",
344
texpr.GetSignatureForError (), ns.GetSignatureForError ());
347
if (texpr.Type.MemberDefinition.IsImported)
355
// Completes types with the given `prefix'
357
public IEnumerable<string> CompletionGetTypesStartingWith (string prefix)
360
return Enumerable.Empty<string> ();
362
var res = from item in types
363
where item.Key.StartsWith (prefix) && item.Value.Any (l => (l.Modifiers & Modifiers.PUBLIC) != 0)
366
if (namespaces != null)
367
res = res.Concat (from item in namespaces where item.Key.StartsWith (prefix) select item.Key);
373
// Looks for extension method in this namespace
375
public List<MethodSpec> LookupExtensionMethod (IMemberContext invocationContext, TypeSpec extensionType, string name, int arity)
377
if (extension_method_types == null)
380
List<MethodSpec> found = null;
381
for (int i = 0; i < extension_method_types.Count; ++i) {
382
var ts = extension_method_types[i];
385
// When the list was built we didn't know what members the type
388
if ((ts.Modifiers & Modifiers.METHOD_EXTENSION) == 0) {
389
if (extension_method_types.Count == 1) {
390
extension_method_types = null;
394
extension_method_types.RemoveAt (i--);
398
var res = ts.MemberCache.FindExtensionMethods (invocationContext, extensionType, name, arity);
405
found.AddRange (res);
412
public void AddType (ModuleContainer module, TypeSpec ts)
415
types = new Dictionary<string, IList<TypeSpec>> (64);
418
if ((ts.IsStatic || ts.MemberDefinition.IsPartial) && ts.Arity == 0 &&
419
(ts.MemberDefinition.DeclaringAssembly == null || ts.MemberDefinition.DeclaringAssembly.HasExtensionMethod)) {
420
if (extension_method_types == null)
421
extension_method_types = new List<TypeSpec> ();
423
extension_method_types.Add (ts);
427
IList<TypeSpec> existing;
428
if (types.TryGetValue (name, out existing)) {
429
TypeSpec better_type;
431
if (existing.Count == 1) {
433
if (ts.Arity == found.Arity) {
434
better_type = IsImportedTypeOverride (module, ts, found);
435
if (better_type == found)
438
if (better_type != null) {
439
existing [0] = better_type;
444
existing = new List<TypeSpec> ();
445
existing.Add (found);
446
types[name] = existing;
448
for (int i = 0; i < existing.Count; ++i) {
450
if (ts.Arity != found.Arity)
453
better_type = IsImportedTypeOverride (module, ts, found);
454
if (better_type == found)
457
if (better_type != null) {
458
existing.RemoveAt (i);
467
types.Add (name, new TypeSpec[] { ts });
472
// We import any types but in the situation there are same types
473
// but one has better visibility (either public or internal with friend)
474
// the less visible type is removed from the namespace cache
476
public static TypeSpec IsImportedTypeOverride (ModuleContainer module, TypeSpec ts, TypeSpec found)
478
var ts_accessible = (ts.Modifiers & Modifiers.PUBLIC) != 0 || ts.MemberDefinition.IsInternalAsPublic (module.DeclaringAssembly);
479
var found_accessible = (found.Modifiers & Modifiers.PUBLIC) != 0 || found.MemberDefinition.IsInternalAsPublic (module.DeclaringAssembly);
481
if (ts_accessible && !found_accessible)
484
// found is better always better for accessible or inaccessible ts
491
public void RemoveContainer (TypeContainer tc)
493
types.Remove (tc.Basename);
494
cached_types.Remove (tc.Basename);
497
public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc)
502
public void SetBuiltinType (BuiltinTypeSpec pts)
504
var found = types[pts.Name];
505
cached_types.Remove (pts.Name);
506
if (found.Count == 1) {
507
types[pts.Name][0] = pts;
509
throw new NotImplementedException ();
513
public void VerifyClsCompliance ()
515
if (types == null || cls_checked)
520
// TODO: This is quite ugly way to check for CLS compliance at namespace level
522
var locase_types = new Dictionary<string, List<TypeSpec>> (StringComparer.OrdinalIgnoreCase);
523
foreach (var tgroup in types.Values) {
524
foreach (var tm in tgroup) {
525
if ((tm.Modifiers & Modifiers.PUBLIC) == 0 || !tm.IsCLSCompliant ())
528
List<TypeSpec> found;
529
if (!locase_types.TryGetValue (tm.Name, out found)) {
530
found = new List<TypeSpec> ();
531
locase_types.Add (tm.Name, found);
538
foreach (var locase in locase_types.Values) {
539
if (locase.Count < 2)
542
bool all_same = true;
543
foreach (var notcompliant in locase) {
544
all_same = notcompliant.Name == locase[0].Name;
552
TypeContainer compiled = null;
553
foreach (var notcompliant in locase) {
554
if (!notcompliant.MemberDefinition.IsImported) {
555
if (compiled != null)
556
compiled.Compiler.Report.SymbolRelatedToPreviousError (compiled);
558
compiled = notcompliant.MemberDefinition as TypeContainer;
560
compiled.Compiler.Report.SymbolRelatedToPreviousError (notcompliant);
564
compiled.Compiler.Report.Warning (3005, 1, compiled.Location,
565
"Identifier `{0}' differing only in case is not CLS-compliant", compiled.GetSignatureForError ());
570
public class CompilationSourceFile : NamespaceContainer
572
readonly SourceFile file;
573
CompileUnitEntry comp_unit;
574
Dictionary<string, SourceFile> include_files;
575
Dictionary<string, bool> conditionals;
577
public CompilationSourceFile (ModuleContainer parent, SourceFile sourceFile)
580
this.file = sourceFile;
583
public CompilationSourceFile (ModuleContainer parent)
588
public CompileUnitEntry SymbolUnitEntry {
594
public string FileName {
600
public SourceFile SourceFile {
606
public void AddIncludeFile (SourceFile file)
608
if (file == this.file)
611
if (include_files == null)
612
include_files = new Dictionary<string, SourceFile> ();
614
if (!include_files.ContainsKey (file.FullPathName))
615
include_files.Add (file.FullPathName, file);
618
public void AddDefine (string value)
620
if (conditionals == null)
621
conditionals = new Dictionary<string, bool> (2);
623
conditionals[value] = true;
626
public void AddUndefine (string value)
628
if (conditionals == null)
629
conditionals = new Dictionary<string, bool> (2);
631
conditionals[value] = false;
634
public override void PrepareEmit ()
636
var sw = Module.DeclaringAssembly.SymbolWriter;
638
CreateUnitSymbolInfo (sw);
645
// Creates symbol file index in debug symbol file
647
void CreateUnitSymbolInfo (MonoSymbolFile symwriter)
649
var si = file.CreateSymbolInfo (symwriter);
650
comp_unit = new CompileUnitEntry (symwriter, si);;
652
if (include_files != null) {
653
foreach (SourceFile include in include_files.Values) {
654
si = include.CreateSymbolInfo (symwriter);
655
comp_unit.AddFile (si);
660
public bool IsConditionalDefined (string value)
662
if (conditionals != null) {
664
if (conditionals.TryGetValue (value, out res))
667
// When conditional was undefined
668
if (conditionals.ContainsKey (value))
672
return Compiler.Settings.IsConditionalSymbolDefined (value);
678
// Namespace block as created by the parser
680
public class NamespaceContainer : TypeContainer, IMemberContext
682
static readonly Namespace[] empty_namespaces = new Namespace[0];
684
readonly Namespace ns;
686
public new readonly NamespaceContainer Parent;
688
List<UsingNamespace> clauses;
690
// Used by parsed to check for parser errors
691
public bool DeclarationFound;
693
Namespace[] namespace_using_table;
694
Dictionary<string, UsingAliasNamespace> aliases;
695
public readonly MemberName RealMemberName;
697
public NamespaceContainer (MemberName name, NamespaceContainer parent)
698
: base (parent, name, null, MemberKind.Namespace)
700
this.RealMemberName = name;
701
this.Parent = parent;
702
this.ns = parent.NS.AddNamespace (name);
704
containers = new List<TypeContainer> ();
707
protected NamespaceContainer (ModuleContainer parent)
708
: base (parent, null, null, MemberKind.Namespace)
710
ns = parent.GlobalRootNamespace;
711
containers = new List<TypeContainer> (2);
716
public override AttributeTargets AttributeTargets {
718
throw new NotSupportedException ();
722
public override string DocCommentHeader {
724
throw new NotSupportedException ();
728
public Namespace NS {
734
public List<UsingNamespace> Usings {
740
public override string[] ValidAttributeTargets {
742
throw new NotSupportedException ();
748
public void AddUsing (UsingNamespace un)
750
if (DeclarationFound){
751
Compiler.Report.Error (1529, un.Location, "A using clause must precede all other namespace elements except extern alias declarations");
755
clauses = new List<UsingNamespace> ();
760
public void AddUsing (UsingAliasNamespace un)
762
if (DeclarationFound){
763
Compiler.Report.Error (1529, un.Location, "A using clause must precede all other namespace elements except extern alias declarations");
769
void AddAlias (UsingAliasNamespace un)
771
if (clauses == null) {
772
clauses = new List<UsingNamespace> ();
774
foreach (var entry in clauses) {
775
var a = entry as UsingAliasNamespace;
776
if (a != null && a.Alias.Value == un.Alias.Value) {
777
Compiler.Report.SymbolRelatedToPreviousError (a.Location, "");
778
Compiler.Report.Error (1537, un.Location,
779
"The using alias `{0}' appeared previously in this namespace", un.Alias.Value);
787
public override void AddPartial (TypeDefinition next_part)
789
var existing = ns.LookupType (this, next_part.MemberName.Name, next_part.MemberName.Arity, LookupMode.Probing, Location.Null);
790
var td = existing != null ? existing.Type.MemberDefinition as TypeDefinition : null;
791
AddPartial (next_part, td);
794
public override void AddTypeContainer (TypeContainer tc)
796
string name = tc.Basename;
798
var mn = tc.MemberName;
799
while (mn.Left != null) {
804
var names_container = Parent == null ? Module : (TypeContainer) this;
807
if (names_container.DefinedNames.TryGetValue (name, out mc)) {
808
if (tc is NamespaceContainer && mc is NamespaceContainer) {
813
Report.SymbolRelatedToPreviousError (mc);
814
if ((mc.ModFlags & Modifiers.PARTIAL) != 0 && (tc is ClassOrStruct || tc is Interface)) {
815
Error_MissingPartialModifier (tc);
817
Report.Error (101, tc.Location, "The namespace `{0}' already contains a definition for `{1}'",
818
GetSignatureForError (), mn.GetSignatureForError ());
821
names_container.DefinedNames.Add (name, tc);
824
base.AddTypeContainer (tc);
826
var tdef = tc.PartialContainer;
828
ns.AddType (Module, tdef.Definition);
831
public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
833
throw new NotSupportedException ();
836
public override void EmitContainer ()
838
VerifyClsCompliance ();
840
base.EmitContainer ();
843
public ExtensionMethodCandidates LookupExtensionMethod (IMemberContext invocationContext, TypeSpec extensionType, string name, int arity, int position)
846
// Here we try to resume the search for extension method at the point
847
// where the last bunch of candidates was found. It's more tricky than
848
// it seems as we have to check both namespace containers and namespace
856
// <our first search found candidates in A.B.C.D
860
// In the example above namespace A.B.C.D, A.B.C and A.B have to be
861
// checked before we hit A.N1 using
863
ExtensionMethodCandidates candidates;
864
var container = this;
866
candidates = container.LookupExtensionMethodCandidates (invocationContext, extensionType, name, arity, ref position);
867
if (candidates != null || container.MemberName == null)
870
var container_ns = container.ns.Parent;
871
var mn = container.MemberName.Left;
872
int already_checked = position - 2;
873
while (already_checked-- > 0) {
875
container_ns = container_ns.Parent;
881
var methods = container_ns.LookupExtensionMethod (invocationContext, extensionType, name, arity);
882
if (methods != null) {
883
return new ExtensionMethodCandidates (invocationContext, methods, container, position);
887
container_ns = container_ns.Parent;
891
container = container.Parent;
892
} while (container != null);
897
ExtensionMethodCandidates LookupExtensionMethodCandidates (IMemberContext invocationContext, TypeSpec extensionType, string name, int arity, ref int position)
899
List<MethodSpec> candidates = null;
904
candidates = ns.LookupExtensionMethod (invocationContext, extensionType, name, arity);
905
if (candidates != null) {
906
return new ExtensionMethodCandidates (invocationContext, candidates, this, position);
913
foreach (Namespace n in namespace_using_table) {
914
var a = n.LookupExtensionMethod (invocationContext, extensionType, name, arity);
918
if (candidates == null)
921
candidates.AddRange (a);
924
if (candidates != null)
925
return new ExtensionMethodCandidates (invocationContext, candidates, this, position);
931
public override FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
934
// Only simple names (no dots) will be looked up with this function
936
FullNamedExpression resolved;
937
for (NamespaceContainer container = this; container != null; container = container.Parent) {
938
resolved = container.Lookup (name, arity, mode, loc);
939
if (resolved != null || container.MemberName == null)
942
var container_ns = container.ns.Parent;
943
var mn = container.MemberName.Left;
945
resolved = container_ns.LookupTypeOrNamespace (this, name, arity, mode, loc);
946
if (resolved != null)
950
container_ns = container_ns.Parent;
957
public override void GetCompletionStartingWith (string prefix, List<string> results)
959
foreach (var un in Usings) {
960
if (un.Alias != null)
963
var name = un.NamespaceExpression.Name;
964
if (name.StartsWith (prefix))
969
IEnumerable<string> all = Enumerable.Empty<string> ();
971
foreach (Namespace using_ns in namespace_using_table) {
972
if (prefix.StartsWith (using_ns.Name)) {
973
int ld = prefix.LastIndexOf ('.');
975
string rest = prefix.Substring (ld + 1);
977
all = all.Concat (using_ns.CompletionGetTypesStartingWith (rest));
980
all = all.Concat (using_ns.CompletionGetTypesStartingWith (prefix));
983
results.AddRange (all);
985
base.GetCompletionStartingWith (prefix, results);
990
// Looks-up a alias named @name in this and surrounding namespace declarations
992
public FullNamedExpression LookupExternAlias (string name)
997
UsingAliasNamespace uan;
998
if (aliases.TryGetValue (name, out uan) && uan is UsingExternAlias)
999
return uan.ResolvedExpression;
1005
// Looks-up a alias named @name in this and surrounding namespace declarations
1007
public override FullNamedExpression LookupNamespaceAlias (string name)
1009
for (NamespaceContainer n = this; n != null; n = n.Parent) {
1010
if (n.aliases == null)
1013
UsingAliasNamespace uan;
1014
if (n.aliases.TryGetValue (name, out uan))
1015
return uan.ResolvedExpression;
1021
FullNamedExpression Lookup (string name, int arity, LookupMode mode, Location loc)
1024
// Check whether it's in the namespace.
1026
FullNamedExpression fne = ns.LookupTypeOrNamespace (this, name, arity, mode, loc);
1031
if (aliases != null && arity == 0) {
1032
UsingAliasNamespace uan;
1033
if (aliases.TryGetValue (name, out uan)) {
1035
// TODO: Namespace has broken location
1036
//Report.SymbolRelatedToPreviousError (fne.Location, null);
1037
Compiler.Report.SymbolRelatedToPreviousError (uan.Location, null);
1038
Compiler.Report.Error (576, loc,
1039
"Namespace `{0}' contains a definition with same name as alias `{1}'",
1040
GetSignatureForError (), name);
1043
return uan.ResolvedExpression;
1051
// Lookup can be called before the namespace is defined from different namespace using alias clause
1053
if (namespace_using_table == null) {
1054
DoDefineNamespace ();
1058
// Check using entries.
1060
FullNamedExpression match = null;
1061
foreach (Namespace using_ns in namespace_using_table) {
1063
// A using directive imports only types contained in the namespace, it
1064
// does not import any nested namespaces
1066
fne = using_ns.LookupType (this, name, arity, mode, loc);
1070
if (match == null) {
1075
// Prefer types over namespaces
1076
var texpr_fne = fne as TypeExpr;
1077
var texpr_match = match as TypeExpr;
1078
if (texpr_fne != null && texpr_match == null) {
1081
} else if (texpr_fne == null) {
1085
// It can be top level accessibility only
1086
var better = Namespace.IsImportedTypeOverride (Module, texpr_match.Type, texpr_fne.Type);
1087
if (better == null) {
1088
if (mode == LookupMode.Normal) {
1089
Compiler.Report.SymbolRelatedToPreviousError (texpr_match.Type);
1090
Compiler.Report.SymbolRelatedToPreviousError (texpr_fne.Type);
1091
Compiler.Report.Error (104, loc, "`{0}' is an ambiguous reference between `{1}' and `{2}'",
1092
name, texpr_match.GetSignatureForError (), texpr_fne.GetSignatureForError ());
1098
if (better == texpr_fne.Type)
1105
static void MsgtryRef (string s)
1107
Console.WriteLine (" Try using -r:" + s);
1110
static void MsgtryPkg (string s)
1112
Console.WriteLine (" Try using -pkg:" + s);
1115
public static void Error_NamespaceNotFound (Location loc, string name, Report Report)
1117
Report.Error (246, loc, "The type or namespace name `{0}' could not be found. Are you missing a using directive or an assembly reference?",
1121
case "Gtk": case "GtkSharp":
1122
MsgtryPkg ("gtk-sharp-2.0");
1125
case "Gdk": case "GdkSharp":
1126
MsgtryPkg ("gdk-sharp-2.0");
1129
case "Glade": case "GladeSharp":
1130
MsgtryPkg ("glade-sharp-2.0");
1133
case "System.Drawing":
1134
case "System.Web.Services":
1137
case "System.Windows.Forms":
1143
protected override void DefineNamespace ()
1145
if (namespace_using_table == null)
1146
DoDefineNamespace ();
1148
base.DefineNamespace ();
1151
void DoDefineNamespace ()
1153
namespace_using_table = empty_namespaces;
1155
if (clauses != null) {
1156
var list = new List<Namespace> (clauses.Count);
1157
bool post_process_using_aliases = false;
1159
for (int i = 0; i < clauses.Count; ++i) {
1160
var entry = clauses[i];
1162
if (entry.Alias != null) {
1163
if (aliases == null)
1164
aliases = new Dictionary<string, UsingAliasNamespace> ();
1167
// Aliases are not available when resolving using section
1168
// except extern aliases
1170
if (entry is UsingExternAlias) {
1171
entry.Define (this);
1172
if (entry.ResolvedExpression != null)
1173
aliases.Add (entry.Alias.Value, (UsingExternAlias) entry);
1175
clauses.RemoveAt (i--);
1177
post_process_using_aliases = true;
1183
entry.Define (this);
1185
Namespace using_ns = entry.ResolvedExpression as Namespace;
1186
if (using_ns == null)
1189
if (list.Contains (using_ns)) {
1190
Compiler.Report.Warning (105, 3, entry.Location,
1191
"The using directive for `{0}' appeared previously in this namespace", using_ns.GetSignatureForError ());
1193
list.Add (using_ns);
1197
namespace_using_table = list.ToArray ();
1199
if (post_process_using_aliases) {
1200
for (int i = 0; i < clauses.Count; ++i) {
1201
var entry = clauses[i];
1202
if (entry.Alias != null) {
1203
entry.Define (this);
1204
if (entry.ResolvedExpression != null) {
1205
aliases.Add (entry.Alias.Value, (UsingAliasNamespace) entry);
1208
clauses.RemoveAt (i--);
1215
public void EnableUsingClausesRedefinition ()
1217
namespace_using_table = null;
1220
internal override void GenerateDocComment (DocumentationBuilder builder)
1222
if (containers != null) {
1223
foreach (var tc in containers)
1224
tc.GenerateDocComment (builder);
1228
public override string GetSignatureForError ()
1230
return MemberName == null ? "global::" : base.GetSignatureForError ();
1233
public override void RemoveContainer (TypeContainer cont)
1235
base.RemoveContainer (cont);
1236
NS.RemoveContainer (cont);
1239
protected override bool VerifyClsCompliance ()
1241
if (Module.IsClsComplianceRequired ()) {
1242
if (MemberName != null && MemberName.Name[0] == '_') {
1243
Warning_IdentifierNotCompliant ();
1246
ns.VerifyClsCompliance ();
1253
public override void Accept (StructuralVisitor visitor)
1255
visitor.Visit (this);
1259
public class UsingNamespace
1261
readonly ATypeNameExpression expr;
1262
readonly Location loc;
1263
protected FullNamedExpression resolved;
1265
public UsingNamespace (ATypeNameExpression expr, Location loc)
1273
public virtual SimpleMemberName Alias {
1279
public Location Location {
1285
public ATypeNameExpression NamespaceExpression {
1291
public FullNamedExpression ResolvedExpression {
1299
public string GetSignatureForError ()
1301
return expr.GetSignatureForError ();
1304
public virtual void Define (NamespaceContainer ctx)
1306
resolved = expr.ResolveAsTypeOrNamespace (ctx);
1307
var ns = resolved as Namespace;
1309
if (resolved != null) {
1310
ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (resolved.Type);
1311
ctx.Module.Compiler.Report.Error (138, Location,
1312
"`{0}' is a type not a namespace. A using namespace directive can only be applied to namespaces",
1313
GetSignatureForError ());
1318
public virtual void Accept (StructuralVisitor visitor)
1320
visitor.Visit (this);
1324
public class UsingExternAlias : UsingAliasNamespace
1326
public UsingExternAlias (SimpleMemberName alias, Location loc)
1327
: base (alias, null, loc)
1331
public override void Define (NamespaceContainer ctx)
1333
resolved = ctx.Module.GetRootNamespace (Alias.Value);
1334
if (resolved == null) {
1335
ctx.Module.Compiler.Report.Error (430, Location,
1336
"The extern alias `{0}' was not specified in -reference option",
1341
public override void Accept (StructuralVisitor visitor)
1343
visitor.Visit (this);
1347
public class UsingAliasNamespace : UsingNamespace
1349
readonly SimpleMemberName alias;
1351
public struct AliasContext : IMemberContext
1353
readonly NamespaceContainer ns;
1355
public AliasContext (NamespaceContainer ns)
1360
public TypeSpec CurrentType {
1366
public TypeParameters CurrentTypeParameters {
1372
public MemberCore CurrentMemberDefinition {
1378
public bool IsObsolete {
1384
public bool IsUnsafe {
1386
throw new NotImplementedException ();
1390
public bool IsStatic {
1392
throw new NotImplementedException ();
1396
public ModuleContainer Module {
1402
public string GetSignatureForError ()
1404
throw new NotImplementedException ();
1407
public ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity)
1412
public FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
1414
var fne = ns.NS.LookupTypeOrNamespace (ns, name, arity, mode, loc);
1419
// Only extern aliases are allowed in this context
1421
fne = ns.LookupExternAlias (name);
1422
if (fne != null || ns.MemberName == null)
1425
var container_ns = ns.NS.Parent;
1426
var mn = ns.MemberName.Left;
1427
while (mn != null) {
1428
fne = container_ns.LookupTypeOrNamespace (this, name, arity, mode, loc);
1433
container_ns = container_ns.Parent;
1436
if (ns.Parent != null)
1437
return ns.Parent.LookupNamespaceOrType (name, arity, mode, loc);
1442
public FullNamedExpression LookupNamespaceAlias (string name)
1444
return ns.LookupNamespaceAlias (name);
1448
public UsingAliasNamespace (SimpleMemberName alias, ATypeNameExpression expr, Location loc)
1454
public override SimpleMemberName Alias {
1460
public override void Define (NamespaceContainer ctx)
1463
// The namespace-or-type-name of a using-alias-directive is resolved as if
1464
// the immediately containing compilation unit or namespace body had no
1465
// using-directives. A using-alias-directive may however be affected
1466
// by extern-alias-directives in the immediately containing compilation
1467
// unit or namespace body
1469
// We achieve that by introducing alias-context which redirect any local
1470
// namespace or type resolve calls to parent namespace
1472
resolved = NamespaceExpression.ResolveAsTypeOrNamespace (new AliasContext (ctx));
1475
public override void Accept (StructuralVisitor visitor)
1477
visitor.Visit (this);