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

org.walkmod.javalang.compiler.reflection.FieldInspector Maven / Gradle / Ivy

There is a newer version: 2.3.10
Show newest version
/*
 * Copyright (C) 2015 Raquel Pau and Albert Coroleu.
 * 
 * Walkmod is free software: you can redistribute it and/or modify it under the terms of the GNU
 * Lesser General Public License as published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 * 
 * Walkmod is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License along with Walkmod. If
 * not, see .
 */
package org.walkmod.javalang.compiler.reflection;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.walkmod.javalang.compiler.symbols.SymbolTable;
import org.walkmod.javalang.compiler.symbols.SymbolType;
import org.walkmod.javalang.exceptions.NoSuchExpressionTypeException;

public class FieldInspector {

    public static Set getNonPrivateFields(Class clazz) {
        Set result = new HashSet();
        if (clazz == null || clazz.equals(Object.class)) {
            return result;
        }
        Field[] fields = clazz.getDeclaredFields();

        for (int i = 0; i < fields.length; i++) {
            if (!Modifier.isPrivate(fields[i].getModifiers())) {
                result.add(fields[i]);
            }
        }
        result.addAll(getNonPrivateFields(clazz.getSuperclass()));
        Class[] interfaces = clazz.getInterfaces();
        for (int i = 0; i < interfaces.length; i++) {
            result.addAll(getNonPrivateFields(interfaces[i]));
        }
        return result;
    }

    public static SymbolType findFieldType(SymbolTable symTable, SymbolType scope, String fieldName) {

        SymbolType result = null;
        if (scope != null) {
            List> classes = scope.getBoundClasses();
            Iterator> it = classes.iterator();

            while (it.hasNext() && result == null) {
                try {
                    Class clazz = it.next();

                    Field field = null;
                    if (scope.getArrayCount() > 0 && fieldName.equals("length")) {
                        result = new SymbolType("int");
                    } else {
                        try {
                            field = clazz.getDeclaredField(fieldName);

                        } catch (NoSuchFieldException fe) {

                            field = getField0(clazz.getPackage(), clazz, fieldName);
                            if (field == null) {
                                // check a field with no visibility
                                SymbolType st = symTable.getType("this");

                                Class internal =
                                        ClassInspector.findClassMember(st.getClazz().getPackage(), fieldName, clazz);
                                if (internal != null) {
                                    result = new SymbolType(internal);
                                }

                            }
                        }
                        if (result == null && field != null) {
                            Map typeMapping = new HashMap();

                            Class container = field.getDeclaringClass();

                            if (!container.getName().equals(clazz.getName())) {
                                Set equivalentTypeImplementations =
                                        ClassInspector.getEquivalentParametrizableClasses(clazz);
                                if (equivalentTypeImplementations != null) {
                                    Iterator itTypes = equivalentTypeImplementations.iterator();
                                    while (itTypes.hasNext()) {
                                        java.lang.reflect.Type current = itTypes.next();
                                        if (current instanceof ParameterizedType) {
                                            ParameterizedType paramType = (ParameterizedType) current;
                                            java.lang.reflect.Type rawType = paramType.getRawType();
                                            if (rawType instanceof Class) {
                                                String raw = ((Class) paramType.getRawType()).getName();
                                                if (raw.equals(container.getName())) {

                                                    scope = SymbolType.valueOf(current, typeMapping);
                                                }
                                            }
                                        }
                                    }
                                }
                            }

                            GenericBuilderFromGenericClasses builder =
                                    new GenericBuilderFromGenericClasses(container, scope.getParameterizedTypes());

                            builder.build(typeMapping);

                            result = SymbolType.valueOf(field.getGenericType(), typeMapping);
                            result.setField(field);
                        }
                    }
                } catch (Exception e) {
                    throw new NoSuchExpressionTypeException(e);

                }
            }
        }
        if (result == null) {
            throw new RuntimeException("The field " + fieldName + " is not found");
        }
        return result;
    }

    private static Field getField0(Package pkg, Class clazz, String name) {

        Field res = null;
        try {
            res = clazz.getDeclaredField(name);
        } catch (NoSuchFieldException e) {

        }
        // Search declared public fields
        if (res != null) {
            int modifiers = res.getModifiers();
            if (Modifier.isPublic(modifiers)) {
                return res;
            } else if (Modifier.isProtected(modifiers)) {
                return res;
            } else if (!Modifier.isPrivate(modifiers) && res.getDeclaringClass().getPackage().equals(pkg)) {
                return res;
            }
        }
        // Direct superinterfaces, recursively
        Class[] interfaces = clazz.getInterfaces();
        for (int i = 0; i < interfaces.length; i++) {
            Class c = interfaces[i];
            if ((res = getField0(pkg, c, name)) != null) {
                return res;
            }
        }
        // Direct superclass, recursively
        if (!clazz.isInterface()) {
            Class c = clazz.getSuperclass();
            if (c != null) {
                if ((res = getField0(pkg, c, name)) != null) {
                    return res;
                }
            }
        }
        return null;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy