3using System.Reflection;
16 private IDictionary<string, object> dictionary;
19 private Dictionary<string, PropertyRecord> properties =
null;
20 private readonly
bool readOnly;
22 private class PropertyRecord
24 public PropertyInfo Property;
25 public ParameterInfo[] IndexArguments;
26 public FieldInfo Field;
27 public int NrIndexParameters;
28 public bool IsStringIndex;
30 public PropertyRecord(PropertyInfo Property, FieldInfo Field)
32 this.Property = Property;
34 this.IndexArguments =
null;
35 this.NrIndexParameters = 0;
36 this.IsStringIndex =
false;
39 public PropertyRecord(PropertyInfo Property, FieldInfo Field, ParameterInfo[] IndexArguments)
41 this.Property = Property;
43 this.IndexArguments = IndexArguments;
45 if (IndexArguments is
null)
47 this.NrIndexParameters = 0;
48 this.IsStringIndex =
false;
52 this.NrIndexParameters = this.IndexArguments.Length;
53 this.IsStringIndex = this.NrIndexParameters == 1 &&
54 this.IndexArguments[0].ParameterType == typeof(
string);
58 public object[] GetIndexArguments(
string Name)
60 if (this.IsStringIndex)
61 return new object[] { Name };
65 return new object[] { Converted };
89 this.obj = E.AssociatedObjectValue;
93 this.dictionary = this.obj as IDictionary<string, object>;
94 this.type = this.obj.GetType();
95 this.readOnly = ReadOnly;
109 this.obj = E.AssociatedObjectValue;
113 this.dictionary = this.obj as IDictionary<string, object>;
115 Type T = this.obj.GetType();
120 this.properties?.Clear();
132 if (!(this.dictionary is
null) && this.dictionary.ContainsKey(Name))
135 if (base.ContainsVariable(Name) ||
string.Compare(Name,
"this",
true) == 0)
140 if (this.properties is
null)
141 this.properties =
new Dictionary<string, PropertyRecord>();
143 if (this.properties.TryGetValue(Name, out PropertyRecord Rec))
145 if (Rec.NrIndexParameters == 1)
158 return !(Rec is
null);
161 PropertyInfo PI = this.type.GetRuntimeProperty(Name);
166 FI = this.type.GetRuntimeField(Name);
168 if (!(FI is
null) && !FI.IsPublic)
170 this.properties[Name] =
null;
178 if (!PI.CanRead || !PI.CanWrite || !PI.GetMethod.IsPublic || !PI.SetMethod.IsPublic)
180 this.properties[Name] =
null;
185 if (PI is
null && FI is
null)
188 out ParameterInfo[] IndexArguments))
190 this.properties[Name] =
new PropertyRecord(PI, FI, IndexArguments);
195 this.properties[Name] =
null;
201 this.properties[Name] =
new PropertyRecord(PI, FI);
217 if (
string.Compare(Name,
"this",
true) == 0)
219 Variable = this.CreateVariable(
"this", this.obj);
223 if (!(this.dictionary is
null) && this.dictionary.TryGetValue(Name, out
object Value))
225 Variable = this.CreateVariable(Name, Value);
231 if (this.properties is
null)
232 this.properties =
new Dictionary<string, PropertyRecord>();
234 if (!this.properties.TryGetValue(Name, out Rec))
236 PropertyInfo PI = this.type.GetRuntimeProperty(Name);
241 FI = this.type.GetRuntimeField(Name);
243 if (!(FI is
null) && !FI.IsPublic)
250 if (!PI.CanRead || !PI.CanWrite || !PI.GetMethod.IsPublic || !PI.SetMethod.IsPublic)
254 if (PI is
null && FI is
null)
256 if (this.dictionary is
null)
259 out ParameterInfo[] IndexArguments))
261 Rec =
new PropertyRecord(PI, FI, IndexArguments);
270 Rec =
new PropertyRecord(PI, FI);
272 this.properties[Name] = Rec;
282 if (Rec.Property is
null)
284 else if (Rec.NrIndexParameters == 1)
290 catch (KeyNotFoundException)
309 Variable = this.CreateVariable(Name, Value);
314 if (base.TryGetVariable(Name, out
Variable))
317 Variable = Result ? this.CreateVariable(Name,
null) :
null;
331 if (
string.Compare(Name,
"this",
true) == 0)
337 if (!(this.dictionary is
null) && this.dictionary.TryGetValue(Name, out Value))
342 if (this.properties is
null)
343 this.properties =
new Dictionary<string, PropertyRecord>();
345 if (!this.properties.TryGetValue(Name, out Rec))
347 PropertyInfo PI = this.type.GetRuntimeProperty(Name);
352 FI = this.type.GetRuntimeField(Name);
354 if (!(FI is
null) && !FI.IsPublic)
361 if (!PI.CanRead || !PI.CanWrite || !PI.GetMethod.IsPublic || !PI.SetMethod.IsPublic)
365 if (PI is
null && FI is
null)
367 if (this.dictionary is
null)
370 out ParameterInfo[] IndexArguments))
372 Rec =
new PropertyRecord(PI, FI, IndexArguments);
381 Rec =
new PropertyRecord(PI, FI);
383 this.properties[Name] = Rec;
393 if (Rec.Property is
null)
395 else if (Rec.NrIndexParameters == 1)
401 catch (KeyNotFoundException)
410 if (!(Value is
null))
424 private Variable CreateVariable(
string Name,
object Value)
427 return new Variable(Name, Cis.Value);
441 if (this.readOnly ||
string.Compare(Name,
"this",
true) == 0)
442 return base.Add(Name, Value);
446 if (!(this.dictionary is
null))
448 this.dictionary[Name] = Value is
IElement Element ? Element.AssociatedObjectValue : Value;
454 if (this.properties is
null)
455 this.properties =
new Dictionary<string, PropertyRecord>();
457 if (!this.properties.TryGetValue(Name, out Rec))
459 PropertyInfo PI = this.type.GetRuntimeProperty(Name);
464 FI = this.type.GetRuntimeField(Name);
466 if (!(FI is
null) && !FI.IsPublic)
473 if (!PI.CanRead || !PI.CanWrite || !PI.GetMethod.IsPublic || !PI.SetMethod.IsPublic)
477 if (PI is
null && FI is
null)
480 out ParameterInfo[] IndexArguments))
482 Rec =
new PropertyRecord(PI, FI, IndexArguments);
488 Rec =
new PropertyRecord(PI, FI);
490 this.properties[Name] = Rec;
499 if (Rec.Property is
null)
501 Type ValueType = Value?.GetType() ?? typeof(
object);
502 Type FieldType = Rec.Field.FieldType;
504 if (!FieldType.IsAssignableFrom(ValueType.GetTypeInfo()))
507 Rec.Field.SetValue(this.obj, Value);
511 if (!Rec.Property.CanWrite)
512 throw new InvalidOperationException(
"Property cannot be set.");
513 else if (!Rec.Property.SetMethod.IsPublic)
514 throw new InvalidOperationException(
"Property not accessible.");
517 Type ValueType = Value?.GetType() ?? typeof(
object);
518 Type PropertyType = Rec.Property.PropertyType;
520 if (!PropertyType.IsAssignableFrom(ValueType.GetTypeInfo()))
523 if (Rec.NrIndexParameters == 1)
524 Rec.Property.SetValue(this.obj, Value, Rec.GetIndexArguments(Name));
526 Rec.Property.SetValue(this.obj, Value);
536 return base.Add(Name, Value);
Represents a case-insensitive string.
Base class for all types of elements.
abstract object AssociatedObjectValue
Associated object value.
Class managing a script expression.
static bool TryGetConstant(string Name, Variables Variables, out IElement ValueElement)
Tries to get a constant value, given its name.
static object ConvertTo(IElement Value, Type DesiredType, ScriptNode Node)
Tries to conevert an element value to a desired type.
Represents a constant element value.
Base class for all nodes in a parsed script tree.
static object UnnestPossibleTaskSync(object Result)
Checks if Result is an asynchronous results. If so, blocks the current thread until the result is co...
static bool TryGetIndexProperty(Type T, bool ForReading, bool ForWriting, out PropertyInfo PropertyInfo, out ParameterInfo[] Parameters)
Tries to get a one-dimensional index property of a Type.
override Variable Add(string Name, object Value)
Adds a variable to the collection.
object Object
Current object.
bool TryGetValue(string Name, out object Value)
Tries to get the value, given its variable name.
ObjectProperties(object Object, Variables ContextVariables)
Object properties.
ObjectProperties(object Object, Variables ContextVariables, bool ReadOnly)
Object properties.
override bool TryGetVariable(string Name, out Variable Variable)
Tries to get a variable object, given its name.
override bool ContainsVariable(string Name)
If the collection contains a variable with a given name.
Contains information about a variable.
object ValueObject
Object Value of variable.
IContextVariables ContextVariables
Variables available during the current context.
Dictionary< string, Variable > variables
Internal set of variables.
Basic interface for all types of elements.
bool ContainsVariable(string Name)
If the collection contains a variable with a given name.
Variable Add(string Name, object Value)
Adds a variable to the collection.