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); }
/// <summary> /// Helper function for /// <see cref="GetAllFunctions(Rhino.Debug.DebuggableScript)">GetAllFunctions(Rhino.Debug.DebuggableScript)</see> /// . /// </summary> private static void CollectFunctions_r(DebuggableScript function, ObjArray array) { array.Add(function); for (int i = 0; i != function.GetFunctionCount(); ++i) { CollectFunctions_r(function.GetFunction(i), array); } }
private static void CollectScriptNodes_r(ScriptNode n, ObjArray x) { x.Add(n); int nestedCount = n.GetFunctionCount(); for (int i = 0; i != nestedCount; ++i) { CollectScriptNodes_r(n.GetFunctionNode(i), x); } }
private static void BuildStatementList_r(Node node, ObjArray statements) { int type = node.GetType(); if (type == Token.BLOCK || type == Token.LOCAL_BLOCK || type == Token.LOOP || type == Token.FUNCTION) { Node child = node.GetFirstChild(); while (child != null) { BuildStatementList_r(child, statements); child = child.GetNext(); } } else { statements.Add(node); } }
private static Block[] BuildBlocks(Node[] statementNodes) { // a mapping from each target node to the block it begins IDictionary<Node, Block.FatBlock> theTargetBlocks = new Dictionary<Node, Block.FatBlock>(); ObjArray theBlocks = new ObjArray(); // there's a block that starts at index 0 int beginNodeIndex = 0; for (int i = 0; i < statementNodes.Length; i++) { switch (statementNodes[i].GetType()) { case Token.TARGET: { if (i != beginNodeIndex) { Block.FatBlock fb = NewFatBlock(beginNodeIndex, i - 1); if (statementNodes[beginNodeIndex].GetType() == Token.TARGET) { theTargetBlocks.Put(statementNodes[beginNodeIndex], fb); } theBlocks.Add(fb); // start the next block at this node beginNodeIndex = i; } break; } case Token.IFNE: case Token.IFEQ: case Token.GOTO: { Block.FatBlock fb = NewFatBlock(beginNodeIndex, i); if (statementNodes[beginNodeIndex].GetType() == Token.TARGET) { theTargetBlocks.Put(statementNodes[beginNodeIndex], fb); } theBlocks.Add(fb); // start the next block at the next node beginNodeIndex = i + 1; break; } } } if (beginNodeIndex != statementNodes.Length) { Block.FatBlock fb = NewFatBlock(beginNodeIndex, statementNodes.Length - 1); if (statementNodes[beginNodeIndex].GetType() == Token.TARGET) { theTargetBlocks.Put(statementNodes[beginNodeIndex], fb); } theBlocks.Add(fb); } // build successor and predecessor links for (int i_1 = 0; i_1 < theBlocks.Size(); i_1++) { Block.FatBlock fb = (Block.FatBlock)(theBlocks.Get(i_1)); Node blockEndNode = statementNodes[fb.realBlock.itsEndNodeIndex]; int blockEndNodeType = blockEndNode.GetType(); if ((blockEndNodeType != Token.GOTO) && (i_1 < (theBlocks.Size() - 1))) { Block.FatBlock fallThruTarget = (Block.FatBlock)(theBlocks.Get(i_1 + 1)); fb.AddSuccessor(fallThruTarget); fallThruTarget.AddPredecessor(fb); } if ((blockEndNodeType == Token.IFNE) || (blockEndNodeType == Token.IFEQ) || (blockEndNodeType == Token.GOTO)) { Node target = ((Jump)blockEndNode).target; Block.FatBlock branchTargetBlock = theTargetBlocks.Get(target); target.PutProp(Node.TARGETBLOCK_PROP, branchTargetBlock.realBlock); fb.AddSuccessor(branchTargetBlock); branchTargetBlock.AddPredecessor(fb); } } Block[] result = new Block[theBlocks.Size()]; for (int i_2 = 0; i_2 < theBlocks.Size(); i_2++) { Block.FatBlock fb = (Block.FatBlock)(theBlocks.Get(i_2)); Block b = fb.realBlock; b.itsSuccessors = fb.GetSuccessors(); b.itsPredecessors = fb.GetPredecessors(); b.itsBlockID = i_2; result[i_2] = b; } return result; }