/*
* Copyright 2009-2010 MBTE Sweden AB.
*
* Licensed 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.mbte.groovypp.runtime;
import groovy.lang.GString;
import groovy.lang.GroovyRuntimeException;
import org.codehaus.groovy.runtime.DefaultGroovyMethodsSupport;
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
import org.codehaus.groovy.runtime.InvokerHelper;
import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
import org.codehaus.groovy.runtime.typehandling.NumberMath;
import java.io.Writer;
import java.math.BigDecimal;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;
import static org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.*;
public class DefaultGroovyPPMethods extends DefaultGroovyMethodsSupport {
public static Number plus(Number self, Number other) {
return NumberMath.add(self, other);
}
public static Number minus(Number self, Number other) {
return NumberMath.subtract(self, other);
}
public static Number multiply(Number self, Number other) {
return NumberMath.multiply(self, other);
}
public static Number div(Number self, Number other) {
return NumberMath.divide(self, other);
}
public static Boolean box(boolean value) {
return value ? Boolean.TRUE : Boolean.FALSE;
}
public static Byte box(byte value) {
return value;
}
public static Character box(char value) {
return value;
}
public static Short box(short value) {
return value;
}
public static Integer box(int value) {
return value;
}
public static Long box(long value) {
return value;
}
public static Float box(float value) {
return value;
}
public static Double box(double value) {
return value;
}
public static Class getClass(byte value) {
return Byte.TYPE;
}
public static Class getClass(short value) {
return Short.TYPE;
}
public static Class getClass(int value) {
return Integer.TYPE;
}
public static Class getClass(char value) {
return Character.TYPE;
}
public static Class getClass(long value) {
return Long.TYPE;
}
public static Class getClass(float value) {
return Float.TYPE;
}
public static Class getClass(double value) {
return Double.TYPE;
}
public static Class getClass(boolean value) {
return Boolean.TYPE;
}
public static String[] gstringArrayToStringArray(GString[] data) {
if (data == null)
return null;
String[] strings = new String[data.length];
for (int i = 0; i < strings.length; i++) {
strings[i] = data[i].toString();
}
return strings;
}
public static Pattern bitwiseNegate(GString self) {
return DefaultGroovyMethods.bitwiseNegate(self.toString());
}
public static Iterator<String> iterator(String self) {
return DefaultGroovyMethods.toList(self).iterator();
}
public static void print(Writer self, Object value) {
DefaultGroovyMethods.print(self, value);
}
public static void println(Writer self, Object value) {
DefaultGroovyMethods.println(self, value);
}
public static boolean equals(Object left, Object right) {
return left == right || !(left == null || right == null) && left.equals(right);
}
public static boolean equals(List left, Object right) {
if (left == right) return true;
if (left == null || right == null) return false;
Class rightClass = right.getClass();
if (rightClass.isArray()) {
return compareArrayEqual(left, right);
}
if (right instanceof List)
return DefaultGroovyMethods.equals(left, (List)right);
return false;
}
public static boolean compareEqual(Object left, Object right) {
if (left == right) return true;
if (left == null || right == null) return false;
if (left instanceof Comparable) {
return compareToWithEqualityCheck(left, right) == 0;
}
// handle arrays on both sides as special case for efficiency
Class leftClass = left.getClass();
Class rightClass = right.getClass();
if (leftClass.isArray() && rightClass.isArray()) {
return compareArrayEqual(left, right);
}
if (leftClass.isArray() && leftClass.getComponentType().isPrimitive()) {
left = primitiveArrayToList(left);
}
if (rightClass.isArray() && rightClass.getComponentType().isPrimitive()) {
right = primitiveArrayToList(right);
}
if (left instanceof Object[] && right instanceof List) {
return DefaultGroovyMethods.equals((Object[]) left, (List) right);
}
if (left instanceof List && right instanceof Object[]) {
return DefaultGroovyMethods.equals((List) left, (Object[]) right);
}
if (left instanceof List && right instanceof List) {
return DefaultGroovyMethods.equals((List) left, (List) right);
}
return left.equals(right);
}
private static boolean isValidCharacterString(Object value) {
if (value instanceof String) {
String s = (String) value;
if (s.length() == 1) {
return true;
}
}
return false;
}
public static int compareToWithEqualityCheck(Object left, Object right) {
if (left == right) {
return 0;
}
if (left == null) {
return -1;
}
else if (right == null) {
return 1;
}
if (left instanceof Comparable) {
if (left instanceof Number) {
if (isValidCharacterString(right)) {
return DefaultGroovyMethods.compareTo((Number) left, (Character) box(castToChar(right)));
}
if (right instanceof Character || right instanceof Number) {
return DefaultGroovyMethods.compareTo((Number) left, castToNumber(right));
}
}
else if (left instanceof Character) {
if (isValidCharacterString(right)) {
return DefaultGroovyMethods.compareTo((Character)left,(Character)box(castToChar(right)));
}
if (right instanceof Number) {
return DefaultGroovyMethods.compareTo((Character)left,(Number)right);
}
}
else if (right instanceof Number) {
if (isValidCharacterString(left)) {
return DefaultGroovyMethods.compareTo((Character)box(castToChar(left)),(Number) right);
}
}
else if (left instanceof String && right instanceof Character) {
return ((String) left).compareTo(right.toString());
}
else if (left instanceof String && right instanceof GString) {
return ((String) left).compareTo(right.toString());
}
if (left.getClass().isAssignableFrom(right.getClass())
|| (right.getClass() != Object.class && right.getClass().isAssignableFrom(left.getClass())) //GROOVY-4046
|| (left instanceof GString && right instanceof String)) {
Comparable comparable = (Comparable) left;
return comparable.compareTo(right);
}
}
return -1; // anything other than 0
}
public static BigDecimal asBigDecimal(Number self) {
return self instanceof BigDecimal ? (BigDecimal) self : self instanceof Float || self instanceof Double ? new BigDecimal(self.doubleValue()) : new BigDecimal(self.toString());
}
}