Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
DynamicMemberAssignment.cs
1using System;
2using System.Reflection;
3using System.Threading.Tasks;
9
11{
16 {
27 {
28 }
29
36 {
37 IElement Left = this.left.Evaluate(Variables);
38 IElement Middle = this.middle.Evaluate(Variables);
39 IElement Right = this.right.Evaluate(Variables);
40
41 if (Middle.IsScalar)
42 return this.Evaluate(Left, Middle, Right);
43 else
44 {
45 foreach (IElement MiddleElement in Middle.ChildElements)
46 this.Evaluate(Left, MiddleElement, Right);
47
48 return Right;
49 }
50 }
51
57 public override async Task<IElement> EvaluateAsync(Variables Variables)
58 {
59 if (!this.isAsync)
60 return this.Evaluate(Variables);
61
62 IElement Left = await this.left.EvaluateAsync(Variables);
63 IElement Middle = await this.middle.EvaluateAsync(Variables);
64 IElement Right = await this.right.EvaluateAsync(Variables);
65
66 if (Middle.IsScalar)
67 return this.Evaluate(Left, Middle, Right);
68 else
69 {
70 foreach (IElement MiddleElement in Middle.ChildElements)
71 this.Evaluate(Left, MiddleElement, Right);
72
73 return Right;
74 }
75 }
76
84 public IElement Evaluate(IElement Left, IElement Middle, IElement Right)
85 {
86 if (!(Middle.AssociatedObjectValue is string Name))
87 throw new ScriptRuntimeException("Member names must be strings.", this);
88
89 object LeftValue = Left.AssociatedObjectValue;
90 Type Type = LeftValue.GetType();
91
92 PropertyInfo Property = Type.GetRuntimeProperty(Name);
93 if (!(Property is null))
94 {
95 if (!Property.CanWrite)
96 throw new ScriptRuntimeException("Property cannot be set: " + Name, this);
97 else if (!Property.SetMethod.IsPublic)
98 throw new ScriptRuntimeException("Property not accessible: " + Name, this);
99 else
100 {
101 Type = Property.PropertyType;
102 if (!Type.IsAssignableFrom(Right.GetType().GetTypeInfo()))
103 Property.SetValue(LeftValue, Expression.ConvertTo(Right, Type, this), null);
104 else
105 Property.SetValue(LeftValue, Right, null);
106 }
107 }
108 else
109 {
110 FieldInfo Field = Type.GetRuntimeField(Name);
111 if (!(Field is null))
112 {
113 if (!Field.IsPublic)
114 throw new ScriptRuntimeException("Field not accessible: " + Name, this);
115 else
116 {
117 Type = Field.FieldType;
118 if (!Type.IsAssignableFrom(Right.GetType().GetTypeInfo()))
119 Field.SetValue(Left, Expression.ConvertTo(Right, Type, this));
120 else
121 Field.SetValue(Left, Right);
122 }
123 }
124 else
125 {
126 if (VectorIndex.TryGetIndexProperty(Type, false, true, out Property,
127 out ParameterInfo[] IndexArguments) &&
128 (IndexArguments?.Length ?? 0) == 1)
129 {
130 object[] Index;
131
132 if (IndexArguments[0].ParameterType == typeof(string))
133 Index = new object[] { Name };
134 else
135 Index = new object[] { Expression.ConvertTo(Name, IndexArguments[0].ParameterType, this) };
136
137 Type = Property.PropertyType;
138 if (Type == typeof(object))
139 Property.SetValue(LeftValue, Right.AssociatedObjectValue, Index);
140 else if (Type.IsAssignableFrom(Right.GetType().GetTypeInfo()))
141 Property.SetValue(LeftValue, Right, Index);
142 else
143 Property.SetValue(LeftValue, Expression.ConvertTo(Right, Type, this), Index);
144 }
145 else
146 throw new ScriptRuntimeException("Member '" + Name + "' not found on type '" + Type.FullName + "'.", this);
147 }
148 }
149
150 return Right;
151 }
152
153 }
154}
Class managing a script expression.
Definition: Expression.cs:41
static object ConvertTo(IElement Value, Type DesiredType, ScriptNode Node)
Tries to conevert an element value to a desired type.
Definition: Expression.cs:5385
ScriptNode RightOperand
Right operand.
ScriptNode LeftOperand
Left operand.
ScriptNode right
Right operand.
ScriptNode left
Left operand.
bool isAsync
If subtree is asynchroneous.
Base class for all nodes in a parsed script tree.
Definition: ScriptNode.cs:69
int Length
Length of expression covered by node.
Definition: ScriptNode.cs:101
int Start
Start position in script expression.
Definition: ScriptNode.cs:92
abstract IElement Evaluate(Variables Variables)
Evaluates the node, using the variables provided in the Variables collection. This method should be ...
virtual Task< IElement > EvaluateAsync(Variables Variables)
Evaluates the node, using the variables provided in the Variables collection. This method should be ...
Definition: ScriptNode.cs:158
Base class for all ternary operators.
ScriptNode middle
Middle operand.
DynamicMemberAssignment(DynamicMember DynamicMember, ScriptNode Operand, int Start, int Length, Expression Expression)
Dynamic member Assignment operator.
override IElement Evaluate(Variables Variables)
Evaluates the node, using the variables provided in the Variables collection.
IElement Evaluate(IElement Left, IElement Middle, IElement Right)
Performs scalar dynamic member assignment.
override async Task< IElement > EvaluateAsync(Variables Variables)
Evaluates the node, using the variables provided in the Variables collection.
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.
Definition: VectorIndex.cs:138
Collection of variables.
Definition: Variables.cs:25
Basic interface for all types of elements.
Definition: IElement.cs:21
object AssociatedObjectValue
Associated object value.
Definition: IElement.cs:34
ICollection< IElement > ChildElements
An enumeration of child elements. If the element is a scalar, this property will return null.
Definition: IElement.cs:50
bool IsScalar
If the element represents a scalar value.
Definition: IElement.cs:42