1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.millscript.millscript.functions;
23
24 import org.millscript.millscript.alert.Alerts;
25 import org.millscript.millscript.vm.Machine;
26
27 import java.lang.reflect.Method;
28 import java.util.Arrays;
29
30 /**
31 * This class implements the MillScript <code>javaFunction</code> function.
32 */
33 public class JavaFunctionFunction extends Function {
34
35 /**
36 * @see org.millscript.millscript.functions.Function#apply(org.millscript.millscript.vm.Machine, int)
37 */
38 @Override
39 public void apply( final Machine mc, final int nargs ) {
40 if ( nargs < 2 ) {
41 throw(
42 Alerts.eval(
43 "Insufficient arguments",
44 "javaFunction requires at least two arguments"
45 ).mishap()
46 );
47 }
48 int num = nargs - 2;
49 Class[] ptypes = new Class[ num ];
50 for ( int i = num - 1; i >= 0; i-- ) {
51 String cname = mc.popString();
52 try {
53 ptypes[ i ] = ParameterType.findClass( cname );
54 } catch ( ClassNotFoundException ex ) {
55 throw(
56 Alerts.eval(
57 "No such class",
58 "There does not appear to be a class by that name"
59 ).culprit( "class name", cname ).mishap()
60 );
61 }
62 }
63 String methodName = mc.popString();
64 String className = mc.popString();
65 mc.pushObject( javaFunction( className, methodName, ptypes ) );
66 }
67
68 /**
69 * Returns a <code>Function</code> to access the method with the specified
70 * parameters in the specified Java class.
71 *
72 * @param className the Java class containing the method
73 * @param methodName the Java method we want to invoke
74 * @param ptypes the parameter types for the method
75 * @return a <code>Function</code> to invoke the specified method
76 */
77 static Function javaFunction( final String className, final String methodName, final Class[] ptypes ) {
78 try {
79 Class c = Class.forName( className );
80 Method[] methods = c.getMethods();
81 for ( int i = 0; i < methods.length; i++ ) {
82 Method method = methods[ i ];
83 if (
84 method.getName().equals( methodName ) &&
85 Arrays.equals( method.getParameterTypes(), ptypes )
86 ) {
87
88 return JMethod.make( method );
89 }
90 }
91 } catch ( ClassNotFoundException ex ) {
92 throw(
93 Alerts.eval(
94 "Class cannot be found",
95 null
96 ).culprit( "class name", className ).mishap()
97 );
98 }
99 throw(
100 Alerts.eval(
101 "No such method for this class",
102 "The class does not define a method of that name"
103 ).
104 culprit( "method name", methodName ).
105 culprit( "class name", className ).
106 mishap()
107 );
108 }
109
110 }