public TypeExpr LookupType (CompilerContext ctx, string name, int arity, bool silent, Location loc)
{
if (types == null)
return null;
TypeExpr te;
if (arity == 0 && cached_types.TryGetValue (name, out te))
return te;
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) {
best = ts;
continue;
}
var pts = best as BuildinTypeSpec;
if (pts == null)
pts = ts as BuildinTypeSpec;
if (pts != null) {
ctx.Report.SymbolRelatedToPreviousError (best);
ctx.Report.SymbolRelatedToPreviousError (ts);
// TODO: This should use different warning number but we want to be csc compatible
ctx.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;
continue;
}
if (best.MemberDefinition.IsImported && ts.MemberDefinition.IsImported) {
ctx.Report.SymbolRelatedToPreviousError (best);
ctx.Report.SymbolRelatedToPreviousError (ts);
if (silent) {
ctx.Report.Warning (1685, 1, loc,
"The predefined type `{0}' is defined in multiple assemblies. Using definition from `{1}'",
ts.GetSignatureForError (), best.MemberDefinition.DeclaringAssembly.Name);
} else {
ctx.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 && !best.MemberDefinition.IsInternalAsPublic (RootContext.ToplevelTypes.DeclaringAssembly))
continue;
if (silent)
continue;
if (ts.MemberDefinition.IsImported)
ctx.Report.SymbolRelatedToPreviousError (ts);
ctx.Report.Warning (436, 2, loc,
"The type `{0}' conflicts with the imported type of same name'. Ignoring the imported type definition",
best.GetSignatureForError ());
}
//
// 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;
}
}
}
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
if (arity == 0 && !silent)
cached_types.Add (name, te);
return te;
}