6161
6262using System ;
6363using System . Diagnostics . CodeAnalysis ;
64+ using System . Dynamic ;
6465using System . Globalization ;
6566using System . Linq ;
67+ using System . Linq . Expressions ;
6668using Microsoft . ClearScript . Util ;
6769
6870namespace Microsoft . ClearScript
@@ -100,9 +102,9 @@ public HostFunctions()
100102 /// </summary>
101103 /// <returns>A new empty host object.</returns>
102104 /// <remarks>
103- /// This function is provided for script languages that support "expando" functionality.
104- /// It creates an object that supports dynamic property addition and removal. The host
105- /// can manipulate it via the <see cref="IPropertyBag"/> interface.
105+ /// This function is provided for script languages that do not support external
106+ /// instantiation. It creates an object that supports dynamic property addition and
107+ /// removal. The host can manipulate it via the <see cref="IPropertyBag"/> interface.
106108 /// </remarks>
107109 /// <example>
108110 /// The following code creates an empty host object and adds several properties to it.
@@ -127,8 +129,9 @@ public PropertyBag newObj()
127129 /// <param name="args">Optional constructor arguments.</param>
128130 /// <returns>A new host object of the specified type.</returns>
129131 /// <remarks>
130- /// For information about the mapping between host members and script-callable properties
131- /// and methods, see
132+ /// This function is provided for script languages that do not support external
133+ /// instantiation. For information about the mapping between host members and script-
134+ /// callable properties and methods, see
132135 /// <see cref="ScriptEngine.AddHostObject(string, HostItemFlags, object)">AddHostObject</see>.
133136 /// </remarks>
134137 /// <example>
@@ -151,6 +154,29 @@ public T newObj<T>(params object[] args)
151154 return ( T ) typeof ( T ) . CreateInstance ( args ) ;
152155 }
153156
157+ /// <summary>
158+ /// Performs dynamic instantiation.
159+ /// </summary>
160+ /// <param name="target">The dynamic host object that provides the instantiation operation to perform.</param>
161+ /// <param name="args">Optional instantiation arguments.</param>
162+ /// <returns>The result of the operation, which is usually a new dynamic host object.</returns>
163+ /// <remarks>
164+ /// This function is provided for script languages that do not support external
165+ /// instantiation.
166+ /// </remarks>
167+ public object newObj ( IDynamicMetaObjectProvider target , params object [ ] args )
168+ {
169+ MiscHelpers . VerifyNonNullArgument ( target , "target" ) ;
170+
171+ object result ;
172+ if ( target . GetMetaObject ( Expression . Constant ( target ) ) . TryCreateInstance ( args , out result ) )
173+ {
174+ return result ;
175+ }
176+
177+ throw new InvalidOperationException ( "Invalid dynamic instantiation" ) ;
178+ }
179+
154180 /// <summary>
155181 /// Creates a host array.
156182 /// </summary>
@@ -1000,6 +1026,209 @@ public object toDecimal(IConvertible value)
10001026 return HostObject . Wrap ( Convert . ToDecimal ( value ) ) ;
10011027 }
10021028
1029+ /// <summary>
1030+ /// Gets the value of a property in a dynamic host object that implements <see cref="IPropertyBag"/>.
1031+ /// </summary>
1032+ /// <param name="target">The dynamic host object that contains the property to get.</param>
1033+ /// <param name="name">The name of the property to get.</param>
1034+ /// <returns>The value of the specified property.</returns>
1035+ /// <remarks>
1036+ /// This function is provided for script languages that do not support dynamic properties.
1037+ /// </remarks>
1038+ public object getProperty ( IPropertyBag target , string name )
1039+ {
1040+ MiscHelpers . VerifyNonNullArgument ( target , "target" ) ;
1041+
1042+ object result ;
1043+ if ( target . TryGetValue ( name , out result ) )
1044+ {
1045+ return result ;
1046+ }
1047+
1048+ return Nonexistent . Value ;
1049+ }
1050+
1051+ /// <summary>
1052+ /// Sets a property value in a dynamic host object that implements <see cref="IPropertyBag"/>.
1053+ /// </summary>
1054+ /// <param name="target">The dynamic host object that contains the property to set.</param>
1055+ /// <param name="name">The name of the property to set.</param>
1056+ /// <param name="value">The new value of the specified property.</param>
1057+ /// <returns>The result of the operation, which is usually the value assigned to the specified property.</returns>
1058+ /// <remarks>
1059+ /// This function is provided for script languages that do not support dynamic properties.
1060+ /// </remarks>
1061+ public object setProperty ( IPropertyBag target , string name , object value )
1062+ {
1063+ MiscHelpers . VerifyNonNullArgument ( target , "target" ) ;
1064+ return target [ name ] = value ;
1065+ }
1066+
1067+ /// <summary>
1068+ /// Removes a property from a dynamic host object that implements <see cref="IPropertyBag"/>.
1069+ /// </summary>
1070+ /// <param name="target">The dynamic host object that contains the property to remove.</param>
1071+ /// <param name="name">The name of the property to remove.</param>
1072+ /// <returns><c>True</c> if the property was found and removed, <c>false</c> otherwise.</returns>
1073+ /// <remarks>
1074+ /// This function is provided for script languages that do not support dynamic properties.
1075+ /// </remarks>
1076+ public bool removeProperty ( IPropertyBag target , string name )
1077+ {
1078+ MiscHelpers . VerifyNonNullArgument ( target , "target" ) ;
1079+ return target . Remove ( name ) ;
1080+ }
1081+
1082+ /// <summary>
1083+ /// Gets the value of a property in a dynamic host object that implements <see cref="IDynamicMetaObjectProvider"/>.
1084+ /// </summary>
1085+ /// <param name="target">The dynamic host object that contains the property to get.</param>
1086+ /// <param name="name">The name of the property to get.</param>
1087+ /// <returns>The value of the specified property.</returns>
1088+ /// <remarks>
1089+ /// This function is provided for script languages that do not support dynamic properties.
1090+ /// </remarks>
1091+ public object getProperty ( IDynamicMetaObjectProvider target , string name )
1092+ {
1093+ MiscHelpers . VerifyNonNullArgument ( target , "target" ) ;
1094+
1095+ object result ;
1096+ if ( target . GetMetaObject ( Expression . Constant ( target ) ) . TryGetMember ( name , out result ) )
1097+ {
1098+ return result ;
1099+ }
1100+
1101+ return Nonexistent . Value ;
1102+ }
1103+
1104+ /// <summary>
1105+ /// Sets a property value in a dynamic host object that implements <see cref="IDynamicMetaObjectProvider"/>.
1106+ /// </summary>
1107+ /// <param name="target">The dynamic host object that contains the property to set.</param>
1108+ /// <param name="name">The name of the property to set.</param>
1109+ /// <param name="value">The new value of the specified property.</param>
1110+ /// <returns>The result of the operation, which is usually the value assigned to the specified property.</returns>
1111+ /// <remarks>
1112+ /// This function is provided for script languages that do not support dynamic properties.
1113+ /// </remarks>
1114+ public object setProperty ( IDynamicMetaObjectProvider target , string name , object value )
1115+ {
1116+ MiscHelpers . VerifyNonNullArgument ( target , "target" ) ;
1117+
1118+ object result ;
1119+ if ( target . GetMetaObject ( Expression . Constant ( target ) ) . TrySetMember ( name , value , out result ) )
1120+ {
1121+ return result ;
1122+ }
1123+
1124+ throw new InvalidOperationException ( "Invalid dynamic property assignment" ) ;
1125+ }
1126+
1127+ /// <summary>
1128+ /// Removes a property from a dynamic host object that implements <see cref="IDynamicMetaObjectProvider"/>.
1129+ /// </summary>
1130+ /// <param name="target">The dynamic host object that contains the property to remove.</param>
1131+ /// <param name="name">The name of the property to remove.</param>
1132+ /// <returns><c>True</c> if the property was found and removed, <c>false</c> otherwise.</returns>
1133+ /// <remarks>
1134+ /// This function is provided for script languages that do not support dynamic properties.
1135+ /// </remarks>
1136+ public bool removeProperty ( IDynamicMetaObjectProvider target , string name )
1137+ {
1138+ MiscHelpers . VerifyNonNullArgument ( target , "target" ) ;
1139+
1140+ bool result ;
1141+ if ( target . GetMetaObject ( Expression . Constant ( target ) ) . TryDeleteMember ( name , out result ) )
1142+ {
1143+ return result ;
1144+ }
1145+
1146+ throw new InvalidOperationException ( "Invalid dynamic property deletion" ) ;
1147+ }
1148+
1149+ /// <summary>
1150+ /// Gets the value of an element in a dynamic host object that implements <see cref="IDynamicMetaObjectProvider"/>.
1151+ /// </summary>
1152+ /// <param name="target">The dynamic host object that contains the element to get.</param>
1153+ /// <param name="indices">One or more indices that identify the element to get.</param>
1154+ /// <returns>The value of the specified element.</returns>
1155+ /// <remarks>
1156+ /// This function is provided for script languages that do not support general indexing.
1157+ /// </remarks>
1158+ public object getElement ( IDynamicMetaObjectProvider target , params object [ ] indices )
1159+ {
1160+ MiscHelpers . VerifyNonNullArgument ( target , "target" ) ;
1161+
1162+ object result ;
1163+ if ( target . GetMetaObject ( Expression . Constant ( target ) ) . TryGetIndex ( indices , out result ) )
1164+ {
1165+ return result ;
1166+ }
1167+
1168+ return Nonexistent . Value ;
1169+
1170+ }
1171+
1172+ /// <summary>
1173+ /// Sets an element value in a dynamic host object that implements <see cref="IDynamicMetaObjectProvider"/>.
1174+ /// </summary>
1175+ /// <param name="target">The dynamic host object that contains the element to set.</param>
1176+ /// <param name="value">The new value of the element.</param>
1177+ /// <param name="indices">One or more indices that identify the element to set.</param>
1178+ /// <returns>The result of the operation, which is usually the value assigned to the specified element.</returns>
1179+ /// <remarks>
1180+ /// This function is provided for script languages that do not support general indexing.
1181+ /// </remarks>
1182+ public object setElement ( IDynamicMetaObjectProvider target , object value , params object [ ] indices )
1183+ {
1184+ MiscHelpers . VerifyNonNullArgument ( target , "target" ) ;
1185+
1186+ object result ;
1187+ if ( target . GetMetaObject ( Expression . Constant ( target ) ) . TrySetIndex ( indices , value , out result ) )
1188+ {
1189+ return result ;
1190+ }
1191+
1192+ throw new InvalidOperationException ( "Invalid dynamic element assignment" ) ;
1193+ }
1194+
1195+ /// <summary>
1196+ /// Removes an element from a dynamic host object that implements <see cref="IDynamicMetaObjectProvider"/>.
1197+ /// </summary>
1198+ /// <param name="target">The dynamic host object that contains the element to remove.</param>
1199+ /// <param name="indices">One or more indices that identify the element to remove.</param>
1200+ /// <returns><c>True</c> if the element was found and removed, <c>false</c> otherwise.</returns>
1201+ /// <remarks>
1202+ /// This function is provided for script languages that do not support general indexing.
1203+ /// </remarks>
1204+ public bool removeElement ( IDynamicMetaObjectProvider target , params object [ ] indices )
1205+ {
1206+ MiscHelpers . VerifyNonNullArgument ( target , "target" ) ;
1207+
1208+ bool result ;
1209+ if ( target . GetMetaObject ( Expression . Constant ( target ) ) . TryDeleteIndex ( indices , out result ) )
1210+ {
1211+ return result ;
1212+ }
1213+
1214+ throw new InvalidOperationException ( "Invalid dynamic element deletion" ) ;
1215+ }
1216+
1217+ /// <summary>
1218+ /// Casts a dynamic host object to its static type.
1219+ /// </summary>
1220+ /// <param name="value">The object to cast to its static type.</param>
1221+ /// <returns>The specified object in its static type form, stripped of its dynamic members.</returns>
1222+ /// <remarks>
1223+ /// A dynamic host object that implements <see cref="IDynamicMetaObjectProvider"/> may have
1224+ /// dynamic members that override members of its static type. This function can be used to
1225+ /// gain access to type members overridden in this manner.
1226+ /// </remarks>
1227+ public object toStaticType ( IDynamicMetaObjectProvider value )
1228+ {
1229+ return HostItem . Wrap ( GetEngine ( ) , value , HostItemFlags . HideDynamicMembers ) ;
1230+ }
1231+
10031232 // ReSharper restore InconsistentNaming
10041233
10051234 #endregion
0 commit comments