readonly Dictionary<string, Namespace> all_namespaces;
public RootNamespace (string alias_name)
- : base (null, String.Empty)
+ : base ()
{
this.alias_name = alias_name;
+ RegisterNamespace (this);
all_namespaces = new Dictionary<string, Namespace> ();
all_namespaces.Add ("", this);
//
// For better error reporting where compiler tries to guess missing using directive
//
- public List<string> FindExtensionMethodNamespaces (IMemberContext ctx, TypeSpec extensionType, string name, int arity)
+ public List<string> FindExtensionMethodNamespaces (IMemberContext ctx, string name, int arity)
{
List<string> res = null;
foreach (var ns in all_namespaces) {
- var methods = ns.Value.LookupExtensionMethod (ctx, extensionType, name, arity);
+ if (ns.Key.Length == 0)
+ continue;
+
+ var methods = ns.Value.LookupExtensionMethod (ctx, name, arity);
if (methods != null) {
if (res == null)
res = new List<string> ();
all_namespaces.Add (child.Name, child);
}
- public bool IsNamespace (string name)
- {
- return all_namespaces.ContainsKey (name);
- }
-
- protected void RegisterNamespace (string dotted_name)
- {
- if (dotted_name != null && dotted_name.Length != 0 && ! IsNamespace (dotted_name))
- GetNamespace (dotted_name, true);
- }
-
public override string GetSignatureForError ()
{
return alias_name + "::";
}
}
- public class GlobalRootNamespace : RootNamespace
+ public sealed class GlobalRootNamespace : RootNamespace
{
public GlobalRootNamespace ()
: base ("global")
//
// Namespace cache for imported and compiled namespaces
//
- // This is an Expression to allow it to be referenced in the
- // compiler parse/intermediate tree during name resolution.
- //
- public class Namespace : FullNamedExpression
+ public class Namespace
{
- Namespace parent;
+ readonly Namespace parent;
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;
+ Dictionary<string, TypeSpec> cached_types;
bool cls_checked;
- public readonly MemberName MemberName;
-
/// <summary>
/// Constructor Takes the current namespace and the
/// name. This is bootstrapped with parent == null
/// and name = ""
/// </summary>
public Namespace (Namespace parent, string name)
+ : this ()
{
- // Expression members.
- this.eclass = ExprClass.Namespace;
- this.Type = InternalType.Namespace;
- this.loc = Location.Null;
+ if (name == null)
+ throw new ArgumentNullException ("name");
this.parent = parent;
- if (parent != null)
- this.root = parent.root;
- else
- this.root = this as RootNamespace;
-
- if (this.root == null)
- throw new InternalErrorException ("Root namespaces must be created using RootNamespace");
-
- string pname = parent != null ? parent.fullname : "";
+ string pname = parent != null ? parent.fullname : null;
- if (pname == "")
+ if (pname == null)
fullname = name;
else
- fullname = parent.fullname + "." + name;
+ fullname = pname + "." + name;
- if (fullname == null)
- throw new InternalErrorException ("Namespace has a null fullname");
+ while (parent.parent != null)
+ parent = parent.parent;
- if (parent != null && parent.MemberName != MemberName.Null)
- MemberName = new MemberName (parent.MemberName, name, Location.Null);
- else if (name.Length == 0)
- MemberName = MemberName.Null;
- else
- MemberName = new MemberName (name, Location.Null);
-
- namespaces = new Dictionary<string, Namespace> ();
- cached_types = new Dictionary<string, TypeExpr> ();
+ var root = parent as RootNamespace;
+ if (root == null)
+ throw new InternalErrorException ("Root namespaces must be created using RootNamespace");
root.RegisterNamespace (this);
}
+ protected Namespace ()
+ {
+ namespaces = new Dictionary<string, Namespace> ();
+ cached_types = new Dictionary<string, TypeSpec> ();
+ }
+
#region Properties
/// <summary>
#endregion
- protected override Expression DoResolve (ResolveContext ec)
- {
- return this;
- }
-
- public void Error_NamespaceDoesNotExist (IMemberContext ctx, string name, int arity, Location 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;
- }
-
- Namespace ns;
- if (arity > 0 && namespaces.TryGetValue (name, out ns)) {
- ns.Error_TypeArgumentsCannotBeUsed (ctx, null, arity, loc);
- return;
- }
-
- 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.Forms";
- 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)
{
var ns_parent = name.Left == null ? this : AddNamespace (name.Left);
return ns;
}
+ public bool TryGetNamespace (string name, out Namespace ns)
+ {
+ return namespaces.TryGetValue (name, out ns);
+ }
+
// TODO: Replace with CreateNamespace where MemberName is created for the method call
public Namespace GetNamespace (string name, bool create)
{
return found;
}
- public TypeExpr LookupType (IMemberContext ctx, string name, int arity, LookupMode mode, Location loc)
+ public virtual string GetSignatureForError ()
+ {
+ return fullname;
+ }
+
+ public TypeSpec LookupType (IMemberContext ctx, string name, int arity, LookupMode mode, Location loc)
{
if (types == null)
return null;
- TypeExpr te;
- if (arity == 0 && cached_types.TryGetValue (name, out te))
- return te;
+ TypeSpec best = null;
+ if (arity == 0 && cached_types.TryGetValue (name, out best)) {
+ if (best != null || mode != LookupMode.IgnoreAccessibility)
+ return best;
+ }
IList<TypeSpec> found;
if (!types.TryGetValue (name, out found))
return null;
- TypeSpec best = null;
foreach (var ts in found) {
if (ts.Arity == arity) {
if (best == null) {
}
if (best.MemberDefinition.IsImported && ts.MemberDefinition.IsImported) {
+ if (ts.Kind == MemberKind.MissingType)
+ continue;
+
+ if (best.Kind == MemberKind.MissingType) {
+ best = ts;
+ continue;
+ }
+
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 (ts.Kind == MemberKind.MissingType)
+ continue;
+
if (best.MemberDefinition.IsImported)
best = ts;
}
}
- if (best == null)
- return null;
-
- te = new TypeExpression (best, Location.Null);
-
// TODO MemberCache: Cache more
if (arity == 0 && mode == LookupMode.Normal)
- cached_types.Add (name, te);
+ cached_types.Add (name, best);
+
+ if (best != null) {
+ var dep = best.GetMissingDependencies ();
+ if (dep != null)
+ ImportedTypeDefinition.Error_MissingDependency (ctx, dep, loc);
+ }
- return te;
+ return best;
}
public FullNamedExpression LookupTypeOrNamespace (IMemberContext ctx, string name, int arity, LookupMode mode, Location loc)
Namespace ns;
if (arity == 0 && namespaces.TryGetValue (name, out ns)) {
if (texpr == null)
- return ns;
+ return new NamespaceExpression (ns, loc);
if (mode != LookupMode.Probing) {
- ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (texpr.Type);
+ //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;
+ if (texpr.MemberDefinition.IsImported)
+ return new NamespaceExpression (ns, loc);
}
- return texpr;
+ if (texpr == null)
+ return null;
+
+ return new TypeExpression (texpr, loc);
}
//
//
// Looks for extension method in this namespace
//
- public List<MethodSpec> LookupExtensionMethod (IMemberContext invocationContext, TypeSpec extensionType, string name, int arity)
+ public List<MethodSpec> LookupExtensionMethod (IMemberContext invocationContext, string name, int arity)
{
if (extension_method_types == null)
return null;
continue;
}
- var res = ts.MemberCache.FindExtensionMethods (invocationContext, extensionType, name, arity);
+ var res = ts.MemberCache.FindExtensionMethods (invocationContext, name, arity);
if (res == null)
continue;
public void RemoveContainer (TypeContainer tc)
{
- types.Remove (tc.Basename);
- cached_types.Remove (tc.Basename);
- }
+ IList<TypeSpec> found;
+ if (types.TryGetValue (tc.MemberName.Name, out found)) {
+ for (int i = 0; i < found.Count; ++i) {
+ if (tc.MemberName.Arity != found [i].Arity)
+ continue;
- public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc)
- {
- return this;
+ if (found.Count == 1)
+ types.Remove (tc.MemberName.Name);
+ else
+ found.RemoveAt (i);
+
+ break;
+ }
+ }
+
+ cached_types.Remove (tc.MemberName.Basename);
}
public void SetBuiltinType (BuiltinTypeSpec pts)
"Identifier `{0}' differing only in case is not CLS-compliant", compiled.GetSignatureForError ());
}
}
-
- public override string ToString ()
- {
- return Name;
- }
}
public class CompilationSourceFile : NamespaceContainer
if (include_files == null)
include_files = new Dictionary<string, SourceFile> ();
- if (!include_files.ContainsKey (file.FullPathName))
- include_files.Add (file.FullPathName, file);
+ if (!include_files.ContainsKey (file.OriginalFullPathName))
+ include_files.Add (file.OriginalFullPathName, file);
}
public void AddDefine (string value)
{
var sw = Module.DeclaringAssembly.SymbolWriter;
if (sw != null) {
- CreateUnitSymbolInfo (sw);
+ CreateUnitSymbolInfo (sw, Compiler.Settings.PathMap);
}
base.PrepareEmit ();
//
// Creates symbol file index in debug symbol file
//
- void CreateUnitSymbolInfo (MonoSymbolFile symwriter)
+ void CreateUnitSymbolInfo (MonoSymbolFile symwriter, List<KeyValuePair<string, string>> pathMap)
{
- var si = file.CreateSymbolInfo (symwriter);
- comp_unit = new CompileUnitEntry (symwriter, si);;
+ var si = file.CreateSymbolInfo (symwriter, pathMap);
+ comp_unit = new CompileUnitEntry (symwriter, si);
if (include_files != null) {
foreach (SourceFile include in include_files.Values) {
- si = include.CreateSymbolInfo (symwriter);
+ si = include.CreateSymbolInfo (symwriter, pathMap);
comp_unit.AddFile (si);
}
}
public new readonly NamespaceContainer Parent;
- List<UsingNamespace> clauses;
+ List<UsingClause> clauses;
// Used by parsed to check for parser errors
public bool DeclarationFound;
Namespace[] namespace_using_table;
+ TypeSpec[] types_using_table;
Dictionary<string, UsingAliasNamespace> aliases;
public NamespaceContainer (MemberName name, NamespaceContainer parent)
}
}
- public List<UsingNamespace> Usings {
+ public List<UsingClause> Usings {
get {
return clauses;
}
#endregion
- public void AddUsing (UsingNamespace un)
+ public void AddUsing (UsingClause un)
{
if (DeclarationFound){
Compiler.Report.Error (1529, un.Location, "A using clause must precede all other namespace elements except extern alias declarations");
}
if (clauses == null)
- clauses = new List<UsingNamespace> ();
+ clauses = new List<UsingClause> ();
clauses.Add (un);
}
void AddAlias (UsingAliasNamespace un)
{
if (clauses == null) {
- clauses = new List<UsingNamespace> ();
+ clauses = new List<UsingClause> ();
} else {
foreach (var entry in clauses) {
var a = entry as UsingAliasNamespace;
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;
+ var td = existing != null ? existing.MemberDefinition as TypeDefinition : null;
AddPartial (next_part, td);
}
public override void AddTypeContainer (TypeContainer tc)
{
- string name = tc.Basename;
-
var mn = tc.MemberName;
+ var name = mn.Basename;
while (mn.Left != null) {
mn = mn.Left;
name = mn.Name;
//
// Same name conflict in different namespace containers
//
- var conflict = ns.GetAllTypes (name);
+ var conflict = ns.GetAllTypes (mn.Name);
if (conflict != null) {
foreach (var e in conflict) {
if (e.Arity == mn.Arity) {
base.EmitContainer ();
}
- public ExtensionMethodCandidates LookupExtensionMethod (IMemberContext invocationContext, TypeSpec extensionType, string name, int arity, int position)
+ public ExtensionMethodCandidates LookupExtensionMethod (IMemberContext invocationContext, string name, int arity, int position)
{
//
// Here we try to resume the search for extension method at the point
ExtensionMethodCandidates candidates;
var container = this;
do {
- candidates = container.LookupExtensionMethodCandidates (invocationContext, extensionType, name, arity, ref position);
+ candidates = container.LookupExtensionMethodCandidates (invocationContext, name, arity, ref position);
if (candidates != null || container.MemberName == null)
return candidates;
while (mn != null) {
++position;
- var methods = container_ns.LookupExtensionMethod (invocationContext, extensionType, name, arity);
+ var methods = container_ns.LookupExtensionMethod (invocationContext, name, arity);
if (methods != null) {
return new ExtensionMethodCandidates (invocationContext, methods, container, position);
}
return null;
}
- ExtensionMethodCandidates LookupExtensionMethodCandidates (IMemberContext invocationContext, TypeSpec extensionType, string name, int arity, ref int position)
+ ExtensionMethodCandidates LookupExtensionMethodCandidates (IMemberContext invocationContext, string name, int arity, ref int position)
{
List<MethodSpec> candidates = null;
if (position == 0) {
++position;
- candidates = ns.LookupExtensionMethod (invocationContext, extensionType, name, arity);
+ candidates = ns.LookupExtensionMethod (invocationContext, name, arity);
if (candidates != null) {
return new ExtensionMethodCandidates (invocationContext, candidates, this, position);
}
++position;
foreach (Namespace n in namespace_using_table) {
- var a = n.LookupExtensionMethod (invocationContext, extensionType, name, arity);
+ var a = n.LookupExtensionMethod (invocationContext, name, arity);
if (a == null)
continue;
candidates.AddRange (a);
}
+ if (types_using_table != null) {
+ foreach (var t in types_using_table) {
+
+ var res = t.MemberCache.FindExtensionMethods (invocationContext, name, arity);
+ if (res == null)
+ continue;
+
+ if (candidates == null)
+ candidates = res;
+ else
+ candidates.AddRange (res);
+ }
+ }
+
if (candidates != null)
return new ExtensionMethodCandidates (invocationContext, candidates, this, position);
}
continue;
UsingAliasNamespace uan;
- if (n.aliases.TryGetValue (name, out uan))
+ if (n.aliases.TryGetValue (name, out uan)) {
+ if (uan.ResolvedExpression == null)
+ uan.Define (n);
+
return uan.ResolvedExpression;
+ }
}
return null;
GetSignatureForError (), name);
}
+ if (uan.ResolvedExpression == null)
+ uan.Define (this);
+
return uan.ResolvedExpression;
}
}
// A using directive imports only types contained in the namespace, it
// does not import any nested namespaces
//
- fne = using_ns.LookupType (this, name, arity, mode, loc);
- if (fne == null)
+ var t = using_ns.LookupType (this, name, arity, mode, loc);
+ if (t == null)
continue;
+ fne = new TypeExpression (t, loc);
if (match == null) {
match = fne;
continue;
var better = Namespace.IsImportedTypeOverride (Module, texpr_match.Type, texpr_fne.Type);
if (better == null) {
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 ());
+ Error_AmbiguousReference (name, texpr_match, texpr_fne, loc);
}
return match;
match = texpr_fne;
}
+ if (types_using_table != null && (mode & LookupMode.IgnoreStaticUsing) == 0) {
+ foreach (var using_type in types_using_table) {
+ var type = MemberCache.FindNestedType (using_type, name, arity, true);
+ if (type == null)
+ continue;
+
+ fne = new TypeExpression (type, loc);
+ if (match == null) {
+ match = fne;
+ continue;
+ }
+
+ if (mode == LookupMode.Normal) {
+ Error_AmbiguousReference (name, match, fne, loc);
+ }
+ }
+ }
+
return match;
}
+ void Error_AmbiguousReference (string name, FullNamedExpression a, FullNamedExpression b, Location loc)
+ {
+ var report = Compiler.Report;
+ report.SymbolRelatedToPreviousError (a.Type);
+ report.SymbolRelatedToPreviousError (b.Type);
+ report.Error (104, loc, "`{0}' is an ambiguous reference between `{1}' and `{2}'",
+ name, a.GetSignatureForError (), b.GetSignatureForError ());
+ }
+
+ public static Expression LookupStaticUsings (IMemberContext mc, string name, int arity, Location loc)
+ {
+ for (var m = mc.CurrentMemberDefinition; m != null; m = m.Parent) {
+
+ var nc = m as NamespaceContainer;
+ if (nc == null)
+ continue;
+
+ List<MemberSpec> candidates = null;
+ if (nc.types_using_table != null) {
+ foreach (var using_type in nc.types_using_table) {
+ var members = MemberCache.FindMembers (using_type, name, true);
+ if (members == null)
+ continue;
+
+ foreach (var member in members) {
+ if ((member.Kind & MemberKind.NestedMask) != 0) {
+ // non-static nested type is included with using static
+ } else {
+ if ((member.Modifiers & Modifiers.STATIC) == 0)
+ continue;
+
+ if ((member.Modifiers & Modifiers.METHOD_EXTENSION) != 0)
+ continue;
+ }
+
+ if (arity > 0 && member.Arity != arity)
+ continue;
+
+ if (candidates == null)
+ candidates = new List<MemberSpec> ();
+
+ candidates.Add (member);
+ }
+ }
+ }
+
+ if (candidates != null) {
+ var expr = Expression.MemberLookupToExpression (mc, candidates, false, null, name, arity, Expression.MemberLookupRestrictions.None, loc);
+ if (expr != null)
+ return expr;
+ }
+ }
+
+ return null;
+ }
+
protected override void DefineNamespace ()
{
if (namespace_using_table == null)
namespace_using_table = empty_namespaces;
if (clauses != null) {
- var list = new List<Namespace> (clauses.Count);
+ List<Namespace> namespaces = null;
+ List<TypeSpec> types = null;
+
bool post_process_using_aliases = false;
for (int i = 0; i < clauses.Count; ++i) {
continue;
}
- entry.Define (this);
-
- //
- // 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;
+ try {
+ entry.Define (this);
+ } finally {
+ //
+ // It's needed for repl only, when using clause cannot be resolved don't hold it in
+ // global list which is resolved for every evaluation
+ //
+ if (entry.ResolvedExpression == null) {
+ clauses.RemoveAt (i--);
+ }
}
- Namespace using_ns = entry.ResolvedExpression as Namespace;
- if (using_ns == null)
+ if (entry.ResolvedExpression == null)
continue;
- if (list.Contains (using_ns)) {
- // Ensure we don't report the warning multiple times in repl
- clauses.RemoveAt (i--);
+ var using_ns = entry.ResolvedExpression as NamespaceExpression;
+ if (using_ns == null) {
- Compiler.Report.Warning (105, 3, entry.Location,
- "The using directive for `{0}' appeared previously in this namespace", using_ns.GetSignatureForError ());
+ var type = entry.ResolvedExpression.Type;
+
+ if (types == null)
+ types = new List<TypeSpec> ();
+
+ if (types.Contains (type)) {
+ Warning_DuplicateEntry (entry);
+ } else {
+ types.Add (type);
+ }
} else {
- list.Add (using_ns);
+ if (namespaces == null)
+ namespaces = new List<Namespace> ();
+
+ if (namespaces.Contains (using_ns.Namespace)) {
+ // Ensure we don't report the warning multiple times in repl
+ clauses.RemoveAt (i--);
+
+ Warning_DuplicateEntry (entry);
+ } else {
+ namespaces.Add (using_ns.Namespace);
+ }
}
}
- namespace_using_table = list.ToArray ();
+ namespace_using_table = namespaces == null ? new Namespace [0] : namespaces.ToArray ();
+ if (types != null)
+ types_using_table = types.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--);
+ aliases[entry.Alias.Value] = (UsingAliasNamespace) entry;
}
}
}
}
}
+ protected override void DoDefineContainer ()
+ {
+ base.DoDefineContainer ();
+
+ if (clauses != null) {
+ for (int i = 0; i < clauses.Count; ++i) {
+ var entry = clauses[i];
+
+ //
+ // Finish definition of using aliases not visited during container
+ // definition
+ //
+ if (entry.Alias != null && entry.ResolvedExpression == null) {
+ entry.Define (this);
+ }
+ }
+ }
+ }
+
public void EnableRedefinition ()
{
is_defined = false;
return false;
}
+ void Warning_DuplicateEntry (UsingClause entry)
+ {
+ Compiler.Report.Warning (105, 3, entry.Location,
+ "The using directive for `{0}' appeared previously in this namespace",
+ entry.ResolvedExpression.GetSignatureForError ());
+ }
+
public override void Accept (StructuralVisitor visitor)
{
visitor.Visit (this);
}
}
- public class UsingNamespace
+ public class UsingNamespace : UsingClause
+ {
+ public UsingNamespace (ATypeNameExpression expr, Location loc)
+ : base (expr, loc)
+ {
+ }
+
+ public override void Define (NamespaceContainer ctx)
+ {
+ base.Define (ctx);
+
+ var ns = resolved as NamespaceExpression;
+ if (ns != null)
+ return;
+
+ if (resolved != null) {
+ var compiler = ctx.Module.Compiler;
+ var type = resolved.Type;
+ resolved = null;
+
+ compiler.Report.SymbolRelatedToPreviousError (type);
+ compiler.Report.Error (138, Location,
+ "A `using' directive can only be applied to namespaces but `{0}' denotes a type. Consider using a `using static' instead",
+ type.GetSignatureForError ());
+ }
+ }
+ }
+
+ public class UsingType : UsingClause
+ {
+ public UsingType (ATypeNameExpression expr, Location loc)
+ : base (expr, loc)
+ {
+ }
+
+ public override void Define (NamespaceContainer ctx)
+ {
+ base.Define (ctx);
+
+ if (resolved == null)
+ return;
+
+ var ns = resolved as NamespaceExpression;
+ if (ns != null) {
+ var compiler = ctx.Module.Compiler;
+ compiler.Report.Error (7007, Location,
+ "A 'using static' directive can only be applied to types but `{0}' denotes a namespace. Consider using a `using' directive instead",
+ ns.GetSignatureForError ());
+ return;
+ }
+
+ // TODO: Need to move it to post_process_using_aliases
+ //ObsoleteAttribute obsolete_attr = resolved.Type.GetAttributeObsolete ();
+ //if (obsolete_attr != null) {
+ // AttributeTester.Report_ObsoleteMessage (obsolete_attr, resolved.GetSignatureForError (), Location, ctx.Compiler.Report);
+ //}
+ }
+ }
+
+ public class UsingClause
{
readonly ATypeNameExpression expr;
readonly Location loc;
protected FullNamedExpression resolved;
- public UsingNamespace (ATypeNameExpression expr, Location loc)
+ public UsingClause (ATypeNameExpression expr, Location loc)
{
this.expr = expr;
this.loc = loc;
public virtual void Define (NamespaceContainer ctx)
{
- 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 ());
- }
- }
+ resolved = expr.ResolveAsTypeOrNamespace (ctx, false);
}
public override string ToString()
public override void Define (NamespaceContainer ctx)
{
- resolved = ctx.Module.GetRootNamespace (Alias.Value);
- if (resolved == null) {
+ var ns = ctx.Module.GetRootNamespace (Alias.Value);
+ if (ns == null) {
ctx.Module.Compiler.Report.Error (430, Location,
"The extern alias `{0}' was not specified in -reference option",
Alias.Value);
+ return;
}
+
+ resolved = new NamespaceExpression (ns, Location);
}
}
throw new NotImplementedException ();
}
- public ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity)
+ public ExtensionMethodCandidates LookupExtensionMethod (string name, int arity)
{
return null;
}
// 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));
+ resolved = NamespaceExpression.ResolveAsTypeOrNamespace (new AliasContext (ctx), false) ??
+ new TypeExpression (InternalType.ErrorType, NamespaceExpression.Location);
}
}
}