Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/mcs
diff options
context:
space:
mode:
authorMarek Safar <marek.safar@gmail.com>2006-02-28 01:44:20 +0300
committerMarek Safar <marek.safar@gmail.com>2006-02-28 01:44:20 +0300
commitce9291281593887d381a429ab947004424c376d2 (patch)
treecf2f86f36cdd3343d7053e87679ae8505039f93f /mcs
parent385e817034a3625fbbe1f65bafe7d94359840269 (diff)
2006-02-27 Marek Safar <marek.safar@seznam.cz>
* attribute.cs (Attribute.PosArguments, Attribute.NamedArguments): Use these two separated members to simplify the code. (Attribute.Resolve): Refactored to use new fields and methods. (Attribute.ResolveConstructor): Extracted from ResolveArguments and implemented obsolete attribute checking. (Attribute.ResolveNamedArguments): Extracted from ResolveArguments and implemented obsolete checking again. It look line never ending quest ;-) (GlobalAttribute.ResolveConstructor): Need to override as the rest. * cfold.cs (BinaryFold): TryReduce throws an exception to indicate error. * constanct.cs (TryReduce): Throws OverflowException to indicate error. *class.cs (Property.Define): Add RegisterProperty call. * cs-parser.jay: Replaced ArrayList with fixed array for attribute argument groups (only 2). * ecore.cs (Expression.GetAttributableValue): New virtual method used for encoding expression to arguments. (Expression.ExprClassToResolveFlags): Just turned to property. * expression.cs (ArrayCreation.ValidateInitializers): Slightly optimized. (ArrayCreation.GetAttributableValue): Renamed from EncodeAsAttribute and optimized as well as implemented support for zero-length attributes. * typemanager.cs (TypeManager.RegisterProperty, TypeManager.GetProperty): Add caching of PropertyInfo's. svn path=/trunk/mcs/; revision=57358
Diffstat (limited to 'mcs')
-rw-r--r--mcs/mcs/ChangeLog31
-rw-r--r--mcs/mcs/attribute.cs470
-rw-r--r--mcs/mcs/cfold.cs20
-rw-r--r--mcs/mcs/class.cs1
-rw-r--r--mcs/mcs/constant.cs18
-rw-r--r--mcs/mcs/cs-parser.jay25
-rw-r--r--mcs/mcs/ecore.cs59
-rw-r--r--mcs/mcs/expression.cs77
-rw-r--r--mcs/mcs/typemanager.cs16
9 files changed, 371 insertions, 346 deletions
diff --git a/mcs/mcs/ChangeLog b/mcs/mcs/ChangeLog
index 8b9423aa8e2..315b25dad1c 100644
--- a/mcs/mcs/ChangeLog
+++ b/mcs/mcs/ChangeLog
@@ -1,3 +1,34 @@
+2006-02-27 Marek Safar <marek.safar@seznam.cz>
+
+ * attribute.cs (Attribute.PosArguments, Attribute.NamedArguments): Use
+ these two separated members to simplify the code.
+ (Attribute.Resolve): Refactored to use new fields and methods.
+ (Attribute.ResolveConstructor): Extracted from ResolveArguments and
+ implemented obsolete attribute checking.
+ (Attribute.ResolveNamedArguments): Extracted from ResolveArguments and
+ implemented obsolete checking again. It look line never ending quest ;-)
+ (GlobalAttribute.ResolveConstructor): Need to override as the rest.
+
+ * cfold.cs (BinaryFold): TryReduce throws an exception to indicate error.
+
+ * constanct.cs (TryReduce): Throws OverflowException to indicate error.
+
+ *class.cs (Property.Define): Add RegisterProperty call.
+
+ * cs-parser.jay: Replaced ArrayList with fixed array for attribute
+ argument groups (only 2).
+
+ * ecore.cs (Expression.GetAttributableValue): New virtual method used for
+ encoding expression to arguments.
+ (Expression.ExprClassToResolveFlags): Just turned to property.
+
+ * expression.cs (ArrayCreation.ValidateInitializers): Slightly optimized.
+ (ArrayCreation.GetAttributableValue): Renamed from EncodeAsAttribute and
+ optimized as well as implemented support for zero-length attributes.
+
+ * typemanager.cs (TypeManager.RegisterProperty, TypeManager.GetProperty):
+ Add caching of PropertyInfo's.
+
2006-02-25 Marek Safar <marek.safar@seznam.cz>
* delegate.cs (DelegateCreation.ResolveMethodGroupExpr): Don't report
diff --git a/mcs/mcs/attribute.cs b/mcs/mcs/attribute.cs
index c474d0c4d84..2b8c8031ea4 100644
--- a/mcs/mcs/attribute.cs
+++ b/mcs/mcs/attribute.cs
@@ -83,7 +83,8 @@ namespace Mono.CSharp {
public readonly Expression LeftExpr;
public readonly string Identifier;
- public readonly ArrayList Arguments;
+ readonly ArrayList PosArguments;
+ readonly ArrayList NamedArguments;
public readonly Location Location;
@@ -93,8 +94,9 @@ namespace Mono.CSharp {
readonly bool nameEscaped;
Attributable owner;
- static AttributeUsageAttribute DefaultUsageAttribute = new AttributeUsageAttribute (AttributeTargets.All);
+ static readonly AttributeUsageAttribute DefaultUsageAttribute = new AttributeUsageAttribute (AttributeTargets.All);
static Assembly orig_sec_assembly;
+ public static readonly object[] EmptyObject = new object [0];
// non-null if named args present after Resolve () is called
PropertyInfo [] prop_info_arr;
@@ -104,13 +106,19 @@ namespace Mono.CSharp {
object [] pos_values;
static PtrHashtable usage_attr_cache = new PtrHashtable ();
+
+ // Cache for parameter-less attributes
+ static PtrHashtable att_cache = new PtrHashtable ();
- public Attribute (string target, Expression left_expr, string identifier, ArrayList args, Location loc, bool nameEscaped)
+ public Attribute (string target, Expression left_expr, string identifier, object[] args, Location loc, bool nameEscaped)
{
LeftExpr = left_expr;
Identifier = identifier;
Name = LeftExpr == null ? identifier : LeftExpr + "." + identifier;
- Arguments = args;
+ if (args != null) {
+ PosArguments = (ArrayList)args [0];
+ NamedArguments = (ArrayList)args [1];
+ }
Location = loc;
ExplicitTarget = target;
this.nameEscaped = nameEscaped;
@@ -135,18 +143,12 @@ namespace Mono.CSharp {
"attribute parameter type", name);
}
- static void Error_AttributeArgumentNotValid (string extra, Location loc)
+ public static void Error_AttributeArgumentNotValid (Location loc)
{
Report.Error (182, loc,
"An attribute argument must be a constant expression, typeof " +
- "expression or array creation expression" + extra);
- }
-
- static void Error_AttributeArgumentNotValid (Location loc)
- {
- Error_AttributeArgumentNotValid ("", loc);
- }
-
+ "expression or array creation expression");
+ }
/// <summary>
/// This is rather hack. We report many emit attribute error with same error to be compatible with
@@ -255,41 +257,6 @@ namespace Mono.CSharp {
return LeftExpr == null ? Identifier : LeftExpr.GetSignatureForError () + "." + Identifier;
}
- //
- // Given an expression, if the expression is a valid attribute-argument-expression
- // returns an object that can be used to encode it, or null on failure.
- //
- public static bool GetAttributeArgumentExpression (Expression e, Location loc, Type arg_type, out object result)
- {
- Constant constant = e as Constant;
- if (constant != null) {
- constant = constant.ToType (arg_type, loc);
- if (constant == null) {
- result = null;
- return false;
- }
- result = constant.GetTypedValue ();
- return true;
- } else if (e is TypeOf) {
- result = ((TypeOf) e).TypeArg;
- return true;
- } else if (e is ArrayCreation){
- result = ((ArrayCreation) e).EncodeAsAttribute ();
- if (result != null)
- return true;
- } else if (e is EmptyCast) {
- Expression child = ((EmptyCast)e).Child;
- return GetAttributeArgumentExpression (child, loc, child.Type, out result);
- } else if (e is As) {
- As as_e = (As) e;
- return GetAttributeArgumentExpression (as_e.Expr, loc, as_e.ProbeType.Type, out result);
- }
-
- result = null;
- Error_AttributeArgumentNotValid (loc);
- return false;
- }
-
bool IsValidArgumentType (Type t)
{
if (t.IsArray)
@@ -302,9 +269,6 @@ namespace Mono.CSharp {
t == TypeManager.type_type;
}
- // Cache for parameter-less attributes
- static PtrHashtable att_cache = new PtrHashtable ();
-
public CustomAttributeBuilder Resolve ()
{
if (resolve_error)
@@ -328,7 +292,7 @@ namespace Mono.CSharp {
AttributeTester.Report_ObsoleteMessage (obsolete_attr, TypeManager.CSharpName (Type), Location);
}
- if (Arguments == null) {
+ if (PosArguments == null && NamedArguments == null) {
object o = att_cache [Type];
if (o != null) {
resolve_error = false;
@@ -336,118 +300,177 @@ namespace Mono.CSharp {
}
}
- ConstructorInfo ctor = ResolveArguments ();
+ EmitContext ec = new EmitContext (owner.ResolveContext, owner.ResolveContext.DeclContainer, owner.ResolveContext.DeclContainer,
+ Location, null, null, owner.ResolveContext.DeclContainer.ModFlags, false);
+
+ ConstructorInfo ctor = ResolveConstructor (ec);
if (ctor == null)
return null;
CustomAttributeBuilder cb;
try {
- if (prop_info_arr != null || field_info_arr != null) {
- cb = new CustomAttributeBuilder (
- ctor, pos_values,
- prop_info_arr, prop_values_arr,
- field_info_arr, field_values_arr);
- } else {
- cb = new CustomAttributeBuilder (
- ctor, pos_values);
+ if (NamedArguments == null) {
+ cb = new CustomAttributeBuilder (ctor, pos_values);
if (pos_values.Length == 0)
att_cache.Add (Type, cb);
+
+ resolve_error = false;
+ return cb;
+ }
+
+ if (!ResolveNamedArguments (ec)) {
+ return null;
}
+
+ cb = new CustomAttributeBuilder (ctor, pos_values,
+ prop_info_arr, prop_values_arr,
+ field_info_arr, field_values_arr);
+
+ resolve_error = false;
+ return cb;
}
catch (Exception) {
Error_AttributeArgumentNotValid (Location);
return null;
}
-
- resolve_error = false;
- return cb;
}
- protected virtual ConstructorInfo ResolveArguments ()
+ protected virtual ConstructorInfo ResolveConstructor (EmitContext ec)
{
- // Now we extract the positional and named arguments
-
- ArrayList pos_args = null;
- ArrayList named_args = null;
- int pos_arg_count = 0;
- int named_arg_count = 0;
-
- if (Arguments != null) {
- pos_args = (ArrayList) Arguments [0];
- if (pos_args != null)
- pos_arg_count = pos_args.Count;
- if (Arguments.Count > 1) {
- named_args = (ArrayList) Arguments [1];
- named_arg_count = named_args.Count;
+ if (PosArguments != null) {
+ for (int i = 0; i < PosArguments.Count; i++) {
+ Argument a = (Argument) PosArguments [i];
+
+ if (!a.Resolve (ec, Location))
+ return null;
}
}
- pos_values = new object [pos_arg_count];
+ Expression mg = Expression.MemberLookup (ec.ContainerType,
+ Type, ".ctor", MemberTypes.Constructor,
+ BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
+ Location);
- //
- // First process positional arguments
- //
+ MethodBase constructor = Invocation.OverloadResolve (
+ ec, (MethodGroupExpr) mg, PosArguments, false, Location);
- EmitContext ec = new EmitContext (owner.ResolveContext, owner.ResolveContext.DeclContainer, owner.ResolveContext.DeclContainer,
- Location, null, null, owner.ResolveContext.DeclContainer.ModFlags, false);
+ if (constructor == null)
+ return null;
- int i;
- for (i = 0; i < pos_arg_count; i++) {
- Argument a = (Argument) pos_args [i];
- Expression e;
+ ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (constructor);
+ if (oa != null && !owner.ResolveContext.IsInObsoleteScope) {
+ AttributeTester.Report_ObsoleteMessage (oa, mg.GetSignatureForError (), mg.Location);
+ }
- if (!a.Resolve (ec, Location))
- return null;
+ if (PosArguments == null) {
+ pos_values = EmptyObject;
+ return (ConstructorInfo)constructor;
+ }
- e = a.Expr;
+ ParameterData pd = TypeManager.GetParameterData (constructor);
- object val;
- if (!GetAttributeArgumentExpression (e, Location, a.Type, out val))
- return null;
+ int pos_arg_count = PosArguments.Count;
+ int last_real_param = pd.Count;
+
+ pos_values = new object [pos_arg_count];
- pos_values [i] = val;
+ if (pd.HasParams) {
+ // When the params is not filled we need to put one
+ if (last_real_param > pos_arg_count) {
+ object [] new_pos_values = new object [pos_arg_count + 1];
+ pos_values.CopyTo (new_pos_values, 0);
+ new_pos_values [pos_arg_count] = new object [] {} ;
+ pos_values = new_pos_values;
+ }
+ last_real_param--;
+ }
+
+ for (int j = 0; j < pos_arg_count; ++j) {
+ Argument a = (Argument) PosArguments [j];
- if (i == 0 && Type == TypeManager.attribute_usage_type && (int)val == 0) {
- Report.Error (591, Location, "Invalid value for argument to 'System.AttributeUsage' attribute");
+ if (!a.Expr.GetAttributableValue (out pos_values [j]))
return null;
+
+ if (TypeManager.IsPrimitiveType (a.Type) && a.Type != pos_values [j].GetType ()) {
+ bool fail;
+ // This can happen only for constants in same range
+ pos_values [j] = TypeManager.ChangeType (pos_values [j], a.Type, out fail);
}
+
+ if (j < last_real_param)
+ continue;
+
+ if (j == last_real_param) {
+ object [] array = new object [pos_arg_count - last_real_param];
+ array [0] = pos_values [j];
+ pos_values [j] = array;
+ continue;
+ }
+
+ object [] params_array = (object []) pos_values [last_real_param];
+ params_array [j - last_real_param] = pos_values [j];
}
- //
- // Now process named arguments
- //
+ // Adjust the size of the pos_values if it had params
+ if (last_real_param != pos_arg_count) {
+ object [] new_pos_values = new object [last_real_param + 1];
+ Array.Copy (pos_values, new_pos_values, last_real_param + 1);
+ pos_values = new_pos_values;
+ }
- ArrayList field_infos = null;
- ArrayList prop_infos = null;
- ArrayList field_values = null;
- ArrayList prop_values = null;
- Hashtable seen_names = null;
+ // Here we do the checks which should be done by corlib or by runtime.
+ // However Zoltan doesn't like it and every Mono compiler has to do it again.
+
+ if (Type == TypeManager.guid_attr_type) {
+ try {
+ new Guid ((string)pos_values [0]);
+ }
+ catch (Exception e) {
+ Error_AttributeEmitError (e.Message);
+ return null;
+ }
+ }
- if (named_arg_count > 0) {
- field_infos = new ArrayList (4);
- prop_infos = new ArrayList (4);
- field_values = new ArrayList (4);
- prop_values = new ArrayList (4);
+ if (Type == TypeManager.attribute_usage_type && (int)pos_values [0] == 0) {
+ Report.Error (591, Location, "Invalid value for argument to 'System.AttributeUsage' attribute");
+ return null;
+ }
- seen_names = new Hashtable(4);
+ if (Type == TypeManager.methodimpl_attr_type && pos_values.Length == 1 &&
+ pd.ParameterType (0) == TypeManager.short_type &&
+ !System.Enum.IsDefined (typeof (MethodImplOptions), pos_values [0].ToString ())) {
+ Error_AttributeEmitError ("Incorrect argument value.");
+ return null;
}
+
+ return (ConstructorInfo)constructor;
+ }
+
+ protected virtual bool ResolveNamedArguments (EmitContext ec)
+ {
+ int named_arg_count = NamedArguments.Count;
+
+ ArrayList field_infos = new ArrayList (named_arg_count);
+ ArrayList prop_infos = new ArrayList (named_arg_count);
+ ArrayList field_values = new ArrayList (named_arg_count);
+ ArrayList prop_values = new ArrayList (named_arg_count);
+
+ ArrayList seen_names = new ArrayList(named_arg_count);
- for (i = 0; i < named_arg_count; i++) {
- DictionaryEntry de = (DictionaryEntry) named_args [i];
+ foreach (DictionaryEntry de in NamedArguments) {
string member_name = (string) de.Key;
- Argument a = (Argument) de.Value;
- Expression e;
if (seen_names.Contains(member_name)) {
Report.Error(643, Location, "'" + member_name + "' duplicate named attribute argument");
- return null;
+ return false;
}
- seen_names.Add(member_name, 1);
-
+ seen_names.Add(member_name);
+
+ Argument a = (Argument) de.Value;
if (!a.Resolve (ec, Location))
- return null;
+ return false;
Expression member = Expression.MemberLookup (
ec.ContainerType, Type, member_name,
@@ -462,175 +485,103 @@ namespace Mono.CSharp {
if (member != null) {
Expression.ErrorIsInaccesible (Location, member.GetSignatureForError ());
- return null;
+ return false;
}
}
if (member == null){
Report.Error (117, Location, "`{0}' does not contain a definition for `{1}'",
TypeManager.CSharpName (Type), member_name);
- return null;
+ return false;
}
if (!(member is PropertyExpr || member is FieldExpr)) {
Error_InvalidNamedArgument (member_name);
- return null;
+ return false;
}
- e = a.Expr;
+ ObsoleteAttribute obsolete_attr;
+
if (member is PropertyExpr) {
- PropertyExpr pe = (PropertyExpr) member;
- PropertyInfo pi = pe.PropertyInfo;
+ PropertyInfo pi = ((PropertyExpr) member).PropertyInfo;
if (!pi.CanWrite || !pi.CanRead) {
Report.SymbolRelatedToPreviousError (pi);
Error_InvalidNamedArgument (member_name);
- return null;
+ return false;
}
if (!IsValidArgumentType (pi.PropertyType)) {
Report.SymbolRelatedToPreviousError (pi);
Error_InvalidNamedAgrumentType (member_name);
- return null;
+ return false;
}
+ Expression e = Convert.ImplicitConversionRequired (ec, a.Expr, pi.PropertyType, a.Expr.Location);
+ if (e == null)
+ return false;
+
object value;
- if (!GetAttributeArgumentExpression (e, Location, pi.PropertyType, out value))
- return null;
+ if (!e.GetAttributableValue (out value))
+ return false;
+
+ PropertyBase pb = TypeManager.GetProperty (pi);
+ if (pb != null)
+ obsolete_attr = pb.GetObsoleteAttribute ();
+ else
+ obsolete_attr = AttributeTester.GetMemberObsoleteAttribute (pi);
prop_values.Add (value);
prop_infos.Add (pi);
- } else if (member is FieldExpr) {
- FieldExpr fe = (FieldExpr) member;
- FieldInfo fi = fe.FieldInfo;
+ } else {
+ FieldInfo fi = ((FieldExpr) member).FieldInfo;
if (fi.IsInitOnly) {
Error_InvalidNamedArgument (member_name);
- return null;
+ return false;
}
if (!IsValidArgumentType (fi.FieldType)) {
Report.SymbolRelatedToPreviousError (fi);
Error_InvalidNamedAgrumentType (member_name);
- return null;
+ return false;
}
+ Expression e = Convert.ImplicitConversionRequired (ec, a.Expr, fi.FieldType, a.Expr.Location);
+ if (e == null)
+ return false;
+
object value;
- if (!GetAttributeArgumentExpression (e, Location, fi.FieldType, out value))
- return null;
+ if (!e.GetAttributableValue (out value))
+ return false;
+
+ FieldBase fb = TypeManager.GetField (fi);
+ if (fb != null)
+ obsolete_attr = fb.GetObsoleteAttribute ();
+ else
+ obsolete_attr = AttributeTester.GetMemberObsoleteAttribute (fi);
field_values.Add (value);
field_infos.Add (fi);
}
- }
-
- Expression mg = Expression.MemberLookup (ec.ContainerType,
- Type, ".ctor", MemberTypes.Constructor,
- BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
- Location);
-
- MethodBase constructor = Invocation.OverloadResolve (
- ec, (MethodGroupExpr) mg, pos_args, false, Location);
- if (constructor == null) {
- return null;
- }
-
-
- // Here we do the checks which should be done by corlib or by runtime.
- // However Zoltan doesn't like it and every Mono compiler has to do it again.
-
- if (Type == TypeManager.guid_attr_type) {
- try {
- new Guid ((string)pos_values [0]);
- }
- catch (Exception e) {
- Error_AttributeEmitError (e.Message);
- return null;
- }
+ if (obsolete_attr != null && !owner.ResolveContext.IsInObsoleteScope)
+ AttributeTester.Report_ObsoleteMessage (obsolete_attr, member.GetSignatureForError (), member.Location);
}
- if (Type == TypeManager.methodimpl_attr_type &&
- pos_values.Length == 1 && ((Argument)pos_args [0]).Type == TypeManager.short_type &&
- !System.Enum.IsDefined (typeof (MethodImplOptions), pos_values [0])) {
- Error_AttributeEmitError ("Incorrect argument value.");
- return null;
- }
+ prop_info_arr = new PropertyInfo [prop_infos.Count];
+ field_info_arr = new FieldInfo [field_infos.Count];
+ field_values_arr = new object [field_values.Count];
+ prop_values_arr = new object [prop_values.Count];
- //
- // Now we perform some checks on the positional args as they
- // cannot be null for a constructor which expects a parameter
- // of type object
- //
+ field_infos.CopyTo (field_info_arr, 0);
+ field_values.CopyTo (field_values_arr, 0);
- ParameterData pd = TypeManager.GetParameterData (constructor);
+ prop_values.CopyTo (prop_values_arr, 0);
+ prop_infos.CopyTo (prop_info_arr, 0);
- int last_real_param = pd.Count;
- if (pd.HasParams) {
- // When the params is not filled we need to put one
- if (last_real_param > pos_arg_count) {
- object [] new_pos_values = new object [pos_arg_count + 1];
- pos_values.CopyTo (new_pos_values, 0);
- new_pos_values [pos_arg_count] = new object [] {} ;
- pos_values = new_pos_values;
- }
- last_real_param--;
- }
-
- for (int j = 0; j < pos_arg_count; ++j) {
- Argument a = (Argument) pos_args [j];
-
- if (a.Expr is NullLiteral && pd.ParameterType (j) == TypeManager.object_type) {
- Error_AttributeArgumentNotValid (Location);
- return null;
- }
-
- object value = pos_values [j];
- if (value != null && a.Type != value.GetType () && TypeManager.IsPrimitiveType (a.Type)) {
- bool fail;
- pos_values [j] = TypeManager.ChangeType (value, a.Type, out fail);
- if (fail) {
- // TODO: Can failed ?
- throw new NotImplementedException ();
- }
- }
-
- if (j < last_real_param)
- continue;
-
- if (j == last_real_param) {
- object [] array = new object [pos_arg_count - last_real_param];
- array [0] = pos_values [j];
- pos_values [j] = array;
- continue;
- }
-
- object [] params_array = (object []) pos_values [last_real_param];
- params_array [j - last_real_param] = pos_values [j];
- }
-
- // Adjust the size of the pos_values if it had params
- if (last_real_param != pos_arg_count) {
- object [] new_pos_values = new object [last_real_param + 1];
- Array.Copy (pos_values, new_pos_values, last_real_param + 1);
- pos_values = new_pos_values;
- }
-
- if (named_arg_count > 0) {
- prop_info_arr = new PropertyInfo [prop_infos.Count];
- field_info_arr = new FieldInfo [field_infos.Count];
- field_values_arr = new object [field_values.Count];
- prop_values_arr = new object [prop_values.Count];
-
- field_infos.CopyTo (field_info_arr, 0);
- field_values.CopyTo (field_values_arr, 0);
-
- prop_values.CopyTo (prop_values_arr, 0);
- prop_infos.CopyTo (prop_info_arr, 0);
- }
-
- return (ConstructorInfo) constructor;
+ return true;
}
/// <summary>
@@ -1174,12 +1125,8 @@ namespace Mono.CSharp {
// Here we are testing attribute arguments for array usage (error 3016)
if (owner.IsClsComplianceRequired ()) {
- if (Arguments == null)
- return;
-
- ArrayList pos_args = (ArrayList) Arguments [0];
- if (pos_args != null) {
- foreach (Argument arg in pos_args) {
+ if (PosArguments != null) {
+ foreach (Argument arg in PosArguments) {
// Type is undefined (was error 246)
if (arg.Type == null)
return;
@@ -1191,11 +1138,10 @@ namespace Mono.CSharp {
}
}
- if (Arguments.Count < 2)
+ if (NamedArguments == null)
return;
- ArrayList named_args = (ArrayList) Arguments [1];
- foreach (DictionaryEntry de in named_args) {
+ foreach (DictionaryEntry de in NamedArguments) {
Argument arg = (Argument) de.Value;
// Type is undefined (was error 246)
@@ -1327,15 +1273,10 @@ namespace Mono.CSharp {
private Expression GetValue ()
{
- if ((Arguments == null) || (Arguments.Count < 1))
- return null;
- ArrayList al = (ArrayList) Arguments [0];
- if ((al == null) || (al.Count < 1))
- return null;
- Argument arg = (Argument) al [0];
- if ((arg == null) || (arg.Expr == null))
+ if (PosArguments == null || PosArguments.Count < 1)
return null;
- return arg.Expr;
+
+ return ((Argument) PosArguments [0]).Expr;
}
public string GetString ()
@@ -1365,7 +1306,7 @@ namespace Mono.CSharp {
public readonly NamespaceEntry ns;
public GlobalAttribute (NamespaceEntry ns, string target,
- Expression left_expr, string identifier, ArrayList args, Location loc, bool nameEscaped):
+ Expression left_expr, string identifier, object[] args, Location loc, bool nameEscaped):
base (target, left_expr, identifier, args, loc, nameEscaped)
{
this.ns = ns;
@@ -1414,11 +1355,22 @@ namespace Mono.CSharp {
}
}
- protected override ConstructorInfo ResolveArguments ()
+ protected override ConstructorInfo ResolveConstructor (EmitContext ec)
+ {
+ try {
+ Enter ();
+ return base.ResolveConstructor (ec);
+ }
+ finally {
+ Leave ();
+ }
+ }
+
+ protected override bool ResolveNamedArguments (EmitContext ec)
{
try {
Enter ();
- return base.ResolveArguments ();
+ return base.ResolveNamedArguments (ec);
}
finally {
Leave ();
diff --git a/mcs/mcs/cfold.cs b/mcs/mcs/cfold.cs
index 303002901a6..aba3ad37c48 100644
--- a/mcs/mcs/cfold.cs
+++ b/mcs/mcs/cfold.cs
@@ -550,8 +550,14 @@ namespace Mono.CSharp {
Error_CompileTimeOverflow (loc);
}
- if (wrap_as != null)
- return result.TryReduce (ec, wrap_as, loc);
+ if (wrap_as != null) {
+ try {
+ return result.TryReduce (ec, wrap_as, loc);
+ }
+ catch (OverflowException) {
+ return null;
+ }
+ }
else
return result;
@@ -682,8 +688,14 @@ namespace Mono.CSharp {
Error_CompileTimeOverflow (loc);
}
- if (wrap_as != null)
- return result.TryReduce (ec, wrap_as, loc);
+ if (wrap_as != null) {
+ try {
+ return result.TryReduce (ec, wrap_as, loc);
+ }
+ catch (OverflowException) {
+ return null;
+ }
+ }
return result;
diff --git a/mcs/mcs/class.cs b/mcs/mcs/class.cs
index 514388e8a2f..d98381da6c6 100644
--- a/mcs/mcs/class.cs
+++ b/mcs/mcs/class.cs
@@ -6194,6 +6194,7 @@ namespace Mono.CSharp {
if (!Set.IsDummy)
PropertyBuilder.SetSetMethod (SetBuilder);
+ TypeManager.RegisterProperty (PropertyBuilder, this);
return true;
}
}
diff --git a/mcs/mcs/constant.cs b/mcs/mcs/constant.cs
index 76c2c5667a8..0ccf630311d 100644
--- a/mcs/mcs/constant.cs
+++ b/mcs/mcs/constant.cs
@@ -39,6 +39,12 @@ namespace Mono.CSharp {
return this.GetType ().Name + " (" + AsString () + ")";
}
+ public override bool GetAttributableValue (out object value)
+ {
+ value = GetTypedValue ();
+ return true;
+ }
+
/// <summary>
/// This is used to obtain the actual value of the literal
/// cast into an object.
@@ -233,6 +239,10 @@ namespace Mono.CSharp {
throw new OverflowException ();
}
+ /// <summary>
+ /// Maybe ConvertTo name is better. It tries to convert `this' constant to target_type.
+ /// It throws OverflowException
+ /// </summary>
public abstract Constant Reduce (EmitContext ec, Type target_type);
/// <summary>
@@ -244,11 +254,9 @@ namespace Mono.CSharp {
return TryReduce (ec, target_type);
}
catch (OverflowException) {
- if (ec.ConstantCheckState) {
- Report.Error (221, loc, "Constant value `{0}' cannot be converted to a `{1}' (use `unchecked' syntax to override)",
- GetValue ().ToString (), TypeManager.CSharpName (target_type));
- }
- return null;
+ Report.Error (221, loc, "Constant value `{0}' cannot be converted to a `{1}' (use `unchecked' syntax to override)",
+ GetValue ().ToString (), TypeManager.CSharpName (target_type));
+ throw;
}
}
diff --git a/mcs/mcs/cs-parser.jay b/mcs/mcs/cs-parser.jay
index 2b709ec23bb..3b1c82ec761 100644
--- a/mcs/mcs/cs-parser.jay
+++ b/mcs/mcs/cs-parser.jay
@@ -620,7 +620,7 @@ attribute
: attribute_name opt_attribute_arguments
{
MemberName mname = (MemberName) $1;
- ArrayList arguments = (ArrayList) $2;
+ object[] arguments = (object[]) $2;
MemberName left = mname.Left;
string identifier = mname.Name;
@@ -654,29 +654,18 @@ attribute_arguments
if ($1 == null)
$$ = null;
else {
- ArrayList args = new ArrayList (4);
- args.Add ($1);
-
- $$ = args;
+ $$ = new object [] { $1, null };
}
}
- | positional_argument_list COMMA named_argument_list
+ | positional_argument_list COMMA named_argument_list
{
- ArrayList args = new ArrayList (4);
- args.Add ($1);
- args.Add ($3);
-
- $$ = args;
+ $$ = new object[] { $1, $3 };
}
- | named_argument_list
+ | named_argument_list
{
- ArrayList args = new ArrayList (4);
- args.Add (null);
- args.Add ($1);
-
- $$ = args;
+ $$ = new object [] { null, $1 };
}
- ;
+ ;
opt_positional_argument_list
diff --git a/mcs/mcs/ecore.cs b/mcs/mcs/ecore.cs
index dc2324a363b..8b3e61aa012 100644
--- a/mcs/mcs/ecore.cs
+++ b/mcs/mcs/ecore.cs
@@ -137,6 +137,13 @@ namespace Mono.CSharp {
// Not nice but we have broken hierarchy
public virtual void CheckMarshallByRefAccess (Type container) {}
+ public virtual bool GetAttributableValue (out object value)
+ {
+ Attribute.Error_AttributeArgumentNotValid (loc);
+ value = null;
+ return false;
+ }
+
public virtual string GetSignatureForError ()
{
return TypeManager.CSharpName (type);
@@ -315,28 +322,29 @@ namespace Mono.CSharp {
TypeManager.CSharpName (type), name);
}
- ResolveFlags ExprClassToResolveFlags ()
+ ResolveFlags ExprClassToResolveFlags
{
- switch (eclass) {
- case ExprClass.Type:
- case ExprClass.Namespace:
- return ResolveFlags.Type;
+ get {
+ switch (eclass) {
+ case ExprClass.Type:
+ case ExprClass.Namespace:
+ return ResolveFlags.Type;
- case ExprClass.MethodGroup:
- return ResolveFlags.MethodGroup;
+ case ExprClass.MethodGroup:
+ return ResolveFlags.MethodGroup;
- case ExprClass.Value:
- case ExprClass.Variable:
- case ExprClass.PropertyAccess:
- case ExprClass.EventAccess:
- case ExprClass.IndexerAccess:
- return ResolveFlags.VariableOrValue;
+ case ExprClass.Value:
+ case ExprClass.Variable:
+ case ExprClass.PropertyAccess:
+ case ExprClass.EventAccess:
+ case ExprClass.IndexerAccess:
+ return ResolveFlags.VariableOrValue;
- default:
- throw new Exception ("Expression " + GetType () +
- " ExprClass is Invalid after resolve");
+ default:
+ throw new Exception ("Expression " + GetType () +
+ " ExprClass is Invalid after resolve");
+ }
}
-
}
/// <summary>
@@ -360,10 +368,10 @@ namespace Mono.CSharp {
ec.OmitStructFlowAnalysis = true;
Expression e;
- bool intermediate = (flags & ResolveFlags.Intermediate) == ResolveFlags.Intermediate;
- if (this is SimpleName)
+ if (this is SimpleName) {
+ bool intermediate = (flags & ResolveFlags.Intermediate) == ResolveFlags.Intermediate;
e = ((SimpleName) this).DoResolve (ec, intermediate);
-
+ }
else
e = DoResolve (ec);
@@ -373,7 +381,7 @@ namespace Mono.CSharp {
if (e == null)
return null;
- if ((flags & e.ExprClassToResolveFlags ()) == 0) {
+ if ((flags & e.ExprClassToResolveFlags) == 0) {
e.Error_UnexpectedKind (flags, loc);
return null;
}
@@ -1123,7 +1131,7 @@ namespace Mono.CSharp {
///
/// </summary>
public class EmptyCast : Expression {
- protected Expression child;
+ protected readonly Expression child;
public Expression Child {
get {
@@ -1151,6 +1159,12 @@ namespace Mono.CSharp {
{
child.Emit (ec);
}
+
+ public override bool GetAttributableValue (out object value)
+ {
+ return child.GetAttributableValue (out value);
+ }
+
}
/// <summary>
/// This is a numeric cast to a Decimal
@@ -3194,6 +3208,7 @@ namespace Mono.CSharp {
// We also perform the permission checking here, as the PropertyInfo does not
// hold the information for the accessibility of its setter/getter
//
+ // TODO: can use TypeManager.GetProperty to boost performance
void ResolveAccessors (Type containerType)
{
FindAccessors (containerType);
diff --git a/mcs/mcs/expression.cs b/mcs/mcs/expression.cs
index 432c83d840c..9005f6641e6 100644
--- a/mcs/mcs/expression.cs
+++ b/mcs/mcs/expression.cs
@@ -1252,7 +1252,12 @@ namespace Mono.CSharp {
Error_CannotConvertType (etype, probe_type, loc);
return null;
- }
+ }
+
+ public override bool GetAttributableValue (out object value)
+ {
+ return expr.GetAttributableValue (out value);
+ }
}
/// <summary>
@@ -1327,9 +1332,14 @@ namespace Mono.CSharp {
Constant c = expr as Constant;
if (c != null) {
- c = c.TryReduce (ec, type, loc);
- if (c != null)
- return c;
+ try {
+ c = c.TryReduce (ec, type, loc);
+ if (c != null)
+ return c;
+ }
+ catch (OverflowException) {
+ return null;
+ }
}
if (type.IsPointer && !ec.InUnsafe) {
@@ -6014,10 +6024,7 @@ namespace Mono.CSharp {
public bool ValidateInitializers (EmitContext ec, Type array_type)
{
if (initializers == null) {
- if (expect_initializers)
- return false;
- else
- return true;
+ return !expect_initializers;
}
if (underlying_type == null)
@@ -6030,17 +6037,12 @@ namespace Mono.CSharp {
array_data = new ArrayList ();
bounds = new Hashtable ();
- bool ret;
-
if (arguments != null) {
- ret = CheckIndices (ec, initializers, 0, true);
- return ret;
+ return CheckIndices (ec, initializers, 0, true);
} else {
arguments = new ArrayList ();
- ret = CheckIndices (ec, initializers, 0, false);
-
- if (!ret)
+ if (!CheckIndices (ec, initializers, 0, false))
return false;
UpdateIndices (ec);
@@ -6050,7 +6052,7 @@ namespace Mono.CSharp {
return false;
}
- return ret;
+ return true;
}
}
@@ -6508,32 +6510,33 @@ namespace Mono.CSharp {
}
}
- public object EncodeAsAttribute ()
+ public override bool GetAttributableValue (out object value)
{
if (!is_one_dimensional){
- Report.Error (-211, Location, "attribute can not encode multi-dimensional arrays");
- return null;
+// Report.Error (-211, Location, "attribute can not encode multi-dimensional arrays");
+ return base.GetAttributableValue (out value);
}
- if (array_data == null){
- Report.Error (-212, Location, "array should be initialized when passing it to an attribute");
- return null;
+ if (array_data == null) {
+ Constant c = (Constant)((Argument)arguments [0]).Expr;
+ if (c.IsDefaultValue) {
+ value = new object [0];
+ return true;
+ }
+// Report.Error (-212, Location, "array should be initialized when passing it to an attribute");
+ return base.GetAttributableValue (out value);
}
object [] ret = new object [array_data.Count];
- int i = 0;
- foreach (Expression e in array_data){
- object v;
-
- if (e is NullLiteral)
- v = null;
- else {
- if (!Attribute.GetAttributeArgumentExpression (e, Location, array_element_type, out v))
- return null;
+ for (int i = 0; i < ret.Length; ++i)
+ {
+ if (!((Expression)array_data [i]).GetAttributableValue (out ret [i])) {
+ value = null;
+ return false;
}
- ret [i++] = v;
}
- return ret;
+ value = ret;
+ return true;
}
}
@@ -6794,7 +6797,7 @@ namespace Mono.CSharp {
/// Implements the typeof operator
/// </summary>
public class TypeOf : Expression {
- public Expression QueriedType;
+ readonly Expression QueriedType;
protected Type typearg;
public TypeOf (Expression queried_type, Location l)
@@ -6834,8 +6837,10 @@ namespace Mono.CSharp {
ec.ig.Emit (OpCodes.Call, TypeManager.system_type_get_type_from_handle);
}
- public Type TypeArg {
- get { return typearg; }
+ public override bool GetAttributableValue (out object value)
+ {
+ value = typearg;
+ return true;
}
}
diff --git a/mcs/mcs/typemanager.cs b/mcs/mcs/typemanager.cs
index f132af41948..e797fd0c0e2 100644
--- a/mcs/mcs/typemanager.cs
+++ b/mcs/mcs/typemanager.cs
@@ -244,7 +244,9 @@ public class TypeManager {
public static Hashtable AllClsTopLevelTypes;
static Hashtable fieldbuilders_to_fields;
+ static Hashtable propertybuilder_to_property;
static Hashtable fields;
+ static Hashtable events;
struct Signature {
public string name;
@@ -266,6 +268,7 @@ public class TypeManager {
events = null;
priv_fields_events = null;
type_hash = null;
+ propertybuilder_to_property = null;
TypeHandle.CleanUp ();
}
@@ -360,6 +363,7 @@ public class TypeManager {
builder_to_ifaces = new PtrHashtable ();
fieldbuilders_to_fields = new Hashtable ();
+ propertybuilder_to_property = new Hashtable ();
fields = new Hashtable ();
type_hash = new DoubleHash ();
@@ -1553,6 +1557,16 @@ public class TypeManager {
return (IConstant)fields [fb];
}
+ public static void RegisterProperty (PropertyInfo pi, PropertyBase pb)
+ {
+ propertybuilder_to_property.Add (pi, pb);
+ }
+
+ public static PropertyBase GetProperty (PropertyInfo pi)
+ {
+ return (PropertyBase)propertybuilder_to_property [pi];
+ }
+
static public bool RegisterFieldBase (FieldBuilder fb, FieldBase f)
{
if (fieldbuilders_to_fields.Contains (fb))
@@ -1572,8 +1586,6 @@ public class TypeManager {
return (FieldBase) fieldbuilders_to_fields [fb];
}
- static Hashtable events;
-
static public void RegisterEvent (MyEventBuilder eb, MethodBase add, MethodBase remove)
{
if (events == null)