Invoke the method identified by this name. Performs caching of method resolution using SignatureKey. Name contains a wholely unqualfied messy name; resolve it to ( object | static prefix ) + method name and invoke. The interpreter is necessary to support 'this.inte
( Interpreter interpreter, Object[] args, CallStack callstack, SimpleNode callerInfo )
| 777 | </pre> |
| 778 | */ |
| 779 | public Object invokeMethod( |
| 780 | Interpreter interpreter, Object[] args, CallStack callstack, |
| 781 | SimpleNode callerInfo |
| 782 | ) |
| 783 | throws UtilEvalError, EvalError, ReflectError, InvocationTargetException |
| 784 | { |
| 785 | String methodName = Name.suffix(value, 1); |
| 786 | BshClassManager bcm = interpreter.getClassManager(); |
| 787 | NameSpace namespace = callstack.top(); |
| 788 | |
| 789 | // Optimization - If classOfStaticMethod is set then we have already |
| 790 | // been here and determined that this is a static method invocation. |
| 791 | // Note: maybe factor this out with path below... clean up. |
| 792 | if ( classOfStaticMethod != null ) |
| 793 | { |
| 794 | return Reflect.invokeStaticMethod( |
| 795 | bcm, classOfStaticMethod, methodName, args ); |
| 796 | } |
| 797 | |
| 798 | if ( !Name.isCompound(value) ) |
| 799 | return invokeLocalMethod( |
| 800 | interpreter, args, callstack, callerInfo ); |
| 801 | |
| 802 | // Note: if we want methods declared inside blocks to be accessible via |
| 803 | // this.methodname() inside the block we could handle it here as a |
| 804 | // special case. See also resolveThisFieldReference() special handling |
| 805 | // for BlockNameSpace case. They currently work via the direct name |
| 806 | // e.g. methodName(). |
| 807 | |
| 808 | String prefix = Name.prefix(value); |
| 809 | |
| 810 | // Superclass method invocation? (e.g. super.foo()) |
| 811 | if ( prefix.equals("super") && Name.countParts(value) == 2 ) |
| 812 | { |
| 813 | // Allow getThis() to work through block namespaces first |
| 814 | This ths = namespace.getThis( interpreter ); |
| 815 | NameSpace thisNameSpace = ths.getNameSpace(); |
| 816 | NameSpace classNameSpace = getClassNameSpace( thisNameSpace ); |
| 817 | if ( classNameSpace != null ) |
| 818 | { |
| 819 | Object instance = classNameSpace.getClassInstance(); |
| 820 | return ClassGenerator.getClassGenerator() |
| 821 | .invokeSuperclassMethod( bcm, instance, methodName, args ); |
| 822 | } |
| 823 | } |
| 824 | |
| 825 | // Find target object or class identifier |
| 826 | Name targetName = namespace.getNameResolver( prefix ); |
| 827 | Object obj = targetName.toObject( callstack, interpreter ); |
| 828 | |
| 829 | if ( obj == Primitive.VOID ) |
| 830 | throw new UtilEvalError( "Attempt to resolve method: "+methodName |
| 831 | +"() on undefined variable or class name: "+targetName); |
| 832 | |
| 833 | // if we've got an object, resolve the method |
| 834 | if ( !(obj instanceof ClassIdentifier) ) { |
| 835 | |
| 836 | if (obj instanceof Primitive) { |