Implemented PipeSecurity. GetAccessControl, SetAccessControl, and ACL-containing...
[mono.git] / mcs / mcs / parameter.cs
index 1f2cefd501ad09e674e5667086f23b6a07fd63fa..365f876f0aa4f318f21cd34f114b7a1703dd8d66 100644 (file)
@@ -213,15 +213,19 @@ namespace Mono.CSharp {
                        REF = 1 << 1,
                        OUT = 1 << 2,
                        This = 1 << 3,
+                       CallerMemberName = 1 << 4,
+                       CallerLineNumber = 1 << 5,
+                       CallerFilePath = 1 << 6,
 
                        RefOutMask = REF | OUT,
                        ModifierMask = PARAMS | REF | OUT | This,
+                       CallerMask = CallerMemberName | CallerLineNumber | CallerFilePath
                }
 
                static readonly string[] attribute_targets = new string[] { "param" };
 
                FullNamedExpression texpr;
-               readonly Modifier modFlags;
+               Modifier modFlags;
                string name;
                Expression default_expr;
                protected TypeSpec parameter_type;
@@ -231,7 +235,7 @@ namespace Mono.CSharp {
 
                TemporaryVariableReference expr_tree_variable;
 
-               HoistedVariable hoisted_variant;
+               HoistedParameter hoisted_variant;
 
                public Parameter (FullNamedExpression type, string name, Modifier mod, Attributes attrs, Location loc)
                {
@@ -330,9 +334,7 @@ namespace Mono.CSharp {
 
                        if (a.Type == pa.CLSCompliant) {
                                a.Report.Warning (3022, 1, a.Location, "CLSCompliant attribute has no meaning when applied to parameters. Try putting it on the method instead");
-                       }
-
-                       if (a.Type == pa.DefaultParameterValue || a.Type == pa.OptionalParameter) {
+                       } else if (a.Type == pa.DefaultParameterValue || a.Type == pa.OptionalParameter) {
                                if (HasOptionalExpression) {
                                        a.Report.Error (1745, a.Location,
                                                "Cannot specify `{0}' attribute on optional parameter `{1}'",
@@ -341,6 +343,21 @@ namespace Mono.CSharp {
 
                                if (a.Type == pa.DefaultParameterValue)
                                        return;
+                       } else if (a.Type == pa.CallerMemberNameAttribute) {
+                               if ((modFlags & Modifier.CallerMemberName) == 0) {
+                                       a.Report.Error (4022, a.Location,
+                                               "The CallerMemberName attribute can only be applied to parameters with default value");
+                               }
+                       } else if (a.Type == pa.CallerLineNumberAttribute) {
+                               if ((modFlags & Modifier.CallerLineNumber) == 0) {
+                                       a.Report.Error (4020, a.Location,
+                                               "The CallerLineNumber attribute can only be applied to parameters with default value");
+                               }
+                       } else if (a.Type == pa.CallerFilePathAttribute) {
+                               if ((modFlags & Modifier.CallerFilePath) == 0) {
+                                       a.Report.Error (4021, a.Location,
+                                               "The CallerFilePath attribute can only be applied to parameters with default value");
+                               }
                        }
 
                        base.ApplyAttributeBuilder (a, ctor, cdata, pa);
@@ -395,6 +412,54 @@ namespace Mono.CSharp {
                        return parameter_type;
                }
 
+               void ResolveCallerAttributes (ResolveContext rc)
+               {
+                       var pa = rc.Module.PredefinedAttributes;
+                       TypeSpec caller_type;
+
+                       foreach (var attr in attributes.Attrs) {
+                               var atype = attr.ResolveType ();
+                               if (atype == null)
+                                       continue;
+
+                               if (atype == pa.CallerMemberNameAttribute) {
+                                       caller_type = rc.BuiltinTypes.String;
+                                       if (caller_type != parameter_type && !Convert.ImplicitReferenceConversionExists (caller_type, parameter_type)) {
+                                               rc.Report.Error (4019, attr.Location,
+                                                       "The CallerMemberName attribute cannot be applied because there is no standard conversion from `{0}' to `{1}'",
+                                                       caller_type.GetSignatureForError (), parameter_type.GetSignatureForError ());
+                                       }
+
+                                       modFlags |= Modifier.CallerMemberName;
+                                       continue;
+                               }
+
+                               if (atype == pa.CallerLineNumberAttribute) {
+                                       caller_type = rc.BuiltinTypes.Int;
+                                       if (caller_type != parameter_type && !Convert.ImplicitNumericConversionExists (caller_type, parameter_type)) {
+                                               rc.Report.Error (4017, attr.Location,
+                                                       "The CallerMemberName attribute cannot be applied because there is no standard conversion from `{0}' to `{1}'",
+                                                       caller_type.GetSignatureForError (), parameter_type.GetSignatureForError ());
+                                       }
+
+                                       modFlags |= Modifier.CallerLineNumber;
+                                       continue;
+                               }
+
+                               if (atype == pa.CallerFilePathAttribute) {
+                                       caller_type = rc.BuiltinTypes.String;
+                                       if (caller_type != parameter_type && !Convert.ImplicitReferenceConversionExists (caller_type, parameter_type)) {
+                                               rc.Report.Error (4018, attr.Location,
+                                                       "The CallerFilePath attribute cannot be applied because there is no standard conversion from `{0}' to `{1}'",
+                                                       caller_type.GetSignatureForError (), parameter_type.GetSignatureForError ());
+                                       }
+
+                                       modFlags |= Modifier.CallerFilePath;
+                                       continue;
+                               }
+                       }
+               }
+
                public void ResolveDefaultValue (ResolveContext rc)
                {
                        //
@@ -402,6 +467,9 @@ namespace Mono.CSharp {
                        //
                        if (default_expr != null) {
                                ((DefaultParameterValueExpression)default_expr).Resolve (rc, this);
+                               if (attributes != null)
+                                       ResolveCallerAttributes (rc);
+
                                return;
                        }
 
@@ -409,7 +477,6 @@ namespace Mono.CSharp {
                                return;
 
                        var pa = rc.Module.PredefinedAttributes;
-
                        var def_attr = attributes.Search (pa.DefaultParameterValue);
                        if (def_attr != null) {
                                if (def_attr.Resolve () == null)
@@ -482,7 +549,7 @@ namespace Mono.CSharp {
                //
                // Hoisted parameter variant
                //
-               public HoistedVariable HoistedVariant {
+               public HoistedParameter HoistedVariant {
                        get {
                                return hoisted_variant;
                        }
@@ -750,7 +817,7 @@ namespace Mono.CSharp {
 
                public static ParameterAttributes GetParameterAttribute (Parameter.Modifier modFlags)
                {
-                       return (modFlags & Parameter.Modifier.OUT) == Parameter.Modifier.OUT ?
+                       return (modFlags & Parameter.Modifier.OUT) != 0 ?
                                ParameterAttributes.Out : ParameterAttributes.None;
                }