// <summary> // Resolve is used in method definitions // </summary> public virtual Type Resolve(IResolveContext ec) { // HACK: to resolve attributes correctly this.resolve_context = ec; if (parameter_type != null) { return(parameter_type); } TypeExpr texpr = TypeName.ResolveAsTypeTerminal(ec, false); if (texpr == null) { return(null); } parameter_type = texpr.Type; if ((modFlags & Parameter.Modifier.ISBYREF) != 0 && TypeManager.IsSpecialType(parameter_type)) { Report.Error(1601, Location, "Method or delegate parameter cannot be of type `{0}'", GetSignatureForError()); return(null); } #if GMCS_SOURCE TypeParameterExpr tparam = texpr as TypeParameterExpr; if (tparam != null) { return(parameter_type); } #endif if ((parameter_type.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) { Report.Error(721, Location, "`{0}': static types cannot be used as parameters", texpr.GetSignatureForError()); return(parameter_type); } if ((modFlags & Modifier.This) != 0 && parameter_type.IsPointer) { Report.Error(1103, Location, "The type of extension method cannot be `{0}'", TypeManager.CSharpName(parameter_type)); } return(parameter_type); }
// <summary> // Resolve is used in method definitions // </summary> public virtual Type Resolve(IMemberContext rc) { if (parameter_type != null) { return(parameter_type); } if (attributes != null) { attributes.AttachTo(this, rc); } TypeExpr texpr = TypeName.ResolveAsTypeTerminal(rc, false); if (texpr == null) { return(null); } parameter_type = texpr.Type; // Ignore all checks for dummy members AbstractPropertyEventMethod pem = rc as AbstractPropertyEventMethod; if (pem != null && pem.IsDummy) { return(parameter_type); } if (default_expr != null) { ResolveContext ec = new ResolveContext(rc); default_expr = default_expr.Resolve(ec); if (default_expr != null) { Constant value = default_expr as Constant; if (value == null) { if (default_expr != null) { bool is_valid = false; if (default_expr is DefaultValueExpression) { is_valid = true; } else if (default_expr is New && ((New)default_expr).IsDefaultValueType) { is_valid = TypeManager.IsEqual(parameter_type, default_expr.Type) || (TypeManager.IsNullableType(parameter_type) && Convert.ImplicitNulableConversion(ec, default_expr, parameter_type) != EmptyExpression.Null); } else { rc.Compiler.Report.Error(1736, default_expr.Location, "The expression being assigned to optional parameter `{0}' must be a constant or default value", Name); is_valid = true; } if (!is_valid) { default_expr = null; ec.Compiler.Report.Error(1763, Location, "Optional parameter `{0}' of type `{1}' can only be initialized with `null'", Name, GetSignatureForError()); } } } else { Constant c = value.ConvertImplicitly(parameter_type); if (c == null) { if (parameter_type == TypeManager.object_type) { rc.Compiler.Report.Error(1763, Location, "Optional parameter `{0}' of type `{1}' can only be initialized with `null'", Name, GetSignatureForError()); } else { rc.Compiler.Report.Error(1750, Location, "Optional parameter value `{0}' cannot be converted to parameter type `{1}'", value.GetValue(), GetSignatureForError()); } default_expr = null; } } } } if ((modFlags & Parameter.Modifier.ISBYREF) != 0 && TypeManager.IsSpecialType(parameter_type)) { rc.Compiler.Report.Error(1601, Location, "Method or delegate parameter cannot be of type `{0}'", GetSignatureForError()); return(null); } TypeManager.CheckTypeVariance(parameter_type, (modFlags & Parameter.Modifier.ISBYREF) != 0 ? Variance.None : Variance.Contravariant, rc); if (TypeManager.IsGenericParameter(parameter_type)) { return(parameter_type); } if ((parameter_type.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) { rc.Compiler.Report.Error(721, Location, "`{0}': static types cannot be used as parameters", texpr.GetSignatureForError()); return(parameter_type); } if ((modFlags & Modifier.This) != 0 && (parameter_type.IsPointer || TypeManager.IsDynamicType(parameter_type))) { rc.Compiler.Report.Error(1103, Location, "The extension method cannot be of type `{0}'", TypeManager.CSharpName(parameter_type)); } return(parameter_type); }