//
// Copyright 2001 Ximian, Inc.
// Copyright 2003-2008 Novell, Inc.
+// Copyright 2011 Xamarin Inc
//
using System;
using System.Collections.Generic;
using System.Linq;
+using Mono.CompilerServices.SymbolWriter;
namespace Mono.CSharp {
}
}
+ public static void Error_GlobalNamespaceRedefined (Report report, Location loc)
+ {
+ report.Error (1681, loc, "The global extern alias cannot be redefined");
+ }
+
+ //
+ // For better error reporting where we try to guess missing using directive
+ //
+ public List<string> FindTypeNamespaces (IMemberContext ctx, string name, int arity)
+ {
+ List<string> res = null;
+
+ foreach (var ns in all_namespaces) {
+ var type = ns.Value.LookupType (ctx, name, arity, LookupMode.Normal, Location.Null);
+ if (type != null) {
+ if (res == null)
+ res = new List<string> ();
+
+ res.Add (ns.Key);
+ }
+ }
+
+ return res;
+ }
+
+ //
+ // For better error reporting where compiler tries to guess missing using directive
+ //
+ public List<string> FindExtensionMethodNamespaces (IMemberContext ctx, TypeSpec extensionType, string name, int arity)
+ {
+ List<string> res = null;
+
+ foreach (var ns in all_namespaces) {
+ var methods = ns.Value.LookupExtensionMethod (ctx, extensionType, name, arity);
+ if (methods != null) {
+ if (res == null)
+ res = new List<string> ();
+
+ res.Add (ns.Key);
+ }
+ }
+
+ return res;
+ }
+
public void RegisterNamespace (Namespace child)
{
if (child != this)
: base ("global")
{
}
-
- public override void Error_NamespaceDoesNotExist (Location loc, string name, int arity, IMemberContext ctx)
- {
- ctx.Module.Compiler.Report.Error (400, loc,
- "The type or namespace name `{0}' could not be found in the global namespace (are you missing an assembly reference?)",
- name);
- }
}
//
string fullname;
protected Dictionary<string, Namespace> namespaces;
protected Dictionary<string, IList<TypeSpec>> types;
+ List<TypeSpec> extension_method_types;
Dictionary<string, TypeExpr> cached_types;
RootNamespace root;
bool cls_checked;
throw new InternalErrorException ("Namespace has a null fullname");
if (parent != null && parent.MemberName != MemberName.Null)
- MemberName = new MemberName (parent.MemberName, name);
+ MemberName = new MemberName (parent.MemberName, name, Location.Null);
else if (name.Length == 0)
MemberName = MemberName.Null;
else
- MemberName = new MemberName (name);
+ MemberName = new MemberName (name, Location.Null);
namespaces = new Dictionary<string, Namespace> ();
cached_types = new Dictionary<string, TypeExpr> ();
return this;
}
- public virtual void Error_NamespaceDoesNotExist (Location loc, string name, int arity, IMemberContext ctx)
+ public void Error_NamespaceDoesNotExist (IMemberContext ctx, string name, int arity, Location loc)
{
- var retval = LookupType (ctx, name, -System.Math.Max (1, arity), loc);
+ var retval = LookupType (ctx, name, arity, LookupMode.IgnoreAccessibility, loc);
+ if (retval != null) {
+ ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (retval.Type);
+ ErrorIsInaccesible (ctx, retval.GetSignatureForError (), loc);
+ return;
+ }
+
+ retval = LookupType (ctx, name, -System.Math.Max (1, arity), LookupMode.Probing, loc);
if (retval != null) {
Error_TypeArgumentsCannotBeUsed (ctx, retval.Type, arity, loc);
return;
return;
}
- ctx.Module.Compiler.Report.Error (234, loc,
- "The type or namespace name `{0}' does not exist in the namespace `{1}'. Are you missing an assembly reference?",
- name, GetSignatureForError ());
+ string assembly = null;
+ string possible_name = fullname + "." + name;
+
+ // Only assembly unique name should be added
+ switch (possible_name) {
+ case "System.Drawing":
+ case "System.Web.Services":
+ case "System.Web":
+ case "System.Data":
+ case "System.Configuration":
+ case "System.Data.Services":
+ case "System.DirectoryServices":
+ case "System.Json":
+ case "System.Net.Http":
+ case "System.Numerics":
+ case "System.Runtime.Caching":
+ case "System.ServiceModel":
+ case "System.Transactions":
+ case "System.Web.Routing":
+ case "System.Xml.Linq":
+ case "System.Xml":
+ assembly = possible_name;
+ break;
+
+ case "System.Linq":
+ case "System.Linq.Expressions":
+ assembly = "System.Core";
+ break;
+
+ case "System.Windows.Forms":
+ case "System.Windows.Forms.Layout":
+ assembly = "System.Windows.Name";
+ break;
+ }
+
+ assembly = assembly == null ? "an" : "`" + assembly + "'";
+
+ if (this is GlobalRootNamespace) {
+ ctx.Module.Compiler.Report.Error (400, loc,
+ "The type or namespace name `{0}' could not be found in the global namespace. Are you missing {1} assembly reference?",
+ name, assembly);
+ } else {
+ ctx.Module.Compiler.Report.Error (234, loc,
+ "The type or namespace name `{0}' does not exist in the namespace `{1}'. Are you missing {2} assembly reference?",
+ name, GetSignatureForError (), assembly);
+ }
}
public override string GetSignatureForError ()
{
return fullname;
}
-
+
+ public Namespace AddNamespace (MemberName name)
+ {
+ Namespace ns_parent;
+ if (name.Left != null) {
+ if (parent != null)
+ ns_parent = parent.AddNamespace (name.Left);
+ else
+ ns_parent = AddNamespace (name.Left);
+ } else {
+ ns_parent = this;
+ }
+
+ return ns_parent.TryAddNamespace (name.Basename);
+ }
+
+ Namespace TryAddNamespace (string name)
+ {
+ Namespace ns;
+
+ if (!namespaces.TryGetValue (name, out ns)) {
+ ns = new Namespace (this, name);
+ namespaces.Add (name, ns);
+ }
+
+ return ns;
+ }
+
+ // TODO: Replace with CreateNamespace where MemberName is created for the method call
public Namespace GetNamespace (string name, bool create)
{
int pos = name.IndexOf ('.');
return found;
}
- public TypeExpr LookupType (IMemberContext ctx, string name, int arity, Location loc)
+ public TypeExpr LookupType (IMemberContext ctx, string name, int arity, LookupMode mode, Location loc)
{
if (types == null)
return null;
foreach (var ts in found) {
if (ts.Arity == arity) {
if (best == null) {
+ if ((ts.Modifiers & Modifiers.INTERNAL) != 0 && !ts.MemberDefinition.IsInternalAsPublic (ctx.Module.DeclaringAssembly) && mode != LookupMode.IgnoreAccessibility)
+ continue;
+
best = ts;
continue;
}
if (best.MemberDefinition.IsImported && ts.MemberDefinition.IsImported) {
- ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (best);
- ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ts);
- ctx.Module.Compiler.Report.Error (433, loc, "The imported type `{0}' is defined multiple times", ts.GetSignatureForError ());
+ if (mode == LookupMode.Normal) {
+ ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (best);
+ ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ts);
+ ctx.Module.Compiler.Report.Error (433, loc, "The imported type `{0}' is defined multiple times", ts.GetSignatureForError ());
+ }
break;
}
if ((best.Modifiers & Modifiers.INTERNAL) != 0 && !best.MemberDefinition.IsInternalAsPublic (ctx.Module.DeclaringAssembly))
continue;
+ if (mode != LookupMode.Normal)
+ continue;
+
if (ts.MemberDefinition.IsImported)
ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ts);
}
//
- // Lookup for the best candidate with closest arity match
+ // Lookup for the best candidate with the closest arity match
//
if (arity < 0) {
if (best == null) {
if (best == null)
return null;
- if ((best.Modifiers & Modifiers.INTERNAL) != 0 && !best.MemberDefinition.IsInternalAsPublic (ctx.Module.DeclaringAssembly))
- return null;
-
te = new TypeExpression (best, Location.Null);
// TODO MemberCache: Cache more
- if (arity == 0)
+ if (arity == 0 && mode == LookupMode.Normal)
cached_types.Add (name, te);
return te;
}
- TypeSpec LookupType (string name, int arity)
+ public FullNamedExpression LookupTypeOrNamespace (IMemberContext ctx, string name, int arity, LookupMode mode, Location loc)
{
- if (types == null)
- return null;
-
- IList<TypeSpec> found;
- if (types.TryGetValue (name, out found)) {
- TypeSpec best = null;
-
- foreach (var ts in found) {
- if (ts.Arity == arity)
- return ts;
-
- //
- // Lookup for the best candidate with closest arity match
- //
- if (arity < 0) {
- if (best == null) {
- best = ts;
- } else if (System.Math.Abs (ts.Arity + arity) < System.Math.Abs (best.Arity + arity)) {
- best = ts;
- }
- }
- }
-
- return best;
- }
-
- return null;
- }
-
- public FullNamedExpression LookupTypeOrNamespace (IMemberContext ctx, string name, int arity, Location loc)
- {
- var texpr = LookupType (ctx, name, arity, loc);
+ var texpr = LookupType (ctx, name, arity, mode, loc);
Namespace ns;
if (arity == 0 && namespaces.TryGetValue (name, out ns)) {
if (texpr == null)
return ns;
- ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (texpr.Type);
- // ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ns.loc, "");
- ctx.Module.Compiler.Report.Warning (437, 2, loc,
- "The type `{0}' conflicts with the imported namespace `{1}'. Using the definition found in the source file",
- texpr.GetSignatureForError (), ns.GetSignatureForError ());
+ if (mode != LookupMode.Probing) {
+ ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (texpr.Type);
+ // ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ns.loc, "");
+ ctx.Module.Compiler.Report.Warning (437, 2, loc,
+ "The type `{0}' conflicts with the imported namespace `{1}'. Using the definition found in the source file",
+ texpr.GetSignatureForError (), ns.GetSignatureForError ());
+ }
if (texpr.Type.MemberDefinition.IsImported)
return ns;
return res;
}
- ///
- /// Looks for extension method in this namespace
- ///
+ //
+ // Looks for extension method in this namespace
+ //
public List<MethodSpec> LookupExtensionMethod (IMemberContext invocationContext, TypeSpec extensionType, string name, int arity)
{
- if (types == null)
+ if (extension_method_types == null)
return null;
List<MethodSpec> found = null;
+ for (int i = 0; i < extension_method_types.Count; ++i) {
+ var ts = extension_method_types[i];
- // TODO: Add per namespace flag when at least 1 type has extension
+ //
+ // When the list was built we didn't know what members the type
+ // contains
+ //
+ if ((ts.Modifiers & Modifiers.METHOD_EXTENSION) == 0) {
+ if (extension_method_types.Count == 1) {
+ extension_method_types = null;
+ return found;
+ }
- foreach (var tgroup in types.Values) {
- foreach (var ts in tgroup) {
- if ((ts.Modifiers & Modifiers.METHOD_EXTENSION) == 0)
- continue;
+ extension_method_types.RemoveAt (i--);
+ continue;
+ }
- var res = ts.MemberCache.FindExtensionMethods (invocationContext, extensionType, name, arity);
- if (res == null)
- continue;
+ var res = ts.MemberCache.FindExtensionMethods (invocationContext, extensionType, name, arity);
+ if (res == null)
+ continue;
- if (found == null) {
- found = res;
- } else {
- found.AddRange (res);
- }
+ if (found == null) {
+ found = res;
+ } else {
+ found.AddRange (res);
}
}
types = new Dictionary<string, IList<TypeSpec>> (64);
}
+ if (ts.IsClass && ts.Arity == 0) {
+ var extension_method_allowed = ts.MemberDefinition.IsImported ? (ts.Modifiers & Modifiers.METHOD_EXTENSION) != 0 : (ts.IsStatic || ts.MemberDefinition.IsPartial);
+ if (extension_method_allowed) {
+ if (extension_method_types == null)
+ extension_method_types = new List<TypeSpec> ();
+
+ extension_method_types.Add (ts);
+ }
+ }
+
var name = ts.Name;
IList<TypeSpec> existing;
if (types.TryGetValue (name, out existing)) {
return null;
}
- public void RemoveDeclSpace (string name)
+ public void RemoveContainer (TypeContainer tc)
{
- types.Remove (name);
- cached_types.Remove (name);
+ types.Remove (tc.Basename);
+ cached_types.Remove (tc.Basename);
}
public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc)
"Identifier `{0}' differing only in case is not CLS-compliant", compiled.GetSignatureForError ());
}
}
+
+ public override string ToString ()
+ {
+ return Name;
+ }
}
- //
- // Namespace block as created by the parser
- //
- public class NamespaceContainer : IMemberContext, ITypesContainer
+ public class CompilationSourceFile : NamespaceContainer
{
- Namespace ns;
-
- readonly ModuleContainer module;
- readonly NamespaceContainer parent;
- readonly CompilationSourceFile file;
- readonly Location loc;
-
- NamespaceContainer implicit_parent;
- int symfile_id;
-
- // Namespace using import block
- List<NamespaceUsingAlias> using_aliases;
- List<NamespaceUsing> using_clauses;
- public bool DeclarationFound;
- // End
-
- bool resolved;
-
- public readonly bool IsImplicit;
- public readonly TypeContainer SlaveDeclSpace;
- static readonly Namespace [] empty_namespaces = new Namespace [0];
- static readonly string[] empty_using_list = new string[0];
+ readonly SourceFile file;
+ CompileUnitEntry comp_unit;
+ Dictionary<string, SourceFile> include_files;
+ Dictionary<string, bool> conditionals;
- Namespace [] namespace_using_table;
-
- public NamespaceContainer (MemberName name, ModuleContainer module, NamespaceContainer parent, CompilationSourceFile sourceFile)
+ public CompilationSourceFile (ModuleContainer parent, SourceFile sourceFile)
+ : this (parent)
{
- this.module = module;
- this.parent = parent;
this.file = sourceFile;
- this.loc = name == null ? Location.Null : name.Location;
-
- if (parent != null)
- ns = parent.NS.GetNamespace (name.GetName (), true);
- else if (name != null)
- ns = module.GlobalRootNamespace.GetNamespace (name.GetName (), true);
- else
- ns = module.GlobalRootNamespace;
-
- SlaveDeclSpace = new RootDeclSpace (module, this);
}
- private NamespaceContainer (ModuleContainer module, NamespaceContainer parent, CompilationSourceFile file, Namespace ns, bool slave)
+ public CompilationSourceFile (ModuleContainer parent)
+ : base (parent)
{
- this.module = module;
- this.parent = parent;
- this.file = file;
- this.IsImplicit = true;
- this.ns = ns;
- this.SlaveDeclSpace = slave ? new RootDeclSpace (module, this) : null;
}
- #region Properties
-
- public Location Location {
+ public CompileUnitEntry SymbolUnitEntry {
get {
- return loc;
+ return comp_unit;
}
}
- public MemberName MemberName {
+ public string FileName {
get {
- return ns.MemberName;
+ return file.Name;
}
}
- public CompilationSourceFile SourceFile {
+ public SourceFile SourceFile {
get {
return file;
}
}
- public List<NamespaceUsing> Usings {
- get {
- return using_clauses;
- }
+ public void AddIncludeFile (SourceFile file)
+ {
+ if (file == this.file)
+ return;
+
+ if (include_files == null)
+ include_files = new Dictionary<string, SourceFile> ();
+
+ if (!include_files.ContainsKey (file.FullPathName))
+ include_files.Add (file.FullPathName, file);
}
- #endregion
+ public void AddDefine (string value)
+ {
+ if (conditionals == null)
+ conditionals = new Dictionary<string, bool> (2);
+
+ conditionals[value] = true;
+ }
+
+ public void AddUndefine (string value)
+ {
+ if (conditionals == null)
+ conditionals = new Dictionary<string, bool> (2);
+
+ conditionals[value] = false;
+ }
+
+ public override void PrepareEmit ()
+ {
+ var sw = Module.DeclaringAssembly.SymbolWriter;
+ if (sw != null) {
+ CreateUnitSymbolInfo (sw);
+ }
+
+ base.PrepareEmit ();
+ }
//
- // Extracts the using alises and using clauses into a couple of
- // arrays that might already have the same information; Used by the
- // C# Eval mode.
+ // Creates symbol file index in debug symbol file
//
- public void Extract (List<NamespaceUsingAlias> out_using_aliases, List<NamespaceUsing> out_using_clauses)
- {
- if (using_aliases != null){
- foreach (NamespaceUsingAlias uae in using_aliases){
- bool replaced = false;
-
- for (int i = 0; i < out_using_aliases.Count; i++){
- NamespaceUsingAlias out_uea = (NamespaceUsingAlias) out_using_aliases [i];
-
- if (out_uea.Alias == uae.Alias){
- out_using_aliases [i] = uae;
- replaced = true;
- break;
- }
- }
- if (!replaced)
- out_using_aliases.Add (uae);
+ void CreateUnitSymbolInfo (MonoSymbolFile symwriter)
+ {
+ var si = file.CreateSymbolInfo (symwriter);
+ comp_unit = new CompileUnitEntry (symwriter, si);;
+
+ if (include_files != null) {
+ foreach (SourceFile include in include_files.Values) {
+ si = include.CreateSymbolInfo (symwriter);
+ comp_unit.AddFile (si);
}
}
+ }
- if (using_clauses != null){
- foreach (NamespaceUsing ue in using_clauses){
- bool found = false;
-
- foreach (NamespaceUsing out_ue in out_using_clauses)
- if (out_ue.Name == ue.Name){
- found = true;
- break;
- }
- if (!found)
- out_using_clauses.Add (ue);
- }
+ public bool IsConditionalDefined (string value)
+ {
+ if (conditionals != null) {
+ bool res;
+ if (conditionals.TryGetValue (value, out res))
+ return res;
+
+ // When conditional was undefined
+ if (conditionals.ContainsKey (value))
+ return false;
}
+
+ return Compiler.Settings.IsConditionalSymbolDefined (value);
}
-
- //
- // According to section 16.3.1 (using-alias-directive), the namespace-or-type-name is
- // resolved as if the immediately containing namespace body has no using-directives.
- //
- // Section 16.3.2 says that the same rule is applied when resolving the namespace-name
- // in the using-namespace-directive.
- //
- // To implement these rules, the expressions in the using directives are resolved using
- // the "doppelganger" (ghostly bodiless duplicate).
- //
- NamespaceContainer doppelganger;
- NamespaceContainer Doppelganger {
+ }
+
+
+ //
+ // Namespace block as created by the parser
+ //
+ public class NamespaceContainer : TypeContainer, IMemberContext
+ {
+ static readonly Namespace[] empty_namespaces = new Namespace[0];
+
+ readonly Namespace ns;
+
+ public new readonly NamespaceContainer Parent;
+
+ List<UsingNamespace> clauses;
+
+ // Used by parsed to check for parser errors
+ public bool DeclarationFound;
+
+ Namespace[] namespace_using_table;
+ Dictionary<string, UsingAliasNamespace> aliases;
+
+ public NamespaceContainer (MemberName name, NamespaceContainer parent)
+ : base (parent, name, null, MemberKind.Namespace)
+ {
+ this.Parent = parent;
+ this.ns = parent.NS.AddNamespace (name);
+
+ containers = new List<TypeContainer> ();
+ }
+
+ protected NamespaceContainer (ModuleContainer parent)
+ : base (parent, null, null, MemberKind.Namespace)
+ {
+ ns = parent.GlobalRootNamespace;
+ containers = new List<TypeContainer> (2);
+ }
+
+ #region Properties
+
+ public override AttributeTargets AttributeTargets {
get {
- if (!IsImplicit && doppelganger == null) {
- doppelganger = new NamespaceContainer (module, ImplicitParent, file, ns, true);
- doppelganger.using_aliases = using_aliases;
- }
- return doppelganger;
+ throw new NotSupportedException ();
+ }
+ }
+
+ public override string DocCommentHeader {
+ get {
+ throw new NotSupportedException ();
}
}
public Namespace NS {
- get { return ns; }
+ get {
+ return ns;
+ }
}
- public NamespaceContainer Parent {
- get { return parent; }
+ public List<UsingNamespace> Usings {
+ get {
+ return clauses;
+ }
}
- public NamespaceContainer ImplicitParent {
+ public override string[] ValidAttributeTargets {
get {
- if (parent == null)
- return null;
- if (implicit_parent == null) {
- implicit_parent = (parent.NS == ns.Parent)
- ? parent
- : new NamespaceContainer (module, parent, file, ns.Parent, false);
- }
- return implicit_parent;
+ throw new NotSupportedException ();
}
}
- /// <summary>
- /// Records a new namespace for resolving name references
- /// </summary>
- public void AddUsing (MemberName name, Location loc)
+ #endregion
+
+ public void AddUsing (UsingNamespace un)
{
if (DeclarationFound){
- Compiler.Report.Error (1529, loc, "A using clause must precede all other namespace elements except extern alias declarations");
+ Compiler.Report.Error (1529, un.Location, "A using clause must precede all other namespace elements except extern alias declarations");
}
- if (using_clauses == null) {
- using_clauses = new List<NamespaceUsing> ();
- } else {
- foreach (NamespaceUsing old_entry in using_clauses) {
- if (name.Equals (old_entry.MemberName)) {
- Compiler.Report.SymbolRelatedToPreviousError (old_entry.Location, old_entry.GetSignatureForError ());
- Compiler.Report.Warning (105, 3, loc, "The using directive for `{0}' appeared previously in this namespace", name.GetSignatureForError ());
- return;
- }
- }
- }
+ if (clauses == null)
+ clauses = new List<UsingNamespace> ();
- using_clauses.Add (new NamespaceUsing (name));
+ clauses.Add (un);
}
- public void AddUsingAlias (string alias, MemberName name, Location loc)
+ public void AddUsing (UsingAliasNamespace un)
{
if (DeclarationFound){
- Compiler.Report.Error (1529, loc, "A using clause must precede all other namespace elements except extern alias declarations");
+ Compiler.Report.Error (1529, un.Location, "A using clause must precede all other namespace elements except extern alias declarations");
}
- AddUsingAlias (new LocalUsingAliasEntry (alias, name, loc));
+ AddAlias (un);
}
- public void AddUsingExternalAlias (string alias, Location loc, Report Report)
+ void AddAlias (UsingAliasNamespace un)
{
- bool not_first = using_clauses != null || DeclarationFound;
- if (using_aliases != null && !not_first) {
- foreach (NamespaceUsingAlias uae in using_aliases) {
- if (uae is LocalUsingAliasEntry) {
- not_first = true;
- break;
+ if (clauses == null) {
+ clauses = new List<UsingNamespace> ();
+ } else {
+ foreach (var entry in clauses) {
+ var a = entry as UsingAliasNamespace;
+ if (a != null && a.Alias.Value == un.Alias.Value) {
+ Compiler.Report.SymbolRelatedToPreviousError (a.Location, "");
+ Compiler.Report.Error (1537, un.Location,
+ "The using alias `{0}' appeared previously in this namespace", un.Alias.Value);
}
}
}
- if (not_first)
- Report.Error (439, loc, "An extern alias declaration must precede all other elements");
-
- if (alias == "global") {
- Error_GlobalNamespaceRedefined (loc, Report);
- return;
- }
+ clauses.Add (un);
+ }
- AddUsingAlias (new NamespaceUsingAlias (alias, loc));
+ public override void AddPartial (TypeDefinition next_part)
+ {
+ var existing = ns.LookupType (this, next_part.MemberName.Name, next_part.MemberName.Arity, LookupMode.Probing, Location.Null);
+ var td = existing != null ? existing.Type.MemberDefinition as TypeDefinition : null;
+ AddPartial (next_part, td);
}
- void AddUsingAlias (NamespaceUsingAlias uae)
+ public override void AddTypeContainer (TypeContainer tc)
{
- if (using_aliases == null) {
- using_aliases = new List<NamespaceUsingAlias> ();
+ string name = tc.Basename;
+
+ var mn = tc.MemberName;
+ while (mn.Left != null) {
+ mn = mn.Left;
+ name = mn.Name;
+ }
+
+ var names_container = Parent == null ? Module : (TypeContainer) this;
+
+ MemberCore mc;
+ if (names_container.DefinedNames.TryGetValue (name, out mc)) {
+ if (tc is NamespaceContainer && mc is NamespaceContainer) {
+ containers.Add (tc);
+ return;
+ }
+
+ Report.SymbolRelatedToPreviousError (mc);
+ if ((mc.ModFlags & Modifiers.PARTIAL) != 0 && (tc is ClassOrStruct || tc is Interface)) {
+ Error_MissingPartialModifier (tc);
+ } else {
+ Report.Error (101, tc.Location, "The namespace `{0}' already contains a definition for `{1}'",
+ GetSignatureForError (), mn.GetSignatureForError ());
+ }
} else {
- foreach (NamespaceUsingAlias entry in using_aliases) {
- if (uae.Alias == entry.Alias) {
- Compiler.Report.SymbolRelatedToPreviousError (uae.Location, uae.Alias);
- Compiler.Report.Error (1537, entry.Location, "The using alias `{0}' appeared previously in this namespace",
- entry.Alias);
- return;
+ names_container.DefinedNames.Add (name, tc);
+
+ var tdef = tc.PartialContainer;
+ if (tdef != null) {
+ //
+ // Same name conflict in different namespace containers
+ //
+ var conflict = ns.GetAllTypes (name);
+ if (conflict != null) {
+ foreach (var e in conflict) {
+ if (e.Arity == mn.Arity) {
+ mc = (MemberCore) e.MemberDefinition;
+ break;
+ }
+ }
+ }
+
+ if (mc != null) {
+ Report.SymbolRelatedToPreviousError (mc);
+ Report.Error (101, tc.Location, "The namespace `{0}' already contains a definition for `{1}'",
+ GetSignatureForError (), mn.GetSignatureForError ());
+ } else {
+ ns.AddType (Module, tdef.Definition);
}
}
}
- using_aliases.Add (uae);
+ base.AddTypeContainer (tc);
}
- //
- // Does extension methods look up to find a method which matches name and extensionType.
- // Search starts from this namespace and continues hierarchically up to top level.
- //
- public IList<MethodSpec> LookupExtensionMethod (TypeSpec extensionType, string name, int arity, ref NamespaceContainer scope)
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
- List<MethodSpec> candidates = null;
- foreach (Namespace n in GetUsingTable ()) {
- var a = n.LookupExtensionMethod (this, extensionType, name, arity);
- if (a == null)
- continue;
-
- if (candidates == null)
- candidates = a;
- else
- candidates.AddRange (a);
- }
+ throw new NotSupportedException ();
+ }
- scope = parent;
- if (candidates != null)
- return candidates;
+ public override void EmitContainer ()
+ {
+ VerifyClsCompliance ();
- if (parent == null)
- return null;
+ base.EmitContainer ();
+ }
+ public ExtensionMethodCandidates LookupExtensionMethod (IMemberContext invocationContext, TypeSpec extensionType, string name, int arity, int position)
+ {
//
- // Inspect parent namespaces in namespace expression
+ // Here we try to resume the search for extension method at the point
+ // where the last bunch of candidates was found. It's more tricky than
+ // it seems as we have to check both namespace containers and namespace
+ // in correct order.
//
- Namespace parent_ns = ns.Parent;
+ // Consider:
+ //
+ // namespace A {
+ // using N1;
+ // namespace B.C.D {
+ // <our first search found candidates in A.B.C.D
+ // }
+ // }
+ //
+ // In the example above namespace A.B.C.D, A.B.C and A.B have to be
+ // checked before we hit A.N1 using
+ //
+ ExtensionMethodCandidates candidates;
+ var container = this;
do {
- candidates = parent_ns.LookupExtensionMethod (this, extensionType, name, arity);
- if (candidates != null)
+ candidates = container.LookupExtensionMethodCandidates (invocationContext, extensionType, name, arity, ref position);
+ if (candidates != null || container.MemberName == null)
return candidates;
- parent_ns = parent_ns.Parent;
- } while (parent_ns != null);
+ var container_ns = container.ns.Parent;
+ var mn = container.MemberName.Left;
+ int already_checked = position - 2;
+ while (already_checked-- > 0) {
+ mn = mn.Left;
+ container_ns = container_ns.Parent;
+ }
- //
- // Continue in parent scope
- //
- return parent.LookupExtensionMethod (extensionType, name, arity, ref scope);
+ while (mn != null) {
+ ++position;
+
+ var methods = container_ns.LookupExtensionMethod (invocationContext, extensionType, name, arity);
+ if (methods != null) {
+ return new ExtensionMethodCandidates (invocationContext, methods, container, position);
+ }
+
+ mn = mn.Left;
+ container_ns = container_ns.Parent;
+ }
+
+ position = 0;
+ container = container.Parent;
+ } while (container != null);
+
+ return null;
}
- public FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104)
+ ExtensionMethodCandidates LookupExtensionMethodCandidates (IMemberContext invocationContext, TypeSpec extensionType, string name, int arity, ref int position)
{
- // Precondition: Only simple names (no dots) will be looked up with this function.
- FullNamedExpression resolved = null;
- for (NamespaceContainer curr_ns = this; curr_ns != null; curr_ns = curr_ns.ImplicitParent) {
- if ((resolved = curr_ns.Lookup (name, arity, loc, ignore_cs0104)) != null)
- break;
+ List<MethodSpec> candidates = null;
+
+ if (position == 0) {
+ ++position;
+
+ candidates = ns.LookupExtensionMethod (invocationContext, extensionType, name, arity);
+ if (candidates != null) {
+ return new ExtensionMethodCandidates (invocationContext, candidates, this, position);
+ }
}
- return resolved;
+ if (position == 1) {
+ ++position;
+
+ foreach (Namespace n in namespace_using_table) {
+ var a = n.LookupExtensionMethod (invocationContext, extensionType, name, arity);
+ if (a == null)
+ continue;
+
+ if (candidates == null)
+ candidates = a;
+ else
+ candidates.AddRange (a);
+ }
+
+ if (candidates != null)
+ return new ExtensionMethodCandidates (invocationContext, candidates, this, position);
+ }
+
+ return null;
}
- public IList<string> CompletionGetTypesStartingWith (string prefix)
+ public override FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
{
+ //
+ // Only simple names (no dots) will be looked up with this function
+ //
+ FullNamedExpression resolved;
+ for (NamespaceContainer container = this; container != null; container = container.Parent) {
+ resolved = container.Lookup (name, arity, mode, loc);
+ if (resolved != null || container.MemberName == null)
+ return resolved;
+
+ var container_ns = container.ns.Parent;
+ var mn = container.MemberName.Left;
+ while (mn != null) {
+ resolved = container_ns.LookupTypeOrNamespace (this, name, arity, mode, loc);
+ if (resolved != null)
+ return resolved;
+
+ mn = mn.Left;
+ container_ns = container_ns.Parent;
+ }
+ }
+
+ return null;
+ }
+
+ public override void GetCompletionStartingWith (string prefix, List<string> results)
+ {
+ foreach (var un in Usings) {
+ if (un.Alias != null)
+ continue;
+
+ var name = un.NamespaceExpression.Name;
+ if (name.StartsWith (prefix))
+ results.Add (name);
+ }
+
+
IEnumerable<string> all = Enumerable.Empty<string> ();
-
- for (NamespaceContainer curr_ns = this; curr_ns != null; curr_ns = curr_ns.ImplicitParent){
- foreach (Namespace using_ns in GetUsingTable ()){
- if (prefix.StartsWith (using_ns.Name)){
- int ld = prefix.LastIndexOf ('.');
- if (ld != -1){
- string rest = prefix.Substring (ld+1);
-
- all = all.Concat (using_ns.CompletionGetTypesStartingWith (rest));
- }
+
+ foreach (Namespace using_ns in namespace_using_table) {
+ if (prefix.StartsWith (using_ns.Name)) {
+ int ld = prefix.LastIndexOf ('.');
+ if (ld != -1) {
+ string rest = prefix.Substring (ld + 1);
+
+ all = all.Concat (using_ns.CompletionGetTypesStartingWith (rest));
}
- all = all.Concat (using_ns.CompletionGetTypesStartingWith (prefix));
}
+ all = all.Concat (using_ns.CompletionGetTypesStartingWith (prefix));
}
- return all.Distinct ().ToList ();
+ results.AddRange (all);
+
+ base.GetCompletionStartingWith (prefix, results);
+ }
+
+
+ //
+ // Looks-up a alias named @name in this and surrounding namespace declarations
+ //
+ public FullNamedExpression LookupExternAlias (string name)
+ {
+ if (aliases == null)
+ return null;
+
+ UsingAliasNamespace uan;
+ if (aliases.TryGetValue (name, out uan) && uan is UsingExternAlias)
+ return uan.ResolvedExpression;
+
+ return null;
}
+ //
// Looks-up a alias named @name in this and surrounding namespace declarations
- public FullNamedExpression LookupNamespaceAlias (string name)
+ //
+ public override FullNamedExpression LookupNamespaceAlias (string name)
{
- for (NamespaceContainer n = this; n != null; n = n.ImplicitParent) {
- if (n.using_aliases == null)
+ for (NamespaceContainer n = this; n != null; n = n.Parent) {
+ if (n.aliases == null)
continue;
- foreach (NamespaceUsingAlias ue in n.using_aliases) {
- if (ue.Alias == name)
- return ue.Resolve (Doppelganger ?? this, Doppelganger == null);
- }
+ UsingAliasNamespace uan;
+ if (n.aliases.TryGetValue (name, out uan))
+ return uan.ResolvedExpression;
}
return null;
}
- private FullNamedExpression Lookup (string name, int arity, Location loc, bool ignore_cs0104)
+ FullNamedExpression Lookup (string name, int arity, LookupMode mode, Location loc)
{
//
// Check whether it's in the namespace.
//
- FullNamedExpression fne = ns.LookupTypeOrNamespace (this, name, arity, loc);
+ FullNamedExpression fne = ns.LookupTypeOrNamespace (this, name, arity, mode, loc);
//
// Check aliases.
//
- if (using_aliases != null && arity == 0) {
- foreach (NamespaceUsingAlias ue in using_aliases) {
- if (ue.Alias == name) {
- if (fne != null) {
- if (Doppelganger != null) {
- // TODO: Namespace has broken location
- //Report.SymbolRelatedToPreviousError (fne.Location, null);
- Compiler.Report.SymbolRelatedToPreviousError (ue.Location, null);
- Compiler.Report.Error (576, loc,
- "Namespace `{0}' contains a definition with same name as alias `{1}'",
- GetSignatureForError (), name);
- } else {
- return fne;
- }
- }
-
- return ue.Resolve (Doppelganger ?? this, Doppelganger == null);
+ if (aliases != null && arity == 0) {
+ UsingAliasNamespace uan;
+ if (aliases.TryGetValue (name, out uan)) {
+ if (fne != null) {
+ // TODO: Namespace has broken location
+ //Report.SymbolRelatedToPreviousError (fne.Location, null);
+ Compiler.Report.SymbolRelatedToPreviousError (uan.Location, null);
+ Compiler.Report.Error (576, loc,
+ "Namespace `{0}' contains a definition with same name as alias `{1}'",
+ GetSignatureForError (), name);
}
+
+ return uan.ResolvedExpression;
}
}
- if (fne != null) {
- if (!((fne.Type.Modifiers & Modifiers.INTERNAL) != 0 && !fne.Type.MemberDefinition.IsInternalAsPublic (module.DeclaringAssembly)))
- return fne;
- }
+ if (fne != null)
+ return fne;
- if (IsImplicit)
- return null;
+ //
+ // Lookup can be called before the namespace is defined from different namespace using alias clause
+ //
+ if (namespace_using_table == null) {
+ DoDefineNamespace ();
+ }
//
// Check using entries.
//
FullNamedExpression match = null;
- foreach (Namespace using_ns in GetUsingTable ()) {
+ foreach (Namespace using_ns in namespace_using_table) {
+ //
// A using directive imports only types contained in the namespace, it
// does not import any nested namespaces
- fne = using_ns.LookupType (this, name, arity, loc);
+ //
+ fne = using_ns.LookupType (this, name, arity, mode, loc);
if (fne == null)
continue;
continue;
}
- if (ignore_cs0104)
- return match;
-
// It can be top level accessibility only
- var better = Namespace.IsImportedTypeOverride (module, texpr_match.Type, texpr_fne.Type);
+ var better = Namespace.IsImportedTypeOverride (Module, texpr_match.Type, texpr_fne.Type);
if (better == null) {
- Compiler.Report.SymbolRelatedToPreviousError (texpr_match.Type);
- Compiler.Report.SymbolRelatedToPreviousError (texpr_fne.Type);
- Compiler.Report.Error (104, loc, "`{0}' is an ambiguous reference between `{1}' and `{2}'",
- name, texpr_match.GetSignatureForError (), texpr_fne.GetSignatureForError ());
+ if (mode == LookupMode.Normal) {
+ Compiler.Report.SymbolRelatedToPreviousError (texpr_match.Type);
+ Compiler.Report.SymbolRelatedToPreviousError (texpr_fne.Type);
+ Compiler.Report.Error (104, loc, "`{0}' is an ambiguous reference between `{1}' and `{2}'",
+ name, texpr_match.GetSignatureForError (), texpr_fne.GetSignatureForError ());
+ }
+
return match;
}
return match;
}
- Namespace [] GetUsingTable ()
+ protected override void DefineNamespace ()
{
- if (namespace_using_table != null)
- return namespace_using_table;
+ if (namespace_using_table == null)
+ DoDefineNamespace ();
- if (using_clauses == null) {
- namespace_using_table = empty_namespaces;
- return namespace_using_table;
- }
+ base.DefineNamespace ();
+ }
- var list = new List<Namespace> (using_clauses.Count);
+ void DoDefineNamespace ()
+ {
+ namespace_using_table = empty_namespaces;
+
+ if (clauses != null) {
+ var list = new List<Namespace> (clauses.Count);
+ bool post_process_using_aliases = false;
+
+ for (int i = 0; i < clauses.Count; ++i) {
+ var entry = clauses[i];
+
+ if (entry.Alias != null) {
+ if (aliases == null)
+ aliases = new Dictionary<string, UsingAliasNamespace> ();
+
+ //
+ // Aliases are not available when resolving using section
+ // except extern aliases
+ //
+ if (entry is UsingExternAlias) {
+ entry.Define (this);
+ if (entry.ResolvedExpression != null)
+ aliases.Add (entry.Alias.Value, (UsingExternAlias) entry);
+
+ clauses.RemoveAt (i--);
+ } else {
+ post_process_using_aliases = true;
+ }
- foreach (NamespaceUsing ue in using_clauses) {
- Namespace using_ns = ue.Resolve (Doppelganger);
- if (using_ns == null)
- continue;
+ continue;
+ }
- list.Add (using_ns);
- }
+ entry.Define (this);
- namespace_using_table = list.ToArray ();
- return namespace_using_table;
- }
+ //
+ // It's needed for repl only, when using clause cannot be resolved don't hold it in
+ // global list which is resolved for each evaluation
+ //
+ if (entry.ResolvedExpression == null) {
+ clauses.RemoveAt (i--);
+ continue;
+ }
- public int SymbolFileID {
- get {
- if (symfile_id == 0 && file.SourceFileEntry != null) {
- int parent_id = parent == null ? 0 : parent.SymbolFileID;
-
- string [] using_list = empty_using_list;
- if (using_clauses != null) {
- using_list = new string [using_clauses.Count];
- for (int i = 0; i < using_clauses.Count; i++)
- using_list [i] = ((NamespaceUsing) using_clauses [i]).MemberName.GetName ();
+ Namespace using_ns = entry.ResolvedExpression as Namespace;
+ if (using_ns == null)
+ continue;
+
+ if (list.Contains (using_ns)) {
+ // Ensure we don't report the warning multiple times in repl
+ clauses.RemoveAt (i--);
+
+ Compiler.Report.Warning (105, 3, entry.Location,
+ "The using directive for `{0}' appeared previously in this namespace", using_ns.GetSignatureForError ());
+ } else {
+ list.Add (using_ns);
}
+ }
- symfile_id = SymbolWriter.DefineNamespace (ns.Name, file.CompileUnitEntry, using_list, parent_id);
+ namespace_using_table = list.ToArray ();
+
+ if (post_process_using_aliases) {
+ for (int i = 0; i < clauses.Count; ++i) {
+ var entry = clauses[i];
+ if (entry.Alias != null) {
+ entry.Define (this);
+ if (entry.ResolvedExpression != null) {
+ aliases.Add (entry.Alias.Value, (UsingAliasNamespace) entry);
+ }
+
+ clauses.RemoveAt (i--);
+ }
+ }
}
- return symfile_id;
}
}
- static void MsgtryRef (string s)
+ public void EnableRedefinition ()
{
- Console.WriteLine (" Try using -r:" + s);
+ is_defined = false;
+ namespace_using_table = null;
}
- static void MsgtryPkg (string s)
+ internal override void GenerateDocComment (DocumentationBuilder builder)
{
- Console.WriteLine (" Try using -pkg:" + s);
+ if (containers != null) {
+ foreach (var tc in containers)
+ tc.GenerateDocComment (builder);
+ }
}
- public static void Error_GlobalNamespaceRedefined (Location loc, Report Report)
+ public override string GetSignatureForError ()
{
- Report.Error (1681, loc, "The global extern alias cannot be redefined");
+ return MemberName == null ? "global::" : base.GetSignatureForError ();
}
- public static void Error_NamespaceNotFound (Location loc, string name, Report Report)
+ public override void RemoveContainer (TypeContainer cont)
{
- Report.Error (246, loc, "The type or namespace name `{0}' could not be found. Are you missing a using directive or an assembly reference?",
- name);
-
- switch (name) {
- case "Gtk": case "GtkSharp":
- MsgtryPkg ("gtk-sharp-2.0");
- break;
-
- case "Gdk": case "GdkSharp":
- MsgtryPkg ("gdk-sharp-2.0");
- break;
-
- case "Glade": case "GladeSharp":
- MsgtryPkg ("glade-sharp-2.0");
- break;
-
- case "System.Drawing":
- case "System.Web.Services":
- case "System.Web":
- case "System.Data":
- case "System.Windows.Forms":
- MsgtryRef (name);
- break;
- }
+ base.RemoveContainer (cont);
+ NS.RemoveContainer (cont);
}
- /// <summary>
- /// Used to validate that all the using clauses are correct
- /// after we are finished parsing all the files.
- /// </summary>
- public void Resolve ()
+ protected override bool VerifyClsCompliance ()
{
- if (resolved)
- return;
-
- resolved = true;
-
- if (using_aliases != null) {
- foreach (NamespaceUsingAlias ue in using_aliases)
- ue.Resolve (Doppelganger, Doppelganger == null);
- }
+ if (Module.IsClsComplianceRequired ()) {
+ if (MemberName != null && MemberName.Name[0] == '_') {
+ Warning_IdentifierNotCompliant ();
+ }
- if (using_clauses != null) {
- foreach (NamespaceUsing ue in using_clauses)
- ue.Resolve (Doppelganger);
+ ns.VerifyClsCompliance ();
+ return true;
}
- if (parent != null)
- parent.Resolve ();
- }
-
- public string GetSignatureForError ()
- {
- return ns.GetSignatureForError ();
- }
-
- #region IMemberContext Members
-
- CompilerContext Compiler {
- get { return module.Compiler; }
- }
-
- public TypeSpec CurrentType {
- get { return SlaveDeclSpace.CurrentType; }
+ return false;
}
+ }
- public MemberCore CurrentMemberDefinition {
- get { return SlaveDeclSpace.CurrentMemberDefinition; }
- }
+ public class UsingNamespace
+ {
+ readonly ATypeNameExpression expr;
+ readonly Location loc;
+ protected FullNamedExpression resolved;
- public TypeParameter[] CurrentTypeParameters {
- get { return SlaveDeclSpace.CurrentTypeParameters; }
+ public UsingNamespace (ATypeNameExpression expr, Location loc)
+ {
+ this.expr = expr;
+ this.loc = loc;
}
- // FIXME: It's false for expression types
- public bool HasUnresolvedConstraints {
- get { return true; }
- }
+ #region Properties
- public bool IsObsolete {
- get { return SlaveDeclSpace.IsObsolete; }
+ public virtual SimpleMemberName Alias {
+ get {
+ return null;
+ }
}
- public bool IsUnsafe {
- get { return SlaveDeclSpace.IsUnsafe; }
+ public Location Location {
+ get {
+ return loc;
+ }
}
- public bool IsStatic {
- get { return SlaveDeclSpace.IsStatic; }
+ public ATypeNameExpression NamespaceExpression {
+ get {
+ return expr;
+ }
}
- public ModuleContainer Module {
- get { return module; }
+ public FullNamedExpression ResolvedExpression {
+ get {
+ return resolved;
+ }
}
#endregion
- }
-
- public class NamespaceUsing
- {
- readonly MemberName name;
- Namespace resolved;
-
- public NamespaceUsing (MemberName name)
- {
- this.name = name;
- }
public string GetSignatureForError ()
{
- return name.GetSignatureForError ();
+ return expr.GetSignatureForError ();
}
- public Location Location
+ public virtual void Define (NamespaceContainer ctx)
{
- get { return name.Location; }
+ resolved = expr.ResolveAsTypeOrNamespace (ctx);
+ var ns = resolved as Namespace;
+ if (ns == null) {
+ if (resolved != null) {
+ ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (resolved.Type);
+ ctx.Module.Compiler.Report.Error (138, Location,
+ "`{0}' is a type not a namespace. A using namespace directive can only be applied to namespaces",
+ GetSignatureForError ());
+ }
+ }
}
- public MemberName MemberName
+ public override string ToString()
{
- get { return name; }
+ return resolved.ToString();
}
+ }
- public string Name
+ public class UsingExternAlias : UsingAliasNamespace
+ {
+ public UsingExternAlias (SimpleMemberName alias, Location loc)
+ : base (alias, null, loc)
{
- get { return GetSignatureForError (); }
}
- public Namespace Resolve (IMemberContext rc)
+ public override void Define (NamespaceContainer ctx)
{
- if (resolved != null)
- return resolved;
-
- FullNamedExpression fne = name.GetTypeExpression ().ResolveAsTypeOrNamespace (rc);
- if (fne == null)
- return null;
-
- resolved = fne as Namespace;
+ resolved = ctx.Module.GetRootNamespace (Alias.Value);
if (resolved == null) {
- rc.Module.Compiler.Report.SymbolRelatedToPreviousError (fne.Type);
- rc.Module.Compiler.Report.Error (138, Location,
- "`{0}' is a type not a namespace. A using namespace directive can only be applied to namespaces",
- GetSignatureForError ());
+ ctx.Module.Compiler.Report.Error (430, Location,
+ "The extern alias `{0}' was not specified in -reference option",
+ Alias.Value);
}
- return resolved;
}
}
- public class NamespaceUsingAlias
+ public class UsingAliasNamespace : UsingNamespace
{
- public readonly string Alias;
- public Location Location;
+ readonly SimpleMemberName alias;
- public NamespaceUsingAlias (string alias, Location loc)
+ public struct AliasContext : IMemberContext
{
- this.Alias = alias;
- this.Location = loc;
- }
+ readonly NamespaceContainer ns;
- public virtual FullNamedExpression Resolve (IMemberContext rc, bool local)
- {
- FullNamedExpression fne = rc.Module.GetRootNamespace (Alias);
- if (fne == null) {
- rc.Module.Compiler.Report.Error (430, Location,
- "The extern alias `{0}' was not specified in -reference option",
- Alias);
+ public AliasContext (NamespaceContainer ns)
+ {
+ this.ns = ns;
}
- return fne;
- }
- }
+ public TypeSpec CurrentType {
+ get {
+ return null;
+ }
+ }
- class LocalUsingAliasEntry : NamespaceUsingAlias
- {
- FullNamedExpression resolved;
- MemberName value;
+ public TypeParameters CurrentTypeParameters {
+ get {
+ return null;
+ }
+ }
- public LocalUsingAliasEntry (string alias, MemberName name, Location loc)
- : base (alias, loc)
- {
- this.value = name;
- }
+ public MemberCore CurrentMemberDefinition {
+ get {
+ return null;
+ }
+ }
- public override FullNamedExpression Resolve (IMemberContext rc, bool local)
- {
- if (resolved != null || value == null)
- return resolved;
+ public bool IsObsolete {
+ get {
+ return false;
+ }
+ }
- if (local)
+ public bool IsUnsafe {
+ get {
+ throw new NotImplementedException ();
+ }
+ }
+
+ public bool IsStatic {
+ get {
+ throw new NotImplementedException ();
+ }
+ }
+
+ public ModuleContainer Module {
+ get {
+ return ns.Module;
+ }
+ }
+
+ public string GetSignatureForError ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity)
+ {
return null;
+ }
+
+ public FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
+ {
+ var fne = ns.NS.LookupTypeOrNamespace (ns, name, arity, mode, loc);
+ if (fne != null)
+ return fne;
+
+ //
+ // Only extern aliases are allowed in this context
+ //
+ fne = ns.LookupExternAlias (name);
+ if (fne != null || ns.MemberName == null)
+ return fne;
+
+ var container_ns = ns.NS.Parent;
+ var mn = ns.MemberName.Left;
+ while (mn != null) {
+ fne = container_ns.LookupTypeOrNamespace (this, name, arity, mode, loc);
+ if (fne != null)
+ return fne;
+
+ mn = mn.Left;
+ container_ns = container_ns.Parent;
+ }
+
+ if (ns.Parent != null)
+ return ns.Parent.LookupNamespaceOrType (name, arity, mode, loc);
- resolved = value.GetTypeExpression ().ResolveAsTypeOrNamespace (rc);
- if (resolved == null) {
- value = null;
return null;
}
- if (resolved is TypeExpr)
- resolved = resolved.ResolveAsType (rc);
+ public FullNamedExpression LookupNamespaceAlias (string name)
+ {
+ return ns.LookupNamespaceAlias (name);
+ }
+ }
+
+ public UsingAliasNamespace (SimpleMemberName alias, ATypeNameExpression expr, Location loc)
+ : base (expr, loc)
+ {
+ this.alias = alias;
+ }
+
+ public override SimpleMemberName Alias {
+ get {
+ return alias;
+ }
+ }
- return resolved;
+ public override void Define (NamespaceContainer ctx)
+ {
+ //
+ // The namespace-or-type-name of a using-alias-directive is resolved as if
+ // the immediately containing compilation unit or namespace body had no
+ // using-directives. A using-alias-directive may however be affected
+ // by extern-alias-directives in the immediately containing compilation
+ // unit or namespace body
+ //
+ // We achieve that by introducing alias-context which redirect any local
+ // namespace or type resolve calls to parent namespace
+ //
+ resolved = NamespaceExpression.ResolveAsTypeOrNamespace (new AliasContext (ctx));
}
}
}