List<string> res = null;
foreach (var ns in all_namespaces) {
+ if (ns.Key.Length == 0)
+ continue;
+
var methods = ns.Value.LookupExtensionMethod (ctx, name, arity);
if (methods != null) {
if (res == null)
return null;
foreach (var ts in found) {
- if (ts.Arity == arity || mode == LookupMode.NameOf) {
+ if (ts.Arity == arity) {
if (best == null) {
if ((ts.Modifiers & Modifiers.INTERNAL) != 0 && !ts.MemberDefinition.IsInternalAsPublic (ctx.Module.DeclaringAssembly) && mode != LookupMode.IgnoreAccessibility)
continue;
break;
}
+ if (ts.Kind == MemberKind.MissingType)
+ continue;
+
if (best.MemberDefinition.IsImported)
best = ts;
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);
+ 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;
}
}
- 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;
//
// 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
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;
}
}
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;
}
- public static MethodGroupExpr LookupStaticUsings (IMemberContext mc, string name, int arity, Location loc)
+ 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) {
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) {
- foreach (var member in members) {
- if ((member.Modifiers & Modifiers.METHOD_EXTENSION) != 0)
+ 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 (arity > 0 && member.Arity != arity)
+ if ((member.Modifiers & Modifiers.METHOD_EXTENSION) != 0)
continue;
+ }
- if (candidates == null)
- candidates = new List<MemberSpec> ();
+ if (arity > 0 && member.Arity != arity)
+ continue;
- candidates.Add (member);
- }
+ if (candidates == null)
+ candidates = new List<MemberSpec> ();
+
+ candidates.Add (member);
}
}
}
- if (candidates != null)
- return new MethodGroupExpr (candidates, null, loc);
+ if (candidates != null) {
+ var expr = Expression.MemberLookupToExpression (mc, candidates, false, null, name, arity, Expression.MemberLookupRestrictions.None, loc);
+ if (expr != null)
+ return expr;
+ }
}
return null;
continue;
}
- entry.Define (this);
+ 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--);
+ }
+ }
- //
- // 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--);
+ if (entry.ResolvedExpression == null)
continue;
- }
var using_ns = entry.ResolvedExpression as NamespaceExpression;
if (using_ns == null) {
- var type = ((TypeExpr)entry.ResolvedExpression).Type;
+ var type = entry.ResolvedExpression.Type;
if (types == null)
types = new List<TypeSpec> ();
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 (UsingNamespace entry)
+ void Warning_DuplicateEntry (UsingClause entry)
{
Compiler.Report.Warning (105, 3, entry.Location,
"The using directive for `{0}' appeared previously in this namespace",
}
}
- 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, false);
- var ns = resolved as NamespaceExpression;
- if (ns != null)
- return;
-
- if (resolved != null) {
- var compiler = ctx.Module.Compiler;
- var type = resolved.Type;
- if (compiler.Settings.Version >= LanguageVersion.V_6) {
- if (!type.IsClass || !type.IsStatic) {
- compiler.Report.SymbolRelatedToPreviousError (type);
- compiler.Report.Error (7007, Location,
- "`{0}' is not a static class. A using namespace directive can only be applied to static classes or namespace",
- GetSignatureForError ());
- }
-
- return;
- }
-
- compiler.Report.SymbolRelatedToPreviousError (type);
- compiler.Report.Error (138, Location,
- "`{0}' is a type not a namespace. A using namespace directive can only be applied to namespaces",
- GetSignatureForError ());
- }
}
public override string ToString()
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), false);
+ resolved = NamespaceExpression.ResolveAsTypeOrNamespace (new AliasContext (ctx), false) ??
+ new TypeExpression (InternalType.ErrorType, NamespaceExpression.Location);
}
}
}