All Downloads are FREE. Search and download functionalities are using the official Maven repository.

framework.src.org.checkerframework.common.value.ValueCheckerUtils Maven / Gradle / Ivy

Go to download

Checker Qual is the set of annotations (qualifiers) and supporting classes used by the Checker Framework to type check Java source code. Please see artifact: org.checkerframework:checker

There is a newer version: 3.45.0
Show newest version
package org.checkerframework.common.value;

import org.checkerframework.common.value.qual.ArrayLen;
import org.checkerframework.common.value.qual.BoolVal;
import org.checkerframework.common.value.qual.BottomVal;
import org.checkerframework.common.value.qual.DoubleVal;
import org.checkerframework.common.value.qual.IntVal;
import org.checkerframework.common.value.qual.StringVal;
import org.checkerframework.common.value.qual.UnknownVal;
import org.checkerframework.common.value.util.NumberUtils;
import org.checkerframework.javacutil.AnnotationUtils;
import org.checkerframework.javacutil.TypesUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeMirror;


public class ValueCheckerUtils {
    public static Class getClassFromType(TypeMirror type) {

        switch (type.getKind()) {
        case INT:
            return int.class;
        case LONG:
            return long.class;
        case SHORT:
            return short.class;
        case BYTE:
            return byte.class;
        case CHAR:
            return char.class;
        case DOUBLE:
            return double.class;
        case FLOAT:
            return float.class;
        case BOOLEAN:
            return boolean.class;
        case ARRAY:
            return getArrayClassObject(((ArrayType) type).getComponentType());
        case DECLARED:
            String stringType = TypesUtils.getQualifiedName(
                    (DeclaredType) type).toString();
            if (stringType.equals("")) {
                return Object.class;
            }

            try {
                return Class.forName(stringType);
            } catch (ClassNotFoundException | UnsupportedClassVersionError e) {
                return Object.class;
            }

        default:
            return Object.class;
        }
    }

    public static Class getArrayClassObject(TypeMirror componentType) {
        switch (componentType.getKind()) {
        case INT:
            return int[].class;
        case LONG:
            return long[].class;
        case SHORT:
            return short[].class;
        case BYTE:
            return byte[].class;
        case CHAR:
            return char[].class;
        case DOUBLE:
            return double[].class;
        case FLOAT:
            return float[].class;
        case BOOLEAN:
            return boolean[].class;
        default:
            return Object[].class;
        }
    }

    public static List getValuesCastedToType(AnnotationMirror anno, TypeMirror castTo) {
        Class castType = ValueCheckerUtils.getClassFromType(castTo);
        List values = null;

        if (AnnotationUtils.areSameByClass(anno, DoubleVal.class)) {
            values = convertDoubleVal(anno, castType, castTo);
        } else if (AnnotationUtils.areSameByClass(anno, IntVal.class)) {
            values = convertIntVal(anno, castType, castTo);
        } else if (AnnotationUtils.areSameByClass(anno, StringVal.class)) {
            values = convertStringVal(anno, castType);
        } else if (AnnotationUtils.areSameByClass(anno, BoolVal.class)) {
            values = convertBoolVal(anno, castType);
        } else if (AnnotationUtils.areSameByClass(anno, BottomVal.class)) {
            values = convertBottomVal(anno, castType);
        } else if (AnnotationUtils.areSameByClass(anno, UnknownVal.class) ||
                AnnotationUtils.areSameByClass(anno, ArrayLen.class)) {
            values = new ArrayList<>();
        }
        return values;
    }

    private static List convertBottomVal(AnnotationMirror anno,
            Class newClass) {
        if (newClass == String.class) {
            return Collections.singletonList("null");
        } else {
            return new ArrayList<>();
        }
    }

    private static List convertToStringVal(List origValues) {
        List strings = new ArrayList<>();
        for (Object value : origValues) {
            strings.add(value.toString());
        }
        return strings;
    }

    private static List convertBoolVal(AnnotationMirror anno, Class newClass) {
        List bools = AnnotationUtils.getElementValueArray(anno,
                "value", Boolean.class, true);

        if (newClass == String.class) {
            return convertToStringVal(bools);
        }
        return bools;
    }

    private static List convertStringVal(AnnotationMirror anno,
            Class newClass) {
        List strings = AnnotationUtils.getElementValueArray(anno,
                "value", String.class, true);

        if (newClass == byte[].class) {
            List bytes = new ArrayList<>();
            for (String s : strings) {
                bytes.add(s.getBytes());
            }
            return bytes;
        } else if (newClass == char[].class) {
            List chars = new ArrayList<>();
            for (String s : strings) {
                chars.add(s.toCharArray());
            }
            return chars;
        } else if (newClass == Object.class && strings.size() == 1) {
            if (strings.get(0).equals("null")) {
                return strings;
            }
        }
        return strings;
    }

    private static List convertIntVal(AnnotationMirror anno, Class newClass, TypeMirror newType) {
        List longs = ValueAnnotatedTypeFactory.getIntValues(anno);

        if (newClass == String.class) {
            return convertToStringVal(longs);
        } else if (newClass == Character.class || newClass == char.class) {
            List chars = new ArrayList<>();
            for (Long l : longs) {
                chars.add((char) l.longValue());
            }
            return chars;
        } else if (newClass == Boolean.class) {
            throw new UnsupportedOperationException("ValueAnnotatedTypeFactory: can't convert double to boolean");
        }
        return NumberUtils.castNumbers(newType, longs);
    }

    private static List convertDoubleVal(AnnotationMirror anno,
            Class newClass, TypeMirror newType) {
        List doubles = ValueAnnotatedTypeFactory.getDoubleValues(anno);
        if (newClass == String.class) {
            return convertToStringVal(doubles);
        } else if (newClass == Character.class || newClass == char.class) {
            List chars = new ArrayList<>();
            for (Double l : doubles) {
                chars.add((char) l.doubleValue());
            }
            return chars;
        } else if (newClass == Boolean.class) {
            throw new UnsupportedOperationException("ValueAnnotatedTypeFactory: can't convert double to boolean");
        }
        return NumberUtils.castNumbers(newType, doubles);
    }

    public static > List removeDuplicates(List values) {
        Set set = new TreeSet<>(values);
        return new ArrayList(set);

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy