//
public virtual TypeExpr ResolveAsTypeTerminal (IMemberContext ec , bool silent)
{
- int errors = ec.Compiler.Report.Errors;
+ // FIXME: THIS IS TOO SLOW and it should not be needed either
+ int errors = ec.Module.Compiler.Report.Errors;
FullNamedExpression fne = ResolveAsTypeStep (ec, silent);
TypeExpr te = fne as TypeExpr;
if (te == null) {
- if (!silent && errors == ec.Compiler.Report.Errors)
- fne.Error_UnexpectedKind (ec.Compiler.Report, null, "type", loc);
+ if (!silent && errors == ec.Module.Compiler.Report.Errors)
+ fne.Error_UnexpectedKind (ec.Module.Compiler.Report, null, "type", loc);
return null;
}
if (!te.type.IsAccessible (ec.CurrentType)) {
- ec.Compiler.Report.SymbolRelatedToPreviousError (te.Type);
+ ec.Module.Compiler.Report.SymbolRelatedToPreviousError (te.Type);
ErrorIsInaccesible (ec, te.Type.GetSignatureForError (), loc);
}
te.loc = loc;
+ var dep = te.type.GetMissingDependencies ();
+ if (dep != null) {
+ ImportedTypeDefinition.Error_MissingDependency (ec, dep, loc);
+ }
+
//
// Obsolete checks cannot be done when resolving base context as they
// require type dependecies to be set but we are just resolving them
if (!silent && !(ec is TypeContainer.BaseContext)) {
ObsoleteAttribute obsolete_attr = te.Type.GetAttributeObsolete ();
if (obsolete_attr != null && !ec.IsObsolete) {
- AttributeTester.Report_ObsoleteMessage (obsolete_attr, te.GetSignatureForError (), Location, ec.Compiler.Report);
+ AttributeTester.Report_ObsoleteMessage (obsolete_attr, te.GetSignatureForError (), Location, ec.Module.Compiler.Report);
}
}
public static void ErrorIsInaccesible (IMemberContext rc, string member, Location loc)
{
- rc.Compiler.Report.Error (122, loc, "`{0}' is inaccessible due to its protection level", member);
+ rc.Module.Compiler.Report.Error (122, loc, "`{0}' is inaccessible due to its protection level", member);
}
public void Error_ExpressionMustBeConstant (ResolveContext rc, Location loc, string e_name)
if (type == InternalType.AnonymousMethod)
return;
-/*
- if (TypeManager.IsGenericParameter (Type) && TypeManager.IsGenericParameter (target) && type.Name == target.Name) {
- string sig1 = type.DeclaringMethod == null ?
- TypeManager.CSharpName (type.DeclaringType) :
- TypeManager.CSharpSignature (type.DeclaringMethod);
- string sig2 = target.DeclaringMethod == null ?
- TypeManager.CSharpName (target.DeclaringType) :
- TypeManager.CSharpSignature (target.DeclaringMethod);
- ec.Report.ExtraInformation (loc,
- String.Format (
- "The generic parameter `{0}' of `{1}' cannot be converted to the generic parameter `{0}' of `{2}' (in the previous ",
- Type.Name, sig1, sig2));
- } else if (Type.MetaInfo.FullName == target.MetaInfo.FullName) {
- ec.Report.ExtraInformation (loc,
- String.Format (
- "The type `{0}' has two conflicting definitions, one comes from `{1}' and the other from `{2}' (in the previous ",
- Type.MetaInfo.FullName, Type.Assembly.FullName, target.Assembly.FullName));
+ string from_type = type.GetSignatureForError ();
+ string to_type = target.GetSignatureForError ();
+ if (from_type == to_type) {
+ from_type = string.Format ("{0} [{1}]", from_type, type.MemberDefinition.DeclaringAssembly.FullName);
+ to_type = string.Format ("{0} [{1}]", to_type, target.MemberDefinition.DeclaringAssembly.FullName);
}
-*/
+
if (expl) {
ec.Report.Error (30, loc, "Cannot convert type `{0}' to `{1}'",
- TypeManager.CSharpName (type), TypeManager.CSharpName (target));
+ from_type, to_type);
return;
}
ec.Report.EnableReporting ();
if (expl_exists) {
- ec.Report.Error (266, loc, "Cannot implicitly convert type `{0}' to `{1}'. " +
- "An explicit conversion exists (are you missing a cast?)",
- TypeManager.CSharpName (Type), TypeManager.CSharpName (target));
- return;
+ ec.Report.Error (266, loc,
+ "Cannot implicitly convert type `{0}' to `{1}'. An explicit conversion exists (are you missing a cast?)",
+ from_type, to_type);
+ } else {
+ ec.Report.Error (29, loc, "Cannot implicitly convert type `{0}' to `{1}'",
+ from_type, to_type);
}
-
- ec.Report.Error (29, loc, "Cannot implicitly convert type `{0}' to `{1}'",
- type.GetSignatureForError (), target.GetSignatureForError ());
}
public void Error_TypeArgumentsCannotBeUsed (Report report, Location loc, MemberSpec member, int arity)
public virtual void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
{
- rc.Compiler.Report.Error (182, loc,
+ rc.Module.Compiler.Report.Error (182, loc,
"An attribute argument must be a constant expression, typeof expression or array creation expression");
}
// }
// }
//
- if (rc.Compiler.IsRuntimeBinder && !member.DeclaringType.IsAccessible (currentType))
+ if (rc.IsRuntimeBinder && !member.DeclaringType.IsAccessible (currentType))
continue;
}
this.type = type;
}
- public override string AsString ()
- {
- return child.AsString ();
- }
-
- public override object GetValue ()
- {
- return child.GetValue ();
- }
-
public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
{
if (child.Type == target_type)
child.EmitSideEffect (ec);
}
+ public override object GetValue ()
+ {
+ return child.GetValue ();
+ }
+
+ public override string GetValueAsLiteral ()
+ {
+ return child.GetValueAsLiteral ();
+ }
+
public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec target_type)
{
// FIXME: Do we need to check user conversions?
return System.Enum.ToObject (type.GetMetaInfo (), Child.GetValue ());
}
#endif
-
- public override string AsString ()
+
+ public override string GetValueAsLiteral ()
{
- return Child.AsString ();
+ return Child.GetValueAsLiteral ();
}
public EnumConstant Increment()
public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
{
+ // Only boxing to object type is supported
+ if (targetType != TypeManager.object_type) {
+ base.EncodeAttributeValue (rc, enc, targetType);
+ return;
+ }
+
enc.Encode (child.Type);
child.EncodeAttributeValue (rc, enc, child.Type);
}
return new ReducedExpressionStatement (s, orig);
}
+ public static Expression Create (Expression expr, Expression original_expr)
+ {
+ return Create (expr, original_expr, true);
+ }
+
//
// Creates unresolved reduce expression. The original expression has to be
- // already resolved
+ // already resolved. Created expression is constant based based on `expr'
+ // value unless canBeConstant is used
//
- public static Expression Create (Expression expr, Expression original_expr)
+ public static Expression Create (Expression expr, Expression original_expr, bool canBeConstant)
{
- Constant c = expr as Constant;
- if (c != null)
- return Create (c, original_expr);
+ if (canBeConstant) {
+ Constant c = expr as Constant;
+ if (c != null)
+ return Create (c, original_expr);
+ }
ExpressionStatement s = expr as ExpressionStatement;
if (s != null)
//
public abstract class CompositeExpression : Expression
{
- Expression expr;
+ protected Expression expr;
protected CompositeExpression (Expression expr)
{
if (ec.CurrentMemberDefinition != null) {
MemberCore mc = ec.CurrentMemberDefinition.Parent.GetDefinition (Name);
if (mc != null) {
- Error_UnexpectedKind (ec.Compiler.Report, mc, "type", GetMemberType (mc), loc);
+ Error_UnexpectedKind (ec.Module.Compiler.Report, mc, "type", GetMemberType (mc), loc);
return;
}
}
FullNamedExpression retval = ec.LookupNamespaceOrType (Name, -System.Math.Max (1, Arity), loc, true);
if (retval != null) {
- Error_TypeArgumentsCannotBeUsed (ec.Compiler.Report, loc, retval.Type, Arity);
+ Error_TypeArgumentsCannotBeUsed (ec.Module.Compiler.Report, loc, retval.Type, Arity);
/*
var te = retval as TypeExpr;
if (HasTypeArguments && te != null && !te.Type.IsGeneric)
return;
}
- NamespaceEntry.Error_NamespaceNotFound (loc, Name, ec.Compiler.Report);
+ NamespaceEntry.Error_NamespaceNotFound (loc, Name, ec.Module.Compiler.Report);
}
protected override Expression DoResolve (ResolveContext ec)
public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent)
{
- int errors = ec.Compiler.Report.Errors;
+ int errors = ec.Module.Compiler.Report.Errors;
FullNamedExpression fne = ec.LookupNamespaceOrType (Name, Arity, loc, /*ignore_cs0104=*/ false);
if (fne != null) {
return fne;
}
- if (Arity == 0 && Name == "dynamic" && RootContext.Version > LanguageVersion.V_3) {
+ if (Arity == 0 && Name == "dynamic" && ec.Module.Compiler.Settings.Version > LanguageVersion.V_3) {
if (!ec.Module.PredefinedAttributes.Dynamic.IsDefined) {
- ec.Compiler.Report.Error (1980, Location,
+ ec.Module.Compiler.Report.Error (1980, Location,
"Dynamic keyword requires `{0}' to be defined. Are you missing System.Core.dll assembly reference?",
ec.Module.PredefinedAttributes.Dynamic.GetSignatureForError ());
}
if (fne != null)
return fne;
- if (silent || errors != ec.Compiler.Report.Errors)
+ if (silent || errors != ec.Module.Compiler.Report.Errors)
return null;
Error_TypeOrNamespaceNotFound (ec);
return null;
}
- if (RootContext.EvalMode) {
- var fi = Evaluator.LookupField (Name);
+ if (rc.Module.Evaluator != null) {
+ var fi = rc.Module.Evaluator.LookupField (Name);
if (fi != null)
return new FieldExpr (fi.Item1, loc);
}
}
if (targs != null)
- method = method.MakeGenericMethod (targs);
+ method = method.MakeGenericMethod (rc, targs);
}
//
UnsafeError (rc, loc);
}
+ var dep = member.GetMissingDependencies ();
+ if (dep != null) {
+ ImportedTypeDefinition.Error_MissingDependency (rc, dep, loc);
+ }
+
if (!rc.IsObsolete) {
ObsoleteAttribute oa = member.GetAttributeObsolete ();
if (oa != null)
if (IsStatic) {
if (InstanceExpression != null) {
if (InstanceExpression is TypeExpr) {
- ObsoleteAttribute oa = InstanceExpression.Type.GetAttributeObsolete ();
- if (oa != null && !rc.IsObsolete) {
- AttributeTester.Report_ObsoleteMessage (oa, InstanceExpression.GetSignatureForError (), loc, rc.Report);
- }
+ var t = InstanceExpression.Type;
+ do {
+ ObsoleteAttribute oa = t.GetAttributeObsolete ();
+ if (oa != null && !rc.IsObsolete) {
+ AttributeTester.Report_ObsoleteMessage (oa, t.GetSignatureForError (), loc, rc.Report);
+ }
+
+ t = t.DeclaringType;
+ } while (t != null);
} else {
var runtime_expr = InstanceExpression as RuntimeValueExpression;
if (runtime_expr == null || !runtime_expr.IsSuggestionOnly) {
static int BetterExpressionConversion (ResolveContext ec, Argument a, TypeSpec p, TypeSpec q)
{
TypeSpec argument_type = a.Type;
- if (argument_type == InternalType.AnonymousMethod && RootContext.Version > LanguageVersion.ISO_2) {
+
+ //
+ // If argument is an anonymous function
+ //
+ if (argument_type == InternalType.AnonymousMethod && ec.Module.Compiler.Settings.Version > LanguageVersion.ISO_2) {
//
- // Uwrap delegate from Expression<T>
+ // p and q are delegate types or expression tree types
//
- if (p.GetDefinition () == TypeManager.expression_type) {
+ if (p.GetDefinition () == TypeManager.expression_type || q.GetDefinition () == TypeManager.expression_type) {
+ if (q.MemberDefinition != p.MemberDefinition) {
+ return 0;
+ }
+
+ //
+ // Uwrap delegate from Expression<T>
+ //
+ q = TypeManager.GetTypeArguments (q)[0];
p = TypeManager.GetTypeArguments (p)[0];
}
- if (q.GetDefinition () == TypeManager.expression_type) {
- q = TypeManager.GetTypeArguments (q)[0];
+
+ var p_m = Delegate.GetInvokeMethod (p);
+ var q_m = Delegate.GetInvokeMethod (q);
+
+ //
+ // With identical parameter lists
+ //
+ if (!TypeSpecComparer.Equals (p_m.Parameters.Types,q_m.Parameters.Types))
+ return 0;
+
+ p = p_m.ReturnType;
+ q = q_m.ReturnType;
+
+ //
+ // if p is void returning, and q has a return type Y, then C2 is the better conversion.
+ //
+ if (p == TypeManager.void_type) {
+ return q != TypeManager.void_type ? 2 : 0;
}
- p = Delegate.GetInvokeMethod (ec.Compiler, p).ReturnType;
- q = Delegate.GetInvokeMethod (ec.Compiler, q).ReturnType;
- if (p == TypeManager.void_type && q != TypeManager.void_type)
- return 2;
- if (q == TypeManager.void_type && p != TypeManager.void_type)
- return 1;
+ //
+ // if p has a return type Y, and q is void returning, then C1 is the better conversion.
+ //
+ if (q == TypeManager.void_type) {
+ return p != TypeManager.void_type ? 1: 0;
+ }
} else {
if (argument_type == p)
return 1;
var best_def_pd = ((IParametersMember) best.MemberDefinition).Parameters;
bool specific_at_least_once = false;
- for (j = 0; j < candidate_param_count; ++j) {
+ for (j = 0; j < args_count; ++j) {
NamedArgument na = args_count == 0 ? null : args [j] as NamedArgument;
if (na != null) {
ct = candidate_def_pd.Types[cparam.GetParameterIndexByName (na.Name)];
//
int IsApplicable (ResolveContext ec, ref Arguments arguments, int arg_count, ref MemberSpec candidate, IParametersMember pm, ref bool params_expanded_form, ref bool dynamicArgument, ref TypeSpec returnType)
{
+ // Parameters of most-derived type used mainly for named and optional parameters
var pd = pm.Parameters;
+
+ // Used for params modifier only, that's legacy of C# 1.0 which uses base type for
+ // params modifier instead of most-derived type
+ var cpd = ((IParametersMember) candidate).Parameters;
int param_count = pd.Count;
int optional_count = 0;
int score;
}
}
- int args_gap = System.Math.Abs (arg_count - param_count);
if (optional_count != 0) {
- if (args_gap > optional_count)
- return int.MaxValue - 10000 + args_gap - optional_count;
-
// Readjust expected number when params used
- if (pd.HasParams) {
+ if (cpd.HasParams) {
optional_count--;
if (arg_count < param_count)
param_count--;
} else if (arg_count > param_count) {
+ int args_gap = System.Math.Abs (arg_count - param_count);
return int.MaxValue - 10000 + args_gap;
}
} else if (arg_count != param_count) {
- if (!pd.HasParams)
+ int args_gap = System.Math.Abs (arg_count - param_count);
+ if (!cpd.HasParams)
return int.MaxValue - 10000 + args_gap;
if (arg_count < param_count - 1)
return int.MaxValue - 10000 + args_gap;
Argument temp;
if (index >= param_count) {
// When using parameters which should not be available to the user
- if ((pd.FixedParameters[index].ModFlags & Parameter.Modifier.PARAMS) == 0)
+ if ((cpd.FixedParameters[index].ModFlags & Parameter.Modifier.PARAMS) == 0)
break;
arguments.Add (null);
//
// 1. Handle generic method using type arguments when specified or type inference
//
+ TypeSpec[] ptypes;
var ms = candidate as MethodSpec;
if (ms != null && ms.IsGeneric) {
// Setup constraint checker for probing only
if (g_args_count != type_arguments.Count)
return int.MaxValue - 20000 + System.Math.Abs (type_arguments.Count - g_args_count);
- ms = ms.MakeGenericMethod (type_arguments.Arguments);
+ ms = ms.MakeGenericMethod (ec, type_arguments.Arguments);
} else {
// TODO: It should not be here (we don't know yet whether any argument is lambda) but
// for now it simplifies things. I should probably add a callback to ResolveContext
return ti.InferenceScore - 20000;
if (i_args.Length != 0) {
- ms = ms.MakeGenericMethod (i_args);
+ ms = ms.MakeGenericMethod (ec, i_args);
}
cc.IgnoreInferredDynamic = true;
//
if (candidate != pm) {
MethodSpec override_ms = (MethodSpec) pm;
- var inflator = new TypeParameterInflator (ms.DeclaringType, override_ms.GenericDefinition.TypeParameters, ms.TypeArguments);
+ var inflator = new TypeParameterInflator (ec, ms.DeclaringType, override_ms.GenericDefinition.TypeParameters, ms.TypeArguments);
returnType = inflator.Inflate (returnType);
} else {
returnType = ms.ReturnType;
}
candidate = ms;
-
+ ptypes = ms.Parameters.Types;
} else {
if (type_arguments != null)
return int.MaxValue - 15000;
+
+ ptypes = cpd.Types;
}
//
//
Parameter.Modifier p_mod = 0;
TypeSpec pt = null;
- TypeSpec[] ptypes = ((IParametersMember) candidate).Parameters.Types;
for (int i = 0; i < arg_count; i++) {
Argument a = arguments[i];
}
if (p_mod != Parameter.Modifier.PARAMS) {
- p_mod = pd.FixedParameters[i].ModFlags;
+ p_mod = (pd.FixedParameters[i].ModFlags & ~Parameter.Modifier.PARAMS) | (cpd.FixedParameters[i].ModFlags & Parameter.Modifier.PARAMS);
pt = ptypes [i];
} else if (!params_expanded_form) {
params_expanded_form = true;
//
// When params parameter has no argument it will be provided later if the method is the best candidate
//
- if (arg_count + 1 == pd.Count && (pd.FixedParameters [arg_count].ModFlags & Parameter.Modifier.PARAMS) != 0)
+ if (arg_count + 1 == pd.Count && (cpd.FixedParameters [arg_count].ModFlags & Parameter.Modifier.PARAMS) != 0)
params_expanded_form = true;
//
if (!member.IsAccessible (current_type))
continue;
- if (rc.Compiler.IsRuntimeBinder && !member.DeclaringType.IsAccessible (current_type))
+ if (rc.IsRuntimeBinder && !member.DeclaringType.IsAccessible (current_type))
continue;
}
if (best_candidate.DeclaringType.IsInterface && member.DeclaringType.ImplementsInterface (best_candidate.DeclaringType, false)) {
//
// We pack all interface members into top level type which makes the overload resolution
- // more complicated for interfaces. We accomodate for this by removing methods with same
+ // more complicated for interfaces. We compensate it by removing methods with same
// signature when building the cache hence this path should not really be hit often
//
// Example:
}
if (ambiguous_candidates != null) {
- if (best_candidate.DeclaringType.IsInterface) {
- ambiguous_candidates.Add (new AmbiguousCandidate (best_candidate, best_parameter_member.Parameters, best_candidate_params));
- for (int cix = 0; cix < ambiguous_candidates.Count; ++cix) {
- var tested_type = ambiguous_candidates[cix].Member.DeclaringType;
-
- int ix = 0;
- for (; ix < ambiguous_candidates.Count; ++ix) {
- var amb_cand_type = ambiguous_candidates[ix].Member.DeclaringType;
- if (amb_cand_type == tested_type)
- continue;
-
- if (tested_type.ImplementsInterface (amb_cand_type, false))
- continue;
-
- break;
- }
-
- if (ix != ambiguous_candidates.Count)
- continue;
-
- best_candidate = ambiguous_candidates[cix].Member;
- //best_parameter_member = ambiguous_candidates
-
- throw new NotImplementedException ();
- }
- }
-
//
// Now check that there are no ambiguities i.e the selected method
// should be better than all the others
if (oa != null && !rc.IsObsolete)
AttributeTester.Report_ObsoleteMessage (oa, best_candidate.GetSignatureForError (), loc, rc.Report);
+ var dep = best_candidate.GetMissingDependencies ();
+ if (dep != null) {
+ ImportedTypeDefinition.Error_MissingDependency (rc, dep, loc);
+ }
+
best_candidate.MemberDefinition.SetIsUsed ();
args = best_candidate_args;
// For candidates which match on parameters count report more details about incorrect arguments
//
if (pm != null) {
- int unexpanded_count = pm.Parameters.HasParams ? pm.Parameters.Count - 1 : pm.Parameters.Count;
+ int unexpanded_count = ((IParametersMember) best_candidate).Parameters.HasParams ? pm.Parameters.Count - 1 : pm.Parameters.Count;
if (pm.Parameters.Count == arg_count || params_expanded || unexpanded_count == arg_count) {
// Reject any inaccessible member
if (!best_candidate.IsAccessible (rc.CurrentType) || !best_candidate.DeclaringType.IsAccessible (rc.CurrentType)) {
if (a.Expr.Type == InternalType.Dynamic)
continue;
- if ((restrictions & Restrictions.CovariantDelegate) != 0 && !Delegate.IsTypeCovariant (a.Expr, pt)) {
+ if ((restrictions & Restrictions.CovariantDelegate) != 0 && !Delegate.IsTypeCovariant (ec, a.Expr, pt)) {
custom_errors.NoArgumentMatch (ec, member);
return false;
}
EmitInstance (ec, false);
// Optimization for build-in types
- if (TypeManager.IsStruct (type) && type == ec.MemberContext.CurrentType && InstanceExpression.Type == type) {
+ if (TypeManager.IsStruct (type) && type == ec.CurrentType && InstanceExpression.Type == type) {
ec.EmitLoadFromPtr (type);
} else {
var ff = spec as FixedFieldSpec;
bool need_copy;
if (spec.IsReadOnly){
need_copy = true;
- if (ec.HasSet (EmitContext.Options.ConstructorScope)){
+ if (ec.HasSet (EmitContext.Options.ConstructorScope) && spec.DeclaringType == ec.CurrentType) {
if (IsStatic){
if (ec.IsStatic)
need_copy = false;
//
if (!ec.HasSet (ResolveContext.Options.CompoundAssignmentScope)) {
if (spec.BackingField != null &&
- (spec.DeclaringType == ec.CurrentType || TypeManager.IsNestedChildOf (ec.CurrentType, spec.DeclaringType))) {
+ (spec.DeclaringType == ec.CurrentType || TypeManager.IsNestedChildOf (ec.CurrentType, spec.DeclaringType.MemberDefinition))) {
spec.MemberDefinition.SetIsUsed ();
void Error_AssignmentEventOnly (ResolveContext ec)
{
- if (spec.DeclaringType == ec.CurrentType || TypeManager.IsNestedChildOf (ec.CurrentType, spec.DeclaringType)) {
+ if (spec.DeclaringType == ec.CurrentType || TypeManager.IsNestedChildOf (ec.CurrentType, spec.DeclaringType.MemberDefinition)) {
ec.Report.Error (79, loc,
"The event `{0}' can only appear on the left hand side of `+=' or `-=' operator",
GetSignatureForError ());
protected override void Error_TypeOrNamespaceNotFound (IMemberContext ec)
{
- if (RootContext.Version < LanguageVersion.V_3)
+ if (ec.Module.Compiler.Settings.Version < LanguageVersion.V_3)
base.Error_TypeOrNamespaceNotFound (ec);
else
- ec.Compiler.Report.Error (825, loc, "The contextual keyword `var' may only appear within a local variable declaration");
+ ec.Module.Compiler.Report.Error (825, loc, "The contextual keyword `var' may only appear within a local variable declaration");
}
}
}