namespace Mono.CSharp {
+ public interface GenericConstraints {
+ bool HasConstructor { get; }
+ bool IsReferenceType { get; }
+ bool IsValueType { get; }
+ bool HasClassConstraint { get; }
+ Type ClassConstraint { get; }
+ Type[] InterfaceConstraints { get; }
+ }
+
public interface ParameterData {
Type ParameterType (int pos);
+ GenericConstraints GenericConstraints (int pos);
bool HasArrayParameter { get; }
int Count { get; }
string ParameterName (int pos);
public class ReflectionParameters : ParameterData {
ParameterInfo [] pi;
bool last_arg_is_params = false;
-
+ ParameterData gpd;
+
public ReflectionParameters (MethodBase method)
{
object [] attrs;
-
+
this.pi = method.GetParameters ();
int count = pi.Length-1;
if (count < 0)
return;
- if (method.HasGenericParameters) {
+ if (method.Mono_IsInflatedMethod) {
MethodInfo generic = method.GetGenericMethodDefinition ();
- ParameterData gpd = Invocation.GetParameterData (generic);
+ gpd = Invocation.GetParameterData (generic);
last_arg_is_params = gpd.HasArrayParameter;
- } else {
- attrs = pi [count].GetCustomAttributes (TypeManager.param_array_type, true);
- if (attrs == null)
- return;
-
- if (attrs.Length == 0)
- return;
-
- last_arg_is_params = true;
+ return;
}
+
+ attrs = pi [count].GetCustomAttributes (TypeManager.param_array_type, true);
+ if (attrs == null)
+ return;
+
+ if (attrs.Length == 0)
+ return;
+
+ last_arg_is_params = true;
}
public bool HasArrayParameter {
}
}
+ public GenericConstraints GenericConstraints (int pos)
+ {
+ if (gpd != null)
+ return gpd.GenericConstraints (pos);
+
+ Type t = ParameterType (pos);
+ if (!t.IsGenericParameter)
+ return null;
+
+ return ReflectionConstraints.Create (t);
+ }
+
public string ParameterName (int pos)
{
if (last_arg_is_params && pos >= pi.Length - 1)
return pi.Length;
}
}
-
+
+ protected class ReflectionConstraints : GenericConstraints
+ {
+ bool has_ctor;
+ bool is_reference_type;
+ bool is_value_type;
+ Type class_constraint;
+ Type[] iface_constraints;
+
+ protected ReflectionConstraints (bool has_ctor, Type class_constr,
+ Type[] iface_constrs)
+ {
+ this.has_ctor = has_ctor;
+ this.class_constraint = class_constr;
+ this.iface_constraints = iface_constrs;
+
+ if (class_constraint != null) {
+ if (class_constraint == TypeManager.object_type)
+ is_reference_type = true;
+ else if (class_constraint == TypeManager.value_type)
+ is_value_type = true;
+ }
+ }
+
+ public static GenericConstraints Create (Type t)
+ {
+ Type class_constr = null;
+ Type[] iface_constrs = t.GetInterfaces ();
+ if (iface_constrs == null)
+ iface_constrs = Type.EmptyTypes;
+ if (t.BaseType != TypeManager.object_type)
+ class_constr = t.BaseType;
+
+ return new ReflectionConstraints (
+ false, class_constr, iface_constrs);
+ }
+
+ public bool HasConstructor {
+ get { return has_ctor; }
+ }
+
+ public bool HasClassConstraint {
+ get { return class_constraint != null; }
+ }
+
+ public bool IsReferenceType {
+ get { return is_reference_type; }
+ }
+
+ public bool IsValueType {
+ get { return is_value_type; }
+ }
+
+ public Type ClassConstraint {
+ get { return class_constraint; }
+ }
+
+ public Type[] InterfaceConstraints {
+ get { return iface_constraints; }
+ }
+ }
}
public class InternalParameters : ParameterData {
return GetParameter (pos).ExternalType ();
}
+ public GenericConstraints GenericConstraints (int pos)
+ {
+ if (param_types == null)
+ return null;
+
+ return GetParameter (pos).GenericConstraints;
+ }
public string ParameterName (int pos)
{
{
this.reader = reader;
this.buffer = new char [DefaultCacheSize];
+
+ // Compute the preamble size
+
+ // Let the StreamWriter autodetect the encoder
+ reader.Peek ();
+
+ reader.BaseStream.Position = 0;
+ Encoding enc = reader.CurrentEncoding;
+ // First of all, get at least a char
+
+ byte[] auxb = new byte [50];
+ int num_bytes = 0;
+ int num_chars = 0;
+ int br = 0;
+ do {
+ br = reader.BaseStream.Read (auxb, num_bytes, auxb.Length - num_bytes);
+ num_bytes += br;
+ num_chars = enc.GetCharCount (auxb, 0, num_bytes);
+ }
+ while (num_chars == 0 && br > 0);
+
+ if (num_chars != 0)
+ {
+ // Now, check which bytes at the beginning have no effect in the
+ // char count
+
+ int p = 0;
+ while (enc.GetCharCount (auxb, p, num_bytes-p) >= num_chars)
+ p++;
+
+ preamble_size = p - 1;
+ reader.BaseStream.Position = 0;
+ reader.DiscardBufferedData ();
+
+ buffer_start = preamble_size;
+ }
}
public SeekableStreamReader (Stream stream, Encoding encoding, bool detect_encoding_from_bytemarks)
int buffer_size; // in bytes
int char_count; // count buffer[] valid characters
int pos; // index into buffer[]
+ int preamble_size;
/// <remarks>
/// The difference to the StreamReader's BaseStream.Position is that this one is reliable; ie. it
return;
}
+
+ if (value == 0) // Skip preamble
+ value = preamble_size;
// Ok, now we need to seek.
reader.DiscardBufferedData ();