using System.Reflection;
using System.Reflection.Emit;
using System.Collections;
+using System.Text;
namespace Mono.CSharp {
public abstract class ParameterBase : Attributable {
protected ParameterBuilder builder;
+ public readonly Location Location;
- public ParameterBase (Attributes attrs)
+ public ParameterBase (Attributes attrs, Location loc)
: base (attrs)
{
+ Location = loc;
}
public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
builder.SetCustomAttribute (cb);
}
- public override bool IsClsCompliaceRequired(DeclSpace ds)
+ public override bool IsClsComplianceRequired(DeclSpace ds)
{
return false;
- }
+ }
}
/// <summary>
/// </summary>
public class ReturnParameter: ParameterBase {
public ReturnParameter (MethodBuilder mb, Location location):
- base (null)
+ base (null, location)
{
try {
builder = mb.DefineParameter (0, ParameterAttributes.None, "");
}
catch (ArgumentOutOfRangeException) {
- Report.Warning (-28, location, "The Microsoft .NET Runtime 1.x does not permit setting custom attributes on the return type");
+ Report.Warning (-24, location, "The Microsoft .NET Runtime 1.x does not permit setting custom attributes on the return type");
}
}
/// Class for applying custom attributes on the implicit parameter type
/// of the 'set' method in properties, and the 'add' and 'remove' methods in events.
/// </summary>
- public class ImplicitParameter: ParameterBase {
- public ImplicitParameter (MethodBuilder mb):
- base (null)
+ public class ImplicitParameter: ParameterBase {
+ public ImplicitParameter (MethodBuilder mb, Location loc):
+ base (null, loc)
{
builder = mb.DefineParameter (1, ParameterAttributes.None, "");
}
/// <summary>
/// Represents a single method parameter
/// </summary>
-
- //TODO: Add location member to this or base class for better error location and all methods simplification.
public class Parameter : ParameterBase {
[Flags]
public enum Modifier : byte {
EmitContext ec; // because ApplyAtrribute doesn't have ec
- public Parameter (Expression type, string name, Modifier mod, Attributes attrs)
- : base (attrs)
+ public Parameter (Expression type, string name, Modifier mod, Attributes attrs, Location loc)
+ : base (attrs, loc)
{
Name = name;
ModFlags = mod;
public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
{
if (a.Type == TypeManager.in_attribute_type && Attributes == ParameterAttributes.Out) {
- Report.Error (36, a.Location, "Can not use [In] attribute on out parameter");
+ Report.Error (36, a.Location, "An out parameter cannot have the `In' attribute");
return;
}
if (a.Type == TypeManager.param_array_type) {
- Report.Error (674, a.Location, "Do not use 'System.ParamArrayAttribute'. Use the 'params' keyword instead");
+ Report.Error (674, a.Location, "Do not use `System.ParamArrayAttribute'. Use the `params' keyword instead");
return;
}
if (a.Type == TypeManager.out_attribute_type && (ModFlags & Modifier.REF) != 0 &&
!OptAttributes.Contains (TypeManager.in_attribute_type, ec)) {
Report.Error (662, a.Location,
- "'{0}' cannot specify only Out attribute on a ref parameter. Use both In and Out attributes, or neither", GetSignatureForError ());
+ "Cannot specify only `Out' attribute on a ref parameter. Use both `In' and `Out' attributes or neither");
return;
}
// <summary>
// Resolve is used in method definitions
// </summary>
- public bool Resolve (EmitContext ec, Location l)
+ public bool Resolve (EmitContext ec)
{
TypeExpr texpr = TypeName.ResolveAsTypeTerminal (ec);
this.ec = ec;
parameter_type = texpr.Type;
if (parameter_type.IsAbstract && parameter_type.IsSealed) {
- Report.Error (721, l, "'{0}': static types cannot be used as parameters", GetSignatureForError ());
+ Report.Error (721, Location, "`{0}': static types cannot be used as parameters", GetSignatureForError ());
return false;
}
if (parameter_type == TypeManager.void_type){
- Report.Error (1536, l, "Invalid parameter type 'void'");
+ Report.Error (1536, Location, "Invalid parameter type 'void'");
return false;
}
if ((ModFlags & Parameter.Modifier.ISBYREF) != 0){
if (parameter_type == TypeManager.typed_reference_type ||
parameter_type == TypeManager.arg_iterator_type){
- Report.Error (1601, l,
- "out or ref parameter can not be of type TypedReference or ArgIterator");
+ Report.Error (1601, Location, "Method or delegate parameter cannot be of type `{0}'",
+ GetSignatureForError ());
return false;
}
}
/// Returns the signature for this parameter evaluating it on the
/// @tc context
/// </summary>
- public string GetSignature (EmitContext ec, Location loc)
+ public string GetSignature (EmitContext ec)
{
if (parameter_type == null){
- if (!Resolve (ec, loc))
+ if (!Resolve (ec))
return null;
}
public string GetSignatureForError ()
{
- string typeName;
+ string type_name;
if (parameter_type != null)
- typeName = TypeManager.CSharpName (parameter_type);
+ type_name = TypeManager.CSharpName (parameter_type);
else if (TypeName.Type != null)
- typeName = TypeManager.CSharpName (TypeName.Type);
+ type_name = TypeManager.CSharpName (TypeName.Type);
else
- typeName = TypeName.ToString ();
+ type_name = TypeName.ToString ();
- switch (ModFlags & unchecked (~Modifier.ISBYREF)) {
+ string mod = GetModifierSignature (ModFlags);
+ if (mod.Length > 0)
+ return String.Concat (mod, " ", type_name);
+
+ return type_name;
+ }
+
+ public static string GetModifierSignature (Modifier mod)
+ {
+ switch (mod & unchecked (~Modifier.ISBYREF)) {
case Modifier.OUT:
- return "out " + typeName;
+ return "out";
case Modifier.PARAMS:
- return "params " + typeName;
+ return "params";
case Modifier.REF:
- return "ref " + typeName;
+ return "ref";
+ case Modifier.ARGLIST:
+ return "__arglist";
+ default:
+ return "";
}
- return typeName;
}
- public void DefineParameter (EmitContext ec, MethodBuilder mb, ConstructorBuilder cb, int index, Location loc)
+ public void DefineParameter (EmitContext ec, MethodBuilder mb, ConstructorBuilder cb, int index)
{
ParameterAttributes par_attr = Attributes;
public readonly bool HasArglist;
string signature;
Type [] types;
- Location loc;
static Parameters empty_parameters;
- public Parameters (Parameter [] fixed_parameters, Parameter array_parameter, Location l)
+ public Parameters (Parameter [] fixed_parameters, Parameter array_parameter)
{
FixedParameters = fixed_parameters;
ArrayParameter = array_parameter;
- loc = l;
}
- public Parameters (Parameter [] fixed_parameters, bool has_arglist, Location l)
+ public Parameters (Parameter [] fixed_parameters, bool has_arglist)
{
FixedParameters = fixed_parameters;
HasArglist = has_arglist;
- loc = l;
}
/// <summary>
public static Parameters EmptyReadOnlyParameters {
get {
if (empty_parameters == null)
- empty_parameters = new Parameters (null, null, Location.Null);
+ empty_parameters = new Parameters (null, null);
return empty_parameters;
}
return (FixedParameters == null) && (ArrayParameter == null);
}
}
-
+
public void ComputeSignature (EmitContext ec)
{
signature = "";
for (int i = 0; i < FixedParameters.Length; i++){
Parameter par = FixedParameters [i];
- signature += par.GetSignature (ec, loc);
+ signature += par.GetSignature (ec);
}
}
//
//
}
- void Error_DuplicateParameterName (string name)
+ void Error_DuplicateParameterName (string name, Location loc)
{
Report.Error (
100, loc, "The parameter name `" + name + "' is a duplicate");
for (j = i + 1; j < count; j++){
if (base_name != FixedParameters [j].Name)
continue;
- Error_DuplicateParameterName (base_name);
+ Error_DuplicateParameterName (base_name,
+ FixedParameters [i].Location);
return false;
}
if (base_name == array_par_name){
- Error_DuplicateParameterName (base_name);
+ Error_DuplicateParameterName (base_name,
+ FixedParameters [i].Location);
return false;
}
}
foreach (Parameter p in FixedParameters){
Type t = null;
- if (p.Resolve (ec, loc))
+ if (p.Resolve (ec))
t = p.ExternalType ();
else
failed = true;
}
if (extra > 0){
- if (ArrayParameter.Resolve (ec, loc))
+ if (ArrayParameter.Resolve (ec))
types [i] = ArrayParameter.ExternalType ();
else
failed = true;
// The method's attributes are passed in because we need to extract
// the "return:" attribute from there to apply on the return type
//
- public void LabelParameters (EmitContext ec,
- MethodBase builder,
- Location loc) {
+ public void LabelParameters (EmitContext ec, MethodBase builder)
+ {
//
// Define each type attribute (in/out/ref) and
// the argument names.
if (FixedParameters != null) {
for (i = 0; i < FixedParameters.Length; i++) {
- FixedParameters [i].DefineParameter (ec, mb, cb, i + 1, loc);
+ FixedParameters [i].DefineParameter (ec, mb, cb, i + 1);
}
}
pb.SetCustomAttribute (a);
}
}
+
+ public string GetSignatureForError ()
+ {
+ StringBuilder sb = new StringBuilder ("(");
+ if (FixedParameters != null) {
+ for (int i = 0; i < FixedParameters.Length; ++i) {
+ sb.Append (FixedParameters[i].GetSignatureForError ());
+ if (i < FixedParameters.Length - 1)
+ sb.Append (", ");
+ }
+ }
+ sb.Append (')');
+ return sb.ToString ();
+
+ }
}
}