private void Reflect(Scriptable scope, bool includeProtected, bool includePrivate) { // We reflect methods first, because we want overloaded field/method // names to be allocated to the NativeJavaMethod before the field // gets in the way. MethodInfo[] methods = DiscoverAccessibleMethods(cl, includeProtected, includePrivate); foreach (MethodInfo method in methods) { int mods = method.Attributes; bool isStatic = Modifier.IsStatic(mods); IDictionary<string, object> ht = isStatic ? staticMembers : members; string name = method.Name; object value = ht.Get(name); if (value == null) { ht.Put(name, method); } else { ObjArray overloadedMethods; if (value is ObjArray) { overloadedMethods = (ObjArray)value; } else { if (!(value is MethodInfo)) { Kit.CodeBug(); } // value should be instance of Method as at this stage // staticMembers and members can only contain methods overloadedMethods = new ObjArray(); overloadedMethods.Add(value); ht.Put(name, overloadedMethods); } overloadedMethods.Add(method); } } // replace Method instances by wrapped NativeJavaMethod objects // first in staticMembers and then in members for (int tableCursor = 0; tableCursor != 2; ++tableCursor) { bool isStatic = (tableCursor == 0); IDictionary<string, object> ht = isStatic ? staticMembers : members; foreach (KeyValuePair<string, object> entry in ht.EntrySet()) { MemberBox[] methodBoxes; object value = entry.Value; if (value is MethodInfo) { methodBoxes = new MemberBox[1]; methodBoxes[0] = new MemberBox((MethodInfo)value); } else { ObjArray overloadedMethods = (ObjArray)value; int N = overloadedMethods.Size(); if (N < 2) { Kit.CodeBug(); } methodBoxes = new MemberBox[N]; for (int i = 0; i != N; ++i) { MethodInfo method_1 = (MethodInfo)overloadedMethods.Get(i); methodBoxes[i] = new MemberBox(method_1); } } NativeJavaMethod fun = new NativeJavaMethod(methodBoxes); if (scope != null) { ScriptRuntime.SetFunctionProtoAndParent(fun, scope); } ht.Put(entry.Key, fun); } } // Reflect fields. FieldInfo[] fields = GetAccessibleFields(includeProtected, includePrivate); foreach (FieldInfo field in fields) { string name = field.Name; int mods = field.Attributes; try { bool isStatic = Modifier.IsStatic(mods); IDictionary<string, object> ht = isStatic ? staticMembers : members; object member = ht.Get(name); if (member == null) { ht.Put(name, field); } else { if (member is NativeJavaMethod) { NativeJavaMethod method_1 = (NativeJavaMethod)member; FieldAndMethods fam = new FieldAndMethods(scope, method_1.methods, field); IDictionary<string, FieldAndMethods> fmht = isStatic ? staticFieldAndMethods : fieldAndMethods; if (fmht == null) { fmht = new Dictionary<string, FieldAndMethods>(); if (isStatic) { staticFieldAndMethods = fmht; } else { fieldAndMethods = fmht; } } fmht.Put(name, fam); ht.Put(name, fam); } else { if (member is FieldInfo) { FieldInfo oldField = (FieldInfo)member; // If this newly reflected field shadows an inherited field, // then replace it. Otherwise, since access to the field // would be ambiguous from Java, no field should be // reflected. // For now, the first field found wins, unless another field // explicitly shadows it. if (oldField.DeclaringType.IsAssignableFrom(field.DeclaringType)) { ht.Put(name, field); } } else { // "unknown member type" Kit.CodeBug(); } } } } catch (SecurityException) { // skip this field Context.ReportWarning("Could not access field " + name + " of class " + cl.FullName + " due to lack of privileges."); } } // Create bean properties from corresponding get/set methods first for // static members and then for instance members for (int tableCursor_1 = 0; tableCursor_1 != 2; ++tableCursor_1) { bool isStatic = (tableCursor_1 == 0); IDictionary<string, object> ht = isStatic ? staticMembers : members; IDictionary<string, BeanProperty> toAdd = new Dictionary<string, BeanProperty>(); // Now, For each member, make "bean" properties. foreach (string name in ht.Keys) { // Is this a getter? bool memberIsGetMethod = name.StartsWith("get"); bool memberIsSetMethod = name.StartsWith("set"); bool memberIsIsMethod = name.StartsWith("is"); if (memberIsGetMethod || memberIsIsMethod || memberIsSetMethod) { // Double check name component. string nameComponent = Sharpen.Runtime.Substring(name, memberIsIsMethod ? 2 : 3); if (nameComponent.Length == 0) { continue; } // Make the bean property name. string beanPropertyName = nameComponent; char ch0 = nameComponent[0]; if (System.Char.IsUpper(ch0)) { if (nameComponent.Length == 1) { beanPropertyName = nameComponent.ToLower(); } else { char ch1 = nameComponent[1]; if (!System.Char.IsUpper(ch1)) { beanPropertyName = System.Char.ToLower(ch0) + Sharpen.Runtime.Substring(nameComponent, 1); } } } // If we already have a member by this name, don't do this // property. if (toAdd.ContainsKey(beanPropertyName)) { continue; } object v = ht.Get(beanPropertyName); if (v != null) { // A private field shouldn't mask a public getter/setter if (!includePrivate || !(v is MemberInfo) || !Modifier.IsPrivate(((MemberInfo)v).Attributes)) { continue; } } // Find the getter method, or if there is none, the is- // method. MemberBox getter = null; getter = FindGetter(isStatic, ht, "get", nameComponent); // If there was no valid getter, check for an is- method. if (getter == null) { getter = FindGetter(isStatic, ht, "is", nameComponent); } // setter MemberBox setter = null; NativeJavaMethod setters = null; string setterName = System.String.Concat("set", nameComponent); if (ht.ContainsKey(setterName)) { // Is this value a method? object member = ht.Get(setterName); if (member is NativeJavaMethod) { NativeJavaMethod njmSet = (NativeJavaMethod)member; if (getter != null) { // We have a getter. Now, do we have a matching // setter? Type type = getter.Method().ReturnType; setter = ExtractSetMethod(type, njmSet.methods, isStatic); } else { // No getter, find any set method setter = ExtractSetMethod(njmSet.methods, isStatic); } if (njmSet.methods.Length > 1) { setters = njmSet; } } } // Make the property. BeanProperty bp = new BeanProperty(getter, setter, setters); toAdd.Put(beanPropertyName, bp); } } // Add the new bean properties. foreach (string key in toAdd.Keys) { object value = toAdd.Get(key); ht.Put(key, value); } } // Reflect constructors ConstructorInfo<object>[] constructors = GetAccessibleConstructors(includePrivate); MemberBox[] ctorMembers = new MemberBox[constructors.Length]; for (int i_1 = 0; i_1 != constructors.Length; ++i_1) { ctorMembers[i_1] = new MemberBox(constructors[i_1]); } ctors = new NativeJavaMethod(ctorMembers, cl.Name); }
internal BeanProperty(MemberBox getter, MemberBox setter, NativeJavaMethod setters) { this.getter = getter; this.setter = setter; this.setters = setters; }
private object GetExplicitFunction(Scriptable scope, string name, object javaObject, bool isStatic) { IDictionary<string, object> ht = isStatic ? staticMembers : members; object member = null; MemberBox methodOrCtor = FindExplicitFunction(name, isStatic); if (methodOrCtor != null) { Scriptable prototype = ScriptableObject.GetFunctionPrototype(scope); if (methodOrCtor.IsCtor()) { NativeJavaConstructor fun = new NativeJavaConstructor(methodOrCtor); fun.SetPrototype(prototype); member = fun; ht.Put(name, fun); } else { string trueName = methodOrCtor.GetName(); member = ht.Get(trueName); if (member is NativeJavaMethod && ((NativeJavaMethod)member).methods.Length > 1) { NativeJavaMethod fun = new NativeJavaMethod(methodOrCtor, name); fun.SetPrototype(prototype); ht.Put(name, fun); member = fun; } } } return member; }