namespace Mono.CSharp {
/// <summary>
- /// Base class for parameters of a method. Can also be
- /// used to directly represent the return type of a method
+ /// Abstract Base class for parameters of a method.
/// </summary>
- public class ParameterBase : Attributable {
+ public abstract class ParameterBase : Attributable {
+
+ protected ParameterBuilder builder;
+
public ParameterBase (Attributes attrs)
: base (attrs)
{
}
- public override void ApplyAttributeBuilder (object builder, Attribute a, CustomAttributeBuilder cb)
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
{
- ParameterBuilder pb = builder as ParameterBuilder;
-
if (a.Type == TypeManager.marshal_as_attr_type) {
UnmanagedMarshal marshal = a.GetMarshal ();
- if (marshal == null)
- Report.Warning (-24, a.Location,
- "The Microsoft Runtime cannot set this marshal info. " +
- "Please use the Mono runtime instead.");
- else
- pb.SetMarshal (marshal);
- }
- else {
- try {
- pb.SetCustomAttribute (cb);
- } catch (System.ArgumentException) {
- Report.Warning (-24, a.Location,
- "The Microsoft Runtime cannot set attributes \n" +
- "on the return type of a method. Please use the \n" +
- "Mono runtime instead.");
+ if (marshal != null) {
+ builder.SetMarshal (marshal);
+ return;
+ }
+ Report.Warning_T (-24, a.Location);
+ return;
+ }
+
+ builder.SetCustomAttribute (cb);
+ }
+
+ public override bool IsClsCompliaceRequired(DeclSpace ds)
+ {
+ return false;
}
+ }
+
+ /// <summary>
+ /// Class for applying custom attributes on the return type
+ /// </summary>
+ public class ReturnParameter: ParameterBase {
+ public ReturnParameter (MethodBuilder mb, Location location):
+ base (null)
+ {
+ try {
+ builder = mb.DefineParameter (0, ParameterAttributes.None, "");
+ }
+ catch (ArgumentOutOfRangeException) {
+ Report.Warning_T (-28, location);
+ }
+ }
+
+ public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
+ {
+ // This occurs after Warning -28
+ if (builder == null)
+ return;
+
+ base.ApplyAttributeBuilder (a, cb);
+ }
+
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.ReturnValue;
+ }
+ }
+
+ /// <summary>
+ /// Is never called
+ /// </summary>
+ protected override string[] ValidAttributeTargets {
+ get {
+ return null;
+ }
+ }
+ }
+
+ /// <summary>
+ /// 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)
+ {
+ builder = mb.DefineParameter (1, ParameterAttributes.None, "");
+ }
+
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Parameter;
}
}
+
+ /// <summary>
+ /// Is never called
+ /// </summary>
+ protected override string[] ValidAttributeTargets {
+ get {
+ return null;
+ }
}
+ }
+
/// <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 {
ISBYREF = 8
}
+ static string[] attribute_targets = new string [] { "param" };
+
public readonly Expression TypeName;
public readonly Modifier ModFlags;
public readonly string Name;
}
}
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Parameter;
+ }
+ }
+
/// <summary>
/// Returns the signature for this parameter evaluating it on the
/// @tc context
}
return typeName;
}
+
+ public void DefineParameter (EmitContext ec, MethodBuilder mb, ConstructorBuilder cb, int index, Location loc)
+ {
+ ParameterAttributes par_attr = Attributes;
+
+ if (mb == null)
+ builder = cb.DefineParameter (index, par_attr, Name);
+ else
+ builder = mb.DefineParameter (index, par_attr, Name);
+
+ if (OptAttributes != null) {
+ OptAttributes.Emit (ec, this);
+
+ if (par_attr == ParameterAttributes.Out){
+ if (OptAttributes.Contains (TypeManager.in_attribute_type, ec))
+ Report.Error (36, loc, "Can not use [In] attribute on out parameter");
+ }
+ }
+ }
+
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
}
/// <summary>
// For now this is the only correc thing to do
return CallingConventions.Standard;
}
+
+ //
+ // 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) {
+ //
+ // Define each type attribute (in/out/ref) and
+ // the argument names.
+ //
+ int i = 0;
+
+ MethodBuilder mb = builder as MethodBuilder;
+ ConstructorBuilder cb = builder as ConstructorBuilder;
+
+ if (FixedParameters != null) {
+ for (i = 0; i < FixedParameters.Length; i++) {
+ FixedParameters [i].DefineParameter (ec, mb, cb, i + 1, loc);
+ }
+ }
+
+ if (ArrayParameter != null){
+ ParameterBuilder pb;
+ Parameter array_param = ArrayParameter;
+
+ if (mb == null)
+ pb = cb.DefineParameter (
+ i + 1, array_param.Attributes,
+ array_param.Name);
+ else
+ pb = mb.DefineParameter (
+ i + 1, array_param.Attributes,
+ array_param.Name);
+
+ CustomAttributeBuilder a = new CustomAttributeBuilder (
+ TypeManager.cons_param_array_attribute, new object [0]);
+
+ pb.SetCustomAttribute (a);
+ }
+ }
}
}
-
-
-