2using System.Collections.Generic;
3using System.Reflection;
16 private IDictionary<string, object> dictionary;
19 private Dictionary<string, Tuple<PropertyInfo, FieldInfo, bool>> properties =
null;
20 private readonly
bool readOnly;
42 this.obj = E.AssociatedObjectValue;
46 this.dictionary = this.obj as IDictionary<string, object>;
47 this.type = this.obj.GetType();
48 this.readOnly = ReadOnly;
62 this.obj = E.AssociatedObjectValue;
66 this.dictionary = this.obj as IDictionary<string, object>;
68 Type T = this.obj.GetType();
73 this.properties?.Clear();
85 if (!(this.dictionary is
null) && this.dictionary.ContainsKey(Name))
88 if (base.ContainsVariable(Name) ||
string.Compare(Name,
"this",
true) == 0)
93 if (this.properties is
null)
94 this.properties =
new Dictionary<string, Tuple<PropertyInfo, FieldInfo, bool>>();
96 if (this.properties.TryGetValue(Name, out Tuple<PropertyInfo, FieldInfo, bool> Rec))
111 return !(Rec is
null);
114 PropertyInfo PI = this.type.GetRuntimeProperty(Name);
119 FI = this.type.GetRuntimeField(Name);
121 if (!(FI is
null) && !FI.IsPublic)
123 this.properties[Name] =
null;
131 if (!PI.CanRead || !PI.CanWrite || !PI.GetMethod.IsPublic || !PI.SetMethod.IsPublic)
133 this.properties[Name] =
null;
138 if (PI is
null && FI is
null)
142 this.properties[Name] =
new Tuple<PropertyInfo, FieldInfo, bool>(PI, FI,
true);
147 this.properties[Name] =
null;
153 this.properties[Name] =
new Tuple<PropertyInfo, FieldInfo, bool>(PI, FI,
false);
167 Tuple<PropertyInfo, FieldInfo, bool> Rec;
169 if (
string.Compare(Name,
"this",
true) == 0)
171 Variable = this.CreateVariable(
"this", this.obj);
175 if (!(this.dictionary is
null) && this.dictionary.TryGetValue(Name, out
object Value))
177 Variable = this.CreateVariable(Name, Value);
183 if (this.properties is
null)
184 this.properties =
new Dictionary<string, Tuple<PropertyInfo, FieldInfo, bool>>();
186 if (!this.properties.TryGetValue(Name, out Rec))
188 PropertyInfo PI = this.type.GetRuntimeProperty(Name);
193 FI = this.type.GetRuntimeField(Name);
195 if (!(FI is
null) && !FI.IsPublic)
202 if (!PI.CanRead || !PI.CanWrite || !PI.GetMethod.IsPublic || !PI.SetMethod.IsPublic)
206 if (PI is
null && FI is
null)
208 if (this.dictionary is
null)
211 Rec =
new Tuple<PropertyInfo, FieldInfo, bool>(PI, FI,
true);
219 Rec =
new Tuple<PropertyInfo, FieldInfo, bool>(PI, FI,
false);
221 this.properties[Name] = Rec;
231 if (Rec.Item1 is
null)
239 catch (KeyNotFoundException)
248 if (!(Value is
null))
250 Variable = this.CreateVariable(Name, Value);
255 if (base.TryGetVariable(Name, out
Variable))
258 Variable = Result ? this.CreateVariable(Name,
null) :
null;
270 Tuple<PropertyInfo, FieldInfo, bool> Rec;
272 if (
string.Compare(Name,
"this",
true) == 0)
278 if (!(this.dictionary is
null) && this.dictionary.TryGetValue(Name, out Value))
283 if (this.properties is
null)
284 this.properties =
new Dictionary<string, Tuple<PropertyInfo, FieldInfo, bool>>();
286 if (!this.properties.TryGetValue(Name, out Rec))
288 PropertyInfo PI = this.type.GetRuntimeProperty(Name);
293 FI = this.type.GetRuntimeField(Name);
295 if (!(FI is
null) && !FI.IsPublic)
302 if (!PI.CanRead || !PI.CanWrite || !PI.GetMethod.IsPublic || !PI.SetMethod.IsPublic)
306 if (PI is
null && FI is
null)
308 if (this.dictionary is
null)
311 Rec =
new Tuple<PropertyInfo, FieldInfo, bool>(PI, FI,
true);
319 Rec =
new Tuple<PropertyInfo, FieldInfo, bool>(PI, FI,
false);
321 this.properties[Name] = Rec;
331 if (Rec.Item1 is
null)
339 catch (KeyNotFoundException)
348 if (!(Value is
null))
362 private Variable CreateVariable(
string Name,
object Value)
365 return new Variable(Name, Cis.Value);
379 if (this.readOnly ||
string.Compare(Name,
"this",
true) == 0)
380 return base.Add(Name, Value);
382 Tuple<PropertyInfo, FieldInfo, bool> Rec;
384 if (!(this.dictionary is
null))
386 this.dictionary[Name] = Value is
IElement Element ? Element.AssociatedObjectValue : Value;
392 if (this.properties is
null)
393 this.properties =
new Dictionary<string, Tuple<PropertyInfo, FieldInfo, bool>>();
395 if (!this.properties.TryGetValue(Name, out Rec))
397 PropertyInfo PI = this.type.GetRuntimeProperty(Name);
402 FI = this.type.GetRuntimeField(Name);
404 if (!(FI is
null) && !FI.IsPublic)
411 if (!PI.CanRead || !PI.CanWrite || !PI.GetMethod.IsPublic || !PI.SetMethod.IsPublic)
415 if (PI is
null && FI is
null)
418 Rec =
new Tuple<PropertyInfo, FieldInfo, bool>(PI, FI,
true);
423 Rec =
new Tuple<PropertyInfo, FieldInfo, bool>(PI, FI,
false);
425 this.properties[Name] = Rec;
434 if (Rec.Item1 is
null)
436 Type ValueType = Value?.GetType() ?? typeof(
object);
437 Type FieldType = Rec.Item2.FieldType;
439 if (!FieldType.GetTypeInfo().IsAssignableFrom(ValueType.GetTypeInfo()))
442 Rec.Item2.SetValue(this.obj, Value);
446 if (!Rec.Item1.CanWrite)
447 throw new InvalidOperationException(
"Property cannot be set.");
448 else if (!Rec.Item1.SetMethod.IsPublic)
449 throw new InvalidOperationException(
"Property not accessible.");
452 Type ValueType = Value?.GetType() ?? typeof(
object);
453 Type PropertyType = Rec.Item1.PropertyType;
455 if (!PropertyType.GetTypeInfo().IsAssignableFrom(ValueType.GetTypeInfo()))
459 Rec.Item1.SetValue(this.obj, Value,
new object[] { Name });
461 Rec.Item1.SetValue(this.obj, Value);
471 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 object ConvertTo(IElement Value, Type DesiredType, ScriptNode Node)
Tries to conevert an element value to a desired type.
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.