org.codehaus.groovy.runtime.ScriptBytecodeAdapter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of groovy Show documentation
Show all versions of groovy Show documentation
Groovy: A powerful multi-faceted language for the JVM
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.codehaus.groovy.runtime;
import groovy.lang.Closure;
import groovy.lang.EmptyRange;
import groovy.lang.GroovyInterceptable;
import groovy.lang.GroovyObject;
import groovy.lang.GroovyRuntimeException;
import groovy.lang.GroovySystem;
import groovy.lang.IntRange;
import groovy.lang.MetaClass;
import groovy.lang.MissingMethodException;
import groovy.lang.MissingPropertyException;
import groovy.lang.NumberRange;
import groovy.lang.ObjectRange;
import groovy.lang.Tuple;
import org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack;
import org.codehaus.groovy.runtime.metaclass.MissingMethodExecutionFailed;
import org.codehaus.groovy.runtime.metaclass.MissingPropertyExceptionNoStack;
import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
import org.codehaus.groovy.runtime.wrappers.GroovyObjectWrapper;
import org.codehaus.groovy.runtime.wrappers.PojoWrapper;
import org.codehaus.groovy.runtime.wrappers.Wrapper;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* A static helper class to interface bytecode and runtime
*/
public class ScriptBytecodeAdapter {
public static final Object[] EMPTY_ARGS = {};
private static final Integer ZERO = 0;
private static final Integer MINUS_ONE = -1;
private static final Integer ONE = 1;
// --------------------------------------------------------
// exception handling
// --------------------------------------------------------
public static Throwable unwrap(GroovyRuntimeException gre) {
if (gre.getCause()==null) {
if (gre instanceof MissingPropertyExceptionNoStack) {
MissingPropertyExceptionNoStack noStack = (MissingPropertyExceptionNoStack) gre;
return new MissingPropertyException(noStack.getProperty(), noStack.getType());
}
if (gre instanceof MissingMethodExceptionNoStack) {
MissingMethodExceptionNoStack noStack = (MissingMethodExceptionNoStack) gre;
return new MissingMethodException(noStack.getMethod(), noStack.getType(), noStack.getArguments(), noStack.isStatic());
}
}
Throwable th = gre;
if (th.getCause() != null && th.getCause() != gre) th = th.getCause();
if (th != gre && (th instanceof GroovyRuntimeException)) return unwrap((GroovyRuntimeException) th);
return th;
}
// --------------------------------------------------------
// methods for this
// --------------------------------------------------------
public static Object invokeMethodOnCurrentN(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
Object result = null;
boolean intercepting = receiver instanceof GroovyInterceptable;
try {
try {
// if it's a pure interceptable object (even intercepting toString(), clone(), ...)
if (intercepting) {
result = receiver.invokeMethod(messageName, messageArguments);
}
//else if there's a statically typed method or a GDK method
else {
result = receiver.getMetaClass().invokeMethod(senderClass, receiver, messageName, messageArguments, false, true);
}
} catch (MissingMethodException e) {
if (e instanceof MissingMethodExecutionFailed) {
throw (MissingMethodException)e.getCause();
} else if (!intercepting && receiver.getClass() == e.getType() && e.getMethod().equals(messageName)) {
// in case there's nothing else, invoke the object's own invokeMethod()
result = receiver.invokeMethod(messageName, messageArguments);
} else {
throw e;
}
}
} catch (GroovyRuntimeException gre) {
throw unwrap(gre);
}
return result;
}
public static Object invokeMethodOnCurrentNSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
return invokeMethodOnCurrentN(senderClass, receiver, messageName, messageArguments);
}
public static Object invokeMethodOnCurrentNSpreadSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
List answer = new ArrayList();
for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
answer.add(invokeMethodNSafe(senderClass, it.next(), messageName, messageArguments));
}
return answer;
}
public static Object invokeMethodOnCurrent0(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
return invokeMethodOnCurrentN(senderClass, receiver, messageName, EMPTY_ARGS);
}
public static Object invokeMethodOnCurrent0Safe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
return invokeMethodOnCurrentNSafe(senderClass, receiver, messageName, EMPTY_ARGS);
}
public static Object invokeMethodOnCurrent0SpreadSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
return invokeMethodOnCurrentNSpreadSafe(senderClass, receiver, messageName, EMPTY_ARGS);
}
// --------------------------------------------------------
// methods for super
// --------------------------------------------------------
public static Object invokeMethodOnSuperN(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
MetaClass metaClass = receiver.getMetaClass();
// ignore interception and missing method fallback
Object result = null;
try {
result = metaClass.invokeMethod(senderClass, receiver, messageName, messageArguments, true, true);
} catch (GroovyRuntimeException gre) {
throw unwrap(gre);
}
return result;
}
public static Object invokeMethodOnSuperNSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
return invokeMethodOnSuperN(senderClass, receiver, messageName, messageArguments);
}
public static Object invokeMethodOnSuperNSpreadSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
List answer = new ArrayList();
for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
answer.add(invokeMethodNSafe(senderClass, it.next(), messageName, messageArguments));
}
return answer;
}
public static Object invokeMethodOnSuper0(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
return invokeMethodOnSuperN(senderClass, receiver, messageName, EMPTY_ARGS);
}
public static Object invokeMethodOnSuper0Safe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
return invokeMethodOnSuperNSafe(senderClass, receiver, messageName, EMPTY_ARGS);
}
public static Object invokeMethodOnSuper0SpreadSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
return invokeMethodOnSuperNSpreadSafe(senderClass, receiver, messageName, EMPTY_ARGS);
}
// --------------------------------------------------------
// normal method invocation
// --------------------------------------------------------
public static Object invokeMethodN(Class senderClass, Object receiver, String messageName, Object[] messageArguments) throws Throwable {
try {
return InvokerHelper.invokeMethod(receiver, messageName, messageArguments);
} catch (GroovyRuntimeException gre) {
throw unwrap(gre);
}
}
public static Object invokeMethodNSafe(Class senderClass, Object receiver, String messageName, Object[] messageArguments) throws Throwable {
if (receiver == null) return null;
return invokeMethodN(senderClass, receiver, messageName, messageArguments);
}
public static Object invokeMethodNSpreadSafe(Class senderClass, Object receiver, String messageName, Object[] messageArguments) throws Throwable {
if (receiver == null) return null;
List answer = new ArrayList();
for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
answer.add(invokeMethodNSafe(senderClass, it.next(), messageName, messageArguments));
}
return answer;
}
public static Object invokeMethod0(Class senderClass, Object receiver, String messageName) throws Throwable {
return invokeMethodN(senderClass, receiver, messageName, EMPTY_ARGS);
}
public static Object invokeMethod0Safe(Class senderClass, Object receiver, String messageName) throws Throwable {
if (receiver == null) return null;
return invokeMethodNSafe(senderClass, receiver, messageName, EMPTY_ARGS);
}
public static Object invokeMethod0SpreadSafe(Class senderClass, Object receiver, String messageName) throws Throwable {
return invokeMethodNSpreadSafe(senderClass, receiver, messageName, EMPTY_ARGS);
}
// --------------------------------------------------------
// static normal method invocation
// --------------------------------------------------------
public static Object invokeStaticMethodN(Class senderClass, Class receiver, String messageName, Object[] messageArguments) throws Throwable {
try {
return InvokerHelper.invokeStaticMethod(receiver, messageName, messageArguments);
} catch (GroovyRuntimeException gre) {
throw unwrap(gre);
}
}
public static Object invokeStaticMethod0(Class senderClass, Class receiver, String messageName) throws Throwable {
return invokeStaticMethodN(senderClass, receiver, messageName, EMPTY_ARGS);
}
// --------------------------------------------------------
// normal constructor invocation (via new)
// --------------------------------------------------------
public static Object invokeNewN(Class senderClass, Class receiver, Object arguments) throws Throwable {
try {
return InvokerHelper.invokeConstructorOf(receiver, arguments);
} catch (GroovyRuntimeException gre) {
throw unwrap(gre);
}
}
public static Object invokeNew0(Class senderClass, Class receiver) throws Throwable {
return invokeNewN(senderClass, receiver, EMPTY_ARGS);
}
// --------------------------------------------------------
// special constructor invocation (via this/super)
// --------------------------------------------------------
public static int selectConstructorAndTransformArguments(Object[] arguments, int numberOfConstructors, Class which) throws Throwable {
MetaClass metaClass = GroovySystem.getMetaClassRegistry().getMetaClass(which);
try {
return metaClass.selectConstructorAndTransformArguments(numberOfConstructors, arguments);
} catch (GroovyRuntimeException gre) {
throw unwrap(gre);
}
}
// --------------------------------------------------------
// field handling super: get
// --------------------------------------------------------
public static Object getFieldOnSuper(Class senderClass, Object receiver, String messageName) throws Throwable {
try {
if (receiver instanceof Class) {
return InvokerHelper.getAttribute(receiver, messageName);
} else {
MetaClass mc = ((GroovyObject) receiver).getMetaClass();
return mc.getAttribute(senderClass, receiver, messageName, true);
}
} catch (GroovyRuntimeException gre) {
throw unwrap(gre);
}
}
public static Object getFieldOnSuperSafe(Class senderClass, Object receiver, String messageName) throws Throwable {
return getFieldOnSuper(senderClass, receiver, messageName);
}
public static Object getFieldOnSuperSpreadSafe(Class senderClass, Object receiver, String messageName) throws Throwable {
List answer = new ArrayList();
for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
answer.add(getFieldOnSuper(senderClass, it.next(), messageName));
}
return answer;
}
// --------------------------------------------------------
// field handling super: set
// --------------------------------------------------------
public static void setFieldOnSuper(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable {
try {
if (receiver instanceof Class) {
InvokerHelper.setAttribute(receiver, messageName, messageArgument);
} else {
MetaClass mc = ((GroovyObject) receiver).getMetaClass();
mc.setAttribute(senderClass, receiver, messageName, messageArgument, true, true);
}
} catch (GroovyRuntimeException gre) {
throw unwrap(gre);
}
}
public static void setFieldOnSuperSafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable {
setFieldOnSuper(messageArgument, senderClass, receiver, messageName);
}
public static void setFieldOnSuperSpreadSafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable {
for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
setFieldOnSuper(messageArgument, senderClass, it.next(), messageName);
}
}
// --------------------------------------------------------
// normal field handling : get
// --------------------------------------------------------
public static Object getField(Class senderClass, Object receiver, String messageName) throws Throwable {
try {
return InvokerHelper.getAttribute(receiver, messageName);
} catch (GroovyRuntimeException gre) {
throw unwrap(gre);
}
}
public static Object getFieldSafe(Class senderClass, Object receiver, String messageName) throws Throwable {
if (receiver == null) return null;
return getField(senderClass, receiver, messageName);
}
public static Object getFieldSpreadSafe(Class senderClass, Object receiver, String messageName) throws Throwable {
if (receiver == null) return null;
List answer = new ArrayList();
for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
answer.add(getFieldSafe(senderClass, it.next(), messageName));
}
return answer;
}
// --------------------------------------------------------
// normal field handling : set
// --------------------------------------------------------
public static void setField(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable {
try {
InvokerHelper.setAttribute(receiver, messageName, messageArgument);
} catch (GroovyRuntimeException gre) {
throw unwrap(gre);
}
}
public static void setFieldSafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable {
if (receiver == null) return;
setField(messageArgument, senderClass, receiver, messageName);
}
public static void setFieldSpreadSafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable {
if (receiver == null) return;
for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
setFieldSafe(messageArgument, senderClass, it.next(), messageName);
}
}
// --------------------------------------------------------
// normal GroovyObject field handling : get
// --------------------------------------------------------
public static Object getGroovyObjectField(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
try {
return receiver.getMetaClass().getAttribute(receiver, messageName);
} catch (GroovyRuntimeException gre) {
throw unwrap(gre);
}
}
public static Object getGroovyObjectFieldSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
if (receiver == null) return null;
try {
return receiver.getMetaClass().getAttribute(receiver, messageName);
} catch (GroovyRuntimeException gre) {
throw unwrap(gre);
}
}
public static Object getGroovyObjectFieldSpreadSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
if (receiver == null) return null;
List answer = new ArrayList();
for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
answer.add(getFieldSafe(senderClass, it.next(), messageName));
}
return answer;
}
// --------------------------------------------------------
// normal field handling : set
// --------------------------------------------------------
public static void setGroovyObjectField(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
try {
receiver.getMetaClass().setAttribute(receiver, messageName, messageArgument);
} catch (GroovyRuntimeException gre) {
throw unwrap(gre);
}
}
public static void setGroovyObjectFieldSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
if (receiver == null) return;
try {
receiver.getMetaClass().setAttribute(receiver, messageName, messageArgument);
} catch (GroovyRuntimeException gre) {
throw unwrap(gre);
}
}
public static void setGroovyObjectFieldSpreadSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
if (receiver == null) return;
for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
setFieldSafe(messageArgument, senderClass, it.next(), messageName);
}
}
// --------------------------------------------------------
// Property handling super: get
// --------------------------------------------------------
public static Object getPropertyOnSuper(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
try {
return receiver.getMetaClass().getProperty(senderClass, receiver, messageName, true, false);
} catch (GroovyRuntimeException gre) {
throw unwrap(gre);
}
}
public static Object getPropertyOnSuperSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
return getPropertyOnSuper(senderClass, receiver, messageName);
}
public static Object getPropertyOnSuperSpreadSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
List