// parameter.cs: Parameter definition.
//
// Author: Miguel de Icaza (miguel@gnu.org)
+// Marek Safar (marek.safar@seznam.cz)
//
// Licensed under the terms of the GNU GPL
//
public abstract class ParameterBase : Attributable {
protected ParameterBuilder builder;
- public readonly Location Location;
- public ParameterBase (Attributes attrs, Location loc)
+ protected ParameterBase (Attributes attrs)
: 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()
{
return false;
}
/// </summary>
public class ReturnParameter : ParameterBase {
public ReturnParameter (MethodBuilder mb, Location location):
- base (null, location)
+ base (null)
{
try {
builder = mb.DefineParameter (0, ParameterAttributes.None, "");
}
catch (ArgumentOutOfRangeException) {
- Report.Warning (-24, location, "The Microsoft .NET Runtime 1.x does not permit setting custom attributes on the return type");
+ Report.RuntimeMissingSupport (location, "custom attributes on the return type");
}
}
}
}
+ public override IResolveContext ResolveContext {
+ get {
+ throw new NotSupportedException ();
+ }
+ }
+
/// <summary>
/// Is never called
/// </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>
+ ///
+ // TODO: should use more code from Parameter.ApplyAttributeBuilder
public class ImplicitParameter : ParameterBase {
- public ImplicitParameter (MethodBuilder mb, Location loc):
- base (null, loc)
+ public ImplicitParameter (MethodBuilder mb):
+ base (null)
{
builder = mb.DefineParameter (1, ParameterAttributes.None, "");
}
}
}
+ public override IResolveContext ResolveContext {
+ get {
+ throw new NotSupportedException ();
+ }
+ }
+
/// <summary>
/// Is never called
/// </summary>
}
}
+ public class ImplicitLambdaParameter : Parameter
+ {
+ public ImplicitLambdaParameter (string name, Location loc)
+ : base ((Type)null, name, Modifier.NONE, null, loc)
+ {
+ }
+
+ public override bool Resolve (IResolveContext ec)
+ {
+ if (parameter_type == null)
+ throw new InternalErrorException ("Implicit lambda parameter type is not set");
+
+ return true;
+ }
+ }
+
+ public class ParamsParameter : Parameter {
+ public ParamsParameter (Expression type, string name, Attributes attrs, Location loc):
+ base (type, name, Parameter.Modifier.PARAMS, attrs, loc)
+ {
+ }
+
+ public override bool Resolve (IResolveContext ec)
+ {
+ if (!base.Resolve (ec))
+ return false;
+
+ if (!parameter_type.IsArray || parameter_type.GetArrayRank () != 1) {
+ Report.Error (225, Location, "The params parameter must be a single dimensional array");
+ return false;
+ }
+ return true;
+ }
+
+ public override void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index)
+ {
+ base.ApplyAttributes (mb, cb, index);
+
+ CustomAttributeBuilder a = new CustomAttributeBuilder (
+ TypeManager.cons_param_array_attribute, new object[0]);
+
+ builder.SetCustomAttribute (a);
+ }
+ }
+
+ public class ArglistParameter : Parameter {
+ // Doesn't have proper type because it's never chosen for better conversion
+ public ArglistParameter () :
+ base (typeof (ArglistParameter), String.Empty, Parameter.Modifier.ARGLIST, null, Location.Null)
+ {
+ }
+
+ public override bool CheckAccessibility (InterfaceMemberBase member)
+ {
+ return true;
+ }
+
+ public override bool Resolve (IResolveContext ec)
+ {
+ return true;
+ }
+
+ public override string GetSignatureForError ()
+ {
+ return "__arglist";
+ }
+ }
+
/// <summary>
/// Represents a single method parameter
/// </summary>
[Flags]
public enum Modifier : byte {
NONE = 0,
- REF = 1,
- OUT = 2,
+ REF = REFMASK | ISBYREF,
+ OUT = OUTMASK | ISBYREF,
PARAMS = 4,
// This is a flag which says that it's either REF or OUT.
ISBYREF = 8,
- ARGLIST = 16
+ ARGLIST = 16,
+ REFMASK = 32,
+ OUTMASK = 64,
+ This = 128
}
static string[] attribute_targets = new string [] { "param" };
- public Expression TypeName;
- public readonly Modifier ModFlags;
- public readonly string Name;
- Type parameter_type;
+ Expression TypeName;
+ public Modifier modFlags;
+ public string Name;
+ public bool IsCaptured;
+ protected Type parameter_type;
+ public readonly Location Location;
- EmitContext ec; // because ApplyAtrribute doesn't have ec
+ IResolveContext resolve_context;
+
+ Variable var;
+ public Variable Variable {
+ get { return var; }
+ }
+
+#if GMCS_SOURCE
+ public bool IsTypeParameter;
+ GenericConstraints constraints;
+#else
+ public bool IsTypeParameter {
+ get {
+ return false;
+ }
+ set {
+ if (value)
+ throw new Exception ("You can not se TypeParameter in MCS");
+ }
+ }
+#endif
public Parameter (Expression type, string name, Modifier mod, Attributes attrs, Location loc)
- : base (attrs, loc)
+ : this (type.Type, name, mod, attrs, loc)
{
- Name = name;
- ModFlags = mod;
+ if (type == TypeManager.system_void_expr)
+ Report.Error (1536, loc, "Invalid parameter type `void'");
+
TypeName = type;
}
+ public Parameter (Type type, string name, Modifier mod, Attributes attrs, Location loc)
+ : base (attrs)
+ {
+ Name = name;
+ modFlags = mod;
+ parameter_type = type;
+ Location = loc;
+ }
+
public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
{
- if (a.Type == TypeManager.in_attribute_type && Attributes == ParameterAttributes.Out) {
+ if (a.Type == TypeManager.in_attribute_type && ModFlags == Modifier.OUT) {
Report.Error (36, a.Location, "An out parameter cannot have the `In' attribute");
return;
}
return;
}
- if (a.Type == TypeManager.out_attribute_type && (ModFlags & Modifier.REF) != 0 &&
- !OptAttributes.Contains (TypeManager.in_attribute_type, ec)) {
+ if (a.Type == TypeManager.out_attribute_type && (ModFlags & Modifier.REF) == Modifier.REF &&
+ !OptAttributes.Contains (TypeManager.in_attribute_type)) {
Report.Error (662, a.Location,
"Cannot specify only `Out' attribute on a ref parameter. Use both `In' and `Out' attributes or neither");
return;
Report.Warning (3022, 1, a.Location, "CLSCompliant attribute has no meaning when applied to parameters. Try putting it on the method instead");
}
+ // TypeManager.default_parameter_value_attribute_type is null if !NET_2_0, or if System.dll is not referenced
+ if (a.Type == TypeManager.default_parameter_value_attribute_type) {
+ object val = a.GetParameterDefaultValue ();
+ if (val != null) {
+ Type t = val.GetType ();
+ if (t.IsArray || TypeManager.IsSubclassOf (t, TypeManager.type_type)) {
+ if (parameter_type == TypeManager.object_type) {
+ if (!t.IsArray)
+ t = TypeManager.type_type;
+
+ Report.Error (1910, a.Location, "Argument of type `{0}' is not applicable for the DefaultValue attribute",
+ TypeManager.CSharpName (t));
+ } else {
+ Report.Error (1909, a.Location, "The DefaultValue attribute is not applicable on parameters of type `{0}'",
+ TypeManager.CSharpName (parameter_type)); ;
+ }
+ return;
+ }
+ }
+
+ if (parameter_type == TypeManager.object_type ||
+ (val == null && !TypeManager.IsValueType (parameter_type)) ||
+ (val != null && TypeManager.TypeToCoreType (val.GetType ()) == parameter_type))
+ builder.SetConstant (val);
+ else
+ Report.Error (1908, a.Location, "The type of the default value should match the type of the parameter");
+ return;
+ }
+
base.ApplyAttributeBuilder (a, cb);
}
+
+ public virtual bool CheckAccessibility (InterfaceMemberBase member)
+ {
+ if (IsTypeParameter)
+ return true;
+
+ return member.ds.AsAccessible (parameter_type, member.ModFlags);
+ }
+
+ public override IResolveContext ResolveContext {
+ get {
+ return resolve_context;
+ }
+ }
// <summary>
// Resolve is used in method definitions
// </summary>
- public bool Resolve (EmitContext ec)
+ public virtual bool Resolve (IResolveContext ec)
{
- this.ec = ec;
+ // HACK: to resolve attributes correctly
+ this.resolve_context = ec;
+
+ if (parameter_type != null)
+ return true;
TypeExpr texpr = TypeName.ResolveAsTypeTerminal (ec, false);
if (texpr == null)
return false;
- parameter_type = texpr.ResolveType (ec);
-
- if (parameter_type.IsAbstract && parameter_type.IsSealed) {
- Report.Error (721, Location, "`{0}': static types cannot be used as parameters", GetSignatureForError ());
- return false;
+ parameter_type = texpr.Type;
+
+#if GMCS_SOURCE
+ TypeParameterExpr tparam = texpr as TypeParameterExpr;
+ if (tparam != null) {
+ IsTypeParameter = true;
+ constraints = tparam.TypeParameter.Constraints;
+ return true;
}
+#endif
- if (parameter_type == TypeManager.void_type){
- Report.Error (1536, Location, "Invalid parameter type 'void'");
+ if ((parameter_type.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
+ Report.Error (721, Location, "`{0}': static types cannot be used as parameters",
+ texpr.GetSignatureForError ());
return false;
}
- if ((ModFlags & Parameter.Modifier.ISBYREF) != 0){
+ if ((modFlags & Parameter.Modifier.ISBYREF) != 0){
if (parameter_type == TypeManager.typed_reference_type ||
parameter_type == TypeManager.arg_iterator_type){
Report.Error (1601, Location, "Method or delegate parameter cannot be of type `{0}'",
return false;
}
}
+
+ 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 false;
+ }
- return parameter_type != null;
+ return true;
+ }
+
+ public void ResolveVariable (ToplevelBlock toplevel, int idx)
+ {
+ if (toplevel.RootScope != null)
+ var = toplevel.RootScope.GetCapturedParameter (this);
+ if (var == null)
+ var = new ParameterVariable (this, idx);
}
public Type ExternalType ()
{
- if ((ModFlags & Parameter.Modifier.ISBYREF) != 0)
+ if ((modFlags & Parameter.Modifier.ISBYREF) != 0)
return TypeManager.GetReferenceType (parameter_type);
return parameter_type;
}
+ public bool HasExtensionMethodModifier {
+ get { return (modFlags & Modifier.This) != 0; }
+ }
+
+ public Modifier ModFlags {
+ get { return modFlags & ~Modifier.This; }
+ }
+
public Type ParameterType {
get {
return parameter_type;
}
+ set {
+ parameter_type = value;
+ IsTypeParameter = false;
+ }
}
-
- public ParameterAttributes Attributes {
+
+#if GMCS_SOURCE
+ public GenericConstraints GenericConstraints {
get {
- int flags = ((int) ModFlags) & ~((int) Parameter.Modifier.ISBYREF);
- switch ((Modifier) flags) {
- case Modifier.NONE:
- return ParameterAttributes.None;
- case Modifier.REF:
- return ParameterAttributes.None;
- case Modifier.OUT:
- return ParameterAttributes.Out;
- case Modifier.PARAMS:
- return 0;
- }
-
+ return constraints;
+ }
+ }
+#endif
+
+ ParameterAttributes Attributes {
+ get {
+ return (modFlags & Modifier.OUT) == Modifier.OUT ?
+ ParameterAttributes.Out : ParameterAttributes.None;
+ }
+ }
+
+ // TODO: should be removed !!!!!!!
+ public static ParameterAttributes GetParameterAttributes (Modifier mod)
+ {
+ int flags = ((int) mod) & ~((int) Parameter.Modifier.ISBYREF);
+ switch ((Modifier) flags) {
+ case Modifier.NONE:
return ParameterAttributes.None;
+ case Modifier.REF:
+ return ParameterAttributes.None;
+ case Modifier.OUT:
+ return ParameterAttributes.Out;
+ case Modifier.PARAMS:
+ return 0;
}
+
+ return ParameterAttributes.None;
}
public override AttributeTargets AttributeTargets {
}
}
- /// <summary>
- /// Returns the signature for this parameter evaluating it on the
- /// @tc context
- /// </summary>
- public string GetSignature (EmitContext ec)
- {
- if (parameter_type == null){
- if (!Resolve (ec))
- return null;
- }
-
- return ExternalType ().FullName;
- }
-
- public string GetSignatureForError ()
+ public virtual string GetSignatureForError ()
{
string type_name;
if (parameter_type != null)
type_name = TypeManager.CSharpName (parameter_type);
- else if (TypeName.Type != null)
- type_name = TypeManager.CSharpName (TypeName.Type);
else
- type_name = TypeName.ToString ();
+ type_name = TypeName.GetSignatureForError ();
- string mod = GetModifierSignature (ModFlags);
+ string mod = GetModifierSignature (modFlags);
if (mod.Length > 0)
- return String.Concat (mod, " ", type_name);
+ return String.Concat (mod, ' ', type_name);
return type_name;
}
public static string GetModifierSignature (Modifier mod)
{
- switch (mod & unchecked (~Modifier.ISBYREF)) {
+ switch (mod) {
case Modifier.OUT:
return "out";
case Modifier.PARAMS:
return "ref";
case Modifier.ARGLIST:
return "__arglist";
+ case Modifier.This:
+ return "this";
default:
return "";
}
}
- public void DefineParameter (EmitContext ec, MethodBuilder mb, ConstructorBuilder cb, int index)
+ public void IsClsCompliant ()
+ {
+ if (AttributeTester.IsClsCompliant (ExternalType ()))
+ return;
+
+ Report.Error (3001, Location, "Argument type `{0}' is not CLS-compliant", GetSignatureForError ());
+ }
+
+ public virtual void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index)
{
- ParameterAttributes par_attr = Attributes;
-
+#if !GMCS_SOURCE || !MS_COMPATIBLE
+ // TODO: It should use mb.DefineGenericParameters
if (mb == null)
- builder = cb.DefineParameter (index, par_attr, Name);
+ builder = cb.DefineParameter (index, Attributes, Name);
else
- builder = mb.DefineParameter (index, par_attr, Name);
-
- if (OptAttributes != null) {
- OptAttributes.Emit (ec, this);
- }
+ builder = mb.DefineParameter (index, Attributes, Name);
+#endif
+
+ if (OptAttributes != null)
+ OptAttributes.Emit ();
}
public override string[] ValidAttributeTargets {
return attribute_targets;
}
}
+
+ protected class ParameterVariable : Variable
+ {
+ public readonly Parameter Parameter;
+ public readonly int Idx;
+ public readonly bool IsRef;
+
+ public ParameterVariable (Parameter par, int idx)
+ {
+ this.Parameter = par;
+ this.Idx = idx;
+ this.IsRef = (par.ModFlags & Parameter.Modifier.ISBYREF) != 0;
+ }
+
+ public override Type Type {
+ get { return Parameter.ParameterType; }
+ }
+
+ public override bool HasInstance {
+ get { return false; }
+ }
+
+ public override bool NeedsTemporary {
+ get { return false; }
+ }
+
+ public override void EmitInstance (EmitContext ec)
+ {
+ }
+
+ public override void Emit (EmitContext ec)
+ {
+ int arg_idx = Idx;
+ if (!ec.MethodIsStatic)
+ arg_idx++;
+
+ ParameterReference.EmitLdArg (ec.ig, arg_idx);
+ }
+
+ public override void EmitAssign (EmitContext ec)
+ {
+ int arg_idx = Idx;
+ if (!ec.MethodIsStatic)
+ arg_idx++;
+
+ if (arg_idx <= 255)
+ ec.ig.Emit (OpCodes.Starg_S, (byte) arg_idx);
+ else
+ ec.ig.Emit (OpCodes.Starg, arg_idx);
+ }
+
+ public override void EmitAddressOf (EmitContext ec)
+ {
+ int arg_idx = Idx;
+
+ if (!ec.MethodIsStatic)
+ arg_idx++;
+
+ if (IsRef) {
+ if (arg_idx <= 255)
+ ec.ig.Emit (OpCodes.Ldarg_S, (byte) arg_idx);
+ else
+ ec.ig.Emit (OpCodes.Ldarg, arg_idx);
+ } else {
+ if (arg_idx <= 255)
+ ec.ig.Emit (OpCodes.Ldarga_S, (byte) arg_idx);
+ else
+ ec.ig.Emit (OpCodes.Ldarga, arg_idx);
+ }
+ }
+ }
+
+ public Parameter Clone ()
+ {
+ Parameter p = new Parameter (parameter_type, Name, ModFlags, attributes, Location);
+ p.IsTypeParameter = IsTypeParameter;
+
+ return p;
+ }
}
/// <summary>
/// Represents the methods parameters
/// </summary>
- public class Parameters {
+ public class Parameters : ParameterData {
+ // Null object pattern
public Parameter [] FixedParameters;
- public readonly Parameter ArrayParameter;
public readonly bool HasArglist;
- string signature;
Type [] types;
+ int count;
+
+ public static readonly Parameters EmptyReadOnlyParameters = new Parameters ();
+ static readonly Parameter ArgList = new ArglistParameter ();
+
+#if GMCS_SOURCE
+// public readonly TypeParameter[] TypeParameters;
+#endif
+
+ private Parameters ()
+ {
+ FixedParameters = new Parameter[0];
+ types = new Type [0];
+ }
+
+ private Parameters (Parameter[] parameters, Type[] types)
+ {
+ FixedParameters = parameters;
+ this.types = types;
+ count = types.Length;
+ }
- static Parameters empty_parameters;
-
- public Parameters (Parameter [] fixed_parameters, Parameter array_parameter)
+ public Parameters (params Parameter[] parameters)
{
- FixedParameters = fixed_parameters;
- ArrayParameter = array_parameter;
+ if (parameters == null)
+ throw new ArgumentException ("Use EmptyReadOnlyPatameters");
+
+ FixedParameters = parameters;
+ count = parameters.Length;
}
- public Parameters (Parameter [] fixed_parameters, bool has_arglist)
+ public Parameters (Parameter[] parameters, bool has_arglist):
+ this (parameters)
{
- FixedParameters = fixed_parameters;
HasArglist = has_arglist;
}
+
+ public static Parameters CreateFullyResolved (Parameter p)
+ {
+ return new Parameters (new Parameter [] { p }, new Type [] { p.ParameterType });
+ }
+
+ public static Parameters CreateFullyResolved (Parameter[] parameters, Type[] types)
+ {
+ return new Parameters (parameters, types);
+ }
/// <summary>
- /// This is used to reuse a set of empty parameters, because they
- /// are common
+ /// Use this method when you merge compiler generated argument with user arguments
/// </summary>
- public static Parameters EmptyReadOnlyParameters {
- get {
- if (empty_parameters == null)
- empty_parameters = new Parameters (null, null);
-
- return empty_parameters;
+ public static Parameters MergeGenerated (Parameters userParams, params Parameter[] compilerParams)
+ {
+ Parameter[] all_params = new Parameter [userParams.count + compilerParams.Length];
+ Type[] all_types = new Type[all_params.Length];
+ userParams.FixedParameters.CopyTo(all_params, 0);
+ userParams.Types.CopyTo (all_types, 0);
+
+ int last_filled = userParams.Count;
+ foreach (Parameter p in compilerParams) {
+ for (int i = 0; i < last_filled; ++i) {
+ while (p.Name == all_params [i].Name) {
+ p.Name = '_' + p.Name;
+ }
+ }
+ all_params [last_filled] = p;
+ all_types [last_filled] = p.ParameterType;
+ ++last_filled;
}
+
+ return new Parameters (all_params, all_types);
}
-
+
public bool Empty {
get {
- return (FixedParameters == null) && (ArrayParameter == null);
+ return count == 0;
}
}
- public void ComputeSignature (EmitContext ec)
- {
- signature = "";
- if (FixedParameters != null){
- for (int i = 0; i < FixedParameters.Length; i++){
- Parameter par = FixedParameters [i];
-
- signature += par.GetSignature (ec);
- }
+ public int Count {
+ get {
+ return HasArglist ? count + 1 : count;
}
- //
- // Note: as per the spec, the `params' arguments (ArrayParameter)
- // are not used in the signature computation for a method
- //
}
- void Error_DuplicateParameterName (string name, Location loc)
- {
- Report.Error (
- 100, loc, "The parameter name `" + name + "' is a duplicate");
+ //
+ // The property can be used after parameter types were resolved.
+ //
+ public Type ExtensionMethodType {
+ get {
+ if (count == 0)
+ return null;
+
+ return FixedParameters [0].HasExtensionMethodModifier ?
+ types [0] : null;
+ }
}
-
- public bool VerifyArgs ()
- {
- int count;
- int i, j;
- if (FixedParameters == null)
+ public bool HasExtensionMethodType {
+ get {
+ if (count == 0)
+ return false;
+
+ return FixedParameters [0].HasExtensionMethodModifier;
+ }
+ }
+
+
+ bool VerifyArgs ()
+ {
+ if (count < 2)
return true;
-
- count = FixedParameters.Length;
- string array_par_name = ArrayParameter != null ? ArrayParameter.Name : null;
- for (i = 0; i < count; i++){
+ for (int i = 0; i < count; i++){
string base_name = FixedParameters [i].Name;
- for (j = i + 1; j < count; j++){
+ for (int j = i + 1; j < count; j++){
if (base_name != FixedParameters [j].Name)
continue;
- Error_DuplicateParameterName (base_name,
- FixedParameters [i].Location);
- return false;
- }
- if (base_name == array_par_name){
- Error_DuplicateParameterName (base_name,
- FixedParameters [i].Location);
+ Report.Error (100, FixedParameters [i].Location,
+ "The parameter name `{0}' is a duplicate", base_name);
return false;
}
}
return true;
}
- /// <summary>
- /// Returns the signature of the Parameters evaluated in
- /// the @ec EmitContext
- /// </summary>
- public string GetSignature (EmitContext ec)
- {
- if (signature == null){
- VerifyArgs ();
- ComputeSignature (ec);
- }
-
- return signature;
- }
/// <summary>
/// Returns the paramenter information based on the name
public Parameter GetParameterByName (string name, out int idx)
{
idx = 0;
- int i = 0;
- if (FixedParameters != null){
- foreach (Parameter par in FixedParameters){
- if (par.Name == name){
- idx = i;
- return par;
- }
- i++;
- }
- }
+ if (count == 0)
+ return null;
+
+ int i = 0;
- if (ArrayParameter != null){
- if (name == ArrayParameter.Name){
+ foreach (Parameter par in FixedParameters){
+ if (par.Name == name){
idx = i;
- return ArrayParameter;
+ return par;
}
+ i++;
}
-
return null;
}
return GetParameterByName (name, out idx);
}
- bool ComputeParameterTypes (EmitContext ec)
+ public bool Resolve (IResolveContext ec)
{
- int extra = (ArrayParameter != null) ? 1 : 0;
- int i = 0;
- int pc;
-
- if (FixedParameters == null)
- pc = extra;
- else
- pc = extra + FixedParameters.Length;
+ if (types != null)
+ return true;
- types = new Type [pc];
+ types = new Type [count];
- if (!VerifyArgs ()){
- FixedParameters = null;
+ if (!VerifyArgs ())
return false;
- }
-
- bool failed = false;
- if (FixedParameters != null){
- foreach (Parameter p in FixedParameters){
- Type t = null;
-
- if (p.Resolve (ec))
- t = p.ExternalType ();
- else
- failed = true;
- types [i] = t;
- i++;
+ bool ok = true;
+ Parameter p;
+ for (int i = 0; i < FixedParameters.Length; ++i) {
+ p = FixedParameters [i];
+ if (!p.Resolve (ec)) {
+ ok = false;
+ continue;
}
- }
-
- if (extra > 0){
- if (ArrayParameter.Resolve (ec))
- types [i] = ArrayParameter.ExternalType ();
- else
- failed = true;
+ types [i] = p.ExternalType ();
}
- if (failed){
- types = null;
- return false;
- }
-
- return true;
+ return ok;
}
-
- /// <summary>
- /// Returns the argument types as an array
- /// </summary>
- static Type [] no_types = new Type [0];
-
- public Type [] GetParameterInfo (EmitContext ec)
- {
- if (types != null)
- return types;
-
- if (FixedParameters == null && ArrayParameter == null)
- return no_types;
- if (ComputeParameterTypes (ec) == false){
- types = null;
- return null;
+ public void ResolveVariable (ToplevelBlock toplevel)
+ {
+ for (int i = 0; i < FixedParameters.Length; ++i) {
+ Parameter p = FixedParameters [i];
+ p.ResolveVariable (toplevel, i);
}
-
- return types;
}
- /// <summary>
- /// Returns the type of a given parameter, and stores in the `is_out'
- /// boolean whether this is an out or ref parameter.
- ///
- /// Note that the returned type will not contain any dereference in this
- /// case (ie, you get "int" for a ref int instead of "int&"
- /// </summary>
- public Type GetParameterInfo (EmitContext ec, int idx, out Parameter.Modifier mod)
+ public CallingConventions CallingConvention
{
- mod = Parameter.Modifier.NONE;
-
- if (!VerifyArgs ()){
- FixedParameters = null;
- return null;
+ get {
+ if (HasArglist)
+ return CallingConventions.VarArgs;
+ else
+ return CallingConventions.Standard;
}
+ }
- if (FixedParameters == null && ArrayParameter == null)
- return null;
-
- if (types == null)
- if (ComputeParameterTypes (ec) == false)
- return null;
-
- //
- // If this is a request for the variable lenght arg.
- //
- int array_idx = (FixedParameters != null ? FixedParameters.Length : 0);
- if (idx == array_idx)
- return types [idx];
-
- //
- // Otherwise, it is a fixed parameter
- //
- Parameter p = FixedParameters [idx];
- mod = p.ModFlags;
+ // Define each type attribute (in/out/ref) and
+ // the argument names.
+ public void ApplyAttributes (MethodBase builder)
+ {
+ if (count == 0)
+ return;
- if ((mod & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) != 0)
- mod |= Parameter.Modifier.ISBYREF;
+ MethodBuilder mb = builder as MethodBuilder;
+ ConstructorBuilder cb = builder as ConstructorBuilder;
- return p.ParameterType;
+ for (int i = 0; i < FixedParameters.Length; i++) {
+ FixedParameters [i].ApplyAttributes (mb, cb, i + 1);
+ }
}
- public CallingConventions GetCallingConvention ()
+#if MS_COMPATIBLE
+ public ParameterData InflateTypes (Type[] genArguments, Type[] argTypes)
{
- if (HasArglist)
- return CallingConventions.VarArgs;
- else
- return CallingConventions.Standard;
- }
+ Parameters p = Clone ();
+ for (int i = 0; i < count; ++i) {
+ if (types[i].IsGenericType) {
+ Type[] gen_arguments_open = new Type [types[i].GetGenericTypeDefinition ().GetGenericArguments ().Length];
+ Type[] gen_arguments = types[i].GetGenericArguments ();
+ for (int ii = 0; ii < gen_arguments_open.Length; ++ii) {
+ if (gen_arguments[ii].IsGenericParameter) {
+ Type t = argTypes[gen_arguments[ii].GenericParameterPosition];
+ gen_arguments_open[ii] = t;
+ } else
+ gen_arguments_open[ii] = gen_arguments[ii];
+ }
- //
- // 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)
- {
- //
- // Define each type attribute (in/out/ref) and
- // the argument names.
- //
- int i = 0;
-
- MethodBuilder mb = builder as MethodBuilder;
- ConstructorBuilder cb = builder as ConstructorBuilder;
+ p.FixedParameters [i].ParameterType = p.types[i] =
+ types[i].GetGenericTypeDefinition ().MakeGenericType (gen_arguments_open);
+ continue;
+ }
- if (FixedParameters != null) {
- for (i = 0; i < FixedParameters.Length; i++) {
- FixedParameters [i].DefineParameter (ec, mb, cb, i + 1);
+ if (types[i].IsGenericParameter) {
+ Type gen_argument = argTypes[types[i].GenericParameterPosition];
+ p.FixedParameters[i].ParameterType = p.types[i] = gen_argument;
+ continue;
}
}
- if (ArrayParameter != null){
- ParameterBuilder pb;
- Parameter array_param = ArrayParameter;
+ return p;
+ }
+#endif
- 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);
- }
+ public void VerifyClsCompliance ()
+ {
+ foreach (Parameter p in FixedParameters)
+ p.IsClsCompliant ();
}
public string GetSignatureForError ()
{
StringBuilder sb = new StringBuilder ("(");
- if (FixedParameters != null) {
+ if (count > 0) {
for (int i = 0; i < FixedParameters.Length; ++i) {
sb.Append (FixedParameters[i].GetSignatureForError ());
if (i < FixedParameters.Length - 1)
sb.Append (", ");
}
}
- if (ArrayParameter != null) {
- if (sb.Length > 0)
- sb.Append (", ");
- sb.Append (ArrayParameter.GetSignatureForError ());
- }
+
if (HasArglist) {
- if (sb.Length > 0)
+ if (sb.Length > 1)
sb.Append (", ");
sb.Append ("__arglist");
}
+
sb.Append (')');
return sb.ToString ();
+ }
+
+ public Type[] Types {
+ get {
+ return types;
+ }
+ //
+ // Dangerous, used by implicit lambda parameters
+ // only to workaround bad design
+ //
+ set {
+ types = value;
+ }
+ }
+
+ public Parameter this [int pos]
+ {
+ get {
+ if (pos >= count && (HasArglist || HasParams)) {
+ if (HasArglist && (pos == 0 || pos >= count))
+ return ArgList;
+ pos = count - 1;
+ }
+
+ return FixedParameters [pos];
+ }
+ }
+
+ #region ParameterData Members
+
+ public Type ParameterType (int pos)
+ {
+ return this [pos].ExternalType ();
+ }
+ public bool HasParams {
+ get {
+ if (count == 0)
+ return false;
+
+ for (int i = count; i != 0; --i) {
+ if ((FixedParameters [i - 1].ModFlags & Parameter.Modifier.PARAMS) != 0)
+ return true;
+ }
+ return false;
+ }
}
+
+ public string ParameterName (int pos)
+ {
+ return this [pos].Name;
+ }
+
+ public string ParameterDesc (int pos)
+ {
+ return this [pos].GetSignatureForError ();
+ }
+
+ public Parameter.Modifier ParameterModifier (int pos)
+ {
+ return this [pos].ModFlags;
+ }
+
+ public Parameters Clone ()
+ {
+ Parameter [] parameters_copy = new Parameter [FixedParameters.Length];
+ int i = 0;
+ foreach (Parameter p in FixedParameters)
+ parameters_copy [i++] = p.Clone ();
+ Parameters ps = new Parameters (parameters_copy, HasArglist);
+ if (types != null)
+ ps.types = (Type[])types.Clone ();
+ return ps;
+ }
+
+ #endregion
}
}