cc.kave.commons.pointsto.analysis.utils.GenericNameUtils.java Source code

Java tutorial

Introduction

Here is the source code for cc.kave.commons.pointsto.analysis.utils.GenericNameUtils.java

Source

/**
 * Copyright 2016 Simon Reu
 *
 * 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 cc.kave.commons.pointsto.analysis.utils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;

import com.google.common.base.Strings;
import com.google.common.collect.Iterables;

import cc.kave.commons.model.naming.Names;
import cc.kave.commons.model.naming.codeelements.IEventName;
import cc.kave.commons.model.naming.codeelements.IFieldName;
import cc.kave.commons.model.naming.codeelements.IMemberName;
import cc.kave.commons.model.naming.codeelements.IMethodName;
import cc.kave.commons.model.naming.codeelements.IParameterName;
import cc.kave.commons.model.naming.codeelements.IPropertyName;
import cc.kave.commons.model.naming.types.ITypeName;
import cc.kave.commons.model.naming.types.ITypeParameterName;
import cc.kave.commons.pointsto.analysis.exceptions.UnexpectedNameException;

public class GenericNameUtils {

    private static final String INSTANTIATION_ARROW = "->";

    @SuppressWarnings("unchecked")
    public static <T extends IMemberName> T eraseGenericInstantiations(T member) {
        if (member instanceof IMethodName) {
            return (T) eraseGenericInstantiations((IMethodName) member);
        } else if (member instanceof IPropertyName) {
            return (T) eraseGenericInstantiations((IPropertyName) member);
        } else if (member instanceof IFieldName) {
            return (T) eraseGenericInstantiations((IFieldName) member);
        } else if (member instanceof IEventName) {
            return (T) eraseGenericInstantiations((IEventName) member);
        } else {
            throw new UnexpectedNameException(member);
        }
    }

    public static IEventName eraseGenericInstantiations(IEventName event) {
        if (!event.getIdentifier().contains(INSTANTIATION_ARROW)) {
            return event;
        }

        return Names
                .newEvent(replaceTypes(event.getIdentifier(), event.getHandlerType(), event.getDeclaringType()));
    }

    public static IFieldName eraseGenericInstantiations(IFieldName field) {
        if (!field.getIdentifier().contains(INSTANTIATION_ARROW)) {
            return field;
        }

        return Names.newField(replaceTypes(field.getIdentifier(), field.getValueType(), field.getDeclaringType()));
    }

    public static IPropertyName eraseGenericInstantiations(IPropertyName property) {
        if (!property.getIdentifier().contains(INSTANTIATION_ARROW)) {
            return property;
        }

        return Names.newProperty(
                replaceTypes(property.getIdentifier(), property.getValueType(), property.getDeclaringType()));
    }

    public static IMethodName eraseGenericInstantiations(IMethodName method) {
        if (!method.getIdentifier().contains(INSTANTIATION_ARROW)) {
            return method;
        }

        List<IParameterName> parameters = method.getParameters();
        List<ITypeName> parameterTypes = new ArrayList<>(parameters.size());
        for (IParameterName parameter : parameters) {
            parameterTypes.add(parameter.getValueType());
        }

        return Names.newMethod(replaceTypes(method.getIdentifier(), Iterables
                .concat(Arrays.asList(method.getReturnType(), method.getDeclaringType()), parameterTypes)));
    }

    public static ITypeName eraseGenericInstantiations(ITypeName type) {
        String id = type.getIdentifier();
        if (!id.contains(INSTANTIATION_ARROW)) {
            return type;
        }

        for (ITypeParameterName typeParam : type.getTypeParameters()) {
            String name = typeParam.getTypeParameterShortName();

            // guard against a bug in TypeName.getTypeParameters producing
            // invalid type parameters
            if (Strings.isNullOrEmpty(name)) {
                return type;
            }

            String pattern = Pattern.quote(
                    name + " " + INSTANTIATION_ARROW + " " + typeParam.getTypeParameterType().getIdentifier());
            id = id.replaceAll(pattern, name);
        }
        return Names.newType(id);
    }

    private static String replaceTypes(String id, ITypeName... types) {
        return replaceTypes(id, Arrays.asList(types));
    }

    private static String replaceTypes(String id, Iterable<ITypeName> types) {
        for (ITypeName type : types) {
            String oldType = type.getIdentifier();
            String newType = eraseGenericInstantiations(type).getIdentifier();
            if (!oldType.equals(newType)) {
                id = id.replace("[" + oldType + "]", "[" + newType + "]");
            }
        }
        return id;
    }
}