at.bestsolution.fxide.jdt.corext.util.JdtFlags.java Source code

Java tutorial

Introduction

Here is the source code for at.bestsolution.fxide.jdt.corext.util.JdtFlags.java

Source

/*******************************************************************************
 * Copyright (c) 2000, 2013 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Rabea Gransberger <rgransberger@gmx.de> - [quick fix] Fix several visibility issues - https://bugs.eclipse.org/394692
 *******************************************************************************/
package at.bestsolution.fxide.jdt.corext.util;

import org.eclipse.core.runtime.Assert;

import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
import org.eclipse.jdt.core.dom.EnumDeclaration;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.TypeDeclaration;

/**
 * Java element flags from a Java language model point of view.
 * <p>
 * {@link IMember#getFlags()} (and hence {@link Flags}) only take explicitly declared flags
 * from source into account.
 * This class also considers the implicit properties as defined in the Java Language Specification.
 * </p>
 * <p>
 * <code>JdtFlags</code> is the right choice for most analysis tasks and for presentation in the UI.
 * </p>
 *
 * @see JDTUIHelperClasses
 */
public class JdtFlags {
    private JdtFlags() {
    }

    public static final String VISIBILITY_STRING_PRIVATE = "private"; //$NON-NLS-1$
    public static final String VISIBILITY_STRING_PACKAGE = ""; //$NON-NLS-1$
    public static final String VISIBILITY_STRING_PROTECTED = "protected"; //$NON-NLS-1$
    public static final String VISIBILITY_STRING_PUBLIC = "public"; //$NON-NLS-1$

    public static final int VISIBILITY_CODE_INVALID = -1;

    public static boolean isDefaultMethod(IMethodBinding method) {
        int modifiers = method.getModifiers();
        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=405517#c7
        ITypeBinding declaringClass = method.getDeclaringClass();
        if (declaringClass.isInterface()) {
            return !Modifier.isAbstract(modifiers) && !Modifier.isStatic(modifiers);
        }
        return false;
    }

    public static boolean isDefaultMethod(IMethod method) throws JavaModelException {
        return Flags.isDefaultMethod(method.getFlags());
    }

    public static boolean isAbstract(IMember member) throws JavaModelException {
        int flags = member.getFlags();
        if (!member.isBinary() && isInterfaceOrAnnotationMethod(member)) {
            return !Flags.isStatic(flags) && !Flags.isDefaultMethod(flags);
        }
        return Flags.isAbstract(flags);
    }

    public static boolean isAbstract(IMethodBinding member) {
        return Modifier.isAbstract(member.getModifiers());
    }

    public static boolean isStatic(BodyDeclaration bodyDeclaration) {
        if (isNestedInterfaceOrAnnotation(bodyDeclaration))
            return true;
        int nodeType = bodyDeclaration.getNodeType();
        if (!(nodeType == ASTNode.METHOD_DECLARATION || nodeType == ASTNode.ANNOTATION_TYPE_MEMBER_DECLARATION)
                && isInterfaceOrAnnotationMember(bodyDeclaration))
            return true;
        if (bodyDeclaration instanceof EnumConstantDeclaration)
            return true;
        if (bodyDeclaration instanceof EnumDeclaration
                && bodyDeclaration.getParent() instanceof AbstractTypeDeclaration)
            return true;
        return Modifier.isStatic(bodyDeclaration.getModifiers());
    }

    public static boolean isStatic(IMember member) throws JavaModelException {
        if (isNestedInterfaceOrAnnotation(member))
            return true;
        if (member.getElementType() != IJavaElement.METHOD && isInterfaceOrAnnotationMember(member))
            return true;
        if (isEnum(member) && (member.getElementType() == IJavaElement.FIELD || member.getDeclaringType() != null))
            return true;
        return Flags.isStatic(member.getFlags());
    }

    public static boolean isStatic(IMethodBinding methodBinding) {
        return Modifier.isStatic(methodBinding.getModifiers());
    }

    public static boolean isDeprecated(IMember member) throws JavaModelException {
        return Flags.isDeprecated(member.getFlags());
    }

    public static boolean isFinal(IMember member) throws JavaModelException {
        if (isInterfaceOrAnnotationField(member))
            return true;
        if (isAnonymousType(member))
            return true;
        if (isEnumConstant(member) || isEnumTypeFinal(member))
            return true;
        return Flags.isFinal(member.getFlags());
    }

    private static boolean isEnumTypeFinal(IMember member) throws JavaModelException {
        if (!(isEnum(member) && member.getElementType() == IJavaElement.TYPE))
            return false;
        // An enum type is implicitly final unless it contains at least one enum constant that has a class body.
        IJavaElement[] children = member.getChildren();
        for (IJavaElement child : children) {
            if (isEnumConstant((IMember) child) && ((IField) child).getChildren().length != 0) {
                return false;
            }
        }
        return true;
    }

    public static boolean isNative(IMember member) throws JavaModelException {
        return Flags.isNative(member.getFlags());
    }

    public static boolean isPackageVisible(IMember member) throws JavaModelException {
        return (!isPrivate(member) && !isProtected(member) && !isPublic(member));
    }

    public static boolean isPackageVisible(BodyDeclaration bodyDeclaration) {
        return (!isPrivate(bodyDeclaration) && !isProtected(bodyDeclaration) && !isPublic(bodyDeclaration));
    }

    public static boolean isPackageVisible(IBinding binding) {
        return (!isPrivate(binding) && !isProtected(binding) && !isPublic(binding));
    }

    public static boolean isPrivate(IMember member) throws JavaModelException {
        return Flags.isPrivate(member.getFlags());
    }

    public static boolean isPrivate(BodyDeclaration bodyDeclaration) {
        return Modifier.isPrivate(bodyDeclaration.getModifiers());
    }

    public static boolean isPrivate(IBinding binding) {
        return Modifier.isPrivate(binding.getModifiers());
    }

    public static boolean isProtected(IMember member) throws JavaModelException {
        return Flags.isProtected(member.getFlags());
    }

    public static boolean isProtected(BodyDeclaration bodyDeclaration) {
        return Modifier.isProtected(bodyDeclaration.getModifiers());
    }

    public static boolean isProtected(IBinding binding) {
        return Modifier.isProtected(binding.getModifiers());
    }

    public static boolean isPublic(IMember member) throws JavaModelException {
        if (isInterfaceOrAnnotationMember(member))
            return true;
        if (isEnumConstant(member))
            return true;
        return Flags.isPublic(member.getFlags());
    }

    public static boolean isPublic(IBinding binding) {
        if (isInterfaceOrAnnotationMember(binding))
            return true;
        return Modifier.isPublic(binding.getModifiers());
    }

    public static boolean isPublic(BodyDeclaration bodyDeclaration) {
        if (isInterfaceOrAnnotationMember(bodyDeclaration))
            return true;
        return Modifier.isPublic(bodyDeclaration.getModifiers());
    }

    public static boolean isStatic(IVariableBinding variableBinding) {
        if (isInterfaceOrAnnotationMember(variableBinding))
            return true;
        return Modifier.isStatic(variableBinding.getModifiers());
    }

    public static boolean isSynchronized(IMember member) throws JavaModelException {
        return Flags.isSynchronized(member.getFlags());
    }

    public static boolean isSynthetic(IMember member) throws JavaModelException {
        return Flags.isSynthetic(member.getFlags());
    }

    public static boolean isAnnotation(IMember member) throws JavaModelException {
        return Flags.isAnnotation(member.getFlags());
    }

    public static boolean isEnum(IMember member) throws JavaModelException {
        return Flags.isEnum(member.getFlags());
    }

    public static boolean isVarargs(IMethod method) throws JavaModelException {
        return Flags.isVarargs(method.getFlags());
    }

    public static boolean isTransient(IMember member) throws JavaModelException {
        return Flags.isTransient(member.getFlags());
    }

    public static boolean isVolatile(IMember member) throws JavaModelException {
        return Flags.isVolatile(member.getFlags());
    }

    private static boolean isInterfaceOrAnnotationMethod(IMember member) throws JavaModelException {
        return member.getElementType() == IJavaElement.METHOD && isInterfaceOrAnnotationMember(member);
    }

    private static boolean isInterfaceOrAnnotationField(IMember member) throws JavaModelException {
        return member.getElementType() == IJavaElement.FIELD && isInterfaceOrAnnotationMember(member);
    }

    private static boolean isInterfaceOrAnnotationMember(IMember member) throws JavaModelException {
        return member.getDeclaringType() != null
                && JavaModelUtil.isInterfaceOrAnnotation(member.getDeclaringType());
    }

    private static boolean isInterfaceOrAnnotationMember(IBinding binding) {
        ITypeBinding declaringType = null;
        if (binding instanceof IVariableBinding) {
            declaringType = ((IVariableBinding) binding).getDeclaringClass();
        } else if (binding instanceof IMethodBinding) {
            declaringType = ((IMethodBinding) binding).getDeclaringClass();
        } else if (binding instanceof ITypeBinding) {
            declaringType = ((ITypeBinding) binding).getDeclaringClass();
        }
        return declaringType != null && (declaringType.isInterface() || declaringType.isAnnotation());
    }

    private static boolean isInterfaceOrAnnotationMember(BodyDeclaration bodyDeclaration) {
        return isInterfaceOrAnnotation(bodyDeclaration.getParent());
    }

    private static boolean isInterfaceOrAnnotation(ASTNode node) {
        boolean isInterface = (node instanceof TypeDeclaration) && ((TypeDeclaration) node).isInterface();
        boolean isAnnotation = node instanceof AnnotationTypeDeclaration;
        return isInterface || isAnnotation;
    }

    private static boolean isNestedInterfaceOrAnnotation(BodyDeclaration bodyDeclaration) {
        return bodyDeclaration.getParent() instanceof AbstractTypeDeclaration
                && isInterfaceOrAnnotation(bodyDeclaration);
    }

    private static boolean isNestedInterfaceOrAnnotation(IMember member) throws JavaModelException {
        return member.getElementType() == IJavaElement.TYPE && member.getDeclaringType() != null
                && JavaModelUtil.isInterfaceOrAnnotation((IType) member);
    }

    private static boolean isEnumConstant(IMember member) throws JavaModelException {
        return member.getElementType() == IJavaElement.FIELD && isEnum(member);
    }

    private static boolean isAnonymousType(IMember member) throws JavaModelException {
        return member.getElementType() == IJavaElement.TYPE && ((IType) member).isAnonymous();
    }

    public static int getVisibilityCode(IMember member) throws JavaModelException {
        if (isPublic(member))
            return Modifier.PUBLIC;
        else if (isProtected(member))
            return Modifier.PROTECTED;
        else if (isPackageVisible(member))
            return Modifier.NONE;
        else if (isPrivate(member))
            return Modifier.PRIVATE;
        Assert.isTrue(false);
        return VISIBILITY_CODE_INVALID;
    }

    public static int getVisibilityCode(BodyDeclaration bodyDeclaration) {
        if (isPublic(bodyDeclaration))
            return Modifier.PUBLIC;
        else if (isProtected(bodyDeclaration))
            return Modifier.PROTECTED;
        else if (isPackageVisible(bodyDeclaration))
            return Modifier.NONE;
        else if (isPrivate(bodyDeclaration))
            return Modifier.PRIVATE;
        Assert.isTrue(false);
        return VISIBILITY_CODE_INVALID;
    }

    public static int getVisibilityCode(IBinding binding) {
        if (isPublic(binding))
            return Modifier.PUBLIC;
        else if (isProtected(binding))
            return Modifier.PROTECTED;
        else if (isPackageVisible(binding))
            return Modifier.NONE;
        else if (isPrivate(binding))
            return Modifier.PRIVATE;
        Assert.isTrue(false);
        return VISIBILITY_CODE_INVALID;
    }

    public static String getVisibilityString(int visibilityCode) {
        if (Modifier.isPublic(visibilityCode))
            return VISIBILITY_STRING_PUBLIC;
        if (Modifier.isProtected(visibilityCode))
            return VISIBILITY_STRING_PROTECTED;
        if (Modifier.isPrivate(visibilityCode))
            return VISIBILITY_STRING_PRIVATE;
        return VISIBILITY_STRING_PACKAGE;
    }

    public static int getVisibilityCode(String visibilityString) {
        Assert.isNotNull(visibilityString);
        if (VISIBILITY_STRING_PACKAGE.equals(visibilityString))
            return 0;
        else if (VISIBILITY_STRING_PRIVATE.equals(visibilityString))
            return Modifier.PRIVATE;
        else if (VISIBILITY_STRING_PROTECTED.equals(visibilityString))
            return Modifier.PROTECTED;
        else if (VISIBILITY_STRING_PUBLIC.equals(visibilityString))
            return Modifier.PUBLIC;
        return VISIBILITY_CODE_INVALID;
    }

    public static void assertVisibility(int visibility) {
        Assert.isTrue(visibility == Modifier.PUBLIC || visibility == Modifier.PROTECTED
                || visibility == Modifier.NONE || visibility == Modifier.PRIVATE);
    }

    /**
     * Compares two visibilities.
     *
     * @param newVisibility the 'new' visibility
     * @param oldVisibility the 'old' visibility
     * @return <code>true</code> iff the 'new' visibility is strictly higher than the old visibility
     *
     * @see Modifier#PUBLIC
     * @see Modifier#PROTECTED
     * @see Modifier#NONE
     * @see Modifier#PRIVATE
     */
    public static boolean isHigherVisibility(int newVisibility, int oldVisibility) {
        assertVisibility(oldVisibility);
        assertVisibility(newVisibility);
        switch (oldVisibility) {
        case Modifier.PRIVATE:
            return newVisibility == Modifier.NONE || newVisibility == Modifier.PUBLIC
                    || newVisibility == Modifier.PROTECTED;
        case Modifier.NONE:
            return newVisibility == Modifier.PUBLIC || newVisibility == Modifier.PROTECTED;

        case Modifier.PROTECTED:
            return newVisibility == Modifier.PUBLIC;

        case Modifier.PUBLIC:
            return false;
        default:
            Assert.isTrue(false);
            return false;
        }
    }

    public static int getLowerVisibility(int visibility1, int visibility2) {
        if (isHigherVisibility(visibility1, visibility2))
            return visibility2;
        else
            return visibility1;
    }

    /**
     * Gets the higher visibility of the given parameters.
     *
     * @param visibility1 First visibility value to compare. Valid inputs are the {@link Modifier} visibility constants.
     * @param visibility2 Second visibility value to compare. Valid inputs are the {@link Modifier} visibility constants.
     * @return The parameter value with the higher visibility.
     * @since 3.9
     */
    public static int getHigherVisibility(int visibility1, int visibility2) {
        if (isHigherVisibility(visibility1, visibility2))
            return visibility1;
        else
            return visibility2;
    }

    public static int clearAccessModifiers(int flags) {
        return clearFlag(Modifier.PROTECTED | Modifier.PUBLIC | Modifier.PRIVATE, flags);
    }

    public static int clearFlag(int flag, int flags) {
        return flags & ~flag;
    }
}