| /******************************************************************************* |
| * Copyright (c) 2000, 2017 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Rabea Gransberger <rgransberger@gmx.de> - [quick fix] Fix several visibility issues - https://bugs.eclipse.org/394692 |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.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) { |
| return Modifier.isDefault(method.getModifiers()); |
| } |
| |
| 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.isPrivate(flags) && !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 (null != visibilityString) |
| switch (visibilityString) { |
| case VISIBILITY_STRING_PACKAGE: |
| return 0; |
| case VISIBILITY_STRING_PRIVATE: |
| return Modifier.PRIVATE; |
| case VISIBILITY_STRING_PROTECTED: |
| return Modifier.PROTECTED; |
| case VISIBILITY_STRING_PUBLIC: |
| return Modifier.PUBLIC; |
| default: |
| break; |
| } |
| 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; |
| } |
| } |