mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-14 10:43:24 +00:00
NativeJavaMethod.add is removed. It allows to assume that after NativeJavaMethod constructor methods array will remain the same, which I will use in the following patch to add caching of Method.getParameterTypes.
Instead of calling NativeJavaMethod.add, JavaMembers assemble the method list directly and then pass it to NativeJavaMethod when done.
This commit is contained in:
parent
2dd779b626
commit
32619aac8e
@ -281,18 +281,50 @@ class JavaMembers
|
||||
boolean isStatic = Modifier.isStatic(mods);
|
||||
Hashtable ht = isStatic ? staticMembers : members;
|
||||
String name = method.getName();
|
||||
NativeJavaMethod fun = (NativeJavaMethod) ht.get(name);
|
||||
if (fun == null) {
|
||||
fun = new NativeJavaMethod(method, name);
|
||||
if (scope != null) {
|
||||
fun.setPrototype(
|
||||
ScriptableObject.getFunctionPrototype(scope));
|
||||
}
|
||||
ht.put(name, fun);
|
||||
Object value = ht.get(name);
|
||||
if (value == null) {
|
||||
ht.put(name, method);
|
||||
} else {
|
||||
fun.add(method);
|
||||
ObjArray overloadedMethods;
|
||||
if (value instanceof ObjArray) {
|
||||
overloadedMethods = (ObjArray)value;
|
||||
} else {
|
||||
if (!(value instanceof Method)) Context.codeBug();
|
||||
// value should be instance of Method as reflectMethods is
|
||||
// called when staticMembers and members are empty
|
||||
overloadedMethods = new ObjArray();
|
||||
overloadedMethods.add(value);
|
||||
ht.put(name, overloadedMethods);
|
||||
}
|
||||
overloadedMethods.add(method);
|
||||
}
|
||||
}
|
||||
initNativeMethods(staticMembers, scope);
|
||||
initNativeMethods(members, scope);
|
||||
}
|
||||
|
||||
private static void initNativeMethods(Hashtable ht, Scriptable scope)
|
||||
{
|
||||
Enumeration e = ht.keys();
|
||||
while (e.hasMoreElements()) {
|
||||
String name = (String)e.nextElement();
|
||||
Method[] methods;
|
||||
Object value = ht.get(name);
|
||||
if (value instanceof Method) {
|
||||
methods = new Method[1];
|
||||
methods[0] = (Method)value;
|
||||
} else {
|
||||
ObjArray overloadedMethods = (ObjArray)value;
|
||||
if (overloadedMethods.size() < 2) Context.codeBug();
|
||||
methods = new Method[overloadedMethods.size()];
|
||||
overloadedMethods.toArray(methods);
|
||||
}
|
||||
NativeJavaMethod fun = new NativeJavaMethod(methods);
|
||||
if (scope != null) {
|
||||
fun.setPrototype(ScriptableObject.getFunctionPrototype(scope));
|
||||
}
|
||||
ht.put(name, fun);
|
||||
}
|
||||
}
|
||||
|
||||
private void reflectFields(Scriptable scope)
|
||||
@ -371,12 +403,16 @@ class JavaMembers
|
||||
|
||||
// Make the bean property name.
|
||||
String beanPropertyName = nameComponent;
|
||||
if (Character.isUpperCase(nameComponent.charAt(0))) {
|
||||
char ch0 = nameComponent.charAt(0);
|
||||
if (Character.isUpperCase(ch0)) {
|
||||
if (nameComponent.length() == 1) {
|
||||
beanPropertyName = nameComponent.substring(0, 1).toLowerCase();
|
||||
} else if (!Character.isUpperCase(nameComponent.charAt(1))) {
|
||||
beanPropertyName = Character.toLowerCase(nameComponent.charAt(0)) +
|
||||
nameComponent.substring(1);
|
||||
beanPropertyName = nameComponent.toLowerCase();
|
||||
} else {
|
||||
char ch1 = nameComponent.charAt(1);
|
||||
if (!Character.isUpperCase(ch1)) {
|
||||
beanPropertyName = Character.toLowerCase(ch0)
|
||||
+nameComponent.substring(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -391,61 +427,25 @@ class JavaMembers
|
||||
continue;
|
||||
NativeJavaMethod getJavaMethod = (NativeJavaMethod) method;
|
||||
|
||||
// Grab and inspect the getter method; does it have an empty parameter list,
|
||||
// with a return value (eg. a getSomething() or isSomething())?
|
||||
Class[] params;
|
||||
Method[] getMethods = getJavaMethod.methods;
|
||||
Class type;
|
||||
if (getMethods != null &&
|
||||
getMethods.length == 1 &&
|
||||
(type = getMethods[0].getReturnType()) != null &&
|
||||
(params = getMethods[0].getParameterTypes()) != null &&
|
||||
params.length == 0)
|
||||
{
|
||||
|
||||
// Make sure the method static-ness is preserved for this property.
|
||||
if (isStatic && !Modifier.isStatic(getMethods[0].getModifiers()))
|
||||
continue;
|
||||
Method getMethod = extractGetMethod(getJavaMethod, isStatic);
|
||||
if (getMethod != null) {
|
||||
|
||||
// We have a getter. Now, do we have a setter?
|
||||
Method setMethod = null;
|
||||
String setter = "set" + nameComponent;
|
||||
String setter = "set".concat(nameComponent);
|
||||
if (ht.containsKey(setter)) {
|
||||
|
||||
// Is this value a method?
|
||||
method = ht.get(setter);
|
||||
if (method instanceof NativeJavaMethod) {
|
||||
|
||||
//
|
||||
// Note: it may be preferable to allow NativeJavaMethod.findFunction()
|
||||
// to find the appropriate setter; unfortunately, it requires an
|
||||
// instance of the target arg to determine that.
|
||||
//
|
||||
|
||||
// Make two passes: one to find a method with direct type assignment,
|
||||
// and one to find a widening conversion.
|
||||
NativeJavaMethod setJavaMethod = (NativeJavaMethod) method;
|
||||
Method[] setMethods = setJavaMethod.methods;
|
||||
for (int pass = 1; pass <= 2 && setMethod == null; ++pass) {
|
||||
for (int i = 0; i < setMethods.length; ++i) {
|
||||
if (setMethods[i].getReturnType() == Void.TYPE &&
|
||||
(!isStatic || Modifier.isStatic(setMethods[i].getModifiers())) &&
|
||||
(params = setMethods[i].getParameterTypes()) != null &&
|
||||
params.length == 1 ) {
|
||||
|
||||
if ((pass == 1 && params[0] == type) ||
|
||||
(pass == 2 && params[0].isAssignableFrom(type))) {
|
||||
setMethod = setMethods[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
NativeJavaMethod njm = (NativeJavaMethod) method;
|
||||
Class type = getMethod.getReturnType();
|
||||
setMethod = extractSetMethod(type, njm, isStatic);
|
||||
}
|
||||
}
|
||||
|
||||
// Make the property.
|
||||
BeanProperty bp = new BeanProperty(getMethods[0], setMethod);
|
||||
BeanProperty bp = new BeanProperty(getMethod, setMethod);
|
||||
toAdd.put(beanPropertyName, bp);
|
||||
}
|
||||
}
|
||||
@ -459,6 +459,66 @@ class JavaMembers
|
||||
}
|
||||
}
|
||||
|
||||
private static Method extractGetMethod(NativeJavaMethod njm,
|
||||
boolean isStatic)
|
||||
{
|
||||
// Grab and inspect the getter method; does it have an empty parameter
|
||||
// list with a return value (eg. a getSomething() or isSomething())?
|
||||
Method[] methods = njm.methods;
|
||||
if (methods.length == 1) {
|
||||
Method method = methods[0];
|
||||
// Make sure the method static-ness is preserved for this property.
|
||||
if (!isStatic || Modifier.isStatic(method.getModifiers())) {
|
||||
Class[] params = method.getParameterTypes();
|
||||
if (params != null && params.length == 0) {
|
||||
Class type = method.getReturnType();
|
||||
if (type != null && type != Void.TYPE) {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Method extractSetMethod(Class type,
|
||||
NativeJavaMethod njm,
|
||||
boolean isStatic)
|
||||
{
|
||||
//
|
||||
// Note: it may be preferable to allow NativeJavaMethod.findFunction()
|
||||
// to find the appropriate setter; unfortunately, it requires an
|
||||
// instance of the target arg to determine that.
|
||||
//
|
||||
|
||||
// Make two passes: one to find a method with direct type assignment,
|
||||
// and one to find a widening conversion.
|
||||
Method[] methods = njm.methods;
|
||||
for (int pass = 1; pass <= 2; ++pass) {
|
||||
for (int i = 0; i < methods.length; ++i) {
|
||||
Method method = methods[i];
|
||||
if (!isStatic || Modifier.isStatic(method.getModifiers())) {
|
||||
if (method.getReturnType() == Void.TYPE) {
|
||||
Class[] params = method.getParameterTypes();
|
||||
if (params != null && params.length == 1) {
|
||||
if (pass == 1) {
|
||||
if (params[0] == type) {
|
||||
return method;
|
||||
}
|
||||
} else {
|
||||
if (pass != 2) Context.codeBug();
|
||||
if (params[0].isAssignableFrom(type)) {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Hashtable getFieldAndMethodsObjects(Scriptable scope, Object javaObject,
|
||||
boolean isStatic)
|
||||
{
|
||||
|
@ -68,22 +68,6 @@ public class NativeJavaMethod extends BaseFunction
|
||||
this.functionName = name;
|
||||
}
|
||||
|
||||
public void add(Method method)
|
||||
{
|
||||
if (functionName == null) {
|
||||
functionName = method.getName();
|
||||
} else if (!functionName.equals(method.getName())) {
|
||||
throw new RuntimeException("internal method name mismatch");
|
||||
}
|
||||
// XXX a more intelligent growth algorithm would be nice
|
||||
int len = methods == null ? 0 : methods.length;
|
||||
Method[] newMeths = new Method[len + 1];
|
||||
for (int i = 0; i < len; i++)
|
||||
newMeths[i] = methods[i];
|
||||
newMeths[len] = method;
|
||||
methods = newMeths;
|
||||
}
|
||||
|
||||
private static String scriptSignature(Object value)
|
||||
{
|
||||
if (value == null) {
|
||||
|
Loading…
Reference in New Issue
Block a user