public MethodGroup(MethodProxy[] methods) { this.methods = methods; if (methods == null) throw new ArgumentNullException(); var len = 0; for (var i = 0; i < methods.Length; i++) len = System.Math.Max(len, methods[i].parameters.Length); _length = new BaseLibrary.Number(len) { attributes = JSObjectAttributesInternal.ReadOnly | JSObjectAttributesInternal.DoNotDelete | JSObjectAttributesInternal.DoNotEnum }; passCount = 2; // На втором проходе будет выбираться первый метод, // для которого получится сгенерировать параметры по-умолчанию. // Если нужен более строгий подбор, то количество проходов нужно // уменьшить до одного }
public Element(NativeList owner, int index) { this.owner = owner; this.index = index; attributes |= JSObjectAttributesInternal.Reassign; var value = owner.data[index]; valueType = JSObjectType.Undefined; if (value is JSObject) base.Assign(value as JSObject); else if (value is sbyte) { iValue = (int)(sbyte)value; valueType = JSObjectType.Int; } else if (value is byte) { iValue = (int)(byte)value; valueType = JSObjectType.Int; } else if (value is short) { iValue = (int)(short)value; valueType = JSObjectType.Int; } else if (value is ushort) { iValue = (int)(ushort)value; valueType = JSObjectType.Int; } else if (value is int) { iValue = (int)value; valueType = JSObjectType.Int; } else if (value is uint) { dValue = (long)(uint)value; valueType = JSObjectType.Double; } else if (value is long) { dValue = (long)value; valueType = JSObjectType.Double; } else if (value is ulong) { dValue = (double)(ulong)value; valueType = JSObjectType.Double; } else if (value is float) { dValue = (double)(float)value; valueType = JSObjectType.Double; } else if (value is double) { dValue = (double)value; valueType = JSObjectType.Double; } else if (value is string) { oValue = value.ToString(); valueType = JSObjectType.String; } else if (value is char) { oValue = value.ToString(); valueType = JSObjectType.String; } else if (value is bool) { iValue = (bool)value ? 1 : 0; valueType = JSObjectType.Bool; } else if (value is Delegate) { #if PORTABLE oValue = new MethodProxy(((Delegate)value).GetMethodInfo(), ((Delegate)value).Target); #else oValue = new MethodProxy(((Delegate)value).Method, ((Delegate)value).Target); #endif valueType = JSObjectType.Function; } else if (value is IList) { oValue = new NativeList(value as IList); valueType = JSObjectType.Object; } else { var type = value.GetType(); __proto__ = TypeProxy.GetPrototype(type); attributes |= __proto__.attributes & JSObjectAttributesInternal.Immutable; } }
internal protected override JSObject GetMember(JSObject nameObj, bool create, bool own) { string name = nameObj.ToString(); JSObject r = null; if (fields.TryGetValue(name, out r)) { if (r.valueType < JSObjectType.Undefined) { if (!create) { var t = DefaultFieldGetter(nameObj, false, own); if (t.IsExist) r.Assign(t); } } if (create && ((attributes & JSObjectAttributesInternal.Immutable) == 0) && (r.attributes & (JSObjectAttributesInternal.SystemObject | JSObjectAttributesInternal.ReadOnly)) == JSObjectAttributesInternal.SystemObject) fields[name] = r = r.CloneImpl(); return r; } if (members == null) fillMembers(); IList<MemberInfo> m = null; members.TryGetValue(name, out m); if (m == null || m.Count == 0) { var pi = prototypeInstance as JSObject; if (pi != null) return pi.GetMember(nameObj, create, own); else return DefaultFieldGetter(nameObj, create, own); } if (m.Count > 1) { for (int i = 0; i < m.Count; i++) if (!(m[i] is MethodBase)) throw new JSException(Proxy(new TypeError("Incompatible fields type."))); var cache = new MethodProxy[m.Count]; for (int i = 0; i < m.Count; i++) cache[i] = new MethodProxy(m[i] as MethodBase); r = new MethodGroup(cache); } else { #if PORTABLE switch (m[0].get_MemberType()) #else switch (m[0].MemberType) #endif { case MemberTypes.Constructor: throw new InvalidOperationException("Constructor can not be called directly"); case MemberTypes.Method: { var method = (MethodInfo)m[0]; r = new MethodProxy(method); r.attributes &= ~(JSObjectAttributesInternal.ReadOnly | JSObjectAttributesInternal.DoNotDelete | JSObjectAttributesInternal.NotConfigurable | JSObjectAttributesInternal.DoNotEnum); break; } case MemberTypes.Field: { var field = (m[0] as FieldInfo); if ((field.Attributes & (FieldAttributes.Literal | FieldAttributes.InitOnly)) != 0 && (field.Attributes & FieldAttributes.Static) != 0) { r = Proxy(field.GetValue(null)); r.attributes |= JSObjectAttributesInternal.ReadOnly; } else { r = new JSObject() { valueType = JSObjectType.Property, oValue = new PropertyPair ( new ExternalFunction((thisBind, a) => { return Proxy(field.GetValue(field.IsStatic ? null : thisBind.Value)); }), !m[0].IsDefined(typeof(Modules.ReadOnlyAttribute), false) ? new ExternalFunction((thisBind, a) => { field.SetValue(field.IsStatic ? null : thisBind.Value, a[0].Value); return null; }) : null ) }; r.attributes = JSObjectAttributesInternal.Immutable | JSObjectAttributesInternal.Field; if ((r.oValue as PropertyPair).set == null) r.attributes |= JSObjectAttributesInternal.ReadOnly; } break; } case MemberTypes.Property: { var pinfo = (PropertyInfo)m[0]; r = new JSObject() { valueType = JSObjectType.Property, oValue = new PropertyPair ( #if PORTABLE pinfo.CanRead && pinfo.GetMethod != null ? new MethodProxy(pinfo.GetMethod) : null, pinfo.CanWrite && pinfo.SetMethod != null && !pinfo.IsDefined(typeof(ReadOnlyAttribute), false) ? new MethodProxy(pinfo.SetMethod) : null #else pinfo.CanRead && pinfo.GetGetMethod(false) != null ? new MethodProxy(pinfo.GetGetMethod(false)) : null, pinfo.CanWrite && pinfo.GetSetMethod(false) != null && !pinfo.IsDefined(typeof(ReadOnlyAttribute), false) ? new MethodProxy(pinfo.GetSetMethod(false)) : null #endif ) }; r.attributes = JSObjectAttributesInternal.Immutable; if ((r.oValue as PropertyPair).set == null) r.attributes |= JSObjectAttributesInternal.ReadOnly; if (pinfo.IsDefined(typeof(FieldAttribute), false)) r.attributes |= JSObjectAttributesInternal.Field; break; } case MemberTypes.Event: { var pinfo = (EventInfo)m[0]; r = new JSObject() { valueType = JSObjectType.Property, oValue = new PropertyPair ( null, #if PORTABLE new MethodProxy(pinfo.AddMethod) #else new MethodProxy(pinfo.GetAddMethod()) #endif ) }; break; } case MemberTypes.TypeInfo: #if PORTABLE { r = GetConstructor((m[0] as TypeInfo).AsType()); break; } #else case MemberTypes.NestedType: { r = GetConstructor((Type)m[0]); break; } default: throw new NotImplementedException("Convertion from " + m[0].MemberType + " not implemented"); #endif } } if (m[0].IsDefined(typeof(DoNotEnumerateAttribute), false)) r.attributes |= JSObjectAttributesInternal.DoNotEnum; lock (fields) fields[name] = create && (r.attributes & (JSObjectAttributesInternal.ReadOnly | JSObjectAttributesInternal.SystemObject)) == JSObjectAttributesInternal.SystemObject ? (r = r.CloneImpl()) : r; for (var i = m.Count; i-- > 0; ) { if (!m[i].IsDefined(typeof(DoNotEnumerateAttribute), false)) { r.attributes &= ~JSObjectAttributesInternal.DoNotEnum; break; } if (m[i].IsDefined(typeof(ReadOnlyAttribute), false)) r.attributes |= JSObjectAttributesInternal.ReadOnly; if (m[i].IsDefined(typeof(NotConfigurable), false)) r.attributes |= JSObjectAttributesInternal.NotConfigurable; if (m[i].IsDefined(typeof(DoNotDeleteAttribute), false)) r.attributes |= JSObjectAttributesInternal.DoNotDelete; } return r; }