//
using System;
using System.Collections.Generic;
-using System.Reflection;
using System.Linq;
namespace Mono.CSharp {
public class RootNamespace : Namespace {
- protected readonly string alias_name;
- protected Assembly [] referenced_assemblies;
-
- Dictionary<string, Namespace> all_namespaces;
+ readonly string alias_name;
+ readonly Dictionary<string, Namespace> all_namespaces;
public RootNamespace (string alias_name)
: base (null, String.Empty)
{
this.alias_name = alias_name;
- referenced_assemblies = new Assembly [0];
all_namespaces = new Dictionary<string, Namespace> ();
all_namespaces.Add ("", this);
}
- public void AddAssemblyReference (Assembly a)
- {
- foreach (Assembly assembly in referenced_assemblies) {
- if (a == assembly)
- return;
- }
-
- int top = referenced_assemblies.Length;
- Assembly [] n = new Assembly [top + 1];
- referenced_assemblies.CopyTo (n, 0);
- n [top] = a;
- referenced_assemblies = n;
- }
-
- public void ImportTypes (CompilerContext ctx)
- {
- foreach (Assembly a in referenced_assemblies) {
- try {
- ctx.MetaImporter.ImportAssembly (a, this);
- } catch (TypeLoadException e) {
- ctx.Report.Error (11, Location.Null, e.Message);
- } catch (System.IO.FileNotFoundException) {
- ctx.Report.Error (12, Location.Null, "An assembly `{0}' is used without being referenced",
- a.FullName);
- }
+ public string Alias {
+ get {
+ return alias_name;
}
}
}
}
- public class GlobalRootNamespace : RootNamespace {
- Module [] modules;
- Dictionary<string, RootNamespace> root_namespaces;
-
- // TODO: Breaks dynamic/eval
- public static GlobalRootNamespace Instance = new GlobalRootNamespace ();
-
- GlobalRootNamespace ()
+ public class GlobalRootNamespace : RootNamespace
+ {
+ public GlobalRootNamespace ()
: base ("global")
{
- root_namespaces = new Dictionary<string, RootNamespace> ();
- root_namespaces.Add (alias_name, this);
- }
-
- public static void Reset ()
- {
- Instance = new GlobalRootNamespace ();
- }
-
- public Assembly [] Assemblies {
- get { return referenced_assemblies; }
- }
-
- public Module [] Modules {
- get { return modules; }
- }
-
- public void AddModuleReference (Module m)
- {
- int top = modules != null ? modules.Length : 0;
- Module [] n = new Module [top + 1];
- if (modules != null)
- modules.CopyTo (n, 0);
- n [top] = m;
- modules = n;
-
- if (m == RootContext.ToplevelTypes.Builder)
- return;
-
- foreach (var t in m.GetTypes ())
- RegisterNamespace (t.Namespace);
- }
-
- public void ComputeNamespaces (CompilerContext ctx)
- {
- foreach (RootNamespace rn in root_namespaces.Values) {
- rn.ImportTypes (ctx);
- }
- }
-
- public void DefineRootNamespace (string alias, Assembly assembly, CompilerContext ctx)
- {
- if (alias == alias_name) {
- NamespaceEntry.Error_GlobalNamespaceRedefined (Location.Null, ctx.Report);
- return;
- }
-
- RootNamespace retval = GetRootNamespace (alias);
- if (retval == null) {
- retval = new RootNamespace (alias);
- root_namespaces.Add (alias, retval);
- }
-
- retval.AddAssemblyReference (assembly);
}
public override void Error_NamespaceDoesNotExist (Location loc, string name, int arity, IMemberContext ctx)
{
- ctx.Compiler.Report.Error (400, loc,
+ 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);
}
-
- public RootNamespace GetRootNamespace (string name)
- {
- RootNamespace rn;
- if (!root_namespaces.TryGetValue (name, out rn))
- return null;
-
- return rn;
- }
}
/// <summary>
public virtual void Error_NamespaceDoesNotExist (Location loc, string name, int arity, IMemberContext ctx)
{
- FullNamedExpression retval = Lookup (ctx.Compiler, name, -System.Math.Max (1, arity), loc);
+ FullNamedExpression retval = Lookup (ctx, name, -System.Math.Max (1, arity), loc);
if (retval != null) {
- Error_TypeArgumentsCannotBeUsed (ctx.Compiler.Report, loc, retval.Type, arity);
+ Error_TypeArgumentsCannotBeUsed (ctx.Module.Compiler.Report, loc, retval.Type, arity);
return;
}
Namespace ns;
if (arity > 0 && namespaces.TryGetValue (name, out ns)) {
- ns.Error_TypeArgumentsCannotBeUsed (ctx.Compiler.Report, loc, null, arity);
+ ns.Error_TypeArgumentsCannotBeUsed (ctx.Module.Compiler.Report, loc, null, arity);
return;
}
- ctx.Compiler.Report.Error (234, loc,
+ 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 ());
}
return ns;
}
- public TypeExpr LookupType (CompilerContext ctx, string name, int arity, bool silent, Location loc)
+ public TypeExpr LookupType (IMemberContext ctx, string name, int arity, bool silent, Location loc)
{
if (types == null)
return null;
continue;
}
- var pts = best as PredefinedTypeSpec;
+ var pts = best as BuildinTypeSpec;
if (pts == null)
- pts = ts as PredefinedTypeSpec;
+ pts = ts as BuildinTypeSpec;
if (pts != null) {
- ctx.Report.SymbolRelatedToPreviousError (best);
- ctx.Report.SymbolRelatedToPreviousError (ts);
+ ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (best);
+ ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ts);
// TODO: This should use different warning number but we want to be csc compatible
- ctx.Report.Warning (1685, 1, loc,
+ ctx.Module.Compiler.Report.Warning (1685, 1, loc,
"The predefined type `{0}.{1}' is redefined in the source code. Ignoring the local type definition",
pts.Namespace, pts.Name);
best = pts;
}
if (best.MemberDefinition.IsImported && ts.MemberDefinition.IsImported) {
- ctx.Report.SymbolRelatedToPreviousError (best);
- ctx.Report.SymbolRelatedToPreviousError (ts);
+ ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (best);
+ ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ts);
if (silent) {
- ctx.Report.Warning (1685, 1, loc,
+ ctx.Module.Compiler.Report.Warning (1685, 1, loc,
"The predefined type `{0}' is defined in multiple assemblies. Using definition from `{1}'",
- ts.GetSignatureForError (), best.Assembly.GetName ().Name);
+ ts.GetSignatureForError (), best.MemberDefinition.DeclaringAssembly.Name);
} else {
- ctx.Report.Error (433, loc, "The imported type `{0}' is defined multiple times", ts.GetSignatureForError ());
+ ctx.Module.Compiler.Report.Error (433, loc, "The imported type `{0}' is defined multiple times", ts.GetSignatureForError ());
}
break;
if (best.MemberDefinition.IsImported)
best = ts;
- if ((best.Modifiers & Modifiers.INTERNAL) != 0 && !TypeManager.IsThisOrFriendAssembly (CodeGen.Assembly.Builder, best.MemberDefinition.Assembly))
+ if ((best.Modifiers & Modifiers.INTERNAL) != 0 && !best.MemberDefinition.IsInternalAsPublic (RootContext.ToplevelTypes.DeclaringAssembly))
continue;
if (silent)
continue;
if (ts.MemberDefinition.IsImported)
- ctx.Report.SymbolRelatedToPreviousError (ts);
+ ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ts);
- ctx.Report.Warning (436, 2, loc,
+ ctx.Module.Compiler.Report.Warning (436, 2, loc,
"The type `{0}' conflicts with the imported type of same name'. Ignoring the imported type definition",
best.GetSignatureForError ());
}
if (best == null)
return null;
+ if ((best.Modifiers & Modifiers.INTERNAL) != 0 && !best.MemberDefinition.IsInternalAsPublic (RootContext.ToplevelTypes.DeclaringAssembly))
+ return null;
+
te = new TypeExpression (best, Location.Null);
// TODO MemberCache: Cache more
return null;
}
- public FullNamedExpression Lookup (CompilerContext ctx, string name, int arity, Location loc)
+ public FullNamedExpression Lookup (IMemberContext ctx, string name, int arity, Location loc)
{
if (arity == 0 && namespaces.ContainsKey (name))
return namespaces [name];
///
/// Looks for extension method in this namespace
///
- public List<MethodSpec> LookupExtensionMethod (TypeSpec extensionType, ClassOrStruct currentClass, string name, int arity)
+ public List<MethodSpec> LookupExtensionMethod (TypeSpec extensionType, TypeContainer invocationContext, string name, int arity)
{
if (types == null)
return null;
List<MethodSpec> found = null;
- var invocation_type = currentClass == null ? InternalType.FakeInternalType : currentClass.CurrentType;
-
// TODO: Add per namespace flag when at least 1 type has extension
foreach (var tgroup in types.Values) {
if ((ts.Modifiers & Modifiers.METHOD_EXTENSION) == 0)
continue;
- var res = ts.MemberCache.FindExtensionMethods (invocation_type, extensionType, name, arity);
+ var res = ts.MemberCache.FindExtensionMethods (invocationContext, extensionType, name, arity);
if (res == null)
continue;
//
public static TypeSpec IsImportedTypeOverride (TypeSpec ts, TypeSpec found)
{
- var ts_accessible = (ts.Modifiers & Modifiers.PUBLIC) != 0 || TypeManager.IsThisOrFriendAssembly (CodeGen.Assembly.Builder, ts.MemberDefinition.Assembly);
- var found_accessible = (found.Modifiers & Modifiers.PUBLIC) != 0 || TypeManager.IsThisOrFriendAssembly (CodeGen.Assembly.Builder, found.MemberDefinition.Assembly);
+ var ts_accessible = (ts.Modifiers & Modifiers.PUBLIC) != 0 || ts.MemberDefinition.IsInternalAsPublic (RootContext.ToplevelTypes.DeclaringAssembly);
+ var found_accessible = (found.Modifiers & Modifiers.PUBLIC) != 0 || found.MemberDefinition.IsInternalAsPublic (RootContext.ToplevelTypes.DeclaringAssembly);
if (ts_accessible && !found_accessible)
return ts;
types.Remove (name);
}
- public void ReplaceTypeWithPredefined (TypeSpec ts, PredefinedTypeSpec pts)
+ public void ReplaceTypeWithPredefined (TypeSpec ts, BuildinTypeSpec pts)
{
var found = types [ts.Name];
cached_types.Remove (ts.Name);
resolved = fne as Namespace;
if (resolved == null) {
- rc.Compiler.Report.SymbolRelatedToPreviousError (fne.Type);
- rc.Compiler.Report.Error (138, Location,
+ 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 ());
}
this.Location = loc;
}
- public virtual FullNamedExpression Resolve (IMemberContext rc)
+ public virtual FullNamedExpression Resolve (IMemberContext rc, bool local)
{
- FullNamedExpression fne = GlobalRootNamespace.Instance.GetRootNamespace (Alias);
+ FullNamedExpression fne = rc.Module.GetRootNamespace (Alias);
if (fne == null) {
- rc.Compiler.Report.Error (430, Location,
+ rc.Module.Compiler.Report.Error (430, Location,
"The extern alias `{0}' was not specified in -reference option",
Alias);
}
this.value = name;
}
- public override FullNamedExpression Resolve (IMemberContext rc)
+ public override FullNamedExpression Resolve (IMemberContext rc, bool local)
{
if (resolved != null || value == null)
return resolved;
- if (rc == null)
+ if (local)
return null;
resolved = value.GetTypeExpression ().ResolveAsTypeStep (rc, false);
public readonly DeclSpace SlaveDeclSpace;
static readonly Namespace [] empty_namespaces = new Namespace [0];
Namespace [] namespace_using_table;
+ ModuleContainer ctx;
static List<NamespaceEntry> entries = new List<NamespaceEntry> ();
entries = new List<NamespaceEntry> ();
}
- public NamespaceEntry (NamespaceEntry parent, CompilationUnit file, string name)
+ public NamespaceEntry (ModuleContainer ctx, NamespaceEntry parent, CompilationUnit file, string name)
{
+ this.ctx = ctx;
this.parent = parent;
this.file = file;
entries.Add (this);
if (parent != null)
ns = parent.NS.GetNamespace (name, true);
else if (name != null)
- ns = GlobalRootNamespace.Instance.GetNamespace (name, true);
+ ns = ctx.GlobalRootNamespace.GetNamespace (name, true);
else
- ns = GlobalRootNamespace.Instance;
+ ns = ctx.GlobalRootNamespace;
+
SlaveDeclSpace = new RootDeclSpace (this);
}
- private NamespaceEntry (NamespaceEntry parent, CompilationUnit file, Namespace ns, bool slave)
+ private NamespaceEntry (ModuleContainer ctx, NamespaceEntry parent, CompilationUnit file, Namespace ns, bool slave)
{
+ this.ctx = ctx;
this.parent = parent;
this.file = file;
this.IsImplicit = true;
this.SlaveDeclSpace = slave ? new RootDeclSpace (this) : null;
}
- //
- // Populates the Namespace with some using declarations, used by the
- // eval mode.
- //
- public void Populate (List<UsingAliasEntry> source_using_aliases, List<UsingEntry> source_using_clauses)
- {
- foreach (UsingAliasEntry uae in source_using_aliases){
- if (using_aliases == null)
- using_aliases = new List<UsingAliasEntry> ();
-
- using_aliases.Add (uae);
- }
-
- foreach (UsingEntry ue in source_using_clauses){
- if (using_clauses == null)
- using_clauses = new List<UsingEntry> ();
-
- using_clauses.Add (ue);
+ public List<UsingEntry> Usings {
+ get {
+ return using_clauses;
}
}
NamespaceEntry Doppelganger {
get {
if (!IsImplicit && doppelganger == null) {
- doppelganger = new NamespaceEntry (ImplicitParent, file, ns, true);
+ doppelganger = new NamespaceEntry (ctx, ImplicitParent, file, ns, true);
doppelganger.using_aliases = using_aliases;
}
return doppelganger;
if (implicit_parent == null) {
implicit_parent = (parent.NS == ns.Parent)
? parent
- : new NamespaceEntry (parent, file, ns.Parent, false);
+ : new NamespaceEntry (ctx, parent, file, ns.Parent, false);
}
return implicit_parent;
}
{
List<MethodSpec> candidates = null;
foreach (Namespace n in GetUsingTable ()) {
- var a = n.LookupExtensionMethod (extensionType, null, name, arity);
+ var a = n.LookupExtensionMethod (extensionType, RootContext.ToplevelTypes, name, arity);
if (a == null)
continue;
//
Namespace parent_ns = ns.Parent;
do {
- candidates = parent_ns.LookupExtensionMethod (extensionType, null, name, arity);
+ candidates = parent_ns.LookupExtensionMethod (extensionType, RootContext.ToplevelTypes, name, arity);
if (candidates != null)
return candidates;
foreach (UsingAliasEntry ue in n.using_aliases) {
if (ue.Alias == name)
- return ue.Resolve (Doppelganger);
+ return ue.Resolve (Doppelganger ?? this, Doppelganger == null);
}
}
//
// Check whether it's in the namespace.
//
- FullNamedExpression fne = ns.Lookup (Compiler, name, arity, loc);
+ FullNamedExpression fne = ns.Lookup (this, name, arity, loc);
//
// Check aliases.
}
}
- return ue.Resolve (Doppelganger);
+ return ue.Resolve (Doppelganger ?? this, Doppelganger == null);
}
}
}
if (fne != null) {
- if (!((fne.Type.Modifiers & Modifiers.INTERNAL) != 0 && !TypeManager.IsThisOrFriendAssembly (CodeGen.Assembly.Builder, fne.Type.Assembly)))
+ if (!((fne.Type.Modifiers & Modifiers.INTERNAL) != 0 && !fne.Type.MemberDefinition.IsInternalAsPublic (RootContext.ToplevelTypes.DeclaringAssembly)))
return fne;
}
foreach (Namespace using_ns in GetUsingTable ()) {
// A using directive imports only types contained in the namespace, it
// does not import any nested namespaces
- fne = using_ns.LookupType (Compiler, name, arity, false, loc);
+ fne = using_ns.LookupType (this, name, arity, false, loc);
if (fne == null)
continue;
public static void Error_GlobalNamespaceRedefined (Location loc, Report Report)
{
- Report.Error (1681, loc, "You cannot redefine the global extern alias");
+ Report.Error (1681, loc, "The global extern alias cannot be redefined");
}
public static void Error_NamespaceNotFound (Location loc, string name, Report Report)
{
if (using_aliases != null) {
foreach (UsingAliasEntry ue in using_aliases)
- ue.Resolve (Doppelganger);
+ ue.Resolve (Doppelganger, Doppelganger == null);
}
if (using_clauses != null) {
#region IMemberContext Members
public CompilerContext Compiler {
- get { return RootContext.ToplevelTypes.Compiler; }
+ get { return ctx.Compiler; }
}
public TypeSpec CurrentType {
get { return SlaveDeclSpace.IsStatic; }
}
+ public ModuleContainer Module {
+ get { return ctx; }
+ }
+
#endregion
}
}